What is the difference between variables, locals, and outputs?

4 minbeginnerterraformvariableslocalsoutputs

Quick Answer

Variables are inputs supplied from outside the module (CLI, tfvars, env vars). Locals (locals { ... }) are named expressions computed inside a module to avoid repeating logic. They can't be overridden from outside. Outputs (output "name" { value = ... }) expose values out of a module, either for the CLI (terraform output), for another module that calls this one, or for remote state consumers (terraform_remote_state). Together they form a module's public interface: variables in, outputs out, locals as private helpers in between.

Detailed Answer

These three constructs — variables, locals, and outputs — form the complete "interface" of any Terraform module: inputs in, computed helpers in the middle, values out.

Variables — inputs

variable "environment" {
  type = string
}

Set from outside the module: CLI flags, tfvars files, environment variables, or (for a child module) the calling module's module block arguments. A module's author defines what variables exist; the caller decides their values.

Locals — internal, derived values

locals {
  name_prefix = "${var.project}-${var.environment}"
  common_tags = {
    Project     = var.project
    Environment = var.environment
    ManagedBy   = "terraform"
  }
}

Locals compute a value once, inside the module, from variables/other locals/resource attributes, and are referenced as local.name_prefix. They exist purely to avoid repeating the same expression across many resource blocks. They cannot be set or overridden from outside the module; they're private implementation detail.

Outputs — what the module exposes

output "bucket_arn" {
  value       = aws_s3_bucket.assets.arn
  description = "ARN of the created assets bucket"
}

Outputs expose values out of a module for three audiences:

  • The CLI, via terraform output (handy for scripting or quick inspection).
  • A parent module, referenced as module.<name>.bucket_arn.
  • Anyone consuming this configuration's remote state via terraform_remote_state, letting a completely separate configuration read values it produced.

Putting it together

variables (external input)
     │
     ▼
 locals (internal computation, DRY helpers)
     │
     ▼
resources (actually created, using vars + locals)
     │
     ▼
 outputs (external-facing results)

A well-designed module minimizes what it exposes as variables/outputs (a clean, stable public interface) while doing as much repeated computation as possible in locals, keeping the resource blocks themselves simple and readable.

Related Resources