Understanding Terraform Data Sources and Why They Matter
Terraform data sources provide a way to query and reference existing resources in your AWS environment (or any provider) without creating new ones.
This is essential for automation and avoiding manual hardcoding, especially when resource IDs change frequently or you want to ensure you always use the latest available versions.
Unlike resources:
❌ Data sources do not create anything,
✅ They only read pre-provisioned AWS infrastructure without hardcoding.
In this article, we’ll deploy an EC2 instance into an already existing VPC and subnet — without recreating or managing the network itself.
Deploying EC2 in an Existing VPC
- A shared VPC and subnet already exist
- Create two EC2 instances in subnet one, and two in subnet two
- Instead of creating new resource, reference those existing
- Use data sources to fetch:
- VPC ID by filtering on the VPC name tag (e.g., default).
- Subnet ID by filtering subnet name under the VPC.
- Latest Amazon Linux 2 AMI ID matching owner and virtualization type
Architecture(Text Diagram)
AWS Account
│
├── Shared Network (Managed Separately)
│ ├── VPC: shared-network-vpc
│ │
│ └── Subnet: shared-primary-subnet
│
└── Application Terraform (Day 13)
├── data.aws_vpc.shared
├── data.aws_subnet.shared
├── data.aws_ami.amazon_linux_2
│
└── aws_instance.day13_instance
└── Uses existing subnet & AMI
Implementation Using Terraform
Step 1: Provider Setup
We start by telling Terraform to use AWS.
provider "aws" {
region = "ap-south-1"
}
Step 2: Data Source for VPC
data "aws_vpc" "selected" {
filter {
name = "tag:Name"
values = ["default"]
}
}
This selects the existing default VPC in the AWS environment.
Step 3: Data Source for Subnet
data "aws_subnet" "shared" {
filter {
name = "tag:Name"
values = ["Subneta"]
}
vpc_id = data.aws_vpc.selected.id
}
Provide vpc_id to restrict search to the selected VPC.
Step 4: Data Source for AMI Image
Use data "aws_ami" "linux2".
Set most_recent = true to pick latest AMI.
data "aws_ami" "Linux2" {
most_recent = true
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["amazon"]
}
Step 5: Using Data Sources in EC2 Resource:
Reference AMI ID, as data.aws_ami.Linux2.id.
Reference subnet ID as data.aws_subnet.shared.id.
resource "aws_instance" "example"{
ami = data.aws_ami.Linux2.id
instance_type = "t2.micro"
subnet_id = data.aws_subnet.shared.id
}
Conclusion
Automation: Using data sources prevents manual hardcoding of AMI, VPC, and subnet IDs.
Reliability: Always uses the latest Amazon Linux 2 AMI available.
Reuse: Leverages existing network resources shared by multiple teams.
Scalability: Making it simple to scale instances with consistent configurations.
Top comments (0)