What are IAM Roles?
Using IAM we can define who can access which resource in EC2, RDS, S3 and all the other AWS services. In addition, IAM lets us define a set of temporary permissions that are not attached or do not belong to users or groups. These permissions are called Roles and can be assumed by applications or AWS services to enable programmatic access to defined resources.
IAM roles are a secure way to grant permissions to entities that you trust. Examples of entities include the following:
- IAM user in another account
- Application code running on an EC2 instance that needs to perform actions on AWS resources
- An AWS service that needs to act on resources in your account to provide its features
- Users from a corporate directory who use identity federation with SAML
IAM roles issue keys that are valid for short duration, making them a more secure way to grant access.
Related: What is IAM in AWS and How to Create user in IAM
Why IAM Role?
There is wide scope that we might need this if your application within the EC2 instance makes a lot of API calls with other AWS services. One good example I can think of is your application accessing S3 bucket to retrieve files or your EC2 instance requiring access to cloudwatch to send log data for customized metrics. If your EC2 instance does not assume any role, then you need to pass the API keys within your application (SDK) to access the relevant service.
This approach becomes challenging when you securely distribute credentials to each instance, especially those that AWS creates on your behalf, such as Spot instances or instances in Auto Scaling groups. Also this becomes a problem when you rotate the keys since you will need to update it in all the instance.
In order to overcome such a problem, we can make use of EC2 Roles.
Let’s see the steps on how to create and attach an IAM Role while launching an EC2 instance.
Note: You can’t assign a role to an existing instance; you can only specify a role while launching a new instance.
Create a Role
- Login to AWS console and select Identity & Access Management (IAM).
- Click on Role and select “Create Role”
- Click on “Select” for “Amazon EC2” and its use case and hit Next Step
- In the next step it will prompt you to attach a policy. You can skip this step and attach a custom policy later on if you hadn’t created one. Or you can choose from the list of generic policies that are predefined.
- Give a name for the role and click “Next Step”. We are naming it as “FoxuTech” for this example. Add description and review your selection and “Create role”
We have successfully created a role and you can view our newly created role under Roles section.
Attach the role while launching an EC2 Instance
In this step let’s see, how we can attach the newly created role while launching an EC2 instance. I have skipped the first few steps of creating an EC2 instance since that is pretty straight forward.
At Step 3 of creating a new EC2 Instance, you’ll be configuring your instance details. Click the drop down next to IAM role option and you’ll see the name of the role that we created. Select the role and carry on with the usual procedure to launch an instance.
And that’s it!! We have attached an IAM EC2 Role for our new instance. We can further create our own custom policies (like accessing a specific bucket in S3) and attach it to this role. Through this way, we can avoid passing API keys within our code and server.
Implementation through command line
You can follow the below steps for implementing the above using command line.
- Create the following trust policy and save it in a text file named ec2-role-trust-policy.json (This step is equivalent to step 4 – Select Role Type that we followed above)
{ "Version": "2017-09-11", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" } ] }
- Create the “FoxuTech” role and specify the trust policy that we created above.
# aws iam create-role --role-name foxutech --assume-role-policy-document file://ec2-role-trust-policy.json
{ "Role": { "AssumeRolePolicyDocument": { "Version": "2017-09-11", "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" } } ] }, "RoleId": "DWHSHC2JSH32DEXAMPLE", "CreateDate": "2017-09-12T23:46:37.247Z", "RoleName": "s3access", "Path": "/", "Arn": "arn:aws:iam::123456789012:role/s3access" } }
And we are done. We can further assign relevant policies to this role.