Variable Precedence: Six Ways to Set a Variable
Scenario
Your team uses the same Terraform config for dev, staging, and prod. Different environments need different values — but the team is unsure which input method takes priority when the same variable is set in multiple places.
You need to demonstrate all six ways to set a variable and confirm the precedence order by setting the same variable via multiple methods simultaneously and observing which one wins.
Your Objectives
- Declare a variable environment with a default of "from-default".
- Create a terraform.tfvars file that sets environment = "from-tfvars".
- Create a prod.auto.tfvars file that sets environment = "from-auto-tfvars".
- Create a override.tfvars file that sets environment = "from-var-file".
- Set TF_VAR_environment=from-env-var as an environment variable.
- Pass -var="environment=from-cli" on the command line.
- Output the resolved value and confirm the precedence order.
Additional Context
Terraform processes variable values in this order (lowest to highest priority):
- Default in the variable declaration
- Environment variables (TF_VAR_name)
- terraform.tfvars (auto-loaded)
- *.auto.tfvars (auto-loaded, alphabetical)
- -var-file flag (in order specified)
- -var flag (highest priority — always wins)
The rule is simple: more specific beats less specific. Defaults are the most general; a -var flag is the most targeted.
variables.tf
# variables.tf
variable "environment" {
description = "Which environment are we deploying to?"
type = string
default = "from-default" # Priority 1 (lowest)
}
variable "aws_region" {
type = string
default = "us-east-1"
}terraform.tfvars
# terraform.tfvars — auto-loaded by Terraform (Priority 3)
environment = "from-tfvars"prod.auto.tfvars
# prod.auto.tfvars — auto-loaded, alphabetically after terraform.tfvars (Priority 4)
environment = "from-auto-tfvars"override.tfvars
# override.tfvars — only loaded if passed with -var-file (Priority 5)
environment = "from-var-file"main.tf
# main.tf
terraform {
required_version = ">= 1.5.0"
required_providers {
aws = { source = "hashicorp/aws", version = "~> 5.0" }
}
}
provider "aws" { region = var.aws_region }
resource "aws_s3_bucket" "demo" {
bucket = "var-precedence-${var.environment}"
tags = { Environment = var.environment, ManagedBy = "terraform" }
}outputs.tf
output "resolved_environment" {
description = "The final value after all precedence rules are applied."
value = var.environment
}Workflow Commands — Testing Precedence
terraform init
# Test 1: Only defaults (delete/rename tfvars files temporarily)
# Result: "from-default"
# Test 2: With terraform.tfvars present
terraform plan # → "from-auto-tfvars" (auto.tfvars beats terraform.tfvars)
# Test 3: Add environment variable
export TF_VAR_environment="from-env-var"
terraform plan # → "from-auto-tfvars" (auto.tfvars beats env var!)
# Test 4: Add -var-file flag
terraform plan -var-file="override.tfvars" # → "from-var-file"
# Test 5: Add -var flag (HIGHEST PRIORITY)
terraform plan -var="environment=from-cli" # → "from-cli" (always wins)
# Clean up env var
unset TF_VAR_environment
✓ Precedence Order (Lowest → Highest)
1. default → "from-default" 2. TF_VAR_* → "from-env-var" 3. terraform.tfvars → "from-tfvars" 4. *.auto.tfvars → "from-auto-tfvars" 5. -var-file → "from-var-file" 6. -var → "from-cli" ← ALWAYS WINS

