Outputs: Basic, Sensitive and Complex Types
Scenario
You've deployed several resources and need to expose key information — bucket names, ARNs, connection strings — so other team members (or other Terraform configs) can reference them. Some values are sensitive (like generated passwords) and must be masked in CLI output.
Your task is to create outputs of various types — strings, lists, maps, and sensitive values — and learn how to query them from the CLI.
- Create a basic string output for the bucket name.
- Create a sensitive output that is masked in terminal output.
- Create a list output returning multiple values.
- Create a map output returning a structured object.
- Use terraform output, terraform output -raw, and terraform output -json to query values.
Additional Context
Outputs serve two purposes: they display values after terraform apply for human consumption, and they expose values for cross-configuration references via terraform_remote_state data sources or module outputs.
Marking an output as sensitive = true hides the value in CLI output (shows (sensitive value)). However, the value is still stored in plain text in the state file. Sensitive outputs prevent accidental exposure in CI logs — they don't encrypt the state.
main.tf
# main.tf
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
provider "aws" { region = "us-east-1" }
data "aws_caller_identity" "current" {}
resource "aws_s3_bucket" "app" {
bucket = "outputs-demo-${data.aws_caller_identity.current.account_id}"
tags = { Environment = "dev", ManagedBy = "terraform" }
}
resource "aws_s3_bucket_versioning" "app" {
bucket = aws_s3_bucket.app.id
versioning_configuration { status = "Enabled" }
}outputs.tf
# outputs.tf
# BASIC STRING OUTPUT — shown after apply
output "bucket_name" {
description = "The name of the S3 bucket."
value = aws_s3_bucket.app.id
}
output "bucket_arn" {
description = "The ARN of the S3 bucket."
value = aws_s3_bucket.app.arn
}
# SENSITIVE OUTPUT — masked in CLI, still in state file
output "account_id" {
description = "AWS account ID (masked in output)."
value = data.aws_caller_identity.current.account_id
sensitive = true
}
# LIST OUTPUT — returns multiple values as a list
output "bucket_details_list" {
description = "Bucket name and ARN as a list."
value = [aws_s3_bucket.app.id, aws_s3_bucket.app.arn]
}
# MAP OUTPUT — returns a structured object
output "bucket_summary" {
description = "Full summary of the bucket as a map."
value = {
name = aws_s3_bucket.app.id
arn = aws_s3_bucket.app.arn
region = aws_s3_bucket.app.region
versioning = "Enabled"
}
}Workflow Commands
terraform init && terraform apply
# View ALL outputs
terraform output
# View a single output
terraform output bucket_name
# View raw value (no quotes) — useful for scripting
terraform output -raw bucket_name
# View as JSON — useful for piping to jq
terraform output -json
# View a sensitive output (Terraform shows the value with -raw or -json)
terraform output -raw account_id
# View just the map output as JSON
terraform output -json bucket_summary
terraform destroyApply complete! Resources: 2 added, 0 changed, 0 destroyed.
Outputs:
account_id = (sensitive value)
bucket_arn = "arn:aws:s3:::outputs-demo-123456789012"
bucket_details_list = [
"outputs-demo-123456789012",
"arn:aws:s3:::outputs-demo-123456789012",
]
bucket_name = "outputs-demo-123456789012"
bucket_summary = {
"arn" = "arn:aws:s3:::outputs-demo-123456789012"
"name" = "outputs-demo-123456789012"
"region" = "us-east-1"
"versioning" = "Enabled"
}
