[AWS] Using EC2 Roles and Instance Profiles in AWS
Instance Profile contains
- Temporary credentials
- Role
IP will help to rotate the temporary credentials on your behalf.
in short, IP works as "Who am I", Role works as "What can I do".
From bastion instance
Trust policy
This is a policy that's going to allow the EC2 service to assume the role.
trust_policy_ec2.json
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" } ] }
Create a Role
aws iam create-role --role-name DEV_ROLE --assume-role-policy-document file://trust_policy_ec2.json
output:
{ "Role": { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" } } ] }, "RoleId": "AROA47D3RVJAWO66RBUQO", "CreateDate": "2021-12-03T06:29:28Z", "RoleName": "DEV_ROLE", "Path": "/", "Arn": "arn:aws:iam::891464821313:role/DEV_ROLE" } }
Assign the read premission for S3 bucket
Create a IAM policy
dev_s3_read_access.json
{ "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>" ] } ] }
aws iam create-policy --policy-name DevS3ReadAccess --policy-document file://dev_s3_read_access.json
Output:
{ "Policy": { "PolicyName": "DevS3ReadAccess", "PermissionsBoundaryUsageCount": 0, "CreateDate": "2021-12-03T06:46:34Z", "AttachmentCount": 0, "IsAttachable": true, "PolicyId": "ANPA47D3RVJAVY25G7FJD", "DefaultVersionId": "v1", "Path": "/", "Arn": "arn:aws:iam::xxxxxxxxxxxxx:policy/DevS3ReadAccess", "UpdateDate": "2021-12-03T06:46:34Z" } }
Attach the policy just create to the Role:
aws iam attach-role-policy --role-name DEV_ROLE --policy-arn "arn:aws:iam::xxxxxxxxxx:policy/DevS3ReadAccess"
We can check the attached policy:
aws iam list-attached-role-policies --role-name DEV_ROLE
Output:
{ "AttachedPolicies": [ { "PolicyName": "DevS3ReadAccess", "PolicyArn": "arn:aws:iam::xxxxxxxxxx:policy/DevS3ReadAccess" } ] }
Create Instnace Profile
aws iam create-instance-profile --instance-profile-name DEV_PROFILE
Add role to the Instance profile:
aws iam add-role-to-instance-profile --instance-profile-name DEV_PROFILE --role-name DEV_ROLE
Verify the configuration:
aws iam get-instance-profile --instance-profile-name DEV_PROFILE
Output:
{ "InstanceProfile": { "InstanceProfileId": "AIPA47D3RVJAXRQTVYALZ", "Roles": [ { "AssumeRolePolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Principal": { "Service": "ec2.amazonaws.com" } } ] }, "RoleId": "AROA47D3RVJAWO66RBUQO", "CreateDate": "2021-12-03T06:29:28Z", "RoleName": "DEV_ROLE", "Path": "/", "Arn": "arn:aws:iam::xxxxxxxxx:role/DEV_ROLE" } ], "CreateDate": "2021-12-03T06:53:01Z", "InstanceProfileName": "DEV_PROFILE", "Path": "/", "Arn": "arn:aws:iam::xxxxxxxxxxx:instance-profile/DEV_PROFILE" } }
Associate the IAM Instance profile with EC2 instance ID:
aws ec2 associate-iam-instance-profile --instance-id <LAB_WEB_SERVER_INSTANCE_ID> --iam-instance-profile Name="DEV_PROFILE"
Verify the configuration:
aws ec2 describe-instances --instance-ids <LAB_WEB_SERVER_INSTANCE_ID>
Then we can ssh into web server EC2 instance.
Determine the identity currently being used:
aws sts get-caller-identity
Output:
{ "Account": "891464821313", "UserId": "AROA47D3RVJAWO66RBUQO:i-03b3df010e7557b9c", "Arn": "arn:aws:sts::xxxxxxxx:assumed-role/DEV_ROLE/i-03b3df010e7557b9c" }
List the bucket
aws s3 ls aws s3 ls s3://<s3bucketprod-123>
Summary:
- We created a Role, so that EC2 instance can assume this role
- Created a policy allowing that role to access an S3 bucket
- Assoicated the policy with the role
- Created a development instance profile and associated that instance
- Attached the instance profile to EC2 instance
- Verified that Web server EC2 instnace can read from S3
Create a Policy for PROD from Console
1. create a policy called it "ProdS3ReadAccess"
2. create a role for EC2:
In this step, it will automaticlly create a Trust policy allowing EC2 to assume the role we are creating.
You can notice it has Trusted entities:
Assign PROD_ROLE to web server instance
Now, if we do:
aws sts get-caller-identity
Output:
{ "Account": "891464821313", "UserId": "AROA47D3RVJAVLWZUY6X7:i-03b3df010e7557b9c", "Arn": "arn:aws:sts::xxxxxxxxx:assumed-role/PROD_ROLE/i-03b3df010e7557b9c" }
Now you can veiw the PROD bucket but not other bucket.