DEV Community

1suleyman
1suleyman

Posted on

💻 Stop Hardcoding AMIs! Use Terraform to Automatically Fetch the Latest OS Image

Hey everyone 👋

If you’ve ever launched an EC2 instance with Terraform, chances are you’ve pasted in an AMI ID like it’s no big deal. But here’s the thing — AMI IDs are not your friends forever. They change, vary across regions, and hardcoding them can silently break your infrastructure.

Today I’ll walk you through a better approach using Terraform data sources. Trust me — once you try it, you’ll never want to hardcode another AMI ID again 👇


🧸 Think of AMIs Like Store Inventory (That Changes Every Day)

Let’s say you’re running a sandwich shop 🥪. Every morning, you check what ingredients just arrived. If you blindly use yesterday’s list (e.g., “use cheddar from Box 143”), you might be out of luck if Box 143 was replaced overnight.

Same thing with Amazon Machine Images (AMIs). Even if you’re always using Ubuntu 22.04, the actual AMI ID changes over time and by region.


⚠️ What’s Wrong With Hardcoding AMI IDs?

Here’s the typical (but flawed) approach:

resource "aws_instance" "web" {
  ami           = "ami-0fec8e9f3dc"
  instance_type = "t2.micro"
}
Enter fullscreen mode Exit fullscreen mode

It works… until:

  • 🔁 The AMI gets deprecated
  • 🌍 You switch to a different region
  • 🧱 A patch gets released and you miss it

💥 Result: your Terraform code fails silently or breaks when it shouldn’t.


🛠️ Enter data "aws_ami": Your Personal AMI Lookup Assistant

Instead of hardcoding, you can ask Terraform to dynamically fetch the latest AMI ID that matches your criteria.

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-amd64-server-*"]
  }
}
Enter fullscreen mode Exit fullscreen mode

Then reference it in your EC2 config:

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.image_id
  instance_type = "t2.micro"
}
Enter fullscreen mode Exit fullscreen mode

💡 Boom. This works across regions, always gets the latest AMI, and never needs manual updates.


🧠 Why This Is So Powerful

Works across regions
Each AWS region has its own AMI IDs. The data source will automatically find the right one.

Stays up-to-date
As new images are published (e.g., security patches), your code always uses the freshest one.

No more copy-paste mistakes
Less room for human error when building infra.


🔍 Quick Breakdown of What’s Happening

Terraform Block What It Does
data "aws_ami" Queries AWS for matching AMIs
filter Narrows results by name, architecture, etc.
most_recent Ensures you get the latest version
.image_id Gives you the actual AMI ID to use

⚙️ A Real-World Example: Ubuntu in Mumbai (ap-south-1)

Let’s say we want to launch an Ubuntu 22.04 instance in Mumbai region with the most recent AMI.

provider "aws" {
  region = "ap-south-1"
}

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-amd64-server-*"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.image_id
  instance_type = "t2.micro"
}
Enter fullscreen mode Exit fullscreen mode

✅ This will work today, tomorrow, next week — no matter how often Ubuntu pushes AMI updates.


😵 What About ARM vs AMD Architectures?

You might see errors like:

The architecture of the specified instance type does not match the architecture 'arm64' of the specified AMI

That’s just Terraform trying to launch an AMI built for ARM on an x86_64 instance. Just adjust your filter like this:

values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-amd64-server-*"]
Enter fullscreen mode Exit fullscreen mode

💡 Pro tip: Match your instance type (like t2.micro) with the correct AMI architecture (like amd64).


🧩 Final Thoughts

Using data "aws_ami" might feel like extra work at first, but it gives you:

  • Portability across regions
  • Freshness of latest OS images
  • Cleaner, more resilient code
  • Less maintenance in the long run

It’s one of those “small wins” that makes your Terraform code feel ✨ production-ready ✨.

Let me know if you’ve used this technique — or if you have any Terraform tips or stories to share. I’d love to connect on LinkedIn with more folks building cool things with IaC! 🙌

Top comments (0)