Terraform outputs are the interface that exposes important identifiers and endpoints of the resources you build. Bad design leads to incidents: values you cannot fetch, leaks, or broken pipelines.
This article walks through defining outputs, retrieving them safely from the CLI, sharing them across modules and stacks, and handing them off to CI/CD — organized around the angles the Associate exam tests most often.
An output is a value that a root module (or child module) exposes to the outside. After apply, it is written to the state file and can be referenced from the CLI or other code. Note that at plan time the value may still be undetermined (known after apply).
Adding sensitive = true masks the value in the standard CLI display. The raw value is still stored in state, however, so protecting the state (backend access control, encryption) is a prerequisite.
Minimal outputs.tf (with a sensitive value)
output "bucket_name" {
description = "S3 bucket name that stores app artifacts"
value = aws_s3_bucket.app_bucket.id
}
output "db_password" {
description = "Initial DB user password (display is masked)"
value = random_password.db.result
sensitive = true
}terraform output lists post-apply output values or fetches them individually. Use the bare form for humans, -json for machine-readable consumption, and -raw when you need a plain string.
Sensitive outputs are masked in the standard display. -json returns JSON that includes the value (with a sensitive flag), which is convenient for automation but risks leaks via logs. -raw is for strings only and may refuse or mask sensitive outputs.
| Method | Output format | Handling of sensitive values | Typical use |
|---|---|---|---|
| terraform output | Human-readable text | Values masked | Manual inspection |
| terraform output name | Human-readable text | Values masked | Inspecting a single value |
| terraform output -raw name | Plain string | Non-sensitive only (sensitive may be refused or masked) | Assigning to env vars and similar |
| terraform output -json | JSON | Includes values (flagged with sensitive: true) | CI/CD and script integration |
| terraform show -json | JSON (entire state/plan) | Values stored in state are retrievable | Machine processing including info beyond outputs |
| data.terraform_remote_state | Referenced via HCL | Depends on permissions on the target state | Using another stack's outputs from code |
Output flow (definition → state → retrieval & sharing)
Common retrieval commands
# List (sensitive values masked)
terraform output
# Fetch a single value (sensitive values masked)
terraform output bucket_name
# Machine-readable (includes sensitive values — handle logs with care)
terraform output -json | jq '.bucket_name.value'
# Plain string (for non-sensitive strings)
terraform output -raw bucket_name
# Parse the full state as JSON (when you want fields beyond outputs)
terraform show -json | jq '.values.outputs'
A child module's output can be referenced from the parent as module.<name>.<output_name>. Re-exposing (wrapping) it from the parent stabilizes the external interface and makes it resilient to internal implementation changes.
When you want to return several things at once, using an object or map as value keeps consumption simple. Outputs do not carry explicit type declarations, but you can pass an object as the value.
Example: re-exposing a child module's output from the parent
# child/outputs.tf
output "vpc" {
description = "Key VPC attributes"
value = {
id = aws_vpc.main.id
cidr = aws_vpc.main.cidr_block
rt_ids = [for r in aws_route_table.this : r.id]
}
}
# root/main.tf
module "network" {
source = "./child"
# ...
}
# root/outputs.tf
output "vpc_id" {
value = module.network.vpc.id
description = "VPC ID consumed by the application"
}
When you need to reference outputs in a different state, data "terraform_remote_state" is the tool. It fits separated topologies — for example, the application layer reading a VPC ID from the network layer.
It creates an implicit cross-stack dependency, so you must manage apply order (run network → app in CI) and set access permissions on the referenced state. If the coupling becomes problematic, consider a single-repo root/child module layout instead.
Referencing another state's outputs via terraform_remote_state
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "tfstate-shared-bucket"
key = "envs/prod/network/terraform.tfstate"
region = "ap-northeast-1"
}
}
# Usage (consume the VPC ID)
resource "aws_subnet" "app" {
vpc_id = data.terraform_remote_state.network.outputs.vpc_id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-1a"
}
For automation, use terraform output -json, extract only the keys you need, and pass them as artifacts or environment variables. Use masking and permission separation to keep sensitive values out of logs.
Outputs cannot be fed back as resource inputs directly (they exist to expose values externally), so it is simplest to generate files via the CLI. When -raw is not applicable, fall back to -json with jq.
Example CI steps (JSON → .env/file output)
# 1) Save to JSON
terraform output -json > outputs.json
# 2) Extract just the values you need into .env (mask/skip sensitive ones)
VPC_ID=$(jq -r '.vpc_id.value' outputs.json)
echo "VPC_ID=$VPC_ID" >> app.env
# 3) Convert to another format (for system configuration, etc.)
jq '{service_url: .service_endpoint.value, bucket: .bucket_name.value}' outputs.json > runtime_config.json
Outputs should be retrieved after apply as a rule — at plan time they can be unknown. sensitive=true masks CLI output; it does not encrypt state. -json includes sensitive values, so be careful with logs.
Cross-stack references are possible via data.terraform_remote_state, but the recommended approach is explicit dependency management through modularization. -raw is string-only and cannot be used with composite types.
What known after apply looks like
# Plan display (conceptual)
# + output "bucket_name" {
# value = (known after apply)
# }
# -> After apply, retrieve the finalized value with terraform output
Associate
問題 1
The root module has an output marked sensitive = true, and you need to fetch its actual value via automation and pass it to a downstream job. Which approach is most appropriate?
正解: A
Sensitive outputs are masked in the standard display, so terraform output will not give you the raw value. -json returns JSON that includes the value (with a sensitive: true flag), which is well suited to automation. -raw is string-only and may refuse sensitive values, and reading text output by eye is not appropriate for automation.
Does sensitive = true encrypt the value inside the state file?
No. sensitive only masks values in CLI output and plan/apply logs. The raw value is still stored in state, so you must protect it through backend access controls and encryption (for example, S3 server-side encryption, KMS, or Terraform Cloud workspace settings).
Why is terraform output empty or unable to fetch a value?
The usual causes are: 1) the value is not yet determined before apply, 2) the root module has no output defined (a child module output was not re-exposed), 3) you are looking at a different workspace or backend, 4) the state is corrupted or your permissions are insufficient. Start by running terraform apply, verify your workspace and backend configuration, and confirm state integrity.
How do I bundle multiple values into a single output?
The practical approach is to wrap them into an object or map in value. For example, returning value = { id = aws_vpc.main.id, cidr = aws_vpc.main.cidr_block } lets consumers reference them with dot notation such as module.x.vpc.id.
Practice with certification-focused question sets
無料で問題を解いてみるNicheeLab Editorial Team
NicheeLab editorial team focused on data engineering and cloud certification learning. Content is structured around practical study needs and official exam domains.
HCL Syntax: Terraform's Configuration Language (2026)
HCL2 fundamentals for Terraform — blocks, attributes, expres...
Terraform Authoring & Operations Pro: Complete Guide (2026)
Tactics for the Terraform Pro exam — module authoring, works...
Terraform Providers: Plugin Management Fundamentals (2026)
Provider mechanics — required_providers, versions, mirrors, ...
Terraform Resource Blocks: Declarative Infra Units (2026)
Resource block fundamentals — addresses, references, common ...
Terraform Data Sources: Read-Only External Data (2026)
Data source basics — declaration, refresh behavior, dependen...