Using Terraform Data Sources to Query Existing Infrastructure
📖 Scenario: You are managing cloud infrastructure using Terraform. Sometimes, you need to use information about resources that already exist outside your current Terraform configuration. For example, you want to find the ID of an existing virtual network or security group to connect new resources to it.
🎯 Goal: Learn how to use Terraform data sources to query existing infrastructure resources and use their attributes in your Terraform configuration.
📋 What You'll Learn
Create a Terraform data source block to query an existing AWS VPC by its ID
Create a variable to hold the VPC ID
Use the data source's attributes to configure a new subnet resource
Add a tag to the subnet referencing the VPC's name
💡 Why This Matters
🌍 Real World
In real cloud projects, you often need to connect new resources to existing networks or security groups. Terraform data sources let you safely reference these existing resources without recreating them.
💼 Career
Cloud engineers and DevOps professionals use data sources to manage hybrid infrastructure setups and avoid conflicts by querying existing resources before creating new ones.
Progress0 / 4 steps
1
Create a variable for the existing VPC ID
Create a Terraform variable called existing_vpc_id of type string with a default value of "vpc-0abcd1234efgh5678".
Terraform
Hint
Use the variable block with type = string and set the default to the exact VPC ID.
2
Add a data source to query the existing VPC
Add a Terraform data block named existing_vpc of type aws_vpc that uses the variable existing_vpc_id to look up the VPC by its ID.
Terraform
Hint
Use a data block with type aws_vpc and set id = var.existing_vpc_id.
3
Create a subnet using the existing VPC data source
Create a Terraform resource block named example_subnet of type aws_subnet. Use the VPC ID from the data source data.aws_vpc.existing_vpc.id for the vpc_id attribute. Set the cidr_block to "10.0.1.0/24".
Terraform
Hint
Use the resource block for aws_subnet and reference the VPC ID from the data source.
4
Add a tag to the subnet using the VPC's name from the data source
Add a tags block inside the aws_subnet.example_subnet resource. Set the tag Name to the VPC's name using data.aws_vpc.existing_vpc.tags["Name"].
Terraform
Hint
Inside the resource block, add a tags map and set Name to the VPC's name from the data source.
Practice
(1/5)
1. What is the main reason Terraform uses data sources to query existing infrastructure?
easy
A. To get information about resources created outside Terraform
B. To create new resources automatically
C. To delete unused resources
D. To backup infrastructure state
Solution
Step 1: Understand Terraform data sources purpose
Data sources allow Terraform to read details about resources that exist but were not created by the current Terraform configuration.
Step 2: Identify the correct use case
Since data sources do not create or delete resources, their main use is to fetch information about existing infrastructure.
Final Answer:
To get information about resources created outside Terraform -> Option A
Quick Check:
Data sources read existing resources = A [OK]
Hint: Data sources read info, they don't create or delete [OK]
Common Mistakes:
Thinking data sources create resources
Confusing data sources with resource blocks
Assuming data sources manage resource lifecycle
2. Which of the following is the correct syntax to define a data source in Terraform?
easy
A. output "aws_vpc" "main" { id = "vpc-123456" }
B. resource "aws_vpc" "main" { id = "vpc-123456" }
C. data "aws_vpc" "main" { id = "vpc-123456" }
D. variable "aws_vpc" "main" { id = "vpc-123456" }
Solution
Step 1: Identify Terraform block types
Terraform uses the keyword data to define data sources, resource for resources, output for outputs, and variable for input variables.
Step 2: Match syntax for data source
The correct syntax for a data source starts with data, followed by the provider and resource type, then the name and configuration.
Final Answer:
data "aws_vpc" "main" { id = "vpc-123456" } -> Option C
Quick Check:
Data source syntax starts with 'data' = A [OK]
Hint: Data sources start with 'data' keyword, not 'resource' [OK]
Common Mistakes:
Using 'resource' instead of 'data' for data sources
Confusing outputs or variables with data sources
Incorrect block structure or missing quotes
3. Given this Terraform data source snippet:
data "aws_subnet" "example" {
filter {
name = "tag:Name"
values = ["public-subnet"]
}
}
What does data.aws_subnet.example.id return?
medium
A. Creates a new subnet with the name public-subnet
B. Throws an error because filter is invalid
C. Returns a list of all subnet IDs in the AWS account
D. The ID of the subnet tagged with Name=public-subnet
Solution
Step 1: Understand the data source filter
The filter selects the subnet resource with the tag Name equal to "public-subnet".
Step 2: Determine the returned value
Accessing data.aws_subnet.example.id returns the ID of the subnet matching the filter, not creating or listing all subnets.
Final Answer:
The ID of the subnet tagged with Name=public-subnet -> Option D
Quick Check:
Filter selects existing subnet ID = B [OK]
Hint: Filters select existing resources; data source returns their attributes [OK]
Common Mistakes:
Thinking data source creates resources
Assuming it returns all subnets without filter
Misunderstanding filter syntax
4. You wrote this Terraform data source:
data "aws_security_group" "web" {
name = "web-sg"
}
But Terraform shows an error: "name" is not a valid argument. What is the likely fix?
medium
A. Remove the block entirely; data sources can't query security groups
B. Replace name with filter block to find security group by name
C. Add id argument instead of name
D. Change data to resource
Solution
Step 1: Check data source argument rules
The aws_security_group data source does not accept a direct name argument; it uses filters to find resources.
Step 2: Correct usage with filter block
Use a filter block with name = "group-name" and values = ["web-sg"] to query by name.
Final Answer:
Replace name with filter block to find security group by name -> Option B
Quick Check:
Use filter block for querying by name = D [OK]
Hint: Use filter blocks, not direct name arguments in data sources [OK]
Common Mistakes:
Using unsupported arguments in data sources
Confusing resource and data source syntax
Assuming data sources create or modify resources
5. You want to use a data source to get the latest AMI ID for Ubuntu in your region. Which approach correctly uses a data source to achieve this?
hard
A. data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"]
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}