What is the difference between a resource and a data source in Terraform?
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 planas 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
resourceblock plans a destroy of real infrastructure; removing adatablock just stops referencing something — nothing is deleted. - Ownership boundaries:
datasources are the standard way to consume infrastructure owned by a different configuration/team without taking on responsibility for its lifecycle (avoiding one team'sapplyaccidentally modifying another team's resources). - Dependency graph: both participate in Terraform's dependency graph — referencing
data.aws_ami.latest_amazon_linux.idstill 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.