Terraform Data Sources: What They Are and When to Use Them
Fast recall
Quick revision
Core answer
Whether you understand the read-only nature of data sources and can articulate the use cases where they are preferable to hard-coding resource IDs or using terraform_remote_state.
Using data sources to look up resources that Terraform itself should manage, creating an implicit dependency on externally managed infrastructure without explicit documentation.
Distinguish between data sources for externally managed resources (AMI IDs, account IDs, existing VPCs) vs terraform_remote_state for outputs from sibling Terraform configurations, and mention the dependency graph implications.
Interview-ready guide
Interview answer
Data sources in Terraform read information from external systems or other Terraform states without managing those resources. They are the mechanism for referencing infrastructure that exists outside the current configuration — another team's VPC, a pre-existing AMI, a certificate managed by the security team.
What data sources do
- A
datablock fetches read-only information and makes it available as attributes —data.aws_ami.ubuntu.idreturns the ID of the latest Ubuntu AMI matching a filter; Terraform fetches this at plan time and uses the live ID, not a hardcoded one that becomes stale - Data sources do not create or manage resources — they observe;
terraform destroydoes not delete a resource referenced by a data source, only resources declared withresourceblocks - Data sources run during
terraform plan, not justapply— if the data source cannot find a matching resource (wrong filter, resource does not exist), the plan fails immediately before any changes are made
Common use cases
- Look up a shared VPC by tag:
data "aws_vpc" "main" { filter { name = "tag:Environment"; values = ["production"] } }— reference the VPC ID in security group and subnet declarations without copying the ID from the console or hardcoding it - Reference another module's state via
data "terraform_remote_state"— the networking team's state exports the VPC ID; your application module reads it without coordination; this is the standard pattern for cross-team infrastructure dependencies - Look up the current AWS account ID:
data "aws_caller_identity" "current"—data.aws_caller_identity.current.account_idconstructs ARNs without hardcoding the account number, making the configuration portable across AWS accounts
When not to use data sources
- Do not use data sources to reference resources in the same configuration — use resource attribute references directly (
aws_vpc.main.id); data sources add an external dependency where none is needed - Do not depend on data sources that can change between plan and apply — a data source that returns the "latest" AMI ID can change in the minutes between plan and apply, causing the apply to use a different AMI than the plan showed
Terraform Data Sources: What They Are and When to Use Them
Direct Answer
Data sources read existing infrastructure without managing it; use them to look up externally managed resources like AMI IDs, existing VPCs, or account IDs that your configuration needs to reference.
Code Example
# 1. Look up the latest Amazon Linux 2 AMI (managed by AWS, not Terraform)
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}
resource "aws_instance" "app" {
ami = data.aws_ami.amazon_linux.id # always up-to-date AMI
instance_type = "t3.medium"
}
# 2. Reference an existing VPC created by another team
data "aws_vpc" "existing" {
tags = { Name = "shared-production-vpc" }
}
resource "aws_subnet" "app" {
vpc_id = data.aws_vpc.existing.id
cidr_block = "10.0.10.0/24"
}
# 3. Get current AWS account ID (no hard-coding)
data "aws_caller_identity" "current" {}
resource "aws_iam_role" "app" {
assume_role_policy = jsonencode({
Statement = [{
Principal = { Service = "ecs-tasks.amazonaws.com" }
Effect = "Allow"
Action = "sts:AssumeRole"
}]
})
}
# 4. Read a secret from Secrets Manager
data "aws_secretsmanager_secret_version" "db_password" {
secret_id = "prod/db/password"
}
locals {
db_password = data.aws_secretsmanager_secret_version.db_password.secret_string
}
Common Mistakes & Pitfalls
Using data sources to look up resources that Terraform itself should manage, creating an implicit dependency on externally managed infrastructure without explicit documentation.
Check your understanding
Answer these without looking back at the article.
- What is the difference between a data source and terraform_remote_state?
- How do you handle a data source that queries a resource that may not exist yet?
- How do you use data sources to avoid hard-coding AWS account IDs?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.