Data Sources
Data sources read information about existing infrastructure without managing it.
Syntax
data "aws_ami" "latest" {
most_recent = true
}A data source lets Terraform read information from a provider without creating or owning anything. It answers questions like "what is the latest Amazon Linux AMI?" or "what is my account ID?".
data vs resource
resource— Terraform creates and manages the object.data— Terraform only reads an existing object.
Referencing data
Read attributes with the data. prefix, for example data.aws_ami.latest.id.
Example
data "aws_ami" "amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["al2023-ami-*-x86_64"]
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.micro"
}When to use it
- A team uses a data source to look up the latest Amazon Linux 2 AMI ID dynamically so their EC2 resources never have a hard-coded AMI that grows stale.
- An engineer reads an existing VPC by its Name tag using a data source so new subnets can be added to the shared network without importing the VPC into state.
- A module uses a data source to fetch the current AWS account ID and region, building ARNs dynamically instead of requiring callers to pass them as variables.
More examples
Look up latest AMI by filter
Queries AWS for the most-recent Amazon Linux 2 AMI matching the filter and uses its id in the instance resource.
data "aws_ami" "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.amazon_linux.id
instance_type = "t3.micro"
}Fetch current account ID
Uses two parameterless data sources to obtain the current account ID and region for building dynamic ARNs.
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
locals {
account_id = data.aws_caller_identity.current.account_id
region = data.aws_region.current.name
}
output "bucket_arn_prefix" {
value = "arn:aws:s3:::myapp-${local.account_id}-${local.region}"
}Read existing IAM policy
Reads a pre-existing AWS-managed IAM policy by ARN so it can be attached to a new role without managing the policy itself.
data "aws_iam_policy" "read_only" {
arn = "arn:aws:iam::aws:policy/ReadOnlyAccess"
}
resource "aws_iam_role_policy_attachment" "readonly" {
role = aws_iam_role.viewer.name
policy_arn = data.aws_iam_policy.read_only.arn
}
Discussion