Skip to main content
Welcome to this lesson on Terraform variable blocks. In this guide you’ll learn what Terraform input variables are, why they matter, and how to use them to make configurations flexible and reusable across environments (production, QA, dev). By the end you’ll know how to declare variables, supply values, and apply best practices for multi-environment infrastructure as code. Let’s jump in.

The problem with hard-coded values

When infrastructure for multiple environments is nearly identical, hard-coded values force you to duplicate resources across files. That duplication increases maintenance effort, creates configuration drift, and raises the risk of human error. Example of repeated resources with hard-coded values:
Common problems when repeating configuration like this:
  • Maintenance burden: single change must be applied in many places.
  • Risk of human error: accidental copy/paste of production values.
  • Configuration drift: environments diverge over time.
  • Onboarding friction: new team members face multiple near-duplicate files.
  • Violates DRY (Don’t Repeat Yourself) principles.

How variables solve this

Variables let one shared configuration accept environment-specific inputs. Teams provide variable values (via files, CLI, or environment variables) and the single codebase produces the appropriate resources for each environment. Refactored resources that reference variables:
With this approach:
  • Use production.tfvars, qa.tfvars, and dev.tfvars to supply environment-specific values.
  • Or override variables with -var on the CLI or with TF_VAR_<NAME> environment variables.
  • One configuration becomes a single source of truth, reducing errors and improving maintainability.

What is a variable block?

A variable block declares an input to your Terraform configuration. It documents intent (via description), constrains values (type), and can provide a default (default). Variables can be simple scalars or complex structures.
A presentation slide titled "Variable Block" with a photo of glossy purple jigsaw puzzle pieces on the left. The right side explains that variable blocks let you parameterize inputs to make configurations reusable and avoid hardcoding values.
Key characteristics of variable blocks:
  • Dynamic inputs that make configurations reusable.
  • Centralized management of environment values.
  • Type validation to catch mistakes early.
A simple string variable:
A variable that holds a list of strings:
These definitions give you:
  • A human-readable description for documentation and plan output.
  • An explicit type so Terraform can validate input.
  • An optional default so values aren’t mandatory at runtime.
If you omit the type argument, Terraform will infer the variable type from the value you provide. Explicit types are recommended for clarity and earlier validation.

Anatomy of a variable block

A variable block follows a predictable structure:
  • Name: referenced in config as var.<name>.
  • Description: purpose and expected values.
  • Type: one of string, number, bool, list(...), map(...), object(...), tuple, etc.
  • Default: optional fallback if no value is supplied.
This structure scales from simple scalars to complex objects and makes documenting inputs straightforward.

Terraform variable types (cheatsheet)

Note: In the table above, examples containing curly braces or angle brackets are wrapped in backticks to avoid MDX parsing issues.

Ways to provide variable values

You can supply values to Terraform variables using several mechanisms. Below is a summary of common methods and a short example for each. Example production.tfvars:
Example CLI usage:
Precedence (higher to lower):
  1. CLI -var or -var-file (explicit on command)
  2. Environment variables (TF_VAR_<NAME>)
  3. terraform.tfvars or files named *.auto.tfvars
  4. default in variable block

Best practices

  • Give variables descriptive names and include description.
  • Explicitly declare type for early validation.
  • Prefer *.tfvars or -var-file for environment-specific values (keeps secrets out of VCS).
  • Keep secrets in a secure secret store and inject them via CI or environment variables (do not commit secrets to source control).
  • Group related values with object or map types for clarity.
  • Use a consistent variable file naming convention: production.tfvars, staging.tfvars, dev.tfvars.
  • Document required variables in a README for each module.

Next steps

You’ll want to explore:
  • Available complex types in detail (object, tuple, nested map).
  • How to pass sensitive values securely and use sensitive = true.
  • How variable scoping works across modules.
  • Organizing variable files and inputs for multi-team workflows.
Links and references:

Watch Video