Using EC2 Roles and Instance Profiles

Hands-On Lab

 

Photo of Miles Baker

Miles Baker

AWS Training Architect II

Length

01:30:00

Difficulty

Advanced

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.

What are Hands-On Labs?

Hands-On Labs are scenario-based learning environments where learners can practice without consequences. Don't compromise a system or waste money on expensive downloads. Practice real-world skills without the real-world risk, no assembly required.

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.

Solution

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

Open the labreferences.txt File

  1. Navigate to S3.
  2. Open the bucket containing the text s3bucketlookupfiles.
  3. Download and open the labreferences.txt file. This will be referenced through other portions of this lab.

Create the DEV IAM Role via the AWS CLI

Set the AWS CLI Region and Output Type

  1. Open a terminal to the bastion host, using the credentials on the lab page (replacing <BASTION_HOST_PUBLIC_IP> with the public IP on the lab page):
    ssh cloud_user@<BASTION_HOST_PUBLIC_IP>
  2. Run the following command:
    aws configure

    Leave the AWS access key ID and AWS secret access key blank. Enter us-east-1 as the default region name and json as the default output format.

Create IAM Trust Policy for an EC2 Role

  1. Use a terminal editor (e.g., vi or Nano) to create a file called trust_policy_ec2.json with the following content:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {"Service": "ec2.amazonaws.com"},
          "Action": "sts:AssumeRole"
        }
      ]
    }

Create the DEV IAM Role

  1. Run the following AWS CLI command:
    aws iam create-role --role-name DEV_ROLE --assume-role-policy-document file://trust_policy_ec2.json

Create the IAM Policy for the S3 Dev Bucket Read Access via the AWS CLI

  1. Use a terminal editor (e.g., vi or Nano) to create a file called dev_s3_read_access.json with the following content (be sure to replace <DEV_S3_BUCKET_NAME> with the bucket name provided in the labreferences.txt file before saving the 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>"
                ]
            }
        ]
    }
  2. Create the managed policy:
    aws iam create-policy --policy-name DevS3ReadAccess --policy-document file://dev_s3_read_access.json
  3. Copy the policy ARN in the output, and paste it into the labreferences.txt file — we'll need it in a minute.

Attach Permissions to the DEV_ROLE via the AWS CLI

Attach Managed Policy to role

  1. Run the following AWS CLI command, and be sure to replace <POLICY_ARN_FROM_LAST_STEP> with the ARN you just copied:
    aws iam attach-role-policy --role-name DEV_ROLE --policy-arn "<POLICY_ARN_FROM_LAST_STEP>"

Verify Settings

  1. Verify the managed policy was attached:
    aws iam list-attached-role-policies --role-name DEV_ROLE
  2. Get the policy details, including the current version (be sure to replace <POLICY_ARN_FROM_LAST_STEP> with the policy ARN you copied):
    aws iam get-policy --policy-arn "<POLICY_ARN_FROM_LAST_STEP>"
  3. Get the permissions associated with the current policy version (be sure to replace the <POLICY_ARN> and <DEFAULT_VERSION_ID> with the output of the get-policy command):
    aws iam get-policy-version --policy-arn "<POLICY_ARN>" --version-id "<DEFAULT_VERSION_ID>"

Create the DEV Instance Profile and add the DEV_ROLE via the AWS CLI

  1. Create instance profile:
    aws iam create-instance-profile --instance-profile-name DEV_PROFILE
  2. Add role to the new instance profile:
    aws iam add-role-to-instance-profile --instance-profile-name DEV_PROFILE --role-name DEV_ROLE
  3. Verify the configuration:
    aws iam get-instance-profile --instance-profile-name DEV_PROFILE

Attach the DEV_PROFILE to an Instance

  1. In the AWS console, navigate to EC2.
  2. Head to the running instances, and copy the instance ID of the web server instance and paste it into the labreferences.txt file — we'll need it in a second.
  3. Attach the DEV_PROFILE to an EC2 instance (be sure to replace the <LAB_WEB_SERVER_INSTANCE_ID> with the web server instance ID you just copied):
    aws ec2 associate-iam-instance-profile --instance-id <LAB_WEB_SERVER_INSTANCE_ID> --iam-instance-profile Name="DEV_PROFILE"
  4. Verify the configuration (be sure to replace the <LAB_WEB_SERVER_INSTANCE_ID> with your web server instance ID):
    aws ec2 describe-instances --instance-ids <LAB_WEB_SERVER_INSTANCE_ID>

Test DEV_ROLE Permissions

Log In to the Web Server Instance via SSH

  1. Open a new terminal.
  2. Log in to the web server via SSH using the credentials on the lab page, including the public IP of the web server.

Test the Configuration

  1. Run the following command to determine the identity currently used in the order:
    aws sts get-caller-identity
  2. Verify access to the <DEV_S3_BUCKET_NAME> in your lab (be sure to replace the <DEV_S3_BUCKET_NAME> with the value provided in the labreferences.txt file):
    aws s3 ls
    aws s3 ls s3://<DEV_S3_BUCKET_NAME>
  3. Verify access is denied to the <SECRET_S3_BUCKET_NAME> (be sure to replace the <SECRET_S3_BUCKET_NAME> with the value provided in the labreferences.txt file):
    aws s3 ls s3://<SECRET_S3_BUCKET_NAME>

The Order of Things: Part 1 — AWS CLI Configuration

AWS CLI Configuration

  1. Assume the permissions for user CaptainKirk (be sure to replace <ACCESS KEY - CAPTAIN KIRK> and <SECRET ACCESS KEY - CAPTAIN KIRK> with the values provided in the labreferences.txt file):
    aws configure
    AWS Access Key ID [None]: <ACCESS KEY - CAPTAIN KIRK>
    AWS Secret Access Key [None]: <SECRET ACCESS KEY - CAPTAIN KIRK>
    Default region name [None]: us-east-1
    Default output format [None]: json

Test the Configuration

  1. Determine the identity currently used in the order (it should be CaptainKirk):
    aws sts get-caller-identity
  2. Verify access to the <SECRET_S3_BUCKET_NAME> in your lab (be sure to replace the <SECRET_S3_BUCKET_NAME> with the value provided in the labreferences.txt file):
    aws s3 ls
    aws s3 ls s3://<SECRET_S3_BUCKET_NAME>

The Order of Things: Part 2 — Environment Variable Configuration

Environment Variable Configuration

  1. Set environment variables to assume the permissions for the EngineerScotty (be sure to replace <ACCESS KEY - ENGINEER SCOTTY> and <SECRET ACCESS KEY - ENGINEER SCOTTY> with the values provided in the labreferences.txt file):
    export AWS_ACCESS_KEY_ID=<ACCESS KEY - ENGINEER SCOTTY>
    export AWS_SECRET_ACCESS_KEY=<SECRET ACCESS KEY - ENGINEER SCOTTY>

Test the Configuration

  1. Determine the identity currently used in the order (it should be EngineerScotty):
    aws sts get-caller-identity
  2. Verify access to the <ENGINEERING_S3_BUCKET_NAME> in your lab (be sure to replace the <ENGINEERING_S3_BUCKET_NAME> with the value provided in the labreferences.txt file):
    aws s3 ls
    aws s3 ls s3://<ENGINEERING_S3_BUCKET_NAME>
  3. Verify access is denied to the <SECRET_S3_BUCKET_NAME> (be sure to replace the <SECRET_S3_BUCKET_NAME> with the value provided in the labreferences.txt file):
    aws s3 ls s3://<SECRET_S3_BUCKET_NAME>

The Order of Things: Part 3 — Cleanup

Clear the Environment Variables

  1. Run the following commands in the terminal:

    unset AWS_ACCESS_KEY_ID
    unset AWS_SECRET_ACCESS_KEY
  2. Determine the identity currently used in the order (it should be CaptainKirk):

    aws sts get-caller-identity

Remove the ~/.aws/credentials File

  1. Run the following command:
    rm ~/.aws/credentials
  2. Determine the identity currently used in the order (it should be the DEV_ROLE):
    aws sts get-caller-identity

Create the IAM Policy for the S3 Prod Bucket Read Access via the AWS Management Console

  1. In the AWS console, navigate to IAM.
  2. Click Policies on the left-hand menu.
  3. Click Create policy.
  4. Click the JSON tab.
  5. Paste the following text as the policy (be sure to replace the <PROD_S3_BUCKET_NAME> text with the bucket name provided in the labreferences.txt file before saving the 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>"
                ]
            }
        ]
    }
  6. Click Review policy.
  7. Enter "ProdS3ReadAccess" as the policy name.
  8. Click Create policy.

Create the PROD IAM Role and Instance Profile via the AWS Management Console

  1. Click Roles on the left-hand menu.
  2. Click Create role.
  3. Select EC2 as the service that will use this role.
  4. Click Next: Permissions.
  5. In the search window, enter "ProdS3ReadAccess".
  6. Click the checkbox to select ProdS3ReadAccess.
  7. Click Next: Tags.
  8. Click Next: Review.
  9. Set the following values:
    • Role name: PROD_ROLE
    • Role description: Provides access to production S3 resources
  10. Click Create role.

Attach the PROD Instance Profile to the Instance via the AWS Management Console

  1. Navigate to EC2.
  2. Click Instances on the left-hand menu.
  3. Select the Web Server.
  4. Click Actions > Instance Settings > Attach/Replace IAM Role.
  5. Select PROD_ROLE as the IAM role.
  6. Click Apply.

Test PROD_ROLE Permissions

Log In to the Web Server Instance via SSH

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

Test the Configuration

  1. Determine the identity currently used in the order (it should be PROD_ROLE):
    aws sts get-caller-identity
  2. Verify access to the :<PROD_S3_BUCKET_NAME> in your lab (be sure to replace the <PROD_S3_BUCKET_NAME> with the value provided in the labreferences.txt file):
    aws s3 ls
    aws s3 ls s3://<PROD_S3_BUCKET_NAME>
  3. Verify access is denied to the <SECRET_S3_BUCKET_NAME> (be sure to replace the <SECRET_S3_BUCKET_NAME> with the value provided in the labreferences.txt file):
    aws s3 ls s3://<SECRET_S3_BUCKET_NAME>

Conclusion

Congratulations on successfully completing this hands-on lab!