DEV Community

Nurul Ramadhona for AWS Community Builders

Posted on • Edited on

Create and Manage AWS IAM Role Using Ansible

As I mentioned before, attaching the policy directly to the IAM user is not the best practice. As an option, we can use the IAM User Group to manage policies at the group level. Now, how if we need unusual and temporary access with specific permissions to any resources, either as an identity such as IAM User or as another resource like from EC2 for example? Then, the IAM Role is the answer.

Just like IAM User, IAM Role can delegate permissions or access to other identities or other resources as well. IAM Role decides who can do what in AWS but it's a little bit different with IAM User cause we don't need any credentials to get access, or in the IAM role it's mentioned as to assume the role. We don't need a password or access key.

For the IAM Role, we use community.aws.iam_role module.

Create Role

In this section, we will only set who can assume the role.

Create a file named role_policy.json as the trust document (please replace 0123456789 with your own account ID).

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Principal": { "AWS": "arn:aws:iam::0123456789:user/name5" },
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Task:

    - name: create new role
      community.aws.iam_role:
        name: "{{ item.name }}"
        assume_role_policy_document: "{{ item.file }}"
      loop: 
        - { name: IAM, file: "{{ lookup('file','role_policy.json') }}" }
      tags:
        - iam_role_new
Enter fullscreen mode Exit fullscreen mode

Run the playbook:

$ ansible-playbook -i host.yml iam.yml -t iam_role_new

PLAY [iam] *********************************************************************

TASK [create new role] *********************************************************
changed: [localhost] => (item={'name': 'IAM', 'file': {'Version': '2012-10-17', 'Statement': [{'Effect': 'Allow', 'Action': 'sts:AssumeRole', 'Principal': {'AWS': 'arn:aws:iam::0123456789:user/name5'}}]}})
Enter fullscreen mode Exit fullscreen mode

The task will allow only user name5 can assume the role. Let's check!

Get role's ARN:

$ aws iam list-roles --query "Roles[?RoleName == 'IAM'].[RoleName, Arn]"
[
    [
        "IAM",
        "arn:aws:iam::0123456789:role/IAM"
    ]
]
Enter fullscreen mode Exit fullscreen mode

Assume role:

$ aws sts assume-role --role-arn "arn:aws:iam::0123456789:role/IAM" --role-session-name IAM-Session --profile name5
{
    "Credentials": {
        "AccessKeyId": "ASIAZ44MXOFLODACDGT6",
        "SecretAccessKey": "9Mo0mlic0SFT+iXfjJLZVF2KcOs5AnkOSRTafkhE",
        "SessionToken": "FwoGZXIvYXdzEFUaDFsU3R/5e1qeVRy4gyKvARr+4uMtDxXGZgyuqld3I32GuaEz+8v8UL94h/cQh3sDEzSu+5p5GPkxwR8oCriLeG8UAzJL3fcbA81408bH/qLj352c64Bdi+OBsDV5kuios/fUHVmWwkq8yHRBomGb1kKPky7pJi+e7ornjMdYxveiYnE0oUacEj5LIbg3gWYr67e+4/+5yz0ClkynDVDycO6V0el+AVSCf9xstiQOZQHYiIf+fdUka5PVBAlXkB0op/SJkgYyLdUBukFyHuM4Hqd3et/N6HCLuOs7v63qINUooo/CwJIq35Kx3z/E7mi3BJn7mw==",
        "Expiration": "2022-03-29T04:16:55Z"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROAZ44MXOFLNNFVT2XDZ:IAM-Session",
        "Arn": "arn:aws:sts::0123456789:assumed-role/IAM/IAM-Session"
    }
}
Enter fullscreen mode Exit fullscreen mode

From the command above, we need some information to be configured. Those are Access Key ID, Secret Access Key, and Session Token. Since we use a secondary IAM user on the local device, we need to set the Profile as well.

$ export AWS_PROFILE=name5
$ export AWS_ACCESS_KEY_ID=ASIAZ44MXOFLODACDGT6
$ export AWS_SECRET_ACCESS_KEY=9Mo0mlic0SFT+iXfjJLZVF2KcOs5AnkOSRTafkhE
$ export AWS_SESSION_TOKEN=FwoGZXIvYXdzEFUaDFsU3R/5e1qeVRy4gyKvARr+4uMtDxXGZgyuqld3I32GuaEz+8v8UL94h/cQh3sDEzSu+5p5GPkxwR8oCriLeG8UAzJL3fcbA81408bH/qLj352c64Bdi+OBsDV5kuios/fUHVmWwkq8yHRBomGb1kKPky7pJi+e7ornjMdYxveiYnE0oUacEj5LIbg3gWYr67e+4/+5yz0ClkynDVDycO6V0el+AVSCf9xstiQOZQHYiIf+fdUka5PVBAlXkB0op/SJkgYyLdUBukFyHuM4Hqd3et/N6HCLuOs7v63qINUooo/CwJIq35Kx3z/E7mi3BJn7mw==
Enter fullscreen mode Exit fullscreen mode

Then, check the identity! It will change to the role session.

$ aws sts get-caller-identity

{
    "UserId": "AROAZ44MXOFLNNFVT2XDZ:IAM-Session",
    "Account": "0123456789",
    "Arn": "arn:aws:sts::0123456789:assumed-role/IAM/IAM-Session"
}
Enter fullscreen mode Exit fullscreen mode

Let's see what we can do with this role!

$ aws iam list-users

An error occurred (AccessDenied) when calling the ListUsers operation: User: arn:aws:sts::0123456789:assumed-role/IAM/IAM-Session is not authorized to perform: iam:ListUsers on resource: arn:aws:iam::0123456789:user/
Enter fullscreen mode Exit fullscreen mode

As we can see, we can't do anything because the role doesn't have policy attached. To remove the role session, we need to do unset:

$ unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_PROFILE
Enter fullscreen mode Exit fullscreen mode

Create Role with Policy Attached

Since we can't do anything with the first role. Now, I'll create a second role and attach a policy to it.

Task:

    - name: create new role and attach managed policy
      community.aws.iam_role:
        name: "{{ item.name }}"
        assume_role_policy_document: "{{ item.file }}"
        managed_policies: "{{ item.policy }}"
      loop: 
        - { name: IAM_Policy, file: "{{ lookup('file','role_policy.json') }}", policy: arn:aws:iam::aws:policy/IAMReadOnlyAccess }
      tags:
        - iam_role_new_policy
Enter fullscreen mode Exit fullscreen mode

Run the playbook:

$ ansible-playbook -i host.yml iam.yml -t iam_role_new_policy

PLAY [iam] *********************************************************************

TASK [create new role and attach managed policy] *******************************
changed: [localhost] => (item={'name': 'IAM_Policy', 'file': {'Version': '2012-10-17', 'Statement': [{'Effect': 'Allow', 'Action': 'sts:AssumeRole', 'Principal': {'AWS': 'arn:aws:iam::0123456789:user/name5'}}]}, 'policy': 'arn:aws:iam::aws:policy/IAMReadOnlyAccess'})
Enter fullscreen mode Exit fullscreen mode

The task will allow only user name5 can assume the role and get permission to IAMReadOnlyAccess policy. Let's check!

Get role's ARN:

$ aws iam list-roles --query "Roles[?RoleName == 'IAM_Policy'].[RoleName, Arn]"
[
    [
        "IAM_Policy",
        "arn:aws:iam::0123456789:role/IAM_Policy"
    ]
]
Enter fullscreen mode Exit fullscreen mode

Assume the role:

$ aws sts assume-role --role-arn "arn:aws:iam::0123456789:role/IAM_Policy" --role-session-name IAM_Policy-Session --profile name5
{
    "Credentials": {
        "AccessKeyId": "ASIAZ44MXOFLDW7ZQUNF",
        "SecretAccessKey": "4NVB0QMGN7HctKAr4HAE2WTPm1NBimC7NT84nsoh",
        "SessionToken": "FwoGZXIvYXdzEFUaDN/9s00S+FEqW1CkTyK2ATx97BWnjATT3/b74RcWwWIJW4BeIM6hUPn5J5R0N1bzDtkV4d50wXA2M1Vd0v6Ao2U5UX2ntJreYjhcKg/TvuIPmQKJ+0plbLt38Sp0mmj6HJbnK46h0+Zt9sJgLVVwmBf0y55dAoHe8xtlT3n3du5ll2nUFFQl9sO0TtVn3PbKYdyEoqzbTs/HBtIpef52b4XTyAhe6u7CPMP5nQwwdDAJdiLD3W64sqqwO/AgkMI6RWQXbm3uKN78iZIGMi21vsUxiS7K9B9CuZW/ZIFoOIkFDyEQxMx9MtEwTVFm1JFJ+KkIx1gPZEFhalY=",
        "Expiration": "2022-03-29T04:34:54Z"
    },
    "AssumedRoleUser": {
        "AssumedRoleId": "AROAZ44MXOFLGEBMCVQLQ:IAM_Policy-Session",
        "Arn": "arn:aws:sts::0123456789:assumed-role/IAM_Policy/IAM_Policy-Session"
    }
}
Enter fullscreen mode Exit fullscreen mode
$ export AWS_PROFILE=name5
$ export AWS_ACCESS_KEY_ID=ASIAZ44MXOFLDW7ZQUNF
$ export AWS_SECRET_ACCESS_KEY=4NVB0QMGN7HctKAr4HAE2WTPm1NBimC7NT84nsoh
$ export AWS_SESSION_TOKEN=FwoGZXIvYXdzEFUaDN/9s00S+FEqW1CkTyK2ATx97BWnjATT3/b74RcWwWIJW4BeIM6hUPn5J5R0N1bzDtkV4d50wXA2M1Vd0v6Ao2U5UX2ntJreYjhcKg/TvuIPmQKJ+0plbLt38Sp0mmj6HJbnK46h0+Zt9sJgLVVwmBf0y55dAoHe8xtlT3n3du5ll2nUFFQl9sO0TtVn3PbKYdyEoqzbTs/HBtIpef52b4XTyAhe6u7CPMP5nQwwdDAJdiLD3W64sqqwO/AgkMI6RWQXbm3uKN78iZIGMi21vsUxiS7K9B9CuZW/ZIFoOIkFDyEQxMx9MtEwTVFm1JFJ+KkIx1gPZEFhalY=
Enter fullscreen mode Exit fullscreen mode
$ aws sts get-caller-identity
{
    "UserId": "AROAZ44MXOFLGEBMCVQLQ:IAM_Policy-Session",
    "Account": "0123456789",
    "Arn": "arn:aws:sts::0123456789:assumed-role/IAM_Policy/IAM_Policy-Session"
}
Enter fullscreen mode Exit fullscreen mode

Now, let's do something with that policy given to the role:

$ aws iam get-user --user-name name1 | grep UserName
        "UserName": "name1",

$ aws iam create-user --user-name test

An error occurred (AccessDenied) when calling the CreateUser operation: User: arn:aws:sts::0123456789:assumed-role/IAM_Policy/IAM_Policy-Session is not authorized to perform: iam:CreateUser on resource: arn:aws:iam::0123456789:user/test
Enter fullscreen mode Exit fullscreen mode

As we can see, we can do get-user but not for create-user. So, the role's policy works.

Let's back to normal IAM User by doing unset!

$ unset AWS_PROFILE AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN
Enter fullscreen mode Exit fullscreen mode

That's it for the IAM Role. Let's continue to Part 5!

Reference:

https://docs.ansible.com/ansible/latest/collections/community/aws/iam_role_module.html

Top comments (0)