Automation runbook to create an AMI for an instance and copy it to another region
One of the AWS SAA questions is about designing resilient architectures.
AMI can be copied to another region.
You can copy an Amazon Machine Image (AMI) within or across AWS Regions.
Copy an AMI
This time, we will create an SSM Automation runbook, create an AMI from an existing EC2 instance, and copy this to another region.
Environment
Create an EC2 instance in a private subnet.
The instance will be the latest Amazon Linux 2.
Create an SSM Automation runbook.
The contents of this runbook are as follows
- Create an AMI for the instance.
- Copy the created AMI to another region.
The region where the EC2 instance is located is ap-northeast-1, and the region where the AMI is copied is us-east-1.
It also creates an association between this runbook and the instance.
CloudFormation template files
The above configuration is built with CloudFormation.
The CloudFormation templates are placed at the following URL
https://github.com/awstut-an-r/awstut-saa/tree/main/01/005
Explanation of key points of template files
(Reference) EC2
Resources:
Instance:
Type: AWS::EC2::Instance
Properties:
IamInstanceProfile: !Ref InstanceProfile
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
NetworkInterfaces:
- DeviceIndex: 0
SubnetId: !Ref PrivateSubnet
GroupSet:
- !Ref InstanceSecurityGroup
Tags:
- Key: !Ref TagKey
Value: !Ref TagValue
Code language: YAML (yaml)
The tag setting is the key point.
This is because SSM association, described below, specifies target instances based on this tag information.
This time, set the tags as follows
- Tag Name: MyRunbook
- Tag Value: true
SSM Automation Runbook
Resources:
CreateAndCopyImageRunbook:
Type: AWS::SSM::Document
Properties:
Content:
assumeRole: "{{AutomationAssumeRole}}"
description: Create and Copy AMI to another region.
schemaVersion: "0.3"
parameters:
AutomationAssumeRole:
type: String
description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf.
default: ""
DestinationRegion:
type: String
description: (Required) The Region to copy image to.
InstanceId:
type: String
description: (Required) The instance ID you want to run commands on.
default: ""
mainSteps:
- name: createImage
action: aws:createImage
maxAttempts: 1
onFailure: Abort
inputs:
InstanceId: "{{InstanceId}}"
ImageName: "{{InstanceId}}_{{global:DATE_TIME}}"
NoReboot: true
- name: copyImage
action: aws:executeScript
inputs:
Runtime: python3.8
Handler: handler
InputPayload:
DestinationRegion: "{{DestinationRegion}}"
InstanceId: "{{InstanceId}}"
SourceImageId: "{{createImage.ImageId}}"
SourceRegion: "{{global:REGION}}"
Script: |-
import boto3
import datetime
def handler(events, context):
destination_region = events['DestinationRegion']
instance_id = events['InstanceId']
source_image_id = events['SourceImageId']
source_region = events['SourceRegion']
now = datetime.datetime.now()
d = now.strftime('%Y-%m-%d_%H.%M.%S')
client = boto3.client('ec2', region_name=destination_region)
response = client.copy_image(
Description='test copy',
Name='{instance_id}_{datetime}'.format(instance_id=instance_id, datetime=d),
SourceImageId=source_image_id,
SourceRegion=source_region
)
return response
DocumentFormat: YAML
DocumentType: Automation
Name: !Sub "${Prefix}-CreateAndCopyImageRunbook"
TargetType: /AWS::EC2::Instance
Code language: YAML (yaml)
Create a custom runbook.
For more information on creating runbooks, please see the following pages.
The Content property defines the contents of the runbook.
In the parameters data element, specify the parameters for executing this runbook.
In this case, we receive the following three parameters
- AutomationAssumeRole: ARN of the service role that Autometion will use to run this runbook
- DestinationRegion: Region to which the AMI will be copied
- InstanceId: ID of the instance where the AMI will be created
The mainSteps data element describes the process to be executed in the runbook.
This runbook consists of two steps.
Step 1
The first step is to create an AMI from the instance.
AMI creation is done using the aws:createImage action provided by SSM Automation.
https://docs.aws.amazon.com/systems-manager/latest/userguide/automation-action-create.html
Specify the parameters required to run aws:createImage on inputss.
You can check the above page for the parameters that can be given when executing this action, but this time we will set three (InstanceId, ImageName, NoReboot).
When specifying parameters to be passed to ImageName, the automation system variables are referenced.
The date and time of execution can be obtained by using “global:DATE_TIME”.
For details on automation system variables, please refer to the following page.
https://docs.aws.amazon.com/systems-manager/latest/userguide/automation-variables.html
Step 2
The second step is to copy the AMI you just created to another region.
AMI copying is done using the action aws:executeScript provided by SSM Automation.
Runs the Python or PowerShell script provided using the specified runtime and handler.
aws:executeScript – Run a script
Specify the parameters required to run aws:executeScript on inputss.
InputPayload and Script are especially important parameters.
The former specifies parameters to be passed to the script described below.
SourceImageId refers to the ImageId received as a result of the execution of aws:createImage in the first step.
In SourceRegion, refer to the automation system variable global:REGION.
This region is the region where the EC2 instance is created and Automation is executed, i.e., the region from which the AMI is copied.
The Script parameter describes the script to be executed.
In this case, we will specify Python code.
The content of the code to be executed is as follows
- Receive the variables set in InputPayload.
- Create a client object for boto3 EC2.
- Execute the copy_image method of the client object to copy the AMI.
- Return the result of the method execution.
The key to copying an AMI is to create a client object.
When creating the object, specify the copy destination in the region_name parameter.
This will allow you to copy the AMI to the intended region.
In SSM Automation, if you simply want to copy an AMI, you can also execute the aws:copyImage action.
https://docs.aws.amazon.com/systems-manager/latest/userguide/automation-action-copyimage.html
However, this action allows the source region to be specified, but not the destination region, so it was not used because it did not meet the requirements of this project.
SSM Association
Resources:
CreateAndCopyImageAssociation:
Type: AWS::SSM::Association
Properties:
AssociationName: !Sub "${Prefix}-CreateAndCopyImageAssociation"
AutomationTargetParameterName: InstanceId
Name: !Ref CreateAndCopyImageRunbook
Parameters:
AutomationAssumeRole:
- !GetAtt CreateAndCopyImageRunbookRole.Arn
DestinationRegion:
- !Ref DestinationRegion
InstanceId:
- "{{RESOURCE_ID}}"
Targets:
- Key: !Sub "tag:${TagKey}"
Values:
- !Ref TagValue
WaitForSuccessTimeoutSeconds: !Ref WaitForSuccessTimeoutSeconds
Code language: YAML (yaml)
Associate the aforementioned runbook with an EC2 instance.
For information on how to create SSM associations and run SSM Automation runbooks on EC2 instances, please see the following page.
In the Targets property, set the tag information so that the aforementioned EC2 instance is the target of the association.
IAM Role for SSM
Resources:
CreateAndCopyImageRunbookRole:
Type: AWS::IAM::Role
DeletionPolicy: Delete
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- ssm.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole
Policies:
- PolicyName: CreateAndCopyImagePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- iam:PassRole
Resource:
- "*"
Code language: YAML (yaml)
Normally, if no service role is specified, the default service link role (SLR), AWSServiceRoleforAmazonSSM, is used.
In this case, create the service role according to the following official AWS page.
https://docs.aws.amazon.com/systems-manager/latest/userguide/automation-setup-iam.html
In addition, grant the necessary permissions (iam:PassRole) for AMI creation and sharing as an inline policy.
Architecting
Use CloudFormation to build this environment and check its actual behavior.
Create CloudFormation stacks and check the resources in the stacks
Create CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following pages.
After reviewing the resources in each stack, information on the main resources created in this case is as follows
- EC2 instance: i-07bd1e5c166136c88
- SSM Automation runbook: saa-01-005-CreateAndCopyImageRunbook
- SSM association: 9954eb73-83f6-4652-aa5b-4e29f78d4cab
Operation Check
Now that you are ready, check each resource from the AWS Management Console.
EC2 Instance
The instance is successfully created.
The tag information shows that a tag specifying the target of the association has been set.
SSM Automation Runbook
Check the runbook you have created.
You can see that the runbook has been successfully created.
There are three parameters in this runbook, the contents of which are to copy the AMI of the EC2 instance to another region after it is created.
SSM Association
Check association.
You can see that an association has been created for the aforementioned runbook.
Parameters for running the runbook.
Specify the IAM role, instance ID, and copy destination region.
Note that the instance ID is a pseudo-parameter.
https://docs.aws.amazon.com/systems-manager/latest/userguide/mw-cli-register-tasks-parameters.html
An association is created with an instance that meets the tag criteria.
SSM Automation
Check the execution history of Automation.
Automation is started for the instance.
Check the history of Step 1.
aws:createImage has been executed and an AMI for the instance has been created.
The ID of the AMI created this time is “ami-011aba43717b3cfcd”.
Then check step 2.
The aws:executeScript has been executed and the AMI created in step 1 has been copied to another region.
The ID of the AMI created this time is “ami-056701e3b4d8001d8”.
Check the created AMI.
First is the AMI from which the copy was made.
Indeed, an AMI is created in the Tokyo region (ap-northeast-1).
Next is the AMI to copy to.
The AMI is indeed copied to the Virginia Region (us-east-1).
Summary
We have shown you how to create an SSM Automation runbook, create an AMI from an existing EC2 instance, and copy this to another region.