What are input variables, and how does Terraform resolve variable precedence?

4 minbeginnerterraformvariableshcl

Quick Answer

Input variables (`variable "name" { type = string }`) parameterize a configuration so the same code can be reused with different values. Terraform resolves a value for each variable using a defined precedence (highest wins): `-var`/`-var-file` CLI flags, `*.auto.tfvars` files (alphabetical), explicit `-var-file` files, `terraform.tfvars`, `TF_VAR_name` environment variables, then the variable's `default` in configuration. This lets you keep sane defaults in code while overriding per-environment values via tfvars files or CI secrets.

Detailed Answer

Input variables are how a Terraform configuration accepts external parameters instead of hardcoding values, making the same code reusable across environments, regions, and teams.

Declaring a variable

variable "instance_type" {
  type        = string
  description = "EC2 instance type for the web tier"
  default     = "t3.micro"
}

Referenced elsewhere as var.instance_type.

The precedence order

Terraform must decide which value "wins" when a variable could be set in multiple places. From highest to lowest precedence:

  1. -var or -var-file flags passed on the terraform plan/apply command line.
  2. *.auto.tfvars (or .auto.tfvars.json) files in the working directory, processed in alphabetical order.
  3. terraform.tfvars (or terraform.tfvars.json), if present.
  4. TF_VAR_<name> environment variables (e.g., TF_VAR_instance_type=t3.large).
  5. The variable's default value in configuration, if no other source provides one.

(Within a given precedence level, later definitions on the command line override earlier ones.)

Why this matters in practice

  • CI/CD pipelines typically inject environment-specific and sensitive values via TF_VAR_* environment variables (pulled from a secrets store), while terraform.tfvars holds non-sensitive, checked-in defaults for local development.
  • Layering *.auto.tfvars files (e.g., common.auto.tfvars, prod.auto.tfvars) lets teams share baseline values while still allowing an explicit -var override for a one-off plan during debugging.
  • If a variable has no default and no value supplied from any source, Terraform will interactively prompt for it (or fail in non-interactive/CI contexts) — which is a useful safety net for variables that must always be explicitly set (like an account ID), but a nuisance if forgotten in automation.

Getting this precedence order right is what lets teams keep sane defaults in version-controlled code while still safely overriding per-environment or per-run values without editing the configuration itself.

Related Resources