linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Knowledge base
  • Cheat sheet
  • Capstone
  • Interview prep
home/terraform/kb/Variables & outputs/tf-output

kb/variables ── Variables & outputs ── beginner

The output block: what Terraform exposes to the outside

An output is a value that Terraform displays after apply and stores in state. Use it to (a) show the user the ID or ARN of a created resource, (b) pass values between modules, or (c) feed values to scripts via `terraform output -raw`.

view as markdown

Why outputs exist

When Terraform creates a resource, that resource gains attributes: id, arn, endpoint. Those values are often needed by:

  • The user, to see which URL the new service received.
  • Another Terraform project, via remote state.
  • An external script: aws_endpoint=$(terraform output -raw endpoint).
  • The parent module, when a child module returns its values upward.

An output is how you expose a value to the outside world.

Basic syntax

hcl
resource "aws_s3_bucket" "demo" {
  bucket = "my-bucket-12345"
}
output "bucket_arn" {
  value       = aws_s3_bucket.demo.arn
  description = "ARN of the created bucket: needed for cross-account IAM policies."
}
output "bucket_url" {
  value = "https://${aws_s3_bucket.demo.bucket}.s3.amazonaws.com"
}

After apply Terraform prints:

Outputs:
bucket_arn = "arn:aws:s3:::my-bucket-12345"
bucket_url = "https://my-bucket-12345.s3.amazonaws.com"

sensitive: hiding a value

hcl
output "db_password" {
  value     = aws_db_instance.main.password
  sensitive = true
}

What this means in practice:

  • During terraform apply the value is shown as (sensitive value).
  • terraform output db_password prints the real value (useful for scripts).
  • terraform output -raw db_password does the same.
  • The state file stores the value in plain text. sensitive controls logging only.

When the value comes from a sensitive variable

If an output references a variable with sensitive = true, that output is also automatically treated as sensitive. Otherwise Terraform exits with an error about exposing a sensitive value in a non-sensitive output.

To output the value explicitly, mark the output as sensitive.

depends_on in an output

This is rare, but sometimes you need to guarantee the creation order of resources that an output references indirectly:

hcl
output "endpoint" {
  value      = aws_lb.web.dns_name
  depends_on = [aws_lb_listener.https]
}

Why bother? If another project reads this output via remote state, you can guarantee the listener is configured before that project reads the value, rather than getting an empty result.

In most cases depends_on in an output is unnecessary.

Reading outputs from the CLI

bash
# All outputs as JSON
terraform output -json
# One output in human-readable format
terraform output bucket_arn
# "arn:aws:s3:::my-bucket-12345"
# One output without quotes or JSON wrapping, for shell substitution
terraform output -raw bucket_arn
# arn:aws:s3:::my-bucket-12345
# Assign to a bash variable
BUCKET_ARN=$(terraform output -raw bucket_arn)

-raw works only for simple types (string/number). For list or map, use -json + jq.

Outputs between modules

Given a child module:

hcl
# modules/vpc/outputs.tf
output "vpc_id" {
  value = aws_vpc.main.id
}

In the parent HCL:

hcl
module "network" {
  source = "./modules/vpc"
}
resource "aws_subnet" "private" {
  vpc_id = module.network.vpc_id   # ← reference to the module output
}

The prefix is module.<module_name>.<output_name>. This is the only way a child module can return a value to its caller. Internal attributes of the module are not accessible from outside.

Common pitfalls

  • The state file is not encrypted. No matter how many outputs you mark sensitive = true, values sit in terraform.tfstate in plain text. For secrets, encrypt state at the backend level (S3 with SSE-KMS, Terraform Cloud with encryption).

  • You cannot reference your own output from elsewhere in HCL. There is no way to use an output value inside the same configuration that defines it. For a reusable value, use tf-locals.

  • When a resource is destroyed, its output disappears. If another project depends on this output via remote state, that project will break. Think before deleting.

  • The output value must be computable. You cannot write value = "${unknown_var}" if unknown_var is not defined. Terraform exits with a clear error.

  • description is useful. It is documentation for anyone who will use your output, including yourself a year from now. Fill it in.

  • -raw on a complex type is an error. Running terraform output -raw all_tags where all_tags is a map will fail. -raw accepts string and number only.

§ команды

bash
terraform output

Show all outputs in human-readable format (after apply).

bash
terraform output -json

All outputs as JSON, for parsing in scripts.

bash
terraform output -raw bucket_arn

One output without quotes, for assignment to a bash variable.

bash
terraform output -raw bucket_arn | xargs aws s3 ls

Shell composition: read the ARN and pass it to the next command.

§ см. также

  • tf-variableThe variable block: input to your configurationA variable is a parameter that receives its value from outside the configuration (CLI, environment variable, .tfvars file). You declare it in HCL with type, default, description, and validation, then reference it as var.name. Variables remove hardcoded values and let one HCL configuration serve multiple environments.
  • tf-localslocals: computed internal nameslocals is a block with names visible only inside HCL (not input, not output). Useful for DRY: compute a common prefix or tag set once, then use it everywhere via local.x. Do not confuse with variable (input) and output (output).
  • tf-referencesReferences in HCL: how to read aws_s3_bucket.demo.bucketAny value in HCL is reachable through an address: var.x, local.x, aws_s3_bucket.demo.arn, module.net.vpc_id, data.aws_region.current.name. Knowing this syntax is half of your productivity in Terraform.
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies