Terraform Cheatsheet

Outputs

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

Declaring Outputs

# outputs.tf
output "instance_public_ip" {
  description = "Public IP of the web server"
  value       = aws_instance.web.public_ip
}

output "db_endpoint" {
  value     = aws_db_instance.main.endpoint
  sensitive = true   # redacted in terminal; still accessible programmatically
}

Viewing Outputs

terraform output                        # show all outputs after apply
terraform output instance_public_ip     # show one output
terraform output -json                  # machine-readable JSON
terraform output -json | jq '.db_endpoint.value'   # extract specific value
terraform output -raw instance_public_ip           # raw value, no quotes

Outputs From count Resources

resource "aws_instance" "worker" {
  count         = 3
  ami           = var.ami_id
  instance_type = "t3.small"
}

output "worker_ips" {
  value = aws_instance.worker[*].private_ip   # list of all private IPs
}

output "first_worker_ip" {
  value = aws_instance.worker[0].private_ip
}

Outputs From for_each Resources

resource "aws_instance" "app" {
  for_each      = toset(["web", "api", "worker"])
  ami           = var.ami_id
  instance_type = "t3.micro"
}

output "instance_ids" {
  value = { for k, v in aws_instance.app : k => v.id }
}
# => { web = "i-...", api = "i-...", worker = "i-..." }

Outputs in Modules

Child module outputs are the only values the parent can consume.

# modules/vpc/outputs.tf
output "vpc_id" {
  value = aws_vpc.main.id
}

output "public_subnet_ids" {
  value = aws_subnet.public[*].id
}
# root main.tf
module "vpc" {
  source = "./modules/vpc"
}

resource "aws_instance" "web" {
  subnet_id = module.vpc.public_subnet_ids[0]  # consume module output
}

output "vpc_id" {
  value = module.vpc.vpc_id  # re-export module output
}

Sensitive Outputs

output "db_password" {
  value     = random_password.db.result
  sensitive = true
}
  • Marked (sensitive value) in terminal output
  • Still readable with terraform output -json or terraform output -raw
  • Passed to child modules without re-declaring sensitive

Precondition on Outputs (1.2+)

output "api_url" {
  value = "https://${aws_lb.api.dns_name}"

  precondition {
    condition     = aws_lb.api.load_balancer_type == "application"
    error_message = "Expected an ALB, got a different load balancer type."
  }
}

Using Outputs in Scripts

# Bash: export all outputs as env vars
eval "$(terraform output -json | jq -r 'to_entries[] | "export TF_OUT_\(.key|ascii_upcase)=\(.value.value)"')"

# Pass DB endpoint to an app config
DB_HOST=$(terraform output -raw db_endpoint)
sed -i "s|DB_HOST_PLACEHOLDER|$DB_HOST|g" app.conf

Output Attributes Reference

AttributeRequiredDescription
valueyesexpression to expose
descriptionnohuman-readable docs
sensitivenoredact from terminal
depends_onnoexplicit dependency (rare)
preconditionnoassert condition before output