You are on page 1of 21

Using EC2 Roles and Instance Profiles in AWS

Create a Trust Policy and Role Using the AWS CLI


1. From the AWS Management Console, open the provisioned S3 bucket
with s3bucketlookupfiles in its name and obtain the  labreferences.txt  file. This
file serves as a reference containing the S3 bucket names used throughout the
lab.
2. Open a new terminal session.
3. Log in to the EC2 Bastion Host instance using the provided lab credentials
and set the AWS CLI region and output type.
4. Create an IAM trust policy for an EC2 role.
5. Create an IAM role named  DEV_ROLE .
6. Create an IAM policy named  DevS3ReadAccess  and define read-only access
permissions for the provisioned S3 bucket with s3bucketdev in its name .
Create Instance Profile and Attach Role to an EC2 Instance
1. Attach the  DevS3ReadAccess  policy to the  DEV  role.
2. Create the instance profile  DEV_PROFILE  and add the  DEV_ROLE  to it via the AWS
CLI.
3. Attach the  DEV_PROFILE  role to the EC2 Web Server instance.
Test S3 Permissions via the AWS CLI
1. Log in to the EC2 Web Server instance using the provided lab credentials.
2. Verify that the Web Server instance is assuming the  DEV_ROLE  role.
3. List the buckets in the account.
4. Attempt to view the files in the  s3bucketdev  bucket.
Create an IAM Policy and Role Using the AWS Management Console
1. From the AWS Management Console, navigate to IAM > Policies.
2. Create an IAM policy named  ProdS3ReadAccess  and define read-only access
permissions for the provisioned S3 bucket with s3bucketprod in its name .
3. Create a  PROD_ROLE  role and attach it to the  ProdS3ReadAccess  policy.
Attach IAM Role to an EC2 Instance Using the AWS Management Console
1. Navigate to EC2 > Instances.
2. Attach the  PROD_ROLE  role to the Web Server instance.
3. Open a terminal session and log in to the EC2 Web Server instance using the
provided lab credentials.
4. Verify that the Web Server instance is assuming the  PROD_ROLE .
5. List the buckets.
6. Attempt to view the files in the  s3bucketprod  bucket.
7. Attempt to view the files in the  s3bucketsecret  bucket.
Using EC2 Roles and Instance Profiles

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.

Create a Trust Policy and Role Using the AWS CLI


Obtain the  labreferences.txt  File
1. Navigate to S3.

2. From the list of buckets, open the one that contains the
text s3bucketlookupfiles in the middle of its name.

3. Select the  labreferences.txt  file.

4. Click Actions > Download.

5. Open the  labreferences.txt  file, as we will need to reference it throughout


the lab.

Log in to Bastion Host and Set the AWS CLI Region and Output Type
1. Navigate to EC2 > Instances.

2. Copy the public IP of the Bastion Host instance.


3. Open a terminal, and log in to the bastion host via SSH:

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.

4. Enter the password provided for it on the lab page.

5. Run the following command:

[cloud_user@bastion]$ aws configure


6. Press Enter twice to leave the AWS Access Key ID and AWS Secret Access
Key blank.

7. Enter  us-east-1  as the default region name.

8. Enter  json  as the default output format.

Create IAM Trust Policy for an EC2 Role


1. Create a file called  trust_policy_ec2.json :

[cloud_user@bastion]$ vim trust_policy_ec2.json


2. To avoid adding unnecessary spaces or hashes, type  :set paste  and then  i  to
enter  insert  mode.

3. Paste in the following content:

"Version": "2012-10-17",

"Statement": [

"Effect": "Allow",

"Principal": {"Service": "ec2.amazonaws.com"},

"Action": "sts:AssumeRole"
}

4. Save and quit the file by pressing Escape followed by  :wq! .

Create the  DEV_ROLE  IAM Role


1. Run the following AWS CLI command:

[cloud_user@bastion]$ aws iam create-role --role-name DEV_ROLE --assume-


role-policy-document file://trust_policy_ec2.json

{
"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"
}
}

Create an IAM Policy Defining Read-Only Access Permissions to an S3 Bucket


1. Create a file called  dev_s3_read_access.json :
[cloud_user@bastion]$ vim dev_s3_read_access.json
2. To avoid adding unnecessary spaces or hashes, type  :set paste  and then  i  to
enter  insert  mode.

3. Enter the following content, replacing  <DEV_S3_BUCKET_NAME>  with the bucket


name provided in the  labreferences.txt  file:

"Version": "2012-10-17",

"Statement": [

"Sid": "AllowUserToSeeBucketListInTheConsole",

"Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],

"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>"

]
}

4. Save and quit the file by pressing Escape followed by  :wq! .

5. Create the managed policy called  DevS3ReadAccess :

[cloud_user@bastion]$ aws iam create-policy --policy-name DevS3ReadAccess


--policy-document file://dev_s3_read_access.json

"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:

[cloud_user@bastion]$ aws iam attach-role-policy --role-name DEV_ROLE --


policy-arn "<DevS3ReadAccess_POLICY_ARN>"
2. Verify the managed policy was attached:

[cloud_user@bastion]$ aws iam list-attached-role-policies --role-name


DEV_ROLE

"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 :

[cloud_user@bastion]$ aws iam create-instance-profile --instance-profile-


name 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 :

[cloud_user@bastion]$ aws iam add-role-to-instance-profile --instance-


profile-name DEV_PROFILE --role-name DEV_ROLE
3. Verify the configuration:

[cloud_user@bastion]$ aws iam get-instance-profile --instance-profile-name


DEV_PROFILE

"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.

2. Copy the instance ID of the instance named Web Server instance and paste it


into the  labreferences.txt  file — we'll need it in a second.

3. In the terminal, attach the  DEV_PROFILE  to an EC2 instance,


replacing  <LAB_WEB_SERVER_INSTANCE_ID>  with the Web Server instance ID you
just copied:

[cloud_user@bastion]$ aws ec2 associate-iam-instance-profile --instance-id


<LAB_WEB_SERVER_INSTANCE_ID> --iam-instance-profile Name="DEV_PROFILE"

{
"IamInstanceProfileAssociation": {

"InstanceId": "i-019b5951e3d753d44",

"State": "associating",

"AssociationId": "iip-assoc-0b46fbbac31138dde",

"IamInstanceProfile": {

"Id": "AIPA26XO4TDGFGPI5PZKL",

"Arn": "arn:aws:iam::753194014924:instance-profile/DEV_PROFILE"

}
}

4. Verify the configuration (be sure to replace  <LAB_WEB_SERVER_INSTANCE_ID>  with


the Web Server instance ID again):

[cloud_user@bastion]$ aws ec2 describe-instances --instance-ids


<LAB_WEB_SERVER_INSTANCE_ID>

"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"

},

"Value": "Web Server",

"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 .

Test S3 Permissions via the AWS CLI


1. In the AWS console, copy the public IP of the Web Server instance.

2. Open a new terminal.

3. Log in to the web server instance via SSH:

ssh cloud_user@<WEB_SERVER_PUBLIC_IP>
4. Use the same password for the bastion host provided on the lab page.

5. Verify the instance is assuming the  DEV_ROLE  role:

[cloud_user@webserver]$ aws sts get-caller-identity


We should see  DEV_ROLE  in the  Arn .
6. List the buckets in the account:

[cloud_user@webserver]$ aws s3 ls
Copy the entire name (starting with  cfst ) of the bucket with  s3bucketdev  in its
name.

7. Attempt to view the files in the  s3bucketdev-  bucket, replacing  <s3bucketdev-


123>  with the bucket name you just copied:

[cloud_user@webserver]$ aws s3 ls s3://<s3bucketdev-123>


We should see a list of files.

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.

4. Paste the following text as the policy, replacing  <PROD_S3_BUCKET_NAME>  with


the bucket name provided in the  labreferences.txt  file:

"Version": "2012-10-17",

"Statement": [

"Sid": "AllowUserToSeeBucketListInTheConsole",

"Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],

"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.

7. Enter ProdS3ReadAccess as the policy name.

8. Click Create policy.

Create Role
1. Click Roles in the left-hand menu.

2. Click Create role.

3. Under Choose a use case, select EC2.

4. Click Next: Permissions.

5. In the Filter policies search box, enter ProdS3ReadAccess.

6. Click the checkbox to select ProdS3ReadAccess.

7. Click Next: Tags.

8. Click Next: Review.
9. Give it a Role name of PROD_ROLE.

10. Click Create role.

Attach IAM Role to an EC2 Instance Using the AWS Management Console
1. Navigate to EC2 > Instances.

2. Select the Web Server instance.

3. Click Actions > Security > Modify IAM role.

4. In the IAM role dropdown, select PROD_ROLE.

5. Click Save.

Test the Configuration


1. Open the existing terminal connected to the Web Server instance. (You may
need to reconnect if you've been disconnected.)

2. Determine the identity currently being used:

[cloud_user@webserver]$ aws sts get-caller-identity


This time, we should see  PROD_ROLE  in the  Arn .

3. List the buckets:

[cloud_user@webserver]$ aws s3 ls
4. Copy the entire name (starting with  cfst ) of the bucket with  s3bucketprod  in
its name.

5. Attempt to view the files in the  s3bucketprod-  bucket,


replacing  <s3bucketprod-123>  with the bucket name you just copied:

[cloud_user@webserver]$ aws s3 ls s3://<s3bucketprod-123>


It should list the files.

6. In the  aws s3 ls  command output, copy the entire name (starting with  cfst )
of the bucket with  s3bucketsecret  in its name.

7. Attempt to view the files in the  <s3bucketsecret-123>  bucket,


replacing  <s3bucketsecret-123>  with the bucket name you just copied:

[cloud_user@webserver]$ aws s3 ls s3://<s3bucketsecret-123>


This time, our access will be denied — which means our configuration is
properly set up.
Conclusion

You might also like