Skip to content

6 — Data sources

Folder: 01-basics/6-data-sources/

A data block reads something Terraform doesn't own. No create, no update, no destroy — and it re-queries live on every single plan/apply rather than serving a value cached in state.

The code

resource "local_file" "pet" {
  filename        = "/tmp/hello.txt"
  content         = data.local_file.my_file.content
  file_permission = "0700"
}

data "local_file" "my_file" {
  filename = "/tmp/my_file.txt"
}

Run it

/tmp/my_file.txt doesn't exist yet, and a data block will never create it:

echo "read by a data source" > /tmp/my_file.txt
terraform init && terraform apply
cat /tmp/hello.txt                # contents copied from the data source

The experiment — same missing file, opposite behaviour

This is the whole point of the topic.

rm /tmp/my_file.txt
terraform plan     # errors: there is nothing to read

Now compare with deleting /tmp/hello.txt, which is a resource:

rm /tmp/hello.txt
terraform plan     # calmly offers to recreate it

Same missing file, opposite behaviour, because ownership differs. A resource that has gone missing is drift Terraform will fix. A data source that has gone missing is an error, because Terraform has no authority to create it.

This is the distinction Theory §11 describes, and the one that got answered wrong in Session 1.

Destroy never touches what a data block reads

echo "pre-existing content, not managed by terraform" > /tmp/external-file.txt
data "local_file" "external" {
  filename = "/tmp/external-file.txt"
}

output "external_file_content" {
  value = data.local_file.external.content
}
terraform apply
terraform output external_file_content
terraform destroy
cat /tmp/external-file.txt   # still there

Only Terraform-managed resources get deleted on destroy. The GCP equivalent behaves identically — see Lab 7 and data.tf in the core GCP root, which reads a project and a network that Terraform didn't create.

Key takeaway

Data sources show as reads in plan, never as create or destroy. Use them to reference infrastructure you don't own in this config — an existing network, another team's project, a value another repo published — instead of hardcoding IDs.


Theory: §11 Data sources · Quiz: Resources, state & drift · Next: count and for_each