Terraform Cheatsheet

Data Sources

Use this Terraform reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

What Data Sources Are

Data sources let you read existing infrastructure or external data without managing it. They query the provider API and expose attributes for use in your config.

data "<PROVIDER_TYPE>" "<LOCAL_NAME>" {
  # filter arguments
}

# Reference: data.<type>.<name>.<attribute>

Common AWS Data Sources

# Latest Amazon Linux 2023 AMI
data "aws_ami" "al2023" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

resource "aws_instance" "web" {
  ami = data.aws_ami.al2023.id
}

# Current AWS account and region
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}

output "account_id" { value = data.aws_caller_identity.current.account_id }
output "region"     { value = data.aws_region.current.name }

# Existing VPC by tag
data "aws_vpc" "main" {
  tags = { Name = "production" }
}

# All subnets in a VPC
data "aws_subnets" "private" {
  filter {
    name   = "vpc-id"
    values = [data.aws_vpc.main.id]
  }
  tags = { Tier = "private" }
}

# Existing Route 53 zone
data "aws_route53_zone" "main" {
  name         = "example.com"
  private_zone = false
}

# IAM policy document
data "aws_iam_policy_document" "s3_access" {
  statement {
    actions   = ["s3:GetObject", "s3:PutObject"]
    resources = ["${aws_s3_bucket.app.arn}/*"]
    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }
  }
}

resource "aws_s3_bucket_policy" "app" {
  bucket = aws_s3_bucket.app.id
  policy = data.aws_iam_policy_document.s3_access.json
}

# Availability zones
data "aws_availability_zones" "available" {
  state = "available"
}

resource "aws_subnet" "pub" {
  count             = 2
  availability_zone = data.aws_availability_zones.available.names[count.index]
}

# SSM Parameter Store
data "aws_ssm_parameter" "db_password" {
  name            = "/myapp/prod/db_password"
  with_decryption = true
}

# Secrets Manager
data "aws_secretsmanager_secret_version" "db" {
  secret_id = "myapp/prod/db"
}

locals {
  db_creds = jsondecode(data.aws_secretsmanager_secret_version.db.secret_string)
}

Common GCP Data Sources

data "google_compute_image" "debian" {
  family  = "debian-12"
  project = "debian-cloud"
}

data "google_container_cluster" "main" {
  name     = "prod-cluster"
  location = "us-central1"
}

data "google_project" "current" {}

Common Kubernetes Data Sources

data "kubernetes_namespace" "kube_system" {
  metadata { name = "kube-system" }
}

data "kubernetes_service" "ingress" {
  metadata {
    name      = "ingress-nginx"
    namespace = "ingress-nginx"
  }
}

terraform_remote_state

Read outputs from another Terraform root module.

data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket = "my-tf-state"
    key    = "shared/network/terraform.tfstate"
    region = "us-east-1"
  }
}

resource "aws_instance" "app" {
  subnet_id = data.terraform_remote_state.network.outputs.private_subnet_ids[0]
}

http Data Source

data "http" "my_ip" {
  url = "https://checkip.amazonaws.com"
}

locals {
  my_cidr = "${chomp(data.http.my_ip.response_body)}/32"
}

external Data Source

Run a script and parse its JSON output.

data "external" "git_sha" {
  program = ["bash", "-c", "echo '{\"sha\":\"'$(git rev-parse --short HEAD)'\"}'"]
}

locals {
  image_tag = data.external.git_sha.result.sha
}

Data Source Refresh Behavior

ScenarioBehavior
terraform planreads data sources that don't depend on unknown values
terraform applyreads all data sources before creating resources
terraform refreshre-reads state + data sources
-refresh=false flagskips data source reads (uses cached state)

Filtering Patterns

# Multiple filters are ANDed
data "aws_ami" "app" {
  most_recent = true
  owners      = ["self"]

  filter {
    name   = "tag:Project"
    values = ["myapp"]
  }

  filter {
    name   = "tag:Env"
    values = ["prod"]
  }

  filter {
    name   = "state"
    values = ["available"]
  }
}