Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Approved/Golden AMIs

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: Medium (should be achieved)
Rule ID: EC2-028

Ensure that all the Amazon EC2 instances necessary for your application stack are launched from approved Amazon Machine Images (AMIs), also known as golden AMIs, in order to enforce consistency and save time when scaling your cloud applications. The AMI(s) approved by your organization must be defined in the conformity rule settings, on the Trend Cloud One™ – Conformity account console.

This rule can help you with the following compliance standards:

  • APRA
  • MAS
  • NIST4

For further details on compliance standards supported by Conformity, see here.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Security

An approved/golden AMI is a base image that contains a pre-configured OS and a well-defined stack of server software fully configured to run your application. Using golden AMIs to create new Amazon EC2 instances within your AWS environment brings major benefits such as fast and stable application deployment and scaling, secure application stack upgrades, and versioning. You can go even further and automate your golden AMIs creation with open source tools like Packer and Netflix Aminator.


Audit

To determine if your Amazon EC2 instances are being launched using approved Amazon Machine Images (AMI), perform the following operations:

Using AWS Console

01 Sign in to your Trend Cloud One™ – Conformity account, access Check for Approved (Golden) Amazon Machine Images conformity rule settings, and identify the ID(s) of the AMI(s) approved by your organization.

02 Sign in to the AWS Management Console.

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

04 In the navigation panel, under Instances, choose Instances.

05 Select the Amazon EC2 instance that you want to examine.

06 Choose the Details tab from the console bottom panel to access the instance configuration details.

07 In the Instance details section, check the AMI ID attribute value to identify the ID of the image used to launch the selected instance. Compare the AMI ID attribute value against each ID listed in the rule configuration section, identified at step no. 1. If the instance AMI ID is not found in the list of approved AMIs, the selected Amazon EC2 instance was not launched from an approved (golden) AMI, therefore the software configuration of the verified instance may not be secured.

08 Repeat steps no. 5 – 7 for each Amazon EC2 instance available within the current AWS cloud region.

09 Change the AWS region from the console navigation bar and repeat the audit process for other regions.

Using AWS CLI

01 Sign in to your Trend Cloud One™ – Conformity account, access Check for Approved (Golden) Amazon Machine Images conformity rule settings, and identify the ID(s) of the AMI(s) approved by your organization.

02 Run describe-instances command (OSX/Linux/UNIX) with custom query filters to list the IDs of the Amazon EC2 instances available in the selected AWS cloud 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 identifiers (IDs):

-------------------------
|   DescribeInstances   |
+-----------------------+
|  i-0abcdabcdabcdabcd  |
|  i-0abcd1234abcd1234  |
|  i-01234abcd1234abcd  |
+-----------------------+

04 Run describe-instances command (OSX/Linux/UNIX) using the ID of the Amazon EC2 instance that you want to examine as the identifier parameter and custom query filters to describe the ID of the image used to create the selected EC2 instance:

aws ec2 describe-instances
  --region us-east-1
  --instance-ids i-0abcdabcdabcdabcd
  --query 'Reservations[*].Instances[*].ImageId[]'

05 The command output should return the requested image ID:

[
    "ami-0abcd1234abcd1234"
]

Compare the image ID returned by the describe-instances command output against each ID listed in the rule configuration section, identified at step no. 1. If the instance image ID is not found in the list of approved AMIs, the selected Amazon EC2 instance was not launched from an approved (golden) AMI, therefore the software configuration of the verified instance may not be secured.

06 Repeat steps no. 4 and 5 for each Amazon EC2 instance provisioned in the selected AWS cloud region.

07 Change the AWS region by updating the --region command parameter value and repeat the audit process for other regions.

Remediation / Resolution

To create a golden/approved Amazon Machine Image (AMI) and force your AWS cloud administrators to launch Amazon EC2 instances using approved AMIs only, perform the following operations:

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf):

terraform {
    required_providers {
        aws = {
            source  = "hashicorp/aws"
            version = "~> 3.27"
        }
    }

    required_version = ">= 0.14.9"
}

provider "aws" {
    profile = "default"
    region  = "us-east-1"
}

# Create the base EC2 instance
resource "aws_instance" "base-ec2-instance" {

    ami = "ami-0abcdabcdabcdabcd"
    instance_type = "t2.micro"
    key_name = "ssh-key"
    subnet_id = "subnet-abcd1234"
    vpc_security_group_ids = [ "sg-01234abcd1234abcd" ]

    ebs_block_device {
        device_name = "/dev/xvda"
        volume_size = 30
        volume_type = "gp2"
    }

    user_data = <<-EOF
    #!/bin/bash
    sudo apt-get update -y
    sudo apt-get upgrade -y
    sudo apt install apache2 -y
    sudo systemctl start apache2
    sudo systemctl enable apache2
    EOF 

    tags = {
        Name = "Base Instance"  
    }  

}

# Create the Golden/Approved AMI
resource "aws_ami_from_instance" "golden-ami" {

    name = "approved-ami"
    source_instance_id = aws_instance.base-ec2-instance.id

    tags = {
        Name = "Golden AMI"  
    }  

}

# Enforce users to create EC2 instances from Golden AMI only
resource "aws_iam_policy" "admin-policy" {
    name = "golden-image-enforcement-policy"
    policy = jsonencode({
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "EnforceGoldenAMI",
                "Action": [
                    "ec2:RunInstances"
                ],
                "Effect": "Allow",
                "Resource": "*",
                "Condition": {
                    "StringEquals": {
                        "ec2:ResourceTag/Name": "Golden AMI"
                    }
                }
            }
        ]
    })
}

# Attach the enforcement policy to the EC2 admin group
resource "aws_iam_group_policy_attachment" "attach-group-policy" {
    group = "ec2-admin-group"
    policy_arn = aws_iam_policy.admin-policy.arn
}

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon EC2 console at https://console.aws.amazon.com/ec2/.

03 In the navigation panel, under Instances, choose Instances.

04 Choose Launch instances to create your base Amazon EC2 instance. During the instance launch you can pass user data (shell scripts, cloud-init directives, etc.) or use configuration management tools to automatically install server software on the new Amazon EC2 instance. To launch the base EC2 instance perform the following actions:

  1. For Step 1: Choose an Amazon Machine Image (AMI), choose the base Amazon Machine Image (AMI) for your new EC2 instance. You can select an AMI provided by AWS, AWS Marketplace, or another trusted provider.
  2. For Step 2: Choose an Instance Type, select the required instance type. Choose Next: Configure Instance Details to continue the setup process.
  3. For Configure Instance Details, configure the instance network, identity management, behavior, and metadata settings. Choose Next: Add Storage to continue the setup process.
  4. For Step 4: Add Storage, configure the storage device settings, then click Next: Add Tags to set up the instance tags.
  5. For Step 5: Add Tags, use the Add tag button to create and apply user-defined tags to the new EC2 instance. Choose Configure Security Group to continue the setup process.
  6. For Step 6: Configure Security Group, chooseSelect an existing security group and select the required security group(s). Choose Review and Launch to continue.
  7. For Step 7: Review Instance Launch, review your EC2 instance configuration details, then choose Launch.
  8. In the Select an existing key pair or create a new key pair configuration box, select Choose an existing key pair and use a secure key pair. Select the I acknowledge that I have access to the selected private key file (<key-name>.pem), and that without this file, I won't be able to log into my instance checkbox for confirmation, then choose Launch Instances to launch your new Amazon EC2 instance.
  9. Choose View Instances to return to the Instances page.

05 Once the new Amazon EC2 instance is running, install and configure the necessary software to run your application(s), secure the operating system (OS) and the software stack, and upload your application(s). Test the entire software stack to make sure that the new EC2 instance qualifies for the golden Amazon Machine Image (AMI).

06 Select the compliant Amazon EC2 instance created and configured at the previous steps.

07 Click on the Actions dropdown menu from the console top menu, select Image and templates, and choose Create image to create your golden (approved) AMI.

08 On the Create image setup page, provide the following information:

  1. In the Image name box, enter a unique name for the golden AMI.
  2. (Optional) In the Image description box, provide a short description that reflects the usage of the AMI.
  3. Deselect Enable under No reboot so that Amazon EC2 service can guarantee the file system integrity for the new AMI.
  4. (Optional) For Tags, chooseTag image and snapshots together and use the Add tag button to create and apply user-defined tags to the new image.
  5. Choose Create image to create your golden (approved) Amazon Machine Image (AMI).

09 Once the golden AMI is ready for use, update the access permissions of your AWS cloud administrator in order to enforce creating Amazon EC2 instances from the golden/approved AMI only. To enforce this restriction, you must create a custom IAM policy and attach it to the AWS cloud administrators group. To create the required policy, perform the following actions:

  1. Navigate to Amazon IAM console at https://console.aws.amazon.com/iam/.
  2. In the navigation panel, under Access management, choose Policies.
  3. Click on the Create policybutton from the console top menu to create a new custom policy.
  4. On the Create policy setup page, perform the following actions:
    • Select the JSON tab and paste the following policy document. Replace the highlighted information with your own information (i.e. the ARN of the snapshot associated with your golden AMI):
      {
          "Version": "2012-10-17",
          "Statement": [
          {
              "Sid": "cc-enforce-approved-image",
              "Action": [
                  "ec2:RunInstances"
              ],
              "Effect": "Allow",
              "Resource": "*",
              "Condition": {
                  "ArnEquals": {
                      "ec2:ParentSnapshot": "arn:aws:ec2:<aws-region>::snapshot/<snapshot-id>"
                  }
              }
          }
          ]
      }
      
    • Choose Next: Tags and use the Add tag button to create and apply user-defined tags to the new IAM policy.
    • Choose Next: Review and use the Name and Description fields to assign a unique name and a description for the IAM policy.
    • Choose Create policy to create your new IAM policy.

10 To attach the custom IAM policy create at the previous step to the AWS cloud administrators group, perform the following actions:

  1. In the navigation panel, under Access management, choose Groups.
  2. Click on the name of the IAM group that you want to reconfigure.
  3. Select the Permissions tab and choose Attach Policy.
  4. Select the name of the IAM policy created at step no. 7 and choose Attach Policy to attach the policy to the selected IAM group.

Using AWS CLI

01 Run run-instances command (OSX/Linux/UNIX) to create your base Amazon EC2 instance. Choose a base Amazon Machine Image (AMI) to create the new EC2 instance. You can use a secure AMI provided by AWS, AWS Marketplace, or another trusted provider:

aws ec2 run-instances
  --region us-east-1
  --image-id ami-01234abcd1234abcd
  --count 1
  --instance-type t2.micro
  --key-name conformity
  --security-group-ids sg-01234abcd1234abcd

02 The command output should return the metadata available for the newly created Amazon EC2 instance:

{
    "Groups": [],
    "Instances": [
        {
            "AmiLaunchIndex": 0,
            "ImageId": "ami-01234abcd1234abcd",
            "InstanceId": "i-01234123412341234",
            "InstanceType": "t2.micro",
            "KeyName": "conformity.aws",
            "LaunchTime": "2021-03-22T17:29:43+00:00",
            "Monitoring": {
                "State": "disabled"
            },
            "Placement": {
                "AvailabilityZone": "us-east-1e",
                "GroupName": "",
                "Tenancy": "default"
            },
            "PrivateDnsName": "ip-10-0-0-5.ec2.internal",
            "PrivateIpAddress": "10.0.0.5",
            "ProductCodes": [],
            "PublicDnsName": "",
            "State": {
                "Code": 0,
                "Name": "pending"
            },
            "StateTransitionReason": "",
            "SubnetId": "subnet-abcd1234",
            "VpcId": "vpc-1234abcd",
            "Architecture": "x86_64",
            "BlockDeviceMappings": [],
            "EbsOptimized": false,
            "EnaSupport": true,
            "Hypervisor": "xen",
            "IamInstanceProfile": "",
            "NetworkInterfaces": [
                {
                    "Attachment": {
                        "AttachTime": "2021-03-22T17:29:43+00:00",
                        "AttachmentId": "eni-attach-0abcd1234abcd1234",
                        "DeleteOnTermination": true,
                        "DeviceIndex": 0,
                        "Status": "attaching",
                        "NetworkCardIndex": 0
                    },
                    "Description": "",
                    "Groups": [
                        {
                            "GroupName": "cc-prod-security-group",
                            "GroupId": "sg-01234abcd1234abcd"
                        }
                    ],
                    "Ipv6Addresses": [],
                    "MacAddress": "06:00:c7:12:51:99",
                    "NetworkInterfaceId": "eni-0abcd1234abcd1234",
                    "OwnerId": "123456789012",
                    "PrivateDnsName": "ip-10-0-0-5.ec2.internal",
                    "PrivateIpAddress": "10.0.0.5",
                    "PrivateIpAddresses": [
                        {
                            "Primary": true,
                            "PrivateDnsName": "ip-10-0-0-5.ec2.internal",
                            "PrivateIpAddress": "10.0.0.5"
                        }
                    ],
                    "SourceDestCheck": true,
                    "Status": "in-use",
                    "SubnetId": "subnet-abcd1234",
                    "VpcId": "vpc-1234abcd",
                    "InterfaceType": "interface"
                }
            ],
            "RootDeviceName": "/dev/xvda",
            "RootDeviceType": "ebs",
            "SecurityGroups": [
                {
                    "GroupName": "cc-prod-security-group",
                    "GroupId": "sg-01234abcd1234abcd"
                }
            ],
            "SourceDestCheck": true,
            "StateReason": {
                "Code": "pending",
                "Message": "pending"
            },
            "VirtualizationType": "hvm",
            "CpuOptions": {
                "CoreCount": 1,
                "ThreadsPerCore": 1
            },
            "CapacityReservationSpecification": {
                "CapacityReservationPreference": "open"
            },
            "MetadataOptions": {
                "State": "pending",
                "HttpTokens": "optional",
                "HttpPutResponseHopLimit": 1,
                "HttpEndpoint": "enabled"
            },
            "EnclaveOptions": {
                "Enabled": false
            }
        }
    ],
    "OwnerId": "123456789012",
    "ReservationId": "r-0abcd1234abcd1234"
}

03 Once the new Amazon EC2 instance is running, install and configure the necessary software to run your application(s), secure the operating system (OS) and the software stack, and upload your application(s). Test the entire software stack to make sure that the new EC2 instance qualifies for the golden Amazon Machine Image (AMI).

04 Run create-image command (OSX/Linux/UNIX) to create your golden (approved) AMI from the base Amazon EC2 instance created and configured at the previous steps. Include the --no-reboot command parameter to guarantee the file system integrity for your new AMI:

aws ec2 create-image
  --region us-east-1
  --instance-id i-01234abcd1234abcd
  --name "Golden Amazon Machine Image (AMI)"
  --description "Project5 Approved-Golden Secure AMI"
  --no-reboot

05 The command output should return the ID of the golden Amazon Machine Image (AMI):

{
    "ImageId": "ami-0abcdabcdabcdabcd"
}

06 Once the golden AMI is ready for use, update the access permissions of your AWS cloud administrator in order to enforce creating Amazon EC2 instances from the golden/approved AMI only. To enforce this restriction, you must create a custom IAM policy and attach it to the AWS cloud administrators group. To implement the restriction, perform the following actions:

  1. Paste the following IAM policy document to a JSON file named cc-enforce-approved-image.json. Replace the highlighted information with your own information (i.e. the ARN of the EBS snapshot associated with your golden AMI):
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Sid": "cc-enforce-approved-image",
                "Action": [
                    "ec2:RunInstances"
                ],
                "Effect": "Allow",
                "Resource": "*",
                "Condition": {
                    "ArnEquals": {
                        "ec2:ParentSnapshot": "arn:aws:ec2:<aws-region>::snapshot/<snapshot-id>"
                    }
                }
            }
        ]
    }
    
  2. Run create-policy command (OSX/Linux/UNIX) to create the IAM policy that will force your AWS cloud administrators to create Amazon EC2 instances using the golden AMI only:
    aws iam create-policy
      --policy-name cc-approved-image-policy
      --policy-document file://cc-enforce-approved-image.json
    
  3. The command output should return the metadata available for the new IAM policy:
    {
        "Policy": {
            "PolicyName": "cc-approved-image-policy",
            "CreateDate": "2021-04-01T16:12:43.987Z",
            "AttachmentCount": 0,
            "IsAttachable": true,
            "DefaultVersionId": "v1",
            "Path": "/",
            "Arn": "arn:aws:iam::123456789012:policy/cc-approved-image-policy",
            "UpdateDate": "2021-04-01T16:12:43.987Z"
        }
    }
    
  4. Run attach-group-policy command (OSX/Linux/UNIX) to attach the IAM policy created at the previous steps to the AWS cloud administrators group (if the command request succeeds, no output is returned):
    aws iam attach-group-policy
      --policy-arn arn:aws:iam::123456789012:policy/cc-approved-image-policy
      --group-name cc-ec2-admin-group
    

References

Publication date Jun 2, 2016