DEV Community 👩‍💻👨‍💻

Nurul Ramadhona for AWS Community Builders

Posted on • Updated on

Create and Manage AWS IAM Role Using Ansible

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

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

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


Create Role
In this section, we'll only set who can assume the role.

Create 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/aira" },
        }
    ]
}
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/aira'}}]}})
Enter fullscreen mode Exit fullscreen mode

The task will allow only user aira 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 aira
{
    "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 secondary IAM user on the local device, we need to set the Profile as well.

$ export AWS_PROFILE=aira
$ 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'll 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'm going to create second role and attach 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/aira'}}]}, 'policy': 'arn:aws:iam::aws:policy/IAMReadOnlyAccess'})
Enter fullscreen mode Exit fullscreen mode

The task will allow only user aira 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 aira
{
    "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=aira
$ 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 nurul | grep UserName
        "UserName": "nurul",

$ 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 IAM Role. Let's continue to Part 5 for IAM Policy.

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

Top comments (0)

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.