Bird
Raised Fist0
Terraformcloud~10 mins

AMI lookup data source example in Terraform - Step-by-Step Execution

Choose your learning style10 modes available
Process Flow - AMI lookup data source example
Start Terraform Apply
↓
Invoke data source: aws_ami
↓
Query AWS for AMI matching filters
↓
Receive AMI details
↓
Use AMI ID in resource creation
↓
Create EC2 instance with AMI
↓
End Terraform Apply
Terraform starts, queries AWS for an AMI matching filters, then uses the found AMI ID to create an EC2 instance.
Execution Sample
Terraform
data "aws_ami" "example" {
  most_recent = true
  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
  owners = ["amazon"]
}

resource "aws_instance" "example" {
  ami           = data.aws_ami.example.id
  instance_type = "t2.micro"
}
This Terraform code looks up the latest Amazon Linux 2 AMI and launches a t2.micro EC2 instance using it.
Process Table
StepActionInput/FilterAWS ResponseResulting Value
1Start Terraform apply---
2Invoke aws_ami data sourceFilter: name=amzn2-ami-hvm-*-x86_64-gp2, owners=amazon, most_recent=trueList of matching AMIsSelect most recent AMI ID: ami-0abcdef1234567890
3Assign AMI ID to aws_instance resourceAMI ID from data source-ami-0abcdef1234567890
4Create EC2 instanceAMI ID=ami-0abcdef1234567890, instance_type=t2.microInstance created with ID i-0123456789abcdef0EC2 instance running
5Terraform apply complete---
💡 Terraform apply finishes after EC2 instance is created using the looked-up AMI.
Status Tracker
VariableStartAfter Step 2After Step 3Final
data.aws_ami.example.idundefinedami-0abcdef1234567890ami-0abcdef1234567890ami-0abcdef1234567890
aws_instance.example.amiundefinedundefinedami-0abcdef1234567890ami-0abcdef1234567890
aws_instance.example.instance_typeundefinedundefinedt2.microt2.micro
Key Moments - 3 Insights
Why does Terraform query AWS before creating the EC2 instance?
Terraform uses the aws_ami data source to find the latest AMI ID matching the filters before it can assign that AMI ID to the EC2 instance resource, as shown in step 2 and 3 of the execution_table.
What happens if no AMI matches the filter?
Terraform will fail during the data source lookup (step 2) because it cannot find a valid AMI ID to assign to the EC2 instance, stopping the apply process.
Why do we use 'most_recent = true' in the data source?
This ensures Terraform picks the newest AMI matching the filter, so the EC2 instance uses the latest image, as reflected in the AWS response selecting the most recent AMI ID in step 2.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what AMI ID is selected at step 2?
Aami-0fedcba9876543210
Bami-0abcdef1234567890
Cami-1234567890abcdef0
Dami-11111111111111111
💡 Hint
Check the AWS Response and Resulting Value columns at step 2 in the execution_table.
At which step is the EC2 instance created?
AStep 4
BStep 3
CStep 2
DStep 5
💡 Hint
Look for the action mentioning 'Create EC2 instance' in the execution_table.
If we remove 'most_recent = true', how would the execution_table change?
ATerraform would fail to find any AMI.
BTerraform would select a random AMI from the list.
CTerraform would error because multiple matching AMIs are found.
DTerraform would select the AMI with the smallest ID.
💡 Hint
Without 'most_recent = true', the data source will error if more than one AMI matches the filter in step 2.
Concept Snapshot
Terraform AMI lookup data source:
- Use 'data "aws_ami"' with filters to find AMI
- 'most_recent = true' picks latest AMI
- Use 'data.aws_ami.example.id' in resource
- Ensures EC2 uses correct AMI
- Lookup happens before resource creation
Full Transcript
This example shows how Terraform uses the aws_ami data source to find the latest Amazon Linux 2 AMI by filtering on name and owner. Terraform queries AWS during apply, receives the most recent AMI ID, then uses that ID to create an EC2 instance. The execution table traces each step: starting apply, querying AMI, assigning AMI ID, creating instance, and finishing. Variables track the AMI ID and instance type values as they update. Key moments clarify why the lookup happens first, what if no AMI matches, and why most_recent is important. The quiz tests understanding of AMI selection, creation step, and effect of removing most_recent. This process ensures Terraform dynamically uses the latest AMI without hardcoding IDs.

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