Day 13: Terraform Data Sources
Source: Dev.to
Data Source
Think of a data source like a phone directory with a username and phone number as key‑value pairs accessed via an API. Instead of hard‑coding values, you can retrieve them using a key.
In short, Terraform data sources for AWS allow you to retrieve information about existing AWS resources or external data that can then be referenced within your Terraform configurations.
Example: When creating an EC2 instance you need an AMI ID. Rather than manually looking up the latest Amazon Linux 2 AMI, you can use a data source to fetch the AMI ID automatically.
Data sources allow Terraform to read information about existing infrastructure. They:
- Do not create, update, or delete resources
- Allow you to reference resources managed elsewhere
- Enable sharing infrastructure between teams
- Are defined with
datablocks instead ofresourceblocks

How to Use AWS Data Sources
You define a data source using the data block in your Terraform configuration:
data "provider_type" "name" {
# Configuration settings for filtering or identifying the data source
}
- provider_type – The type of AWS data source (e.g.,
aws_ami,aws_vpc,aws_s3_bucket). - name – A local identifier used to reference the data source.
- Configuration settings – Vary by data source and typically include
id,name, orfilterblocks withnameandvaluesarguments.
Examples: Data vs. Resource Block
# Resource Block – Terraform MANAGES this
resource "aws_vpc" "my_vpc" {
cidr_block = "10.0.0.0/16"
}
# Data Block – Terraform READS this
data "aws_vpc" "existing_vpc" {
filter {
name = "tag:Name"
values = ["shared-network-vpc"]
}
}
In the resource block, Terraform creates and manages the VPC. In the data block, Terraform only reads information about an existing VPC that matches the provided filter.
Task
Create a VPC using Terraform, then use a data source to fetch an AMI ID and launch an EC2 instance within the VPC you just created.

Creation of VPC
# Simulated infrastructure created by another team
provider "aws" {
region = "us-east-1"
}
resource "aws_vpc" "shared" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "shared-network-vpc"
}
}
resource "aws_subnet" "shared" {
vpc_id = aws_vpc.shared.id
cidr_block = "10.0.1.0/24"
tags = {
Name = "shared-primary-subnet" # ← This tag is important!
}
}
Run the plan to see the actions Terraform will take:
terraform plan
Typical output (truncated for brevity):
# aws_subnet.shared will be created
+ resource "aws_subnet" "shared" {
+ cidr_block = "10.0.1.0/24"
+ tags = {
+ "Name" = "shared-primary-subnet"
}
+ vpc_id = (known after apply)
}
# aws_vpc.shared will be created
+ resource "aws_vpc" "shared" {
+ cidr_block = "10.0.0.0/16"
+ enable_dns_support = true
+ tags = {
+ "Name" = "shared-network-vpc"
}
}