Skip to main content

Output Value

A Terraform output value exposes specific attributes from your infrastructure after an apply — like an EC2 instance's IP address or an S3 bucket's name. Outputs are printed to the terminal after apply and can be read by other Terraform configurations through remote state data sources.

What Is a Terraform Output Value?

A Terraform output value is how your configuration shares information with the outside world. After terraform apply creates resources, outputs print the values you care about — the RDS endpoint to put in your application config, the S3 bucket name to set as an environment variable, the VPC ID for another Terraform configuration to reference.

Think of outputs as the return values of your Terraform configuration. Just as a function returns a value for its caller to use, an output makes an infrastructure attribute available for humans and other systems to consume.

At Hotstar, the networking team's Terraform configuration outputs the VPC ID and subnet IDs. The platform team's configuration reads those outputs via terraform_remote_state to know where to place EC2 instances — without duplicating or hardcoding any IDs.

◈ DIAGRAM
+------------------------------------------+
| resource "aws_db_instance" "main" { |
| identifier = "hotstar-prod-postgres" |
| } |
+------------------------------------------+
|
v
+------------------------------------------+
| output "rds_endpoint" { |
| value = aws_db_instance.main.address |
| } |
+------------------------------------------+
|
+-----------+-----------+
| |
v v
+---------------+ +---------------------------+
| Terminal | | Other Terraform config |
| after apply: | | data "terraform_remote_ |
| rds_endpoint | | state" "network" {} |
| = "abc.rds.." | | data.terraform_remote_ |
| | | state.network.outputs |
| | | .rds_endpoint |
+---------------+ +---------------------------+

Declaring Outputs

HCL
# outputs.tf
# Basic string output
output "s3_bucket_name" {
description = "S3 bucket name — set as APP_DATA_BUCKET environment variable"
value = aws_s3_bucket.app_data.id # .id is the bucket name for S3
}
# ARN output — for use in IAM policies
output "s3_bucket_arn" {
description = "S3 bucket ARN — reference in IAM policy resource fields"
value = aws_s3_bucket.app_data.arn
}
# Sensitive output — hidden in terminal, requires explicit flag to read
output "db_connection_string" {
description = "Full PostgreSQL connection string"
value = "postgres://${aws_db_instance.main.username}@${aws_db_instance.main.endpoint}/${aws_db_instance.main.db_name}"
sensitive = true
}
# Map output — group related values
output "database" {
description = "Database connection parameters for application configuration"
value = {
host = aws_db_instance.main.address
port = aws_db_instance.main.port
name = aws_db_instance.main.db_name
endpoint = aws_db_instance.main.endpoint
}
}
# List output — from count or for_each resources
output "private_subnet_ids" {
description = "Private subnet IDs — use in RDS subnet groups and EC2 placement"
value = aws_subnet.private[*].id
}
# Computed output — derived from resource attributes
output "app_url" {
description = "Application URL — add this to your DNS records"
value = "https://${aws_lb.main.dns_name}"
}

Reading Outputs

Bash
# Print all outputs after apply
terraform output
# Print one specific output (with type info and quotes)
terraform output rds_endpoint
# Print raw value — no quotes, for use in shell scripts
RDS_HOST=$(terraform output -raw rds_endpoint)
echo "Database host: $RDS_HOST"
# Print all outputs as machine-readable JSON
terraform output -json
# Read a sensitive output — requires -raw or -json
terraform output -raw db_connection_string
# Use output in a script
BUCKET=$(terraform output -raw s3_bucket_name)
aws s3 cp myfile.txt s3://$BUCKET/

Outputs Between Configurations (Remote State)

Outputs are the mechanism for sharing infrastructure data between separate Terraform configurations:

HCL
# networking/outputs.tf — networking team exposes VPC details
output "vpc_id" {
value = aws_vpc.main.id
}
output "private_subnet_ids" {
value = aws_subnet.private[*].id
}
HCL
# compute/main.tf — platform team reads networking outputs via remote state
data "terraform_remote_state" "networking" {
backend = "s3"
config = {
bucket = "razorpay-terraform-state"
key = "prod/networking/terraform.tfstate"
region = "ap-south-1"
}
}
resource "aws_instance" "app" {
subnet_id = data.terraform_remote_state.networking.outputs.private_subnet_ids[0]
# No hardcoded subnet IDs — always current from the networking state
}

Output Formatting Tips

HCL
# Output that includes computed expression
output "s3_console_url" {
description = "Direct link to the S3 bucket in the AWS console"
value = "https://s3.console.aws.amazon.com/s3/buckets/${aws_s3_bucket.data.id}"
}
# Output structured connection info as a JSON-friendly map
output "app_config" {
description = "Environment variables to set in the application"
value = {
DB_HOST = aws_db_instance.main.address
DB_PORT = tostring(aws_db_instance.main.port)
S3_BUCKET = aws_s3_bucket.data.id
AWS_REGION = data.aws_region.current.name
ENVIRONMENT = var.environment
}
}

Troubleshooting Outputs

Error Root Cause Fix
Error: Output refers to an undeclared resource Typo in resource address Check resource type and name spelling
Output shows (sensitive value) Output has sensitive = true Use terraform output -raw <name>
Error: Unsupported attribute Wrong attribute name on resource Check provider docs for valid attributes
Output missing after apply Output block not in any .tf file Add output block to outputs.tf and reapply
Remote state output not found Spelling mismatch between configs Check exact output name in source config
Tip

Add terraform output -json at the end of your CI/CD apply step and store the JSON as a build artifact. Downstream pipelines can read infrastructure values without re-running Terraform.

Common Mistake

Outputting sensitive values without sensitive = true. Database passwords and connection strings will be printed to the terminal and logged in CI/CD unless marked sensitive. Always mark outputs that contain secrets.

Frequently Asked Questions

What's the main real-world use case for Terraform output values beyond just printing to the terminal?

Outputs are how one Terraform configuration hands data to another without hardcoding it — a networking module can output a VPC ID and subnet IDs, which an application module then reads via a `terraform_remote_state` data source or, in newer patterns, via cross-module references in a root module. This lets infrastructure be split into independently managed layers (network, data, app) while still wiring them together programmatically instead of copy-pasting IDs between configs.

What's a common mistake teams make with sensitive data in Terraform outputs?

Outputting a value like a generated database password without marking it `sensitive = true` causes it to print in plain text in CI logs and `terraform apply` output, which is a real credential leak risk in shared pipelines. Marking an output `sensitive` suppresses it from CLI output, but it's worth remembering the value is still stored in plaintext in the state file itself, so state file access control matters just as much as the sensitive flag.