DEV Community

Nurul Ramadhona for AWS Community Builders

Posted on • Edited on

Create and Manage AWS IAM User Using Ansible

So, let's start with the IAM User. As I mentioned in Part 1, IAM is the first service we need after we create an AWS (root) account. It's really unsafe to use a root account too often for any reason. Don't do that!

Now, we will create an IAM user along with the login profile and the access key (optional). Then, in case you need to create some IAM users because your company has new employees and needs access through AWS. Here we will use Ansible. That's the main point of using Ansible here, we can use it for multiple tasks to create multiple users by just pressing Enter once! How is it going? We just need to play with variables and tags!

For IAM User, we use community.aws.iam_user module.

1. Create User

    - name: create user
      community.aws.iam_user:
        name: "{{ item }}"
        state: present
      loop: 
        - "{{ user1 }}"
        - "{{ user2 }}"
        - "{{ user3 }}"
        - "{{ user4 }}"
      tags:
        - iam_user_new ### create user + pass + key
        - iam_user_only ### create user only
        - iam_user_key ### create user + key
        - iam_user_pass ### create user + pass
Enter fullscreen mode Exit fullscreen mode

The task above will create 4 new users. As we can see I also provide 4 different tags for different use cases. The tags will give us the freedom to choose which tasks we want to run. For example, I just wanna create a user only without any credentials. So I'll just go with the iam_user_only tag. Then, I wanna create a user with a password only. I'll go with the iam_user_pass tag. That's how we play with the tags.

2. Create User's Access Key

    - name: create user's key
      shell: 'aws iam create-access-key --user-name "{{ item.name }}" >> key_list.txt'
      loop: 
        - { name: "{{ user1 }}" }
        - { name: "{{ user2 }}" }
        - { name: "{{ user3 }}" }
        - { name: "{{ user4 }}" }
      tags:
        - iam_user_new
        - iam_user_key
        - iam_user_key_only

    - name: list user's key
      shell: 'cat key_list.txt | grep "UserName\|AccessKeyId\|SecretAccessKey" | sed "s/,$//"'
      register: list_key
      tags:
        - iam_user_new
        - iam_user_key

    - debug:
        var: list_key.stdout_lines
      tags:
        - iam_user_new
        - iam_user_key
Enter fullscreen mode Exit fullscreen mode

As we can see above, for the access key I combine it with a shell command. Actually, there's a module to create it. It's community.aws.iam_access_key and looks like this.

    - name: create user's key
      community.aws.iam_access_key:
        user_name: "{{ item }}"
        state: present
      loop: 
        - { name: "{{ user1 }}" }
        - { name: "{{ user2 }}" }
        - { name: "{{ user3 }}" }
        - { name: "{{ user4 }}" }
      tags:
        - iam_user_new
        - iam_user_key
Enter fullscreen mode Exit fullscreen mode

But since we need the access key and secret access key information as well, I'll go with the first option going with the shell command because the second one is not giving us the output. Then since we use CLI, we can't download the access key file directly like we can do through the Console. So I combined 3 tasks to create an access key, save the output to a file, and show the values we need. That's why!

3. Create User's Password

    - name: create user's password
      command: aws iam create-login-profile --user-name "{{ item.name }}" --password "{{ item.pass }}" --password-reset-required
      loop: 
         - { name: "{{ user1 }}", pass: "{{ temp_pass }}" }
         - { name: "{{ user2 }}", pass: "{{ temp_pass }}" }
         - { name: "{{ user3 }}", pass: "{{ temp_pass }}" }
         - { name: "{{ user4 }}", pass: "{{ temp_pass }}" }
      tags:
        - iam_user_new
        - iam_user_pass
Enter fullscreen mode Exit fullscreen mode

Now, I'll run a playbook with all the tasks above using iam_user_new tag to create 4 new users along with a password and access key.

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

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

TASK [create user] *****************************************************************
changed: [localhost] => (item=name1)
changed: [localhost] => (item=name2)
changed: [localhost] => (item=name3)
changed: [localhost] => (item=name4)

TASK [create user's key] ***********************************************************
changed: [localhost] => (item={'name': 'name1'})
changed: [localhost] => (item={'name': 'name2'})
changed: [localhost] => (item={'name': 'name3'})
changed: [localhost] => (item={'name': 'name4'})

TASK [list user's key] *************************************************************
changed: [localhost]

TASK [debug] ***********************************************************************
ok: [localhost] => {
    "list_key.stdout_lines": [
        "        \"UserName\": \"name1\"",
        "        \"AccessKeyId\": \"AKIAZ44MXOFLL5MRZWON\"",
        "        \"SecretAccessKey\": \"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\"",
        "        \"UserName\": \"name2\"",
        "        \"AccessKeyId\": \"AKIAZ44MXOFLL36LYJKV\"",
        "        \"SecretAccessKey\": \"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\"",
        "        \"UserName\": \"name3\"",
        "        \"AccessKeyId\": \"AKIAZ44MXOFLCMV33DHV\"",
        "        \"SecretAccessKey\": \"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\"",
        "        \"UserName\": \"name4\"",
        "        \"AccessKeyId\": \"AKIAZ44MXOFLDJASSSVD\"",
        "        \"SecretAccessKey\": \"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\""
    ]
}

TASK [create user's password] ******************************************************
changed: [localhost] => (item={'name': 'name1', 'pass': 'passwordup2U!'})
changed: [localhost] => (item={'name': 'name2', 'pass': 'passwordup2U!'})
changed: [localhost] => (item={'name': 'name3', 'pass': 'passwordup2U!'})
changed: [localhost] => (item={'name': 'name4', 'pass': 'passwordup2U!'})
Enter fullscreen mode Exit fullscreen mode

Note*: Please don't show the access keys to anyone else. This is just an example that I'll delete later.

After running the tasks above, 4 users will have a password and access key along with them. Remember that a reset password is required for each user, let's check!

Enter Password

Reset Password

It works. The reset password instruction comes up after we enter the password.

4. Create User and Attach Managed Policy

In addition to creating users, we can also create users and attach a managed policy. Okay, this is not the best practice but here I'll show you that we can do this with Ansible.

    - name: create a user and attach a managed policy
      community.aws.iam_user:
        name: "{{ item.name }}"
        managed_policies: "{{ item.policy }}"
        state: present
      loop: 
        - { name: "{{ user5 }}", policy: arn:aws:iam::aws:policy/IAMFullAccess }
      tags:
        - iam_user_new_policy
Enter fullscreen mode Exit fullscreen mode

Then, I'll run the playbook with iam_user_new_policy tag.

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

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

TASK [create a user and attach a managed policy] ***********************************
changed: [localhost] => (item={'name': 'name5', 'policy': 'arn:aws:iam::aws:policy/IAMFullAccess'})
Enter fullscreen mode Exit fullscreen mode

Alright, now we have one more user named name5 with IAMFullAccess policy is attached. Let's check!

  • Create an access key for the user name5.

    Remember to update the loop's value of the access key's task and use the specific tag when you're running the playbook. Don't forget to comment on any users that have been created before! If not, ansible will create a new access key for the existing users.

    - name: create user's key
      community.aws.iam_access_key:
        user_name: "{{ item }}"
        state: present
      loop: 
#        - { name: "{{ user1 }}" }
#        - { name: "{{ user2 }}" }
#        - { name: "{{ user3 }}" }
#        - { name: "{{ user4 }}" }
        - { name: "{{ user5 }}" }
      tags:
        - iam_user_new
        - iam_user_key
        - iam_user_key_only
Enter fullscreen mode Exit fullscreen mode
$ ansible-playbook -i host.yml iam.yml -t iam_user_key_only

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

TASK [create user's key] ***********************************************************
changed: [localhost] => (item={'name': 'name5'})
Enter fullscreen mode Exit fullscreen mode
$ cat key_list.txt | grep -A3 name5 | grep -v Status 
        "UserName": "name5",
        "AccessKeyId": "AKIAZ44MXOFLNSZ6RO3F",
        "SecretAccessKey": "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"
Enter fullscreen mode Exit fullscreen mode
  • Setup IAM User.

    We can add --profile if we don't use it as the default user.

$ aws configure --profile name5
AWS Access Key ID [None]: AKIAZ44MXOFLNSZ6RO3F
AWS Secret Access Key [None]: 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
Default region name [None]: 
Default output format [None]:

$ cat ~/.aws/credentials | grep -A2 name5
[name5]
aws_access_key_id = AKIAZ44MXOFLNSZ6RO3F
aws_secret_access_key = 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
Enter fullscreen mode Exit fullscreen mode
  • Check the policy access:
$ aws iam create-user --user-name test --profile name5 | grep UserName
        "UserName": "test",

$ aws iam delete-user --user-name test --profile name5

$ aws iam get-user --user-name test --profile name5

An error occurred (NoSuchEntity) when calling the GetUser operation: The user with name test cannot be found.
Enter fullscreen mode Exit fullscreen mode

It works. As we can see we can create and delete user.

That's it for the Part 2. Let's move to the Part 3 for IAM User Group.

Reference:

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

Top comments (0)