Terraform 1.x variable precedence broken?

Am I misreading the documentation? or is this a design change in Terraform 1.0?

I found when a variable is defined in both terraform.tfvars and also in an environment variable, the terraform.tfvars will take precedence (or the TF_VAR is completely ignored).

For example, when you have this:

# terraform.tfvars

And run this:

export TF_VAR_resource_group_name="overridegroup"
terraform apply

The final value when doing terraform apply will be defaultgroup, not overridegroup.

Followup, the documentation from earlier is more clear,

In here is says that environment variables are considered defaults, so variable definitions override that, which is something I think is inconsistent with other tools in this space, and thus violates least surprise principal in UX.

The current documentation documents precedence in reverse order with lowest precedence on the top, so this was quite confusing.

Hi @darkn3rd!

Referring to the first documentation you linked to, I see it state this (excerpted to just the parts relevant to our discussion here):

Terraform loads variables in the following order, with later sources taking precedence over earlier ones:

  • Environment variables
  • The terraform.tfvars file, if present.
  • (…and then various others not relevant to this question)

So this documentation agrees with what you observed: the terraform.tfvars file takes precedence over the environment variables.

I think implied in your question here is that you’d like to know why this is the precedence order Terraform uses. This is a long-standing rule from before I was directly involved in Terraform, but my sense is that the idea is that environment variables are session-level settings that would apply to all of the configurations you work with in that session, whereas terraform.tfvars applies only to one particular configuration and is therefore more specific. The behavior prioritizes more specific (that is, more “localized”) definitions over less specific ones, and so the settings for the current directory, if any, override the settings from your “session”.

Rationale aside though, at this point what Terraform does in this regard is just what it does: these behaviors are covered by the Terraform v1.0 Compatibility Promises, and so are locked in for the foreseeable future.

1 Like