Open menu
-->

IAM Roles for App-Tier EC2 Instances

Cloud Conformity allows you to automate the auditing process of this resolution page. Register for a 14 day evaluation and check your compliance level for free!

Start a Free Trial Product features
Security

Risk level: Medium (should be achieved)

Ensure that your app-tier EC2 instances are using IAM roles to grant the necessary permissions (following the principle of least privilege) to the applications running on these instances. This conformity rule assumes that all AWS resources provisioned in your app tier are tagged with <app_tier_tag>:<app_tier_tag_value>, where <app_tier_tag> is the tag name and <app_tier_tag_value> the tag value. Prior to running this rule by the Cloud Conformity engine, the app-tier tags must be known and configured in the rule settings, on your Cloud Conformity account dashboard.

This rule resolution is part of the Cloud Conformity Base Auditing Package

Applications that run on EC2 instances need credentials in order to access other AWS services. An IAM role associated with an app-tier instance dynamically provides these authentication credentials. Multiple benefits are gained when your applications are using IAM roles to sign their API requests with AWS credentials. For example, you don't have to manage credentials anymore as the authorization details provided by the IAM roles are temporary and rotated automatically for you. You can use a single role for multiple EC2 instances within your app tier, manage the role access permissions in one place and allow these to propagate automatically to all associated instances. And you can also restrict which role an IAM user can attach to an app-tier EC2 instance during the launch process in order to stop the user from trying to gain elevated privileges. Note: Make sure that you replace all <web_tier_tag>:<web_tier_tag_value> tag placeholders found in the conformity rule content with your own tag name and value created for the web tier.

Audit

To determine if your app-tier EC2 instances are using IAM roles to sign AWS API requests, perform the following actions:

Using AWS Console

01 Sign in to your Cloud Conformity console, access Create IAM Roles for App-Tier EC2 Instances conformity rule settings and copy the tags defined for AWS resources available in your app tier (e.g. <app_tier_tag>:<app_tier_tag_value>).

02 Sign in to the AWS Management Console.

03 Navigate to EC2 dashboard at https://console.aws.amazon.com/ec2/.

04 In the navigation panel, under INSTANCES, click Instances.

05 Paste the tag set copied at step no. 1 in the Filter by tags and attributes or search by keyword box, then add a space before and after the separation colon (i.e. <app_tier_tag> : <app_tier_tag_value>) and press Enter. This filtering mechanism will return only the EC2 instances tagged for the app tier. If no results are returned, there are no instances tagged within your app tier and the audit process ends here. If the EC2 dashboard lists one or more instances, continue the audit with the next step.

06 Select the app-tier EC2 instance that you want to examine.

07 Select the Description tab from the dashboard bottom panel.

08 In the left column, check the IAM role attribute value. If the attribute has no value assigned, there are no IAM roles attached to the selected app-tier EC2 instance.

09 Repeat steps no. 4 – 8 to check other app-tier EC2 instances for IAM roles, provisioned in the selected region.

10 Change the AWS region from the navigation bar and repeat steps no. 5 – 9 for other regions.

Using AWS CLI

01 Sign in to your Cloud Conformity console, access Create IAM Roles for App-Tier EC2 conformity rule settings and copy the tags defined for AWS resources available in your app tier (e.g. <app_tier_tag>:<app_tier_tag_value>).

02 Run describe-instances command (OSX/Linux/UNIX) using custom query filters to list the IDs of all EC2 instances available in the selected region:

aws ec2 describe-instances
	--region us-east-1
	--output table
	--query 'Reservations[*].Instances[*].InstanceId'

03 The command output should return a table with the requested instance IDs:

-------------------------
|   DescribeInstances   |
+-----------------------+
|  i-01234567890aabbcc  |
|  i-01234567890abcabc  |
|  i-01234567890bacbac  |
+-----------------------+

04 Run describe-tags command (OSX/Linux/UNIX) using the ID of the EC2 instance that you want to examine as identifier and custom query filters to describe the tags defined for the selected AWS resource:

aws ec2 describe-tags
	--region us-east-1
	--filters "Name=resource-id,Values=i-01234567890aabbcc"
	--query 'Tags[*].{Value:Value, Key:Key}'

05 The command request should return one of the following outputs:

  1. If the describe-tags command output returns an empty array (i.e. []), as shown in the example below, the verified instance is not tagged, therefore the audit process for the selected resource stops here:
    []
    
  2. If the command output returns a set of tags that is different than the one copied at step no. 1, as shown in the example below, the verified EC2 instance does not belong to your app tier, therefore the audit process for the selected resource ends here:
    [
        {
            "Value": "Stack",
            "Key": "Dev 1.8"
        }
    ]
    
  3. If the describe-tags command output returns a set of tags that match the one copied at step no. 1 (e.g. <app_tier_tag>:<app_tier_tag_value>), as shown in the example below, the verified AWS EC2 instance is tagged as an app-tier resource, therefore the audit process continues with the next step:
    [
        {
            "Key": "<app_tier_tag>",
            "Value": "<app_tier_tag_value>"
        }
    ]
    

06 Run describe-instances command (OSX/Linux/UNIX) using the ID of the app-tier instance that you want to examine as identifier and custom query filters to determine whether the selected app-tier instance has any IAM roles attached:

aws ec2 describe-instances
	--region us-east-1
	--instance-ids i-01234567890aabbcc
	--query 'Reservations[*].Instances[*].IamInstanceProfile[]'

07 The command output should return the configuration metadata for the IAM role(s) associated with the selected app-tier instance (if any):

[]

If the command output returns an empty array (i.e. []), as shown in the example above, there are no IAM roles associated with the selected app-tier EC2 instance, therefore the applications installed on the instance are not using dynamic authentication credentials to sign their API requests.

08 Repeat step no. 6 and 7 to check other app-tier EC2 instances for IAM roles, available in the selected region.

09 Change the AWS region by updating the --region command parameter value and repeat steps no. 2 – 8 to perform the audit process for other regions.

Remediation / Resolution

To attach IAM roles to your running app-tier EC2 instances, you need to re-launch those instances and associate them with the required IAM roles. To create the necessary IAM roles (also known as instance profiles) and attach them to your EC2 instances during the launch process, perform the following actions:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to IAM dashboard at https://console.aws.amazon.com/iam/.

03 In the left navigation panel, choose Roles.

04 Click Create role button from the dashboard top menu to create a new IAM role.

05 On Select type of trusted entity panel, select AWS service category and choose EC2 from Choose the service that will use this role list. Click Next: Permissions to continue.

06 On Permissions panel, perform one of the following actions:

  1. To attach predefined managed policies (e.g. "AmazonEC2FullAccess"), select one or more policies from the list, then click Next: Review button to continue the setup process.
  2. To attach inline policies, click Create policy button and run the setup wizard to create a new custom IAM policy that best suits your needs, following the principle of least privilege. Once the inline policy is created and selected, click Next: Review button to continue the process.

07 On Review panel, provide a name and a description for your new role, then click Create role to finish the IAM role setup process.

08 Now create an Amazon Machine Image (AMI) from your running app-tier instance. To create the necessary AMI, perform the following actions:

  1. Navigate to EC2 dashboard at https://console.aws.amazon.com/ec2/.
  2. In the navigation panel, under INSTANCES, click Instances.
  3. Select the app-tier instance that requires IAM roles for AWS API access (see Audit section part I to identify the right resource).
  4. Click the Actions dropdown button from the dashboard top menu, select Image and click Create Image.
  5. Inside Create Image dialog box, provide the following information:
    • In the Image Name box, enter a name for the new AMI.
    • In the Image description box, provide a description that reflects the usage of the EC2 instance selected.
    • Leave No reboot option unchecked so that AWS can guarantee the file system integrity for the new AMI.
  6. Click Create Image to submit the request to create the image. Click Close to return to the EC2 dashboard.

09 Once the AMI is ready (its status changes from pending to available), use it to re-launch the selected app-tier instance and attach the newly created IAM role (instance profile). To launch the EC2 instance, perform the following actions:

  1. Click the Launch Instance button from the EC2 dashboard top menu to start the process.
  2. On Choose an Amazon Machine Image (AMI) page, choose My AMIs tab then select the AMI created at step no. 8.
  3. On Choose an Instance Type page, select the same instance type used by the source instance, then click Next: Configure Instance Details button.
  4. On Configure Instance Details page, select the new role from the IAM role dropdown list and configure any other options available on the page based on your requirements. Click Next: Add Storage and go through the next pages until you reach the Configure Security Group page, without changing any configuration settings.
  5. On Configure Security Groups, choose Select an existing security group and select the security group attached to the source instance. Click the Review and Launch button, review your app-tier instance configuration details and click Launch.
  6. In the Select an existing key pair or create a new key pair dialog box, select Choose an existing key pair and use the same key pair as the source app-tier instance. Check I acknowledge that I have access to the selected private key file option then click Launch Instances.
  7. Click View Instances to return to the Instances page.

10 Once you have verified and tested the new app-tier EC2 instance, you can transfer the Elastic IP (EIP) from the source EC2 instance to the new instance (if any). If the source instance does not have an EIP attached, you will need to update the domain DNS record(s) or any other app application references to switch to the new IP. To transfer the EIP, perform the following:

  1. In the navigation panel, under NETWORK & SECURITY, select Elastic IPs.
  2. Select the EIP address attached to the source app-tier instance, click on the Actions dropdown button, then select Disassociate Address.
  3. In the Disassociate Address dialog box, review the details then click Yes, Disassociate.
  4. Select the same address, disassociated in the previous step, click the ActionsA dropdown button then select Associate Address.
  5. In the Associate Address dialog box, select the new app-tier instance created at step no. 9 from the Instance dropdown list and then click Associate to attach the Elastic IP.

11 Now it’s safe to shut down the source EC2 instance in order to stop incurring charges for the resource. To terminate the instance, perform the following actions:

  1. In the navigation panel, under INSTANCES, select Instances.
  2. Select the app-tier EC2 instance that you want to shut down.
  3. Click the Actions dropdown button from the dashboard top menu, select Instance State and click Terminate.
  4. In the Terminate Instances confirmation box, review the instance details then click Yes, Terminate.

12 Repeat steps no. 8 – 11 to attach IAM roles to other app-tier EC2 instances launched in the selected region.

13 Change the AWS region from the navigation bar and repeat steps no. 8 – 12 for other regions.

Using AWS CLI

01 Create the trust relationship policy for the required IAM role. To create the trust relationship policy for the new role, paste the following information into a new policy document named cc-iam-role-trust-policy.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

02 Run create-role command (OSX/Linux/UNIX) to create the necessary Amazon IAM role using the trust relationship policy defined at the previous step:

aws iam create-role
	--role-name cc-app-tier-role
	--assume-role-policy-document file://cc-iam-role-trust-policy.json

03 The command output should return the new IAM role metadata:

{
    "Role": {
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "Service": "ec2.amazonaws.com"
              },
              "Action": "sts:AssumeRole"
            }
          ]
        },
        "RoleId": "ABCDABCDABCDABCDABCD",
        "CreateDate": "2019-03-11T11:32:12.252Z",
        "RoleName": "cc-app-tier-role",
        "Path": "/",
        "Arn": "arn:aws:iam::123456789012:role/cc-app-tier-role"
    }
}

04 To define the IAM role permissions, based on the policy type used by the role, perform one of the following set of commands:

  1. To attach managed IAM policies:
    • Run attach-role-policy command (OSX/Linux/UNIX) to attach the specified IAM managed policy to the newly created IAM role (the command does not produce an output):
      aws iam attach-role-policy
      	--policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess
      	--role-name cc-app-tier-role
      
  2. For define and attach inline IAM policies:
    • To define the inline policy for the IAM role, paste your own custom policy into a new JSON-based policy document named "cc-iam-role-inline-access-policy.json". The following example, provides full access to AWS EC2 resources (ver. 4):
      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Action": "ec2:*",
                  "Effect": "Allow",
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": "elasticloadbalancing:*",
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": "cloudwatch:*",
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": "autoscaling:*",
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": "iam:CreateServiceLinkedRole",
                  "Resource": "*",
                  "Condition": {
                      "StringEquals": {
                          "iam:AWSServiceName": [
                              "autoscaling.amazonaws.com",
                              "ec2scheduled.amazonaws.com",
                              "elasticloadbalancing.amazonaws.com",
                              "spot.amazonaws.com",
                              "spotfleet.amazonaws.com"
                          ]
                      }
                  }
              }
          ]
      }
      
    • Run put-role-policy command (OSX/Linux/UNIX) to attach the inline policy defined at the previous step to the new IAM role (the command does not return an output):
      aws iam put-role-policy
      	--role-name cc-app-tier-role
      	--policy-name iam-role-inline-policy
      	--policy-document file://cc-iam-role-custom-access-policy.json
      

05 Create the required IAM instance profile. An instance profile is a container for the IAM role that is attached to the EC2 instance during the launch process. Run create-instance-profile command (OSX/Linux/UNIX) to create the new AWS IAM instance profile:

aws iam create-instance-profile
	--region us-east-1
	--instance-profile-name cc-app-tier-instance-profile

06 The command output should return the newly created instance profile metadata:

{
    "InstanceProfile": {
        "InstanceProfileId": "ABCDABCDABCDABCDABCD",
        "Roles": [],
        "CreateDate": "2018-03-11T19:34:14.600Z",
        "InstanceProfileName": "cc-app-tier-instance-profile",
        "Path": "/",
        "Arn": "arn:aws:iam::123456789012:instance-profile/cc-app-tier-instance-profile"
    }
}

07 Run add-role-to-instance-profile command (OSX/Linux/UNIX) to integrate the IAM role created at step no. 2 with the IAM instance profile created at step no. 5 (the command does not produce an output):

aws iam add-role-to-instance-profile
	--role-name cc-app-tier-role
	--instance-profile-name cc-app-tier-instance-profile

08 Now that the app-tier IAM role is ready for use, run create-image command (OSX/Linux/UNIX) to create an AMI from the source app-tier instance (see Audit section part II to identify the right EC2 resource). Include --no-reboot command parameter to guarantee the file system integrity for your new image:

aws ec2 create-image
	--region us-east-1
	--instance-id i-01234567890aabbcc
	--name "AMI for app-tier instance without IAM role(s) attached"
	--description "App Stack AMI"
	--no-reboot

09 The command output should return the ID of the new AWS AMI:

{
    "ImageId": "ami-1234abcd"
}

10 Execute run-instances command (OSX/Linux/UNIX) to launch a new app-tier EC2 instance from the image created at the previous steps. The following command example re-creates an app-tier instance using an AMI with the ID ami-1234abcd and the IAM instance profile that integrates the app-tier IAM role created earlier:

aws ec2 run-instances
	--region us-east-1
	--iam-instance-profile Name=cc-app-tier-instance-profile
	--image-id ami-abcd1234
	--count 1
	--instance-type m4.xlarge
	--key-name cc-auth-key
	--security-groups cc-app-stack-sg

11 The command output should return the new app-tier instance configuration metadata:

{

    {
            "OwnerId": "123456789012",
            "Instances": [

                    ...

                    "Architecture": "x86_64",
                    "RootDeviceType": "ebs",
                    "IamInstanceProfile": {
                        "Id": "ABCDABCDABCDABCDABCD",
                        "Arn": "arn:aws:iam::123456789012:instance-profile/cc-app-tier-instance-profile"
                    },
                    "RootDeviceName": "/dev/xvda",
                    "VirtualizationType": "hvm",

                    ...

                    "AmiLaunchIndex": 0
                }
            ]
        }
    ]
}

12 Transfer the Elastic IP from the source EC2 instance to the new app-tier instance in order to reference the new EC2 resource. To transfer the Elastic IP, perform the following commands:

  1. Run disassociate-address command (OSX/Linux/UNIX) to detach the Elastic IP (EIP) address from the source EC2 instance:
    aws ec2 disassociate-address
    	--association-id eipassoc-abcd1234
    
  2. Run associate-address command (OSX/Linux/UNIX) to associate the EIP address detached at the previous step with the new app-tier instance:
    aws ec2 associate-address
    	--instance-id i-01234567890bbaacc
    	--allocation-id eipalloc-abcd1234
    

13 Once you have finished testing your new app-tier EC2 instance, you can safely terminate the source instance to stop incurring charges for it. To shut down the source EC2 instance run terminate-instances command (OSX/Linux/UNIX) using the instance ID as identifier:

aws ec2 terminate-instances
	--instance-ids i-01234567890aabbcc

14 The command output should return the shutdown request metadata:

{
    "TerminatingInstances": [
        {
            "InstanceId": "i-01234567890aabbcc",
            "CurrentState": {
                "Code": 32,
                "Name": "shutting-down"
            },
            "PreviousState": {
                "Code": 16,
                "Name": "running"
            }
        }
    ]
}

15 Repeat steps no. 5 – 14 to assign IAM roles to other app-tier EC2 instances available in the selected region.

16 Change the AWS region by updating the --region command parameter value and repeat steps no. 5 – 15 for other regions.

References

Publication date Mar 14, 2018