Since Part 2, I've mentioned policies such as what's the best practice to attach policy and more. Now, we will discuss Identity-based policy which consists of 2 categories: Managed policy and Inline policy.
The managed policy is divided into 2 categories: AWS-managed policy and customer-managed policy. AWS-managed policy is a policy that AWS already provided and a customer-managed policy is the custom policy created by the customer itself based on what they need and it will be created as the new policy as well as the name.
Inline policy is a policy that you attach directly to an identity. It's a 1:1 trust relationship. When you delete the user, the inline policy will go along with it. This is not the best practice but here I'll just show you that we can do it with ansible.
For the IAM Inline Policy, we use community.aws.iam_policy
module. For the IAM Managed Policy, we use community.aws.iam_managed_policy
module.
Inline Policy
Create JSON file:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:ListUsers",
"iam:ListRoles"
],
"Resource": "*"
}
]
}
Task:
- name: create inline policy
community.aws.iam_policy:
iam_type: user
iam_name: "{{ item.user }}"
policy_name: "{{ item.policy }}"
state: present
policy_json: "{{ item.template }}"
loop:
- { user: "{{ user6 }}", policy: IAMListUsers_Roles, template: "{{ lookup('template', 'inline_policy.json.j2') }}" }
tags:
- iam_policy_new_inline
Before we run the playbook, we need an IAM user to be used. I'll create one more along with the access key. Here are the updated tasks:
- name: create user
community.aws.iam_user:
name: "{{ item }}"
state: present
loop:
# - "{{ user1 }}"
# - "{{ user2 }}"
# - "{{ user3 }}"
# - "{{ user4 }}"
- "{{ user6 }}"
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
- 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 }}" }
- { name: "{{ user6 }}" }
tags:
- iam_user_new
- iam_user_key
- iam_user_key_only
$ ansible-playbook -i host.yml iam.yml -t iam_user_key
PLAY [iam] *********************************************************************
TASK [create user] *************************************************************
changed: [localhost] => (item=name6)
TASK [create user's key] *******************************************************
changed: [localhost] => (item={'name': 'name6'})
Then, now we're ready to run the playbook:
$ ansible-playbook -i host.yml iam.yml -t iam_policy_new_inline
PLAY [iam] *********************************************************************
TASK [create inline policy] ****************************************************
changed: [localhost] => (item={'user': 'name6', 'policy': 'IAMListUsers_Roles', 'template': {'Version': '2012-10-17', 'Statement': [{'Effect': 'Allow', 'Action': ['iam:ListUsers', 'iam:ListRoles'], 'Resource': '*'}]}})
Check if the policy works! (Please set up the new user as a secondary IAM user first by running aws configure --profile name6
on the localhost. The access key and secret access key are stored in the file named key_list.txt
)
$ aws iam list-users --profile name6 | grep UserName
"UserName": "name5",
"UserName": "name3",
"UserName": "name6",
"UserName": "name1",
"UserName": "name4",
"UserName": "name2",
$ aws iam list-roles --profile name6 | grep RoleName
"RoleName": "aws-ec2-spot-fleet-tagging-role",
"RoleName": "AWSServiceRoleForAmazonElasticFileSystem",
"RoleName": "AWSServiceRoleForSupport",
"RoleName": "AWSServiceRoleForTrustedAdvisor",
"RoleName": "EC2DemoRole",
"RoleName": "IAM",
"RoleName": "IAM_Policy",
$ aws iam list-groups --profile name6
An error occurred (AccessDenied) when calling the ListGroups operation: User: arn:aws:iam::0123456789:user/name6 is not authorized to perform: iam:ListGroups on resource: arn:aws:iam::0123456789:group/
As we can see, user name6
is only allowed to list users and roles as mentioned in the inline policy document.
Managed Policy
Create JSON file:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "iam:GetUser",
"Resource": "*"
}
]
}
Task:
- name: create managed policy
community.aws.iam_managed_policy:
policy_name: "{{ item.name }}"
policy: "{{ item.policy }}"
state: present
loop:
- { name: IAMGetUser_Only, policy: "{{ lookup('template', 'managed_policy.json.j2') }}" }
tags:
- iam_policy_new_managed
Run the playbook:
$ ansible-playbook -i host.yml iam.yml -t iam_policy_new_managed
PLAY [iam] *********************************************************************
TASK [create managed policy] ***************************************************
changed: [localhost] => (item={'name': 'IAMGetUser_Only', 'policy': {'Version': '2012-10-17', 'Statement': [{'Effect': 'Allow', 'Action': 'iam:GetUser', 'Resource': '*'}]}})
The task above only creates a managed policy. To attach it to an IAM group and user, I'll use the same task as before. I just need to add new value and comment on the existing one, should look like this:
- name: create group and add existing users as members
community.aws.iam_group:
name: "{{ item.name }}"
state: present
users: "{{ item.members }}"
loop:
# - { name: "{{ group1 }}", members: ["{{ user1 }}","{{ user2 }}"] }
- { name: "{{ group1 }}", members: "{{ user4 }}" }
tags:
- iam_group_new_members
- 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 }
- { name: "{{ user3 }}", policy: arn:aws:iam::0123456789:policy/IAMGetUser_Only }
tags:
- iam_user_new_policy
- name: create group + attach managed policy
community.aws.iam_group:
name: "{{ item.name }}"
managed_policies: "{{ item.policy }}"
state: present
loop:
# - { name: "{{ group2 }}", policy: arn:aws:iam::aws:policy/IAMReadOnlyAccess }
- { name: "{{ group1 }}", policy: arn:aws:iam::0123456789:policy/IAMGetUser_Only }
tags:
- iam_group_new_policy
Then, I'll run the existing playbook with multiple tags.
$ ansible-playbook -i host.yml iam.yml -t "iam_user_new_policy, iam_group_new_policy, iam_group_new_members"
PLAY [iam] *********************************************************************
TASK [create group and add existing users as members] **************************
changed: [localhost] => (item={'name': 'developer', 'members': 'name4'})
TASK [create a user and attach a managed policy] *******************************
changed: [localhost] => (item={'name': 'name3', 'policy': 'arn:aws:iam::0123456789:policy/IAMGetUser_Only'})
TASK [create group + attach managed policy] ************************************
changed: [localhost] => (item={'name': 'developer', 'policy': 'arn:aws:iam::0123456789:policy/IAMGetUser_Only'})
The tasks above attach policy directly to user name3
and to group developer, also add user name4
into the group. So, the user name3
and all developer group members have the same policy that is IAMGetUser_Only
. Check if the policy works:
$ aws iam get-user --user-name name1 --profile name3 | grep UserName
"UserName": "name1",
$ aws iam get-user --user-name name1 --profile name4 | grep UserName
"UserName": "name1",
$ aws iam list-users --profile name3
An error occurred (AccessDenied) when calling the ListUsers operation: User: arn:aws:iam::0123456789:user/name3 is not authorized to perform: iam:ListUsers on resource: arn:aws:iam::0123456789:user/
$ aws iam list-users --profile name4
An error occurred (AccessDenied) when calling the ListUsers operation: User: arn:aws:iam::0123456789:user/name4 is not authorized to perform: iam:ListUsers on resource: arn:aws:iam::0123456789:user/
As we can see, the users can get operation but not for the list.
So, we already reached the end of the IAM section. In the next part, we will delete all the things we just created from Part 2 till Part 5. It's optional but in case you need it, I'll show you. Let's move to the last part of this series!
References:
Top comments (0)