Terraform 13: Passing values — tfvars, -var, env vars & precedence
easy⏱ 5 mincourseterraform
The ways to supply a value
You can set a variable via a .tfvars file, an environment variable named TF_VAR_<name>, or the -var / -var-file CLI flags. A terraform.tfvars (or any *.auto.tfvars) file is loaded automatically; other .tfvars files need -var-file.
# dev.tfvars — one file per environment
environment = "dev"
location = "westus2"
instance_count = 1
tags = {
team = "platform"
env = "dev"
}
# --- shell equivalents ---
# export TF_VAR_environment=dev
# terraform apply -var-file="dev.tfvars"
# terraform apply -var="instance_count=3"
Precedence: last-wins, CLI is strongest
When the same variable is set in multiple places, Terraform applies them in this order (each overrides the previous): 1) default, 2) terraform.tfvars / *.auto.tfvars, 3) TF_VAR_* env vars, 4) explicit -var-file, 5) -var on the command line. So a -var flag always wins.
# Given all of these set `instance_count`:
# default = 1
# dev.tfvars = 2 (via -var-file)
# TF_VAR_... = 4
# -var flag = 9
#
# terraform apply -var-file=dev.tfvars -var="instance_count=9"
# => instance_count = 9 (the -var flag wins)
Never commit secrets in tfvars
*.tfvars files are plain text. Keep environment shape there (region, counts, names) but never passwords or keys — those belong in a secret store (e.g. Azure Key Vault, read via a data source) or in TF_VAR_* injected by your CI. Add *.tfvars holding anything sensitive to .gitignore.
Resolve variable precedence
Write resolve(sources) where sources is an object with optional keys default, tfvars, env, varFlag. Return the value from the highest-precedence key that is defined, in Terraform's order (varFlag > env > tfvars > default). Then log resolve({ default: 1, tfvars: 2, env: 4, varFlag: 9 }) (expect 9) and resolve({ default: 1, tfvars: 2 }) (expect 2).