Data Sources and Existing Infrastructure
Terraform is often used to create infrastructure, but real environments are rarely completely owned by one Terraform configuration. You may need an existing network, image, account, DNS zone, or other object without wanting Terraform to create it.
A data source lets Terraform read information about existing infrastructure without taking ownership of creating that object.
Resource or Data Source?
The distinction is simple:
resource → Terraform manages an object
data → Terraform reads information about an objectA resource represents something Terraform is responsible for managing.
For example:
resource "some_provider_network" "main" {
name = "application-network"
}A data source represents information Terraform wants to retrieve:
data "some_provider_network" "existing" {
name = "application-network"
}The exact arguments depend on the provider, but the conceptual difference is the important part.
With the resource, Terraform is declaring:
“This object belongs to the infrastructure I am managing.”
With the data source, Terraform is saying:
“Find this existing object and give me information about it.”
A data source does not make Terraform the creator or owner of that object.
Reading Existing Infrastructure
Imagine a team already has a network, and your application configuration needs its ID.
You could create a second network, but that would be the wrong model.
Instead, read the existing network:
data "some_provider_network" "existing" {
name = "shared-network"
}
resource "some_provider_server" "web" {
name = "web"
network = data.some_provider_network.existing.id
}The relationship becomes:
Existing network
│
│ data source reads it
▼
data.some_provider_network.existing
│
│ .id
▼
some_provider_server.webTerraform can use the discovered ID when planning the server.
Data Sources Don’t Create Infrastructure
This is the most important distinction to remember.
If you write:
data "some_provider_network" "existing" {
name = "shared-network"
}Terraform does not interpret that as:
Create shared-networkIt interprets it as:
Find shared-networkIf the provider cannot find a matching object, Terraform generally cannot continue because the required data is unavailable.
That behavior is useful: a typo in the name should not silently cause Terraform to create an entirely different object.
Warning
A data source does not give Terraform ownership of the object it reads. If the existing object changes outside your configuration, your data lookup may return different information on a later run.
Data Source Syntax
Data sources use the data block:
data "<TYPE>" "<NAME>" {
# lookup arguments
}You reference them using:
data.<TYPE>.<NAME>.<ATTRIBUTE>For example:
data "some_provider_image" "ubuntu" {
name = "ubuntu-24"
}Then:
resource "some_provider_server" "web" {
name = "web"
image = data.some_provider_image.ubuntu.id
}The data source supplies information; the resource consumes it.
A Practical Image Lookup
Image selection is a common reason to use data sources.
You generally do not want to hard-code an image ID forever when the provider publishes updated images.
A lookup can select an image using criteria:
data "some_provider_image" "ubuntu" {
name = "ubuntu-24"
}
resource "some_provider_server" "web" {
name = "web"
image = data.some_provider_image.ubuntu.id
}Conceptually:
Image catalog
│
│ lookup
▼
data.some_provider_image.ubuntu
│
│ id
▼
server.webThe exact filtering options vary by provider, so always check the data source’s provider documentation.
Data Sources and Dependencies
Data sources can participate in Terraform’s dependency graph just like resources.
Consider:
data "some_provider_network" "existing" {
name = "shared-network"
}
resource "some_provider_server" "web" {
name = "web"
network = data.some_provider_network.existing.id
}The server references the data source:
data.network.existing
↓
server.webTerraform therefore knows that it needs the network information before it can fully evaluate the server’s configuration.
Data sources can also depend on resources when the lookup requires information produced by that resource.
The important principle is:
Data sources are part of Terraform’s graph, even though they read rather than create infrastructure.
Common Uses for Data Sources
Data sources are particularly useful when your Terraform configuration needs information from infrastructure that is managed elsewhere.
Typical situations include:
- Using an existing network.
- Looking up an existing subnet.
- Selecting an image.
- Reading information about an existing DNS zone.
- Finding an existing security object.
- Looking up account, region, or availability information.
- Connecting infrastructure managed by different Terraform configurations.
This allows Terraform configurations to cooperate without every configuration having to manage every object.
When Should You Use a Data Source?
Use a data source when the object already exists and your configuration needs information about it.
For example:
Shared network managed elsewhere
│
▼
Data source
│
▼
Your applicationThis is especially useful for shared infrastructure.
Do not use a data source simply because you do not want to write the resource configuration for something that your Terraform project is actually supposed to manage.
If your configuration is responsible for creating and changing the object, a resource is normally the appropriate abstraction.
Resource vs Data Source in Practice
Imagine an existing network called shared.
Read it
data "some_provider_network" "shared" {
name = "shared"
}Create and manage it
resource "some_provider_network" "shared" {
name = "shared"
}These declarations may look superficially similar, but they mean very different things.
data:
"Find this"
resource:
"Manage this"That distinction becomes increasingly important as your Terraform projects grow.
A Useful Mental Model
Think of resources as verbs of management and data sources as queries:
Terraform
/ \
/ \
Manage objects Read objects
│ │
resource data
│ │
▼ ▼
infrastructure informationThe two often work together.
For example:
Existing network
│
▼
data
│
▼
Application resource
│
▼
New serverTerraform can therefore build new infrastructure around infrastructure that already exists.
Tip
Ask yourself: “Am I asking Terraform to create/change this object, or am I asking Terraform to tell me something about an object that already exists?” The answer usually tells you whether you need a resource or a data source.
Once you combine data sources with resources, you can build configurations that interact with existing infrastructure without pretending that Terraform owns everything.
The next step is learning how to create multiple resource instances without copying the same resource block repeatedly.