Datasources in Terraform Explained with Examples

Published: 2025-08-15
8 min read
Share:

Sooner or later, every Terraform engineer needs to work with infrastructure that already exists. Maybe a networking team created a VPC, another Terraform project manages shared resources, or a cloud administrator provisioned infrastructure manually.

This is where datasources in Terraform become valuable.

A Terraform datasource allows you to read information from existing infrastructure without managing its lifecycle. Instead of creating, updating, or deleting resources, Terraform simply retrieves information and makes it available to your configuration.

In this guide, you'll learn how Terraform datasources work, when to use them, common mistakes to avoid, and practical examples that apply to real-world environments.

If you're new to Terraform, start with our guide on getting started with Terraform on AWS and learn the fundamentals before working with advanced infrastructure patterns.

What Are Datasources in Terraform?

Datasources in Terraform allow a configuration to retrieve information about resources that already exist.

Unlike a resource block, a data source block does not create infrastructure. It only reads information and exposes attributes that can be used elsewhere in your Terraform configuration.

Common examples include:

  • Looking up an existing VPC
  • Finding the latest Amazon Machine Image (AMI)
  • Reading an existing security group
  • Accessing information from another Terraform deployment
  • Reading local files created outside Terraform

Terraform evaluates datasources during planning whenever possible and uses the returned values when building the dependency graph.

This makes datasources an important tool for integrating existing infrastructure into new Terraform deployments.

Why Use Datasources in Terraform?

Without datasources, teams often end up hardcoding IDs, manually copying values between projects, or maintaining separate configuration files.

Datasources help eliminate those problems.

Common use cases include:

  • Reading infrastructure created outside Terraform
  • Integrating multiple Terraform projects
  • Retrieving dynamic cloud provider information
  • Reducing hardcoded values
  • Supporting reusable modules

For example, a networking team may create a VPC in one Terraform project while an application team deploys EC2 instances from a separate repository.

Instead of manually sharing the VPC ID, the application team can use a datasource to discover the VPC automatically.

When building reusable infrastructure, datasources are frequently combined with Terraform modules to create more flexible deployments.

Pro Tip

One of the most common AWS datasource use cases is dynamically retrieving the latest Amazon Linux AMI.

Using a datasource is safer than hardcoding an AMI ID because new images become available regularly, and outdated AMIs can introduce security and maintenance issues.

How the Terraform Data Block Works

A datasource is declared using the data block.

The syntax is very similar to a resource block, which makes it easy to learn if you're already familiar with Terraform resources.

Basic Datasource Syntax

data "local_file" "dog" {
  filename = "/root/dogs.txt"
}

In this example:

  • data identifies the block as a datasource
  • local_file is the datasource type
  • dog is the local name used within the configuration

You can reference attributes returned by the datasource using:

data.local_file.dog.content

The returned value can then be passed into resources, modules, outputs, or variables.

If you're still learning how Terraform resources expose attributes, check out our guide on resource attributes in Terraform.

Example: Reading Existing Infrastructure with a Datasource

Suppose a file already exists on a server:

Dogs are awesome.

The file was created manually or by another tool, so Terraform does not manage it.

You can still read the file using a datasource and use its contents elsewhere.

Read the Existing File

data "local_file" "dog" {
  filename = "/root/dogs.txt"
}

Use the Retrieved Data

resource "local_file" "petstore" {
  content  = data.local_file.dog.content
  filename = "/root/petstore.txt"
}

When Terraform applies the configuration, it reads the content from dogs.txt and writes it into petstore.txt.

This simple example demonstrates a core concept:

  • Datasources read information
  • Resources create or manage infrastructure

Real AWS Example

A more common cloud use case is discovering an existing AMI.

data "aws_ami" "amazon_linux" {
  most_recent = true

  owners = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-*"]
  }
}

You can then reference:

data.aws_ami.amazon_linux.id

inside an EC2 resource.

This approach avoids hardcoding AMI IDs and automatically uses the latest matching image.

For more AWS infrastructure examples, see our guide on AWS EC2 with Terraform.

Resources vs Datasources in Terraform

Although the syntax looks similar, resources and datasources serve different purposes.

A resource block:

  • Creates infrastructure
  • Updates infrastructure
  • Deletes infrastructure
  • Is fully managed by Terraform

A datasource block:

  • Reads existing infrastructure
  • Retrieves metadata
  • Exposes attributes
  • Does not modify anything

A useful way to think about it:

  • Resources build infrastructure
  • Datasources discover infrastructure

If Terraform should own the lifecycle of an object, use a resource block.

If Terraform only needs information about an existing object, use a datasource.

Understanding this distinction becomes easier once you're familiar with Terraform state management and how Terraform tracks managed infrastructure.

Most providers published on the Terraform Registry offer numerous datasources.

Some commonly used examples include:

AWS

  • aws_ami
  • aws_vpc
  • aws_subnet
  • aws_security_group
  • aws_caller_identity

Azure

  • azurerm_resource_group
  • azurerm_virtual_network
  • azurerm_storage_account

Google Cloud

  • google_compute_image
  • google_compute_network
  • google_dns_managed_zone

Kubernetes

  • kubernetes_namespace
  • kubernetes_secret
  • kubernetes_service

Each datasource exposes different attributes and requires different input arguments.

Always verify the latest schema and supported arguments in the official provider documentation.

Best Practices for Using Datasources in Terraform

Datasources are powerful, but they should be used carefully.

Follow these best practices:

  • Prefer dynamic lookups over hardcoded IDs.
  • Use precise filters to avoid unexpected matches.
  • Keep dependencies between Terraform projects manageable.
  • Document assumptions when consuming external infrastructure.
  • Validate datasource outputs where possible.
  • Review provider documentation before relying on returned attributes.

For larger deployments, datasources often work alongside Terraform providers and remote state configurations to support cross-project communication.

Common Mistakes When Using Datasources

Many Terraform beginners run into the same issues.

Using Datasources for Resources Terraform Should Manage

If Terraform owns the lifecycle of a resource, use a resource block.

Using a datasource for infrastructure Terraform should create often leads to confusing configurations.

Relying on Unstable Filters

Poorly designed filters can return multiple matches or unexpected resources.

Always use specific filters whenever possible.

Hardcoding Values That Should Be Dynamic

One of the biggest advantages of datasources is eliminating hardcoded values.

If you find yourself manually updating IDs frequently, a datasource may be a better solution.

Assuming Datasource Results Never Change

Datasource values can change over time.

For example, retrieving the most recent AMI may return a different image in future deployments.

Always understand the implications of dynamic lookups.

When Should You Use Datasources?

Use datasources when:

  • Infrastructure already exists
  • Another team owns the resource
  • Multiple Terraform projects need shared information
  • Dynamic provider data is required
  • You want to avoid hardcoded configuration values

Avoid datasources when:

  • Terraform should manage the resource lifecycle
  • The external source is unreliable
  • The data changes unpredictably and could introduce deployment risks

Frequently Asked Questions

What is the purpose of datasources in Terraform?

Datasources allow Terraform to read information from existing infrastructure without creating, modifying, or deleting the resource.

What is the difference between a resource and a datasource?

A resource manages infrastructure, while a datasource only retrieves information about infrastructure that already exists.

Can Terraform datasources be used with AWS, Azure, and GCP?

Yes. Major cloud providers support a wide range of datasources for discovering and referencing existing resources.

Can modules use datasources?

Yes. Datasources are commonly used inside modules to retrieve information dynamically and make modules more reusable.

You can learn more about module design in our guide on creating and using Terraform modules.

Do datasources store information in Terraform state?

Terraform stores information about datasources in state so that values can be referenced during operations. However, Terraform does not manage the lifecycle of the underlying infrastructure.

Key Takeaways

  • Datasources in Terraform read existing infrastructure without managing it.
  • They help eliminate hardcoded values and improve configuration flexibility.
  • Common examples include AMI lookups, VPC discovery, and reading existing cloud resources.
  • Datasources work particularly well alongside modules and shared infrastructure patterns.
  • Understanding the difference between resources and datasources is essential for building maintainable Terraform configurations.
Free Engineering ToolsNEW

8 free, 100% client-side tools for developers — no signup, no data uploads.

Explore all tools