how/variables
Six value sources for one variable, lined up in a queue. Which one overrides which, and why your .tfvars sometimes "doesn't apply."
A variable in Terraform can have six value sources. Each one is optional. If the value came from more than one, the one that is higher in the hierarchy wins.
This is not magic. The order is fixed in the official docs
and applies on every terraform plan and apply. If you
edited terraform.tfvars and Terraform stubbornly uses a different
value, the reason is almost always that something higher in the
hierarchy overrides it.
Press ▶ and watch the same var.region value climb up the
precedence ladder.
In HCL:
variable "region" {type = string
default = "us-east-1"
}
If there is nothing else, Terraform uses "us-east-1".
This is the bottom rung of the ladder.
If no default is set and the value comes from nowhere, plan fails
with No value for required variable. That is exactly a "required
variable."
recap
What to remember:
-var on the CLI wins over everything. Handy for one-off
"run with a different value without editing files." Do not put
such commands in scripts, or later you will not find where the
value came from.*.auto.tfvars are picked up automatically, in alphabetical
order. Often used to split by environment:
prod.auto.tfvars, staging.auto.tfvars. But only one
of them should sit in the directory, otherwise the values mix.terraform.tfvars is the only file with that name Terraform
picks up without a flag. Names like vars.tfvars or
config.tfvars are picked up only through -var-file=.TF_VAR_<name> is especially useful for secrets in CI/CD:
TF_VAR_db_password=$(vault read …) stays out of the HCL, the
.tfvars, and the command logs. See tf-sensitive.default = ... in variable is a fallback, not a "default
value for prod." If a variable should be required,
remove the default. Terraform will fail with No value for required variable,
and you will see it right away.Gotcha: if the value came from two different
*.auto.tfvars files, the alphabetically last one wins.
Not "last by mtime" and not "read during init," just
sorting by name. z-override.auto.tfvars will override
prod.auto.tfvars.
Next: tf-sensitive on how Terraform handles secrets in these sources.