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:- 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:- Use
production.tfvars,qa.tfvars, anddev.tfvarsto supply environment-specific values. - Or override variables with
-varon the CLI or withTF_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 (viadescription), constrains values (type), and can provide a default (default). Variables can be simple scalars or complex structures.

- Dynamic inputs that make configurations reusable.
- Centralized management of environment values.
- Type validation to catch mistakes early.
- A human-readable
descriptionfor documentation and plan output. - An explicit
typeso Terraform can validate input. - An optional
defaultso 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.
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:
- CLI
-varor-var-file(explicit on command) - Environment variables (
TF_VAR_<NAME>) terraform.tfvarsor files named*.auto.tfvarsdefaultin variable block
Best practices
- Give variables descriptive names and include
description. - Explicitly declare
typefor early validation. - Prefer
*.tfvarsor-var-filefor 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
objectormaptypes 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, nestedmap). - 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.