`terraform validate` doesn't (and does) work with variable validations

I got into an friendly argument with a colleague (@nfrappart ) about the nature of terraform validate.

I said that terraform validate, surprisingly, cannot be used to run variable validations against a give set of inputs. He countered with “oh yes it can”. Turns out we were both wrong (and both right)! but why :thinking: ?

When working in a root module and setting a variable value via *.auto.tfvars (or using default keyword), validations are not evaluated until plan. HOWEVER, when calling a module, validations ARE evaluated by the validate command.

Could yall shed some light on why this is the case? Is it possible that the root module could start catching these validation issues? or, could the validate command be modified to accept -var CLI args?

1 Like

Hi @dmullen,

The terraform validate command is broadly intended to check whether a module is valid regardless of what planning options might be used, and so its intended design is to treat all root input variable values as unknown, because input variables are set as part of the planning options.

The main intended use-case for terraform validate is to run it in situations like a standardized CI check, where there is no context to decide what specific input variable values might be relevant and the goal is only to quickly see if the module is valid at all. The terraform plan command is the one responsible for checking that the given planning options make sense for the configuration, along with its other responsibilities.

I agree in retrospect that using the term “validation” to describe the input variable checks is confusing for that reason, and we later coined the terms “precondition” and “postcondition” that we’ve used for similar features elsewhere in the language for that reason. If we could design this over again I expect we’d name the block postcondition for consistency with everything else.

If you want to test whether or not your module can accept specific inputs, I’d suggest using the test framework for that. You can then describe one or more test scenarios which include a set of input variables to send to the root module. You can use mock providers to avoid connecting to real APIs, if you’d prefer these tests to be runnable “offline”.

1 Like

thanks for the feedback @apparentlymart
It makes perfect sense. At the end of the day, test framework is the golden path for validation.
It’s just that having this kind of validation with something as simple as terraform validate command was very attractive. Especially since developing proper testing for root modules with the framework requires more work (lazy me :sweat_smile:)