Using EC2 Roles and Instance Profiles in AWS
Using EC2 Roles and Instance Profiles in AWS
Using EC2 Roles and Instance Profiles in AWS
Introduction
AWS Identity and Access Management (IAM) roles for Amazon Elastic Compute
Cloud (EC2) provide the ability to grant instances temporary credentials. These
temporary credentials can then be used by hosted applications to access permissions
configured within the role. IAM roles eliminate the need for managing credentials,
help mitigate long-term security risks, and simplify permissions management.
Prerequisites for this lab include understanding how to log in to and use the AWS
Management Console, EC2 basics (including how to launch an instance), IAM basics
(including users, policies, and roles), and how to use the AWS CLI.
Note: When connecting to the bastion host and the web server, do so independently of each
other. The bastion host is used for interacting with AWS services via the CLI.
Solution
Log in to the AWS console using the cloud_user credentials provided. Once inside
the AWS account, make sure you are using us-east-1 (N. Virginia) as the selected
region.
Hint: When copying and pasting code into Vim from the lab guide, first enter :set paste (and
then i to enter insert mode) to avoid adding unnecessary spaces and hashes.
2. From the list of buckets, open the one that contains the
text s3bucketlookupfiles in the middle of its name.
4. Click Actions > Download.
Log in to Bastion Host and Set the AWS CLI Region and Output Type
1. Navigate to EC2 > Instances.
ssh cloud_user@<BASTION_HOST_PUBLIC_IP>
For more information on how to connect to a Linux instance using SSH, please
refer to the AWS Documentation . For more information on how to connect to a
Linux instance using Putty, please refer to Connect to your Linux instance from
Windows using PuTTY.
"Version": "2012-10-17",
"Statement": [
"Effect": "Allow",
"Action": "sts:AssumeRole"
}
{
"Role": {
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
]
},
"RoleId": "AROA26XO4TDGDY6NIJ6FT",
"CreateDate": "2022-07-01T08:13:10Z",
"RoleName": "DEV_ROLE",
"Path": "/",
"Arn": "arn:aws:iam::753194014924:role/DEV_ROLE"
}
}
"Version": "2012-10-17",
"Statement": [
"Sid": "AllowUserToSeeBucketListInTheConsole",
"Effect": "Allow",
"Resource": ["arn:aws:s3:::*"]
},
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::<DEV_S3_BUCKET_NAME>/*",
"arn:aws:s3:::<DEV_S3_BUCKET_NAME>"
]
}
"Policy": {
"PolicyName": "DevS3ReadAccess",
"PermissionsBoundaryUsageCount": 0,
"CreateDate": "2022-07-01T08:24:29Z",
"AttachmentCount": 0,
"IsAttachable": true,
"PolicyId": "ANPA26XO4TDGNAW5IOYD4",
"DefaultVersionId": "v1",
"Path": "/",
"Arn": "arn:aws:iam::753194014924:policy/DevS3ReadAccess",
"UpdateDate": "2022-07-01T08:24:29Z"
}
}
6. Copy the policy ARN in the output, and paste it into the labreferences.txt file
— we'll need it in a minute.
Create Instance Profile and Attach Role to an EC2 Instance
Attach Managed Policy to Role
1. Attach the managed policy to the role,
replacing <DevS3ReadAccess_POLICY_ARN> with the ARN you just copied:
"AttachedPolicies": [
"PolicyName": "DevS3ReadAccess",
"PolicyArn": "arn:aws:iam::753194014924:policy/DevS3ReadAccess"
]
}
Create the Instance Profile and Add the DEV_ROLE via the AWS CLI
1. Create instance profile named DEV_PROFILE :
"InstanceProfile": {
"InstanceProfileId": "AIPA26XO4TDGFGPI5PZKL",
"Roles": [],
"CreateDate": "2022-07-01T08:28:43Z",
"InstanceProfileName": "DEV_PROFILE",
"Path": "/",
"Arn": "arn:aws:iam::753194014924:instance-profile/DEV_PROFILE"
}
}
2. Add role to the DEV_PROFILE called DEV_ROLE :
"InstanceProfile": {
"InstanceProfileId": "AIPA26XO4TDGFGPI5PZKL",
"Roles": [
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
]
},
"RoleId": "AROA26XO4TDGDY6NIJ6FT",
"CreateDate": "2022-07-01T08:13:10Z",
"RoleName": "DEV_ROLE",
"Path": "/",
"Arn": "arn:aws:iam::753194014924:role/DEV_ROLE"
],
"CreateDate": "2022-07-01T08:28:43Z",
"InstanceProfileName": "DEV_PROFILE",
"Path": "/",
"Arn": "arn:aws:iam::753194014924:instance-profile/DEV_PROFILE"
}
Attach the DEV_PROFILE Role to an Instance
1. In the AWS console, navigate to EC2 > Instances.
{
"IamInstanceProfileAssociation": {
"InstanceId": "i-019b5951e3d753d44",
"State": "associating",
"AssociationId": "iip-assoc-0b46fbbac31138dde",
"IamInstanceProfile": {
"Id": "AIPA26XO4TDGFGPI5PZKL",
"Arn": "arn:aws:iam::753194014924:instance-profile/DEV_PROFILE"
}
}
"Reservations": [
"Instances": [
"Monitoring": {
"State": "disabled"
},
"PublicDnsName": "ec2-44-192-55-160.compute-
1.amazonaws.com",
"State": {
"Code": 16,
"Name": "running"
},
"EbsOptimized": false,
"LaunchTime": "2022-07-01T07:23:35.000Z",
"PublicIpAddress": "44.192.55.160",
"PrivateIpAddress": "10.0.1.11",
"ProductCodes": [],
"VpcId": "vpc-0c33f40d4e3bc7698",
"CpuOptions": {
"CoreCount": 1,
"ThreadsPerCore": 2
},
"StateTransitionReason": "",
"InstanceId": "i-019b5951e3d753d44",
"EnaSupport": true,
"ImageId": "ami-096e189c66c11b2b5",
"PrivateDnsName": "ip-10-0-1-11.ec2.internal",
"SecurityGroups": [
"GroupName": "cfst-3035-
a45cc36b2e27ca535ba0546f76995a49-SecurityGroupHTTPAndSSH-
1BL038FZK5UZ7",
"GroupId": "sg-0217f326ff666a36a"
],
"ClientToken": "cfst-EC2In-5K4VBHT9NDON",
"SubnetId": "subnet-0fdbac35002d9b440",
"InstanceType": "t3.micro",
"CapacityReservationSpecification": {
"CapacityReservationPreference": "open"
},
"NetworkInterfaces": [
"Status": "in-use",
"MacAddress": "02:a2:50:8b:5a:3d",
"SourceDestCheck": true,
"VpcId": "vpc-0c33f40d4e3bc7698",
"Description": "",
"NetworkInterfaceId": "eni-07af142572a741b63",
"PrivateIpAddresses": [
"PrivateDnsName": "ip-10-0-1-11.ec2.internal",
"PrivateIpAddress": "10.0.1.11",
"Primary": true,
"Association": {
"PublicIp": "44.192.55.160",
"PublicDnsName": "ec2-44-192-55-160.compute-
1.amazonaws.com",
"IpOwnerId": "amazon"
],
"PrivateDnsName": "ip-10-0-1-11.ec2.internal",
"InterfaceType": "interface",
"Attachment": {
"Status": "attached",
"DeviceIndex": 0,
"DeleteOnTermination": true,
"AttachmentId": "eni-attach-0e37467d54570c9ba",
"AttachTime": "2022-07-01T07:23:35.000Z"
},
"Groups": [
"GroupName": "cfst-3035-
a45cc36b2e27ca535ba0546f76995a49-SecurityGroupHTTPAndSSH-
1BL038FZK5UZ7",
"GroupId": "sg-0217f326ff666a36a"
],
"Ipv6Addresses": [],
"OwnerId": "753194014924",
"PrivateIpAddress": "10.0.1.11",
"SubnetId": "subnet-0fdbac35002d9b440",
"Association": {
"PublicIp": "44.192.55.160",
"PublicDnsName": "ec2-44-192-55-160.compute-
1.amazonaws.com",
"IpOwnerId": "amazon"
],
"SourceDestCheck": true,
"Placement": {
"Tenancy": "default",
"GroupName": "",
"AvailabilityZone": "us-east-1a"
},
"Hypervisor": "xen",
"BlockDeviceMappings": [
"DeviceName": "/dev/xvda",
"Ebs": {
"Status": "attached",
"DeleteOnTermination": true,
"VolumeId": "vol-0d64d3b55250e0986",
"AttachTime": "2022-07-01T07:23:36.000Z"
],
"Architecture": "x86_64",
"RootDeviceType": "ebs",
"IamInstanceProfile": {
"Id": "AIPA26XO4TDGFGPI5PZKL",
"Arn":
"arn:aws:iam::753194014924:instance-profile/DEV_PROFILE"
},
"RootDeviceName": "/dev/xvda",
"VirtualizationType": "hvm",
"Tags": [
"Value": "14248119",
"Key": "UserId"
},
"Value": "arn:aws:cloudformation:us-east-
1:753194014924:stack/cfst-3035-a45cc36b2e27ca535ba0546f76995a49/
a49b9200-f90e-11ec-a7a8-0a113ed4b9b7",
"Key": "aws:cloudformation:stack-id"
},
{
"Value": "cfst-3035-a45cc36b2e27ca535ba0546f76995a49",
"Key": "aws:cloudformation:stack-name"
},
"Value": "EC2InstanceWebServer",
"Key": "aws:cloudformation:logical-id"
},
"Key": "Name"
},
"Value": "arn:aws:cloudformation:us-east-
1:753194014924:stack/cfst-3035-a45cc36b2e27ca535ba0546f76995a49/
a49b9200-f90e-11ec-a7a8-0a113ed4b9b7",
"Key": "Application"
],
"HibernationOptions": {
"Configured": false
},
"MetadataOptions": {
"State": "applied",
"HttpEndpoint": "enabled",
"HttpTokens": "optional",
"HttpPutResponseHopLimit": 1
},
"AmiLaunchIndex": 0
],
"ReservationId": "r-01ec0401eb29c2906",
"RequesterId": "043234062703",
"Groups": [],
"OwnerId": "753194014924"
]
}
This command's output should show this instance is using DEV_PROFILE as
an IamInstanceProfile . Verify this by locating the IamInstanceProfile section
in the output, and look below to make sure the "Arn" ends in /DEV_PROFILE .
ssh cloud_user@<WEB_SERVER_PUBLIC_IP>
4. Use the same password for the bastion host provided on the lab page.
[cloud_user@webserver]$ aws s3 ls
Copy the entire name (starting with cfst ) of the bucket with s3bucketdev in its
name.
Create an IAM Policy and Role Using the AWS Management Console
Create Policy
1. In the AWS console, navigate to IAM > Policies.
2. Click Create policy.
3. Click the JSON tab.
"Version": "2012-10-17",
"Statement": [
"Sid": "AllowUserToSeeBucketListInTheConsole",
"Effect": "Allow",
"Resource": ["arn:aws:s3:::*"]
},
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::<PROD_S3_BUCKET_NAME>/*",
"arn:aws:s3:::<PROD_S3_BUCKET_NAME>"
5. Click Next: Tags.
6. Click Next: Review.
8. Click Create policy.
Create Role
1. Click Roles in the left-hand menu.
2. Click Create role.
4. Click Next: Permissions.
7. Click Next: Tags.
8. Click Next: Review.
9. Give it a Role name of PROD_ROLE.
Attach IAM Role to an EC2 Instance Using the AWS Management Console
1. Navigate to EC2 > Instances.
5. Click Save.
[cloud_user@webserver]$ aws s3 ls
4. Copy the entire name (starting with cfst ) of the bucket with s3bucketprod in
its name.
6. In the aws s3 ls command output, copy the entire name (starting with cfst )
of the bucket with s3bucketsecret in its name.