AWS IAM: Creating a Role
For more information on AWS IAM, visit aws.amazon.com
AWS Roles Description
AWS Identity and Access Management or IAM is the centralized service within AWS that handles Authentication for various AWS services. Generally when interacting with an AWS service, and the need to authenticate arises, there are generally 2 methods of authentication that a user can use in order to interact with various services in an authenticated manner. The first is to simply create an IAM user, and then to create access keys for that user. The user would either directly, or indirectly through a group, have a policy attached that would allow the user various access to various services. The problem with this type of authentication is that it requires that an Access Key ID and Secret Access Key are passed with each call via the SDK or CLI. If engineering an application that utilizes these keys, then it can become very easy for a developer to accidentally commit code to a potentially public location that also has your keys hard coded so that your various application components can talk to each other across services. If an unauthorized entity obtains those keys, then they will have the same level of access to spin up services on your behalf, costing you money and time when you discover the breach and have to recycle all of your keys. The second method, which is much more secure is to use AWS Roles. A Role is constructed the same as a user, where the role can have various access policies attached to it, but instead of requiring keys that can be accidentally made public, the role when assigned to a resource such as an EC2 instance will elevate the resources permissions much like a users permissions, allowing that resource to access other resources in AWS based on the permissions that you define by assigning policies, when creating the role. For example, if your application, running on EC2 requires access to S3, instead of having your application pass keys to gain access to S3, you can create a role instead, that will allow the EC2 instance, ReadOnly, ReadWrite or Admin access to S3 once it has assumed the role created to allow such access. You can also create custom policies that only allow certain, more granular actions on specific services. When the EC2 service is launched and the role is assumed by that EC2 instance, it now has the power defined in that role, thus giving it direct access to S3 without the need for any key passing. Roles should be constructed to give resources the least amount of privileges necessary to perform the functions that the resource needs to perform. By default you can have up to 1000 roles defined in your account.
Role Pre-Requisites
The only pre-requisite for creating a custom access policy is to have an active AWS account that you have access to and can log in to follow along with this tutorial.
Creating a Role from the Console
Roles are created as part of IAM, In order to create a role, we will need to first navigate to the IAM console within your AWS account.
1. Log into your AWS account:
Open a browser window and visit the AWS Console Page
2. Locate and navigate to the IAM Service:
From the top left side of the navigational menu bar, click on the Services menu, and then choose IAM by either navigating to the section of the listed services, or by typing the first few letters of the service name in the search box, and then choosing it from the filtered list.
3. Creating a Role:
From the IAM console dashboard, click on Roles in the right side navigational menu to see a list of all available roles. From the Roles view, click on the Add role button to start the process of creating a new role.
4. Choose the Role Service:
Next, we need to pick the service that this role will be used for. We can create roles that will be availalbe for EC2 instances, Lambda functions, S3 buckets, etc.. In this example we want to create a role that will allow an EC2 instance the ability to read and write objects to S3. So from the Select type of trusted entity section, choose AWS service (1), then from the list of available services, click on EC2. (2). Next, as EC2 can be used in a varity of ways, from the list of EC2 use cases at the bottom of the page, select the standard EC2 use case (3). Once everything has been selected, click on the Next: Permissions button (4).
5. Choose Polices:
Next we need to select what policies will be added to the role. The policies are the components that contain the permissions. You can think of a role as a collection of policies, the total sum of permissions given collectively by the policies attached to the role, are what define the roles ultimate permission set. In this case, as we simply want this role to just allow an EC2 instance the ability to have Read/Write access on the S3 service, we can use one of the Amazon pre-defined policies to accomplish our requirement, even if the policy isn't as granular as maybe we would like. Type S3 into the filter box, and select the policy named AmazonS3FullAccess. This policy will give any EC2 instance assigned this role, complete administrative access on S3. Normally we would want to pick a more restrictive policy, or create a custom policy, but to keep things simple, for now we will simply use the full access policy. Once selected, click on the Next:Review button.
Custom Policies
In the event that you can't find a policy that fits the use case that you are trying to accomplish, you can always create a custom policy that will give the role the exact permission sets desired. You can find additional information regarding creating policies here
6. Review Role:
Last, in the Review page, Type a name and description for your new role, and then click the Create role button. This will actually create the role.
7. Verify Role:
The last step in creating a role is to ensure that once the role was created, that it shows properly in the roles list. When you click the Create role button in the previous step, the role was created, and you were returned to the Roles IAM menu. From the Roles menu, Type a few letters of the name that you assigned to the role and verify that it shows up in the roles list. Once you have found your role, click on the role link to bring you to the role summary page.
8. Verify Instance Profile:
The last verification point is to look at the summary page of the new role, and because this role will be used by the EC2 service, we need to verify that the role has an Instance Profile ARN assigned to it. When assigning roles to an EC2 instance, the role itself doesn't technically get assigned to the EC2 instance. The Role gets assigned to the Instance Profile, and the Instance Profile gets assigned to the EC2 instance. Once we verify that the EC2 Instance Profile ARN section is populated then we have properly verified that our role was created successfully.
Instance Profile
If you use other means such as CloudFormation to create a role that will be utilized by an EC2 instance, ensure that you also include the resource section code block to create an instance profile or assign the role to an existing instance profile. If no instance profile is defined, the role will be created, however when you try to apply the role to an instance the role will NOT be available in the assignable roles list. EC2 doesn't directly apply roles to instances, it applies instance profiles, and roles are attached to those instance profiles. Without an instance profile, you will not be able to assign your role.
Creating a Role from the CLI
Now that we have walked through creating the role in the AWS console, lets walk through a quick example on how to create this same role using the AWS CLI.
1. Create the role:
First we need to create the role and associate the role trust policy of the role, to instantiate the role, use the following syntax:
Syntax:
aws iam create-role --path {PATH} \ --role-name {RoleName} \ --max-session-duration {Duration in Seconds} \ --description {"My Role Descripton Here"} \ --assume-role-policy-document {"Role InLine Trust Policy JSON"}
Example Request:
aws iam create-role --path / \ --role-name S3CLIRole \ --max-session-duration 3600 \ --description "This role will allow full access to S3 from an EC2 instances that assumes it." \ --assume-role-policy-document "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}"
Example Response:
{ "Role": { "Path": "/", "RoleName": "S3CLIRole", "RoleId": "ABCDEFGHIJ1234567KLM7", "Arn": "arn:aws:iam::123456789012:role/S3CLIRole", "CreateDate": "2018-06-29T14:42:11.638Z", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": [ "ec2.amazonaws.com" ] }, "Action": [ "sts:AssumeRole" ] } ] } } }
2. Attach Managed Policies:
Now that we have instantiated the role, we need to attach any managed policies to the role that we want, so that the role will grant the permisions for our use case. Use the following syntax to attached any managed policies to the new role.
Syntax:
aws iam attach-role-policy --role-name {RoleName} --policy-arn {Managed Policy ARN}
Example Request:
aws iam attach-role-policy --role-name S3CLIRole --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
Example Response:
None
3. Verify Role:
Next, we just just need to verify that the role was created successfully.
Syntax:
aws iam get-role --role-name {RoleName}
Example Request:
aws iam get-role --role-name S3CLIRole
Examle Response:
{ "Role": { "Path": "/", "RoleName": "S3CLIRole", "RoleId": "ABCDEFGHIJ1234567KLM7", "Arn": "arn:aws:iam::123456789012:role/S3CLIRole", "CreateDate": "2018-06-29T14:42:11Z", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }, "Description": "This role will allow full access to S3 from an EC2 instances that assumes it.", "MaxSessionDuration": 3600 } }
4. Verify Role Policies:
Next, verify that the role that was created successfully has the included managed policies that we attached to the role as well.
Syntax:
aws iam list-attached-role-policies --role-name {RoleName}
Example Request:
aws iam list-attached-role-policies --role-name S3CLIRole
Example Response:
{ "AttachedPolicies": [ { "PolicyName": "AmazonS3FullAccess", "PolicyArn": "arn:aws:iam::aws:policy/AmazonS3FullAccess" } ] }
5. Create an Instance Profile:
Now that our role has been created and verified, because this is an EC2 role, we also need to create an instance profile, and associate the new role with that profile. Again, the instance profile is what EC2 instances can be assigned, not roles directly. If the new role that we just created doesn't have an associated instance profile, then it will not be selectable as an applicable role in the EC2 console.
Instance Profile Naming
It is generally a good recommendation to name your Instance Profiles with the same name as the associated role. That way when assigning your Instance Profile, you can quickly reference the attached role via the Console or CLI.
Syntax:
aws iam create-instance-profile --instance-profile-name {InstanceProfileName}
Example Request:
aws iam create-instance-profile --instance-profile-name S3CLIRole
Example Response:
{ "InstanceProfile": { "Path": "/", "InstanceProfileName": "S3CLIRole", "InstanceProfileId": "ABCDEFGHIJ1234567KLM7", "Arn": "arn:aws:iam::123456789012:instance-profile/S3CLIRole", "CreateDate": "2018-07-03T13:52:22.832Z", "Roles": [] } }
6. Link Role to Instance Profile:
Next, we need to associate the new role to the instance profile.
Syntax:
aws iam add-role-to-instance-profile --instance-profile-name {InstanceProfileName} --role-name {RoleName}
Example Request:
aws iam add-role-to-instance-profile --instance-profile-name S3CLIRole --role-name S3CLIRole
Example Response:
None
7. Verify Instance Profile:
Finally we just just need to also verify that the role that was created has also been successuflly added to an instance profile.
Syntax:
aws iam list-instance-profiles-for-role --role-name {RoleName}
Example Request:
aws iam list-instance-profiles-for-role --role-name S3CLIRole
Example Response:
{ "InstanceProfiles": [ { "Path": "/", "InstanceProfileName": "S3CLIRole", "InstanceProfileId": "ABCDEFGHIJ1234567KLM7", "Arn": "arn:aws:iam::123456789012:instance-profile/S3CLIRole", "CreateDate": "2018-07-03T13:42:08Z", "Roles": [ { "Path": "/", "RoleName": "S3CLIRole", "RoleId": "ABCDEFGHIJ1234567KLM7", "Arn": "arn:aws:iam::123456789012:role/S3CLIRole", "CreateDate": "2018-07-03T13:34:14Z", "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } } ] } ] }
Assigning a Role from the Console
Now that we have our new role, and have verified that the role has an instance profile, we can now assign our role to an EC2 instance. In order to assign a role, we must first navigate to the EC2 console dashboard.
1. Locate and navigate to the EC2 Service:
From the top left side of the navigational menu bar, click on the Services menu, and then choose EC2 by either navigating to the section of the listed services, or by typing the first few letters of the service name in the search box, and then choosing it from the filtered list.
2. Navigate to Instance List:
Once in the EC2 console, click on the # Running Instances link at the top of the dashboard to display a list of available running instances.
3. Assign the role:
From the EC2 Instance list, select an instance that you would like to assign your role to, and once selected, click on the Actions button, and select Instance Settings, then from the sub menu, select Attach/Replace IAM Roles.
Next, from the Attach/Replace IAM Role screen, from the drop list, choose the new role that we just created and hit the Apply button. Once complete, you will be returned back to the main EC2 dashboard, and your instance now has your new role assigned to it and is immediately granted the permissions defined in the policies that are attached to that role.
Assigning a Role from the CLI
Now that we have our new role, and have verified that the role has an instance profile, we can now assign our role to an EC2 instance.
1. Assign Instance Profile:
The instance profile, containing the role, can now be assigned to an EC2 instance. There are 2 ways to associate an instance profile with an EC2 instance. In this first example, we can assign a new instance profile to an instance that has no current role attached to it.
Syntax:
aws ec2 associate-iam-instance-profile --instance-id {InstanceId} --iam-instance-profile Name={InstanceProfileName} --region {InstanceRegion}
Example Request:
aws ec2 associate-iam-instance-profile --instance-id i-012a34b56c7898765 --iam-instance-profile Name=S3CLIRole --region us-east-2
Example Response:
{ "IamInstanceProfileAssociation": { "AssociationId": "iip-assoc-012a34b56c7898765", "InstanceId": "i-012a34b56c7898765", "IamInstanceProfile": { "Arn": "arn:aws:iam::123456789012:instance-profile/S3CLIRole", "Id": "ABCDEFGHIJ1234567KLM7" }, "State": "associating" } }
2. Replace Instance Profile:
Secondly, if the instance already has an associated instance profile, then we can replace the attached instance profile, with the new instance profile that we just created. In order to replace an existing association, we will first need to gather the association ID.
Syntax:
aws ec2 describe-iam-instance-profile-associations --region {InstanceRegion} --filters "Name={instance-id|state},Values={instanceId|state}"
Example Request:
aws ec2 describe-iam-instance-profile-associations --region us-east-2 --filters "Name=instance-id,Values=i-012a34b56c7898765"
Example Response:
{ "IamInstanceProfileAssociations": [ { "AssociationId": "iip-assoc-012a34b56c7898765", "InstanceId": "i-012a34b56c7898765", "IamInstanceProfile": { "Arn": "arn:aws:iam::123456789012:instance-profile/S3CLIRole", "Id": "ABCDEFGHIJ1234567KLM7" }, "State": "associated" } ] }
Now that we have the Intance Association ID, lets swap our instance profiles:
Syntax:
aws ec2 replace-iam-instance-profile-association --association-id {AssociationId} --iam-instance-profile Name={NewIstanceProfile} --region {InstanceRegion}
Example Request:
aws ec2 replace-iam-instance-profile-association --association-id "iip-assoc-012a34b56c7898765" --iam-instance-profile Name=S3CLIRole --region us-east-2
Example Response:
{ "IamInstanceProfileAssociation": { "AssociationId": "iip-assoc-012a34b56c7898765", "InstanceId": "i-012a34b56c7898765", "IamInstanceProfile": { "Arn": "arn:aws:iam::123456789012:instance-profile/S3CLIRole", "Id": "ABCDEFGHIJ1234567KLM7" }, "State": "associating" } }
Creating a Role with CloudFormation
Role CloudFormation Template
The following cloudformation template example will create a role identical the role created in the above example.
AWSTemplateFormatVersion: "2010-09-09" Description: "This cloudformation template will create a role that will include the S3 Full Access AWS Managed policy" ##################### # Define Parameters: ##################### Parameters: RoleName: Type: String Description: The name that will be applied to the Role. SessionDuration: Type: String Description: The maximum session duration (in seconds) for the specified role. Minimum value of 3600. Maximum value of 43200 Default: 3600 ##################### # Define Resources: ##################### Resources: # --------------------- # Define Role Resource: # --------------------- Role: Type: "AWS::IAM::Role" Properties: RoleName: !Ref RoleName AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: "Allow" Principal: Service: - "ec2.amazonaws.com" Action: - "sts:AssumeRole" Path: "/" ManagedPolicyArns: - arn:aws:iam::aws:policy/AmazonS3FullAccess MaxSessionDuration: !Ref SessionDuration # ------------------------------- # Define Instance Profile Resource: # ------------------------------- InstanceProfile: Type: "AWS::IAM::InstanceProfile" Properties: Path: "/" Roles: - !Ref Role ##################### # Define Outputs: ##################### Outputs: RoleName: Description: The name of the newly created role Value: !Ref RoleName RoleARN: Description: The ARN of the newly created role Value: !GetAtt Role.Arn InstanceProfileArn: Description: The ARN of the newly created Instance Profile. Value: !GetAtt InstanceProfile.Arn
IAM Role Additional Resources
No Additional Resources.
Role Site/Information References
Creating a Role to Delegate Permissions to an AWS Service
CloudFormation AWS::IAM::Role
Creating a Role with the AWS CLI
Creating Instance Profiles via the AWS CLI
Listing Instance Profiles for Role via the AWS CLI
Adding a Role to an Instance Profile via the AWS CLI
Checking Instance Profile associations via the AWS CLI
Deleting Instance Profiles via the AWS CLI