Bird
Raised Fist0
Terraformcloud~5 mins

AMI lookup data source example in Terraform - Commands & Configuration

Choose your learning style10 modes available
Introduction
When you want to launch a virtual machine in the cloud, you need an image to start from. This image is called an AMI in AWS. The AMI lookup data source helps you find the right image automatically, so you don't have to type its ID manually.
When you want to launch an EC2 instance with the latest Amazon Linux image without hardcoding the AMI ID.
When you need to find an AMI by name or owner to ensure you use a trusted image.
When you want your Terraform code to work in different AWS regions without changing AMI IDs manually.
When you want to automate updates to your infrastructure using the newest available AMI.
When you want to avoid errors caused by using outdated or incorrect AMI IDs.
Config File - main.tf
main.tf
provider "aws" {
  region = "us-east-1"
}

data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

resource "aws_instance" "example" {
  ami           = data.aws_ami.amazon_linux.id
  instance_type = "t2.micro"
  tags = {
    Name = "example-instance"
  }
}

This Terraform file does three main things:

  • Provider block: Sets AWS region to us-east-1.
  • Data source aws_ami: Looks up the most recent Amazon Linux 2 AMI owned by Amazon, filtering by name pattern.
  • Resource aws_instance: Creates an EC2 instance using the AMI found by the data source and sets instance type and tags.
Commands
This command sets up Terraform in the current folder by downloading the AWS provider plugin and preparing the environment.
Terminal
terraform init
Expected OutputExpected
Initializing the backend... Initializing provider plugins... - Finding latest version of hashicorp/aws... - Installing hashicorp/aws v4.60.0... - Installed hashicorp/aws v4.60.0 (signed by HashiCorp) Terraform has been successfully initialized! You may now begin working with Terraform. Try running "terraform plan" to see any changes that are required for your infrastructure.
This command shows what Terraform will do. It looks up the AMI and plans to create an EC2 instance using it.
Terminal
terraform plan
Expected OutputExpected
Refreshing Terraform state in-memory prior to plan... Data sources: + data.aws_ami.amazon_linux Terraform will perform the following actions: # aws_instance.example will be created + resource "aws_instance" "example" { + ami = "ami-0abcdef1234567890" + arn = (known after apply) + instance_type = "t2.micro" + tags = { + "Name" = "example-instance" } } Plan: 1 to add, 0 to change, 0 to destroy.
This command applies the plan and creates the EC2 instance using the AMI found by the lookup.
Terminal
terraform apply -auto-approve
Expected OutputExpected
aws_instance.example: Creating... aws_instance.example: Still creating... [10s elapsed] aws_instance.example: Creation complete after 20s [id=i-0123456789abcdef0] Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
→
-auto-approve - Automatically approves the apply step without asking for confirmation.
This command removes the EC2 instance created by Terraform to clean up resources.
Terminal
terraform destroy -auto-approve
Expected OutputExpected
aws_instance.example: Destroying... aws_instance.example: Still destroying... [10s elapsed] aws_instance.example: Destruction complete after 15s Destroy complete! Resources: 1 destroyed.
→
-auto-approve - Automatically approves the destroy step without asking for confirmation.
Key Concept

If you remember nothing else from this pattern, remember: use the AMI lookup data source to find the latest image automatically instead of hardcoding AMI IDs.

Common Mistakes
Hardcoding the AMI ID directly in the resource instead of using the data source.
AMI IDs change over time and differ by region, so hardcoding causes errors or outdated images.
Use the aws_ami data source with filters to find the correct AMI dynamically.
Not specifying the owner in the data source filter.
Without the owner filter, Terraform might find an untrusted or incorrect AMI.
Always specify the owner (like "amazon") to ensure trusted images.
Using a name filter that does not match any AMI.
Terraform will fail to find an AMI and the plan/apply will error out.
Use a correct and existing name pattern like "amzn2-ami-hvm-*-x86_64-gp2".
Summary
Initialize Terraform with 'terraform init' to prepare the environment.
Use 'terraform plan' to see the AMI lookup and planned EC2 instance creation.
Apply the plan with 'terraform apply' to create the instance using the latest AMI.
Clean up resources with 'terraform destroy' when done.

Practice

(1/5)
1. What is the main purpose of using the aws_ami data source in Terraform?
easy
A. To find the latest Amazon Machine Image (AMI) based on filters
B. To create a new AMI from an existing instance
C. To delete unused AMIs automatically
D. To launch an EC2 instance directly

Solution

  1. Step 1: Understand the role of aws_ami data source

    The aws_ami data source is used to query existing AMIs, not to create or delete them.
  2. Step 2: Identify its main use

    It helps find the latest AMI by applying filters like name, owner, and tags.
  3. Final Answer:

    To find the latest Amazon Machine Image (AMI) based on filters -> Option A
  4. Quick Check:

    AMI lookup = find latest AMI [OK]
Hint: Remember: data source reads info, does not create resources [OK]
Common Mistakes:
  • Confusing data source with resource creation
  • Thinking it deletes AMIs
  • Assuming it launches instances directly
2. Which of the following is the correct syntax to lookup an AMI by name prefix and owner in Terraform?
easy
A. resource "aws_ami" "example" { filter { name = "name" values = ["my-ami*"] } owners = ["self"] }
B. data "aws_ami" "example" { filter { name = "name" values = ["my-ami*"] } owners = ["self"] }
C. data "aws_ami" "example" { filter { name = "owner" values = ["self"] } owners = ["my-ami*"] }
D. data "aws_ami" "example" { filter { name = "name" values = "my-ami*" } owners = "self" }

Solution

  1. Step 1: Identify correct resource type and block structure

    AMI lookup uses data "aws_ami", not resource. Filters require a block with name and values as a list.
  2. Step 2: Check syntax for filters and owners

    Filters use values = ["my-ami*"] (list), and owners is a list of strings like ["self"].
  3. Final Answer:

    data "aws_ami" "example" { filter { name = "name" values = ["my-ami*"] } owners = ["self"] } -> Option B
  4. Quick Check:

    Correct data source syntax = data "aws_ami" "example" { filter { name = "name" values = ["my-ami*"] } owners = ["self"] } [OK]
Hint: Data source uses 'data', filters need list values [OK]
Common Mistakes:
  • Using 'resource' instead of 'data'
  • Setting 'values' as string instead of list
  • Swapping 'name' and 'owners' fields
3. Given this Terraform snippet:
data "aws_ami" "ubuntu" {
  most_recent = true
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
  owners = ["099720109477"]
}

output "ami_id" {
  value = data.aws_ami.ubuntu.id
}

What will the output ami_id contain?
medium
A. An error because most_recent is not valid here
B. A list of all Ubuntu AMI IDs owned by the user
C. The name of the AMI instead of the ID
D. The ID of the most recent Ubuntu 20.04 AMI owned by Canonical

Solution

  1. Step 1: Understand the most_recent flag

    Setting most_recent = true returns the newest AMI matching the filter.
  2. Step 2: Analyze the filter and owner

    The filter matches Ubuntu 20.04 AMIs by Canonical's owner ID, so the data source returns the latest matching AMI ID.
  3. Final Answer:

    The ID of the most recent Ubuntu 20.04 AMI owned by Canonical -> Option D
  4. Quick Check:

    most_recent true = latest AMI ID [OK]
Hint: most_recent true returns single newest AMI ID [OK]
Common Mistakes:
  • Thinking it returns a list of AMIs
  • Confusing AMI name with ID
  • Assuming most_recent is invalid
4. You wrote this Terraform data source to find an AMI:
data "aws_ami" "example" {
  filter {
    name = "name"
    values = "my-ami-*"
  }
  owners = ["self"]
}

Terraform gives an error. What is the problem?
medium
A. The owners field cannot be a list
B. The filter block is missing the most_recent flag
C. The values field must be a list, not a string
D. The name field should be owner

Solution

  1. Step 1: Check the values field type

    The values field expects a list of strings, but here it is given as a single string.
  2. Step 2: Confirm correct syntax for values

    It should be values = ["my-ami-*"] to be valid.
  3. Final Answer:

    The values field must be a list, not a string -> Option C
  4. Quick Check:

    values needs list brackets [OK]
Hint: Always use square brackets for filter values [OK]
Common Mistakes:
  • Using string instead of list for values
  • Misunderstanding owners field format
  • Adding unnecessary most_recent flag
5. You want to launch an EC2 instance using the latest Amazon Linux 2 AMI in your Terraform code. Which snippet correctly combines AMI lookup and instance resource?
hard
A. data "aws_ami" "amazon_linux" { most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } owners = ["137112412989"] } resource "aws_instance" "web" { ami = data.aws_ami.amazon_linux.id instance_type = "t2.micro" }
B. resource "aws_ami" "amazon_linux" { filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } owners = ["137112412989"] } resource "aws_instance" "web" { ami = aws_ami.amazon_linux.id instance_type = "t2.micro" }
C. data "aws_ami" "amazon_linux" { filter { name = "owner" values = ["137112412989"] } most_recent = true } resource "aws_instance" "web" { ami = data.aws_ami.amazon_linux.id instance_type = "t2.micro" }
D. data "aws_ami" "amazon_linux" { most_recent = true filter { name = "name" values = "amzn2-ami-hvm-*-x86_64-gp2" } owners = ["137112412989"] } resource "aws_instance" "web" { ami = data.aws_ami.amazon_linux.id instance_type = "t2.micro" }

Solution

  1. Step 1: Verify correct use of data source for AMI lookup

    data "aws_ami" "amazon_linux" { most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } owners = ["137112412989"] } resource "aws_instance" "web" { ami = data.aws_ami.amazon_linux.id instance_type = "t2.micro" } correctly uses data "aws_ami" with most_recent = true, proper filter with name = "name" and list for values, and correct owner ID.
  2. Step 2: Check instance resource references the data source ID

    The aws_instance resource uses ami = data.aws_ami.amazon_linux.id, which is correct to launch with the looked-up AMI.
  3. Final Answer:

    data "aws_ami" "amazon_linux" { most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } owners = ["137112412989"] } resource "aws_instance" "web" { ami = data.aws_ami.amazon_linux.id instance_type = "t2.micro" } -> Option A
  4. Quick Check:

    Data source + resource with correct references = data "aws_ami" "amazon_linux" { most_recent = true filter { name = "name" values = ["amzn2-ami-hvm-*-x86_64-gp2"] } owners = ["137112412989"] } resource "aws_instance" "web" { ami = data.aws_ami.amazon_linux.id instance_type = "t2.micro" } [OK]
Hint: Use data source ID in instance AMI field [OK]
Common Mistakes:
  • Using resource instead of data for AMI lookup
  • Passing string instead of list in filter values
  • Incorrect filter name or owner placement
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard