A CI job exports TF_VAR_tags='{"team":"payments","tier":"gold"}' before running terraform plan in a root module whose tags variable is declared as map(string). The plan instead shows the tags defined in the directory's terraform.tfvars file. Why did the environment value not apply?
Select an answer to reveal the explanation.
Short Explanation
Environment variables you export are the quiet voice at the back of the room: only the variable's default ranks lower. Any tfvars file that sets the same name talks over them, terraform.tfvars included. And no, the map didn't get dropped; complex values work fine in TF_VAR_ if the syntax is right.
Full Explanation
Terraform resolves root module variables by precedence: command-line -var and -var-file options and HCP Terraform values first, then .auto.tfvars and .auto.tfvars.json files, then terraform.tfvars.json, then terraform.tfvars, then TF_VAR_ environment variables, and finally the default. Because terraform.tfvars sets tags, it outranks the exported environment variable, and the plan shows the file's tags. Complex types can be supplied through TF_VAR_; the documentation recommends proper JSON syntax, as used here, to survive shell quoting, so the map literal is not the problem. Environment values apply whether or not the variable has a default; the default is the lowest level and is used only when no other source provides a value. TF_VAR_ variables are read by each command that evaluates variables, including plan and apply; they are not cached at init. Exam caveat: Terraform silently ignores TF_VAR_ variables that match no declared variable, so a typo in the name also produces this symptom. Operational check: remove tags from terraform.tfvars or pass the override with -var-file in the job, then run terraform plan and confirm the team and tier tags appear.