# 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.
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 Case | What Output Exposes |
|---|---|
| Operator Terminal | Public IPs, SSH commands, web portal URLs |
| CI/CD Pipelines | JSON metadata for smoke tests and artifact deployment |
| Modular Architecture | VPC Subnet IDs passed into EC2 & RDS child modules |
| Ansible Handoff | Dynamic inventory generation via terraform output -json |
Root Module Outputs
Printed directly to the terminal screen when terraform apply finishes, and queryable anytime with terraform output.
Child Module Outputs
Export internal resource attributes so the calling parent module can access them via module.<NAME>.<OUTPUT>.
Declaring Output Blocks
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}" }
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.
Querying Outputs with the CLI
# 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:
# 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}"
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.
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!
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
Data Flow Between Child and Parent Modules
vpc)Declares output "subnet_id"
main.tf)References module.vpc.subnet_id
aws_instance.web)subnet_id = module.vpc.subnet_id
output "public_subnet_id" { description = "The ID of the newly created public subnet" value = aws_subnet.public.id }
module "network" { source = "./modules/vpc" } resource "aws_instance" "web" { ami = "ami-0123456789abcdef0" instance_type = "t3.micro" subnet_id = module.network.public_subnet_id }
Production Best Practices
| Rule | Why It Matters | Example |
|---|---|---|
| Always add descriptions | Enables automatic documentation generation (terraform-docs). | description = "VPC ID" |
| Flag credentials as sensitive | Prevents token and secret leakage in Jenkins / GitHub Actions logs. | sensitive = true |
Use -raw for shell scripting | Extracts clean strings without parsing quotes. | terraform output -raw ip |
Keep outputs in outputs.tf | Maintains standard Terraform 3-file structure conventions. | Dedicated output file |