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