# terraform / outputs / querying

Expose & Export Values: Output Values

Outputs in Terraform are like return values in a programming function. They expose important infrastructure data — public IP addresses, load balancer DNS names, database endpoints, and resource IDs — on your terminal, to automated CI/CD pipelines, or to parent modules.

$ terraform output
web_public_ip"13.235.45.109"
alb_dns_name"app-lb-9812.aws.com"
db_endpoint"<sensitive>"
3
Declared
1
Sensitive
CLI / JSON
Export Formats
# purpose

Why Output Values Matter

When Terraform finishes provisioning, you often need to know what was created so you can connect to it, configure DNS, or feed the values into an Ansible inventory or CI/CD deploy script. Without output blocks, you would have to open the cloud console and hunt for IDs manually.

Use CaseWhat Output Exposes
Operator TerminalPublic IPs, SSH commands, web portal URLs
CI/CD PipelinesJSON metadata for smoke tests and artifact deployment
Modular ArchitectureVPC Subnet IDs passed into EC2 & RDS child modules
Ansible HandoffDynamic inventory generation via terraform output -json
root output

Root Module Outputs

Printed directly to the terminal screen when terraform apply finishes, and queryable anytime with terraform output.

child output

Child Module Outputs

Export internal resource attributes so the calling parent module can access them via module.<NAME>.<OUTPUT>.

# outputs.tf

Declaring Output Blocks

outputs.tfSTANDARD DECLARATION
1 2 3 4 5 6 7 8 9 10 11
output "web_public_ip" {
  description = "Public IPv4 address of the web EC2 instance"
  value       = aws_instance.web.public_ip
}

output "web_ssh_command" {
  description = "Convenient one-liner to SSH into the instance"
  value       = "ssh -i ~/.ssh/id_rsa ubuntu@${aws_instance.web.public_ip}"
}
key arguments

Output Block Attributes

An output block requires a unique name and a value expression. Adding a clear description is standard practice for production codebases and self-documenting modules.

  • value: The expression exported (resource attribute, string, map, or list).
  • description: Explains the purpose of the output.
  • sensitive: Hides value from standard terminal logs.
  • depends_on: Enforces explicit dependency before reading.
# cli usage

Querying Outputs with the CLI

terminalBASH COMMANDS
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# 1. Print all outputs in key-value format
$ terraform output
web_public_ip   = "13.235.45.109"
web_ssh_command = "ssh -i ~/.ssh/id_rsa ubuntu@13.235.45.109"

# 2. Query a single specific output
$ terraform output web_public_ip
"13.235.45.109"

# 3. Raw output (strip surrounding quotes — ideal for shell scripts)
$ terraform output -raw web_public_ip
13.235.45.109

# 4. JSON format (ideal for jq, Python, Ansible automation)
$ terraform output -json

Integrating with CI/CD & Scripts

In automated deployment pipelines, you can feed Terraform outputs directly into downstream testing or configuration tools without manual copying:

deploy.shPIPELINE INTEGRATION
1 2 3 4
# Extract raw IP and run curl health check
HOST_IP=$(terraform output -raw web_public_ip)
curl -f "http://${HOST_IP}/health" || exit 1
echo "Application is healthy on ${HOST_IP}"
# security

Protecting Secrets: sensitive = true

If an output contains private passwords, database master keys, or private SSH keys, mark it with sensitive = true. Terraform will redact the value in standard CLI logs and CI/CD console output to prevent accidental leaks.

security note

State Still Stores Secrets

Marking an output as sensitive = true prevents terminal display, but the value is still stored in plaintext inside terraform.tfstate. Always secure your remote backend!

outputs.tfSENSITIVE FLAG
1 2 3 4 5 6 7 8 9 10 11 12 13
output "db_password" {
  description = "Generated database root password"
  value       = aws_db_instance.postgres.password
  sensitive   = true
}

# Terminal output when running apply:
# db_password = <sensitive>

# How an authorized engineer views it:
$ terraform output -raw db_password
# architecture

Data Flow Between Child and Parent Modules

Child Module (vpc)
Declares output "subnet_id"
Root Module (main.tf)
References module.vpc.subnet_id
Resource (aws_instance.web)
subnet_id = module.vpc.subnet_id
modules/vpc/outputs.tfCHILD MODULE EXPORT
1 2 3 4
output "public_subnet_id" {
  description = "The ID of the newly created public subnet"
  value       = aws_subnet.public.id
}
main.tfROOT MODULE CONSUMPTION
1 2 3 4 5 6 7 8 9
module "network" {
  source = "./modules/vpc"
}

resource "aws_instance" "web" {
  ami           = "ami-0123456789abcdef0"
  instance_type = "t3.micro"
  subnet_id     = module.network.public_subnet_id
}
# cheat sheet

Production Best Practices

RuleWhy It MattersExample
Always add descriptionsEnables automatic documentation generation (terraform-docs).description = "VPC ID"
Flag credentials as sensitivePrevents token and secret leakage in Jenkins / GitHub Actions logs.sensitive = true
Use -raw for shell scriptingExtracts clean strings without parsing quotes.terraform output -raw ip
Keep outputs in outputs.tfMaintains standard Terraform 3-file structure conventions.Dedicated output file