An IAM role is a container for a policy. Using IAM roles for EC2 instances allows for easy management of access keys and for their automatic rotation, that is, Amazon rotates the keys several times a day without requiring any specific action from your end. Hence, you should not have the access keys as a part of the AMI or your application, as their rotation becomes unnecessarily complicated. We just need to create an IAM role, assign permissions to the role, and then launch the EC2 instances to make this work.
After creating a role, you will also need to create a policy and assign it to the newly created role. For example, if an EC2 instance needs access to other AWS services, such as S3 buckets or DynamoDB tables, then you can create a role for it. You will assign the role permissions that allow access to S3/DynamoDB, and finally launch the EC2 instance with that role. You can create one role and attach it to multiple EC2 instances.
Execute the following commands to create a role for an AWS service. You will need to specify who can assume this role in the JSON document.
S3RoleForEC2.json
:{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" } }
S3RoleForEC2
role using the JSON document:$ aws iam create-role --role-name S3RoleForEC2 --assume-role-policy-document file://F:\S3RoleForEC2.json
After creating a role, you need to assign permissions to it. For example, in our sample policy, we are allowing access to an S3 bucket named appconfiguration
from the EC2 instance.
S3RoleForEC2Policy.json
.{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListBucket" ], "Resource": "arn:aws:s3:::appconfiguration" }, { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:GetObject", "s3:DeleteObject" ], "Resource": "arn:aws:s3:::appconfiguration/*" } ] }
S3RoleForEC2
role.$ aws iam put-role-policy --role-name S3RoleForEC2 --policy-name S3RoleForEC2Policy --policy-document file://F:\S3RoleForEC2Policy.json
Execute the following commands to first create an instance profile, and then add the role to the instance profile.
Execute the following command to create an instance profile named S3RoleForEC2Profile
:
$ aws iam create-instance-profile --instance-profile-name S3RoleForEC2Profile
S3RoleForEC2
to the instance profile named S3RoleForEC2Profile
.$ aws iam add-role-to-instance-profile --instance-profile-name S3RoleForEC2Profile --role-name S3RoleForEC2
After creating the role you can launch your EC2 instance with IAM roles. Execute the following command to create the EC2 instance with the instance profile created earlier. Before executing the command, you should have already created the key pairs, security groups, VPC, and subnet.
$ aws ec2 run-instances --image-id ami-7e2c612c --count 1 --instance-type t2.micro --key-name MyKeyPair --security-group-ids sg-ad70b8c8 --subnet-id subnet-aed11acb --iam-instance-profile Name=S3RoleForEC2Profile
Execute the following command to get the list of objects in the appconfiguration
bucket:
s3 ls s3://appconfiguration/
If you try to access other buckets, you should get an access denied message. In addition, test uploading and deleting files in the appconfiguration
bucket from your EC2 instance.
As a first step, we create an IAM role. In order to do that, we create a policy containing the requisite permissions and specify the policy in the create role command. If you use the AWS console for creating role, AWS automatically creates the instance profile with same name as role. But if you a create role from command line, you have to create the instance profile yourself. Hence, we create an instance profile and add the role to it. You have to provide both role name and instance profile name. Finally, we launch the instance specifying the image, number of instances to create, type of EC2 instances, key/pair name, security group IDs, and the subnet, as a good practice test and verify the installation.
Following a least privilege approach, we would typically create and assign roles to provide appropriate access to an application running on an EC2 instance rather than to the instance itself.
Roles are also used to share access without sharing the actual access credentials. This is particularly useful for giving a user temporary access to perform a task and in cases where you want to provide cross-account access. For example, if you have separate AWS dev and prod accounts, then you can use roles to give your dev users temporary credentials to access the prod environment.
In order to implement these use cases, you need to create a new role and use policies to specify who can assume this role and what they can do (after they assumed this role). After the role is created, you just need to share the role name and the account ID with the user. For example, if you want to give a specific developer belonging to the dev account read access to an RDB database in the production account. For this, you will need to define a new role name and specify in the policy that IAM users from your dev account are allowed read-only access to the resource. The developer's access policy (in the dev account) is also changed to allow him/her to assume the newly defined role in the production account. When developer requests access to the production database using his/her own credentials, and receives a set of temporary credentials to enable the access to the production database.