What is the difference between a resource and a data source in Terraform?

3 minbeginnerterraformresourcesdata-sources

Quick Answer

A `resource` block declares infrastructure that Terraform creates, updates, and destroys, and it's recorded in state as something Terraform owns. A `data` block is a read-only lookup — it queries a provider (or another resource) for information about something that *already exists* (an AMI ID, an existing VPC, a secret) and exposes it for reference, without Terraform managing its lifecycle. Data sources are commonly used to reference resources created outside the current configuration, or by another team/module.

Detailed Answer

These two block types look similar (both reference a provider's schema and expose attributes), but they mean opposite things for who owns the object's lifecycle.

resource — Terraform manages it

resource "aws_vpc" "main" {
  cidr_block = "10.0.0.0/16"
}
  • Terraform creates this VPC, tracks it in state, and will update or destroy it if the configuration changes or the block is removed.
  • It appears in terraform plan as something Terraform will act on.

data — Terraform only reads it

data "aws_ami" "latest_amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["amzn2-ami-hvm-*-x86_64-gp2"]
  }
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.latest_amazon_linux.id
  instance_type = "t3.micro"
}
  • Terraform performs a read-only lookup against the provider on every plan/apply — it does not create, modify, or delete the underlying object.
  • Common uses: looking up the latest AMI, referencing a VPC/subnet created by another team or another Terraform configuration, or pulling a secret's value from a secrets manager.

Why the distinction matters

  • Blast radius: removing a resource block plans a destroy of real infrastructure; removing a data block just stops referencing something — nothing is deleted.
  • Ownership boundaries: data sources are the standard way to consume infrastructure owned by a different configuration/team without taking on responsibility for its lifecycle (avoiding one team's apply accidentally modifying another team's resources).
  • Dependency graph: both participate in Terraform's dependency graph — referencing data.aws_ami.latest_amazon_linux.id still creates an implicit dependency, it just resolves via a read instead of a write.

A good rule of thumb for interviews: if Terraform should be able to delete it, it's a resource; if Terraform should only ever look it up, it's a data source.

Related Resources