Referencing Existing Infra
Data sources let new resources plug into a VPC, subnet, or account you did not create in this config.
Data sources shine when you need to attach new resources to infrastructure that already exists — perhaps created by another team or another Terraform configuration.
Common examples
aws_vpc— look up an existing VPC by tag.aws_caller_identity— get the current account ID.aws_availability_zones— list AZs in the current region.
This keeps configurations decoupled: one team owns the network, another deploys apps into it.
Example
# Find the shared VPC by its Name tag
data "aws_vpc" "shared" {
filter {
name = "tag:Name"
values = ["shared-network"]
}
}
data "aws_availability_zones" "available" {
state = "available"
}
resource "aws_subnet" "app" {
vpc_id = data.aws_vpc.shared.id
availability_zone = data.aws_availability_zones.available.names[0]
cidr_block = "10.0.5.0/24"
}When to use it
- A developer uses filter blocks on a data source to look up the shared staging VPC by its Environment=staging tag and retrieves its ID for a new subnet.
- A team references an existing Route 53 zone data source by domain name so new DNS records are added to the shared zone without owning it in state.
- An SRE finds all subnets tagged with Tier=private using a data source and passes the returned ID list directly to an ECS service's network configuration.
More examples
Look up VPC by name tag
Fetches an existing VPC by its Name tag so a new subnet can be added to it without managing the VPC in this configuration.
data "aws_vpc" "shared" {
filter {
name = "tag:Name"
values = ["shared-network-vpc"]
}
}
resource "aws_subnet" "app" {
vpc_id = data.aws_vpc.shared.id
cidr_block = "10.0.20.0/24"
}Get multiple subnets by tag
Retrieves all private subnet IDs in the shared VPC using two filter blocks and passes them directly to a load balancer.
data "aws_subnets" "private" {
filter {
name = "vpc-id"
values = [data.aws_vpc.shared.id]
}
filter {
name = "tag:Tier"
values = ["private"]
}
}
resource "aws_lb" "internal" {
internal = true
subnets = data.aws_subnets.private.ids
load_balancer_type = "application"
}Existing Route 53 zone for DNS records
Looks up a pre-existing public hosted zone by domain name and uses its zone_id to create a new DNS record.
data "aws_route53_zone" "domain" {
name = "example.com."
private_zone = false
}
resource "aws_route53_record" "app" {
zone_id = data.aws_route53_zone.domain.zone_id
name = "app.example.com"
type = "CNAME"
ttl = 300
records = [aws_lb.app.dns_name]
}
Discussion