Create and Manage AWS IAM User Using Ansible
So, let's start with IAM User. As I mentioned on the Part 1, IAM is the first service you need after you created an AWS (root) account. It's really not secure to use or share root account for any reason. Don't do that!
Now, we're going to create IAM user along with the login profile and also the access key (optional). Then, in case you need to create some IAM users because your company has new employees and need access through AWS. Here we're gonna use ansible. That's the main point of using ansible here. We can use it for multiple tasks to create multiple users just in one click! Wow, how is it going? We just need to play with variable and tag!
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
The task above will create 4 new users. As we can see I also provide 4 different tags for different use case. The tags will give us freedom to choose which tasks we want to run. For example, I just wanna create user only without any credentials. So I'll just go with the iam_user_only
tag. Then, I wanna create user with 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
As we can see above, for access key I combine it with shell command. Actually there's the 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
But since we need the access key and secret access key information as well, so I'll go with first option that going with 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 combine 3 tasks to create 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
Now, I'll run playbook with all the tasks above using iam_user_new
tag to create 4 new users along with password and access key.
$ ansible-playbook -i host.yml iam.yml -t iam_user_new
PLAY [iam] *************************************************************************
TASK [create user] *****************************************************************
changed: [localhost] => (item=nurul)
changed: [localhost] => (item=rama)
changed: [localhost] => (item=beny)
changed: [localhost] => (item=rahman)
TASK [create user's key] ***********************************************************
changed: [localhost] => (item={'name': 'nurul'})
changed: [localhost] => (item={'name': 'rama'})
changed: [localhost] => (item={'name': 'beny'})
changed: [localhost] => (item={'name': 'rahman'})
TASK [list user's key] *************************************************************
changed: [localhost]
TASK [debug] ***********************************************************************
ok: [localhost] => {
"list_key.stdout_lines": [
" \"UserName\": \"nurul\"",
" \"AccessKeyId\": \"AKIAZ44MXOFLL5MRZWON\"",
" \"SecretAccessKey\": \"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\"",
" \"UserName\": \"rama\"",
" \"AccessKeyId\": \"AKIAZ44MXOFLL36LYJKV\"",
" \"SecretAccessKey\": \"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\"",
" \"UserName\": \"beny\"",
" \"AccessKeyId\": \"AKIAZ44MXOFLCMV33DHV\"",
" \"SecretAccessKey\": \"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\"",
" \"UserName\": \"rahman\"",
" \"AccessKeyId\": \"AKIAZ44MXOFLDJASSSVD\"",
" \"SecretAccessKey\": \"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\""
]
}
TASK [create user's password] ******************************************************
changed: [localhost] => (item={'name': 'nurul', 'pass': 'passwordup2U!'})
changed: [localhost] => (item={'name': 'rama', 'pass': 'passwordup2U!'})
changed: [localhost] => (item={'name': 'beny', 'pass': 'passwordup2U!'})
changed: [localhost] => (item={'name': 'rahman', 'pass': 'passwordup2U!'})
Note*: Please don't show the access keys to anyone else. This is just an example that I'm going to delete later.
After running the tasks above, 4 users will have password and access key along with them. Remember that reset password is required for each user, let's check!
It works. The reset password instruction comes up after we enter the password.
4. Create User and Attach Managed Policy
In addition to create users, we can also create user and attach a managed policy. Well, this is not the best practice but here I'm gonna 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
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': 'aira', 'policy': 'arn:aws:iam::aws:policy/IAMFullAccess'})
Alright, now we have one more user named aira with IAMFullAccess
policy attached. Let's check!
- Create access key for user aira. Remember to update the loop's value of access key's task and use the specific tag when you're running the playbook. Don't forget to comment any users that have been created before! Because if not, ansible will create 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
$ ansible-playbook -i host.yml iam.yml -t iam_user_key_only
PLAY [iam] *************************************************************************
TASK [create user's key] ***********************************************************
changed: [localhost] => (item={'name': 'aira'})
$ cat key_list.txt | grep -A3 aira | grep -v Status
"UserName": "aira",
"AccessKeyId": "AKIAZ44MXOFLNSZ6RO3F",
"SecretAccessKey": "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"
- Setup IAM User. We can add
--profile
if we don't use it as default user.
$ aws configure --profile aira
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 aira
[aira]
aws_access_key_id = AKIAZ44MXOFLNSZ6RO3F
aws_secret_access_key = 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
- Check the policy access:
$ aws iam create-user --user-name test --profile aira | grep UserName
"UserName": "test",
$ aws iam delete-user --user-name test --profile aira
$ aws iam get-user --user-name test --profile aira
An error occurred (NoSuchEntity) when calling the GetUser operation: The user with name test cannot be found.
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