Fetching Amazon Linux AMI-ID using SSM and Terraform or AWS CloudFormation

Moosa Khalid
3 min readJan 23, 2021

It’s a nice sunny day. You’re sitting outside and a gentle, cool breeze is sweeping across the top of the trees.

A calm, peaceful day out! (PC: unplash.com)

All of a sudden, a light bulb turns on over your head(a figurative one). You finally have a solution for fixing that pesky bug that had kept you up many nights, but before you can test out your awesome idea you need to test it out on an Amazon Linux 2 AMI, particularly, since that’s the de facto development environment your company uses.

You’re pretty savvy with the AWS CLI, however, your joy turns into annoyance as you realize that you have no idea about the AMI ID for Amazon Linux 2 and you don’t want to go through 4 or 5 steps to log into AWS Console to spin up your instance. Hell, there’s no person on this earth who can remember an AMI ID, let alone Amazon Linux 2’s AMI ID.

Well, fear not, nor be frustrated……AWS Systems Manager Parameter Store and Amazon’s own pity on your soul have teamed up to bring to you SSM parameters which track the AMI ID of your favorite Amazon Linux 2 AMI’s. Yes, you heard it right, there are publicly available(region-based) SSM parameters which you can poll and get the AMI-ID against, so you don’t have to use expensive aws ec2 decribe-images API calls with complex filters to look for and sort the latest Amazon AMI’s.

How would one accomplish this you may ask……well, keep on reading.

You’ll need to query the public SSM parameter path exposed by AWS, exactly for this purpose. The base path for every SSM parameter that pertains to Amazon Linux image would be:

/aws/service/ami-amazon-linux-latest/

Beyond this SSM parameter path above you’ll need to pass in the actual identifier for the AMI in question, but if you choose to query up to this path it should return you a list of available AMI ID’s , from which you can pick and choose however you can provide a more specific path to get an exact image and the best part is that the string remains the same regardless if the AMI ID it is referencing changes in the back end.

Here’s an example command for getting the exact value of an Amazon Linux 2 AMI in us-west-2 region. Of course for this you’ll need the read only ssm:GetParametersByPath and ssm:GetParameters set against your IAM user or role.

aws ssm get-parameters \
--names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 \
--query 'Parameters[0].[Value]' \
--output text --region us-west-2

You can leave out the “-- query” filter to get a more verbose result for the object returned.

Well now that I have warmed you all up to SSM Parameter store’s part in this. Let’s showcase a snippet of Terraform and CloudFormation code depicting how to do the same thing with these two tools.

In Terraform you would use the data resource “aws_ssm_parameter” like so

data "aws_ssm_parameter" "my-amzn-linux-ami" {  
name = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}

… and to access the value of returned AMI in Terraform code you’d reference this variable data.aws_ssm_parameter.my-amzn-linux-ami.value

And here’s the same thing in AWS CloudFormation:

"Parameters": {    "LatestAmiId": {        "Type": "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>",        "Default": "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"    }}

The trick with using this SSM Parameter store feature in CloudFormation is that you declare it as a parameter of type :

AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>

As a default value for this parameter you can pass in the string:

/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2

which should resolve to the AMI of latest Amazon Linux 2 AMI, that can be referenced elsewhere in your CloudFormation template using:

{"Ref":"LatestAmiId"}

So this was a quick primer on using this cool feature and not having to go looking for AMI ID’s ever again. Of course the best thing would be to use serverless designs and not have to use virtual machines like EC2 instances at all, but honestly, who’re we kidding, nobody can escape the temptation of spinning a couple of good old EC2 instances.

--

--

Moosa Khalid

Hi My name is Moosa. I love infrastructure as code and party parrot emojis. More often then not you'll find me breaking things before I can get them to work!