Automate EC2 AMI Build and Deployment with AWS Systems Manager
Consider a typical EC2-based application fronted by a load balancer with a number of EC2 instances in an auto-scaling group behind it. The application in this case is baked into the AMI of the instances. Every time a new app release is needed, a new AMI must be built.
The infrastructure is deployed using CloudFormation. The CloudFormation template accepts the AMI ID as a parameter. Every time a new AMI is built, the stack is updated manually with the new AMI ID. CloudFormation then gracefully decommissions the instances with the old AMI and deploys replacement instances with the new AMI.
This article describes a way to automate this entire workflow using Systems Manager. The automation will start by building the AMI and then go on to update the CloudFormation stack as well.
All this will be done using an Automation Document in Systems Manager. The document will have these steps:
- Create AMI by starting an image pipeline in EC2 image builder.
- Wait for the AMI to be built.
- Fetch the ID of the new AMI.
- Update CloudFormation stack with new AMI ID.
- Wait for stack update.
Many of these steps aren’t natively supported by Systems Manager documents but SSM documents can invoke any AWS API directly. We’ll use this feature to accomplish many of the steps!
EC2 Image Builder Pipeline
Before we can write the SSM document, we need a pipeline that will build the AMI. EC2 Image Builder is another service that lets us create such pipelines. Perform the first 3 steps of the following article to create the pipeline, then return here to build the SSM document:
Automate EC2 AMI Builds Triggered by Code Pushed to AWS CodeCommit Repositories
Systems Manager Automation Document
Let’s start writing the document. Go to console.aws.amazon.com/systems-manager/documents/create-document#documentType=Automation, provide a name for the document, scroll down to Step 1 in the Builder section, and let’s start building the document, one step at a time.
Start Image Pipeline
The first step is to invoke the StartImagePipelineExecution
API of the ImageBuilder
service. For this, fill in the Step 1 form as shown below:
The equivalent SSM document YAML is auto-generated by the UI:
name: StartImagePipelineExecution
action: 'aws:executeAwsApi'
inputs:
Service: imagebuilder
Api: StartImagePipelineExecution
imagePipelineArn: Provide ARN of the Image Pipeline here.
outputs:
- Type: String
Name: imageARN
Selector: $.imageBuildVersionArn
Wait for Image State = Available
Add Step 2 to wait for the image build to complete:
The equivalent YAML is generated:
name: WaitForImageStateAvailable
action: 'aws:waitForAwsResourceProperty'
inputs:
Service: imagebuilder
Api: GetImage
imageBuildVersionArn: '{{ StartImagePipelineExecution.imageARN }}'
PropertySelector: image.state.status
DesiredValues:
- AVAILABLE
Get AMI ID
Get the ID of the newly built AMI:
YAML:
name: GetAMI_ID
action: 'aws:executeAwsApi'
inputs:
Service: imagebuilder
Api: GetImage
imageBuildVersionArn: '{{ StartImagePipelineExecution.imageARN }}'
outputs:
- Selector: '$.image.outputResources.amis[0].image'
Type: String
Name: AMI_ID
Update CloudFormation Stack
Next, update the existing CloudFormation stack:
name: UpdateCloudFormationStack
action: 'aws:executeAwsApi'
inputs:
Service: cloudformation
Api: UpdateStack
StackName: Provide your stack name here.
UsePreviousTemplate: true
Parameters:
- ParameterKey: AMI_ID
ParameterValue: '{{ GetAMI_ID.AMI_ID }}'
Capabilities:
- CAPABILITY_IAM
Wait for CloudFormation
name: WaitForCloudFormationUpdateComplete
action: 'aws:waitForAwsResourceProperty'
inputs:
Service: cloudformation
Api: DescribeStacks
StackName: Your stack name.
PropertySelector: 'Stacks[0].StackStatus'
DesiredValues:
- UPDATE_COMPLETE
Conclusion
Finally, click the ‘Create automation’ button to create this automation document. You can now run this document whenever a new deployment is needed!
About the Author ✍🏻
Harish KM is a Principal DevOps Engineer at QloudX & a top-ranked AWS Ambassador since 2020. 👨🏻💻
With over a decade of industry experience as everything from a full-stack engineer to a cloud architect, Harish has built many world-class solutions for clients around the world! 👷🏻♂️
With over 20 certifications in cloud (AWS, Azure, GCP), containers (Kubernetes, Docker) & DevOps (Terraform, Ansible, Jenkins), Harish is an expert in a multitude of technologies. 📚
These days, his focus is on the fascinating world of DevOps & how it can transform the way we do things! 🚀