Keeping your AMIs up to date in CloudFormation

22 Apr, 2018
Xebia Background Header Wave

Referencing virtual machines images in your CloudFormation template is hard. You have to lookup the image you want to use and copy
its non-descriptive id (ami-xxxxxxx) into the template. If you deploy to multiple regions, you have to lookup and add these ids too. Whenever a new version of the virtual machine image is available, you have to repeat the whole process. With our Custom CloudFormation Provider and maintenance utility, referencing virtual machine images becomes both easy to read and maintain.
To ease the specification and maintenance of virtual machine image ids in CloudFormation, we created a
Custom CloudFormation Resource Custom::AMI and a maintainance utility called aws-cfn-update.
The Custom Resource allows you to specify a virtual machine image by name. The utility aws-cfn-update provides the ability
to update these Custom Resource definitions in your templates from the command line.

Specifying an AMI by name

To specify an AMI by name, add a Custom::AMI resource
to your template:

    Type: Custom::AMI
        name: 'amzn-ami-2017.09.a-amazon-ecs-optimized'
      ServiceToken: !Sub 'arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:binxio-cfn-ami-provider'

The Filters property allows you to specify which AMI you want.The name of the image is sufficient, but if you want you can go wild and specify any of the parameters defined in the EC2 describe-images API call.
Once you have added the custom AMI resource definition, you can get the id as follows:

    Type: AWS:EC2::Instance
        Type: AWS::EC2::Instance
            ImageId: !Ref AMI

Keeping your AMI up to date

To keep the AMI up to date, you can use the utility aws-cfn-update:

aws-cfn-update latest-ami --ami-name-pattern 'amzn-ami-2017.09.a-amazon-ecs-optimized' .

The utility takes an AMI name pattern to search for the latest AMI using the describe-images API. The utility will update the name property of the filter if a newer version exists.
Do you want to try it? Than install the custom resource provider and the utility.

Installing the custom resource provider

To install this custom resource provider, type:

aws cloudformation create-stack \
 --capabilities CAPABILITY_IAM \
 --stack-name cfn-ami-provider \
 --template-body file://cloudformation/cfn-ami-provider.json 

aws cloudformation wait stack-create-complete  --stack-name cfn-ami-provider 

This CloudFormation template will use our pre-packaged provider from s3://binxio-public-${AWS_REGION}/lambdas/

installing the aws-cfn-updae utility

To install the aws-cfn-update utility, type:

pip install aws-cfn-update


To demonstrate the use of the Custom Resource, type:

aws cloudformation create-stack --stack-name cfn-ami-provider-demo \
 --template-body file://cloudformation/demo-stack.json
aws cloudformation wait stack-create-complete  --stack-name cfn-ami-provider-demo

and update the template, by typing:

aws-cfn-update latest-ami --ami-name-pattern 'amzn-ami-2017.09.a-amazon-ecs-optimized ./cloudformation

Checkout the updated Custom::AMI resource definition (git diff) and update the template:

aws cloudformation update-stack --stack-name cfn-ami-provider-demo \
 --template-body file://cloudformation/demo-stack.json
aws cloudformation wait stack-update-complete  --stack-name cfn-ami-provider-demo


With this custom CloudFormation Provider and update utility you can declare and maintain an AMI by name, which will ease
the maintainability of your CloudFormation templates.

Mark van Holsteijn
Mark van Holsteijn is a senior software systems architect at Xebia Cloud-native solutions. He is passionate about removing waste in the software delivery process and keeping things clear and simple.

Get in touch with us to learn more about the subject and related solutions

Explore related posts