Dynamic AMI Selection in AWS CloudFormation: Leveraging SSM Parameter Store

Introduction
In the original article, "Demystifying AWS CloudFormation: Understanding Key Template Sections", we created a CloudFormation template with a static mapping for AMI IDs. While functional, it has drawbacks like manual updates and limited region support. In this follow-up, we’ll improve the template by using AWS Systems Manager (SSM) Parameter Store to dynamically retrieve the latest AMI IDs—making your infrastructure code more flexible, maintainable, and region-independent. Additionally, since this article explores the Parameters section in depth, we’ll focus on how SSM integrates with it to enhance reusability and automation.
The 3 Critical Problems with Static AMI Mappings
Before diving into the solution, let's understand why static mappings in CloudFormation templates are problematic:
- Constant Manual Updates Required: Amazon Machine Images (AMIs) are regularly updated with security patches and new features. With static mappings, you must edit your templates with each new AMI release.
- Regional Limitations: If your template only includes mappings for specific regions (like us-east-1 and us-west-2), it will fail when deployed to other regions like eu-central-1 or ap-southeast-2.
- Poor Scalability: As your infrastructure grows across more AWS regions, the maintenance burden increases exponentially with each new region added to your mappings.
What is SSM Parameter Store?
AWS Systems Manager Parameter Store provides a centralised repository for configuration data management. For CloudFormation users, its most valuable feature is access to public parameters that AWS maintains - including up-to-date AMI IDs for all standard AWS images.
This service eliminates the need to track and update AMI IDs manually, as AWS automatically refreshes these parameters when new AMIs are released.
Step-by-Step: Converting Your Template to Use SSM Parameters
Let's transform a basic CloudFormation template to leverage SSM Parameter Store:
Step 1: Remove Your Static Mappings Section
First, identify and remove the outdated static mapping section in your template:
Mappings:
RegionMap:
us-east-1:
AMI: ami-0c55b159cbfafe1f0
us-west-2:
AMI: ami-0c94855ba95c71c99
Step 2: Add an SSM Parameter
Add this parameter definition to fetch the latest Amazon Linux 2 AMI:
Parameters:
LatestAmiId:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
Description: Latest Amazon Linux 2 AMI ID from SSM Parameter Store.
The parameter type AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
tells CloudFormation to retrieve the value from SSM Parameter Store and validate it as a valid EC2 Image ID.
Step 3: Update Your EC2 Instance Resource
Finally, update your EC2 instance to reference the new parameter:
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
ImageId: !Ref LatestAmiId
SecurityGroupIds:
- !Ref InstanceSecurityGroup
Notice how ImageId: !FindInMap [RegionMap, !Ref AWS::Region, AMI]
has been replaced with the simpler ImageId: !Ref LatestAmiId
.
Key Benefits of Using SSM Parameter Store
This approach delivers significant advantages for CloudFormation users:
- Always Up-to-Date: Your templates automatically use the latest secure AMIs without any manual intervention
- Work Anywhere: Deploy to any AWS region without modifying your template
- Reduced Maintenance: Eliminate the time spent tracking and updating AMI IDs
- Improved Security: Automatically incorporate security patches in new AMIs
Complete Working Template With SSM Parameter Store Integration
Here's the complete CloudFormation template incorporating SSM Parameter Store:
AWSTemplateFormatVersion: '2010-09-09'
Description: A simple EC2 instance with SSM Parameter Store for dynamic AMI selection.
Parameters:
InstanceType:
Type: String
Default: t2.micro
AllowedValues: [t2.micro, t2.small, t2.medium]
Description: Enter t2.micro, t2.small, or t2.medium. Default is t2.micro.
KeyName:
Type: AWS::EC2::KeyPair::KeyName
Description: Name of an existing EC2 KeyPair for SSH access.
SSHLocation:
Type: String
Default: 0.0.0.0/0
Description: The IP range that can SSH to the instance (e.g., 203.0.113.0/24).
AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
LatestAmiId:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
Description: Latest Amazon Linux 2 AMI ID from SSM Parameter Store.
Resources:
InstanceSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Enable SSH access
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: !Ref SSHLocation
EC2Instance:
Type: AWS::EC2::Instance
Properties:
InstanceType: !Ref InstanceType
KeyName: !Ref KeyName
ImageId: !Ref LatestAmiId
SecurityGroupIds:
- !Ref InstanceSecurityGroup
Outputs:
InstanceId:
Description: The Instance ID
Value: !Ref EC2Instance
PublicIP:
Description: Public IP address of the instance
Value: !GetAtt EC2Instance.PublicIp
Common SSM Parameter Paths for AWS AMIs
Here are some useful SSM parameter paths for different AWS AMIs:
Operating System | SSM Parameter Path |
---|---|
Amazon Linux 2 | /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 |
Amazon Linux 2023 | /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 |
Ubuntu 22.04 LTS | /aws/service/canonical/ubuntu/server/22.04/stable/current/amd64/hvm/ebs-gp2/ami-id |
Windows Server 2022 | /aws/service/ami-windows-latest/Windows_Server-2022-English-Full-Base |
CentOS Stream 9 | /aws/service/marketplace/ami-centos-latest/centos-stream-9-x86_64 |
Debian 12 | /aws/service/debian/server/12/stable/current/amd64/hvm/ebs-gp2/ami-id |
Implementing the Solution: Practical Steps
- Save the Template: Copy the YAML into a file named
ec2-template-ssm.yaml
- Create a Stack:
- Navigate to CloudFormation in the AWS Console
- Select "Create stack" > "With new resources"
- Upload your
ec2-template-ssm.yaml
file - Configure parameters as needed (instance type, key pair, IP range)
- Review and create the stack
- Verify the Solution: Check the "Outputs" tab after stack creation to find your instance ID and public IP address
Advanced Techniques: Using Multiple AMI Parameters
For more complex deployments requiring different AMI types, you can define multiple SSM parameters:
Parameters:
AmazonLinux2AMI:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
Ubuntu2204AMI:
Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
Default: '/aws/service/canonical/ubuntu/server/22.04/stable/current/amd64/hvm/ebs-gp2/ami-id'
Then reference them in different resources as needed.
Conclusion: Future-Proof Your CloudFormation Templates
By integrating SSM Parameter Store into your CloudFormation templates, you've eliminated one of the most common maintenance headaches in infrastructure as code. Your templates are now:
- More resilient to AMI changes
- Deployable across all AWS regions
- Easier to maintain and share
- Automatically updated with security patches
This approach aligns with AWS best practices for infrastructure as code and exemplifies the "automate everything" philosophy of modern DevOps.
Ready to take your CloudFormation skills to the next level? Start by updating your existing templates to incorporate SSM Parameter Store today.
FAQ About CloudFormation and SSM Parameter Store
Q: Will this work for Windows Server AMIs too?
A: Yes, AWS maintains SSM parameters for Windows Server AMIs as well.
Q: Can I use this technique with AWS CDK?
A: Absolutely! AWS CDK supports SSM parameters through the aws-ec2
module.
Q: Does this work in all AWS regions?
A: Yes, SSM parameters are available in all commercial AWS regions.
Q: What if I need a specific AMI version instead of the latest?
A: AWS also provides versioned parameters, allowing you to select specific AMI versions if needed.
Member discussion