Skip to content

Proposal: terraform validate for static validation only #15895

@apparentlymart

Description

@apparentlymart

The main way to check the validity and impact of a Terraform config is to run terraform plan, which validates the configuration and compares it to existing infrastructure in a single operation.

We also offer terraform validate, which is a strange subset of the plan functionality that does the validation step but then stops before computing the difference with existing state.

The validate command currently offers little advantage over plan, since it still fully instantiates the providers and thus, as described in #15811, requires working credentials and network access.

I'd like to propose that we refine the distinction between these commands, as follows:

  • terraform validate checks whether the configuration syntax is valid, whether constant argument values are suitable, whether all interpolations can be resolved to values of the correct type for their usage. This would not use the backend nor configure the providers and thus not reach out to the network at all.
  • terraform plan does all of the above checks for validate, then checks that provided variables are valid, configures the providers, refreshes existing state, does any additional validation that requires network access, and produces a diff showing changes from current state.

In short, terraform validate does static validation (configuration only) while terraform plan does dynamic validation (considering configuration along with the current state of the world, any variables set, etc).

Most notably:

  • It would no longer consider any existing values in state (would act as if the state is entirely empty, not contact the backend at all, etc).
  • It would not consider variable values, so you can ask generally "will this config work regardless of what variables I set?".
  • Would work without a backend configured at all, so validation is possible in the absence of credentials for the backend. (though a terraform init would still be required in order to get provider plugins installed; perhaps it could support a more limited validation pass if providers aren't installed, emitting a warning for things that can't be checked by core alone.)

A key goal would be that terraform validate is suitable to run, for example, as a hook in a text editor so that errors can be flagged automatically. For this to work well, it must be fast and require no context other than the configuration files.

A secondary motivation for making this distinction clear is that #8769 will more firmly establish that plan is not an offline-capable operation: to improve Terraform's ability to detect more problems during plan rather than during apply, it'll be necessary for Terraform to make API calls during plan in certain cases, so my hope is that this new role for terraform validate would compensate for that by clearly distinguishing the static and dynamic use-cases.

Finally, there are plans (already stubbed out in the backend/ code) to allow backends to run certain operations remotely, so that local credentials are not required. terrform validate, in that world, would always run locally, whereas terraform plan would run remotely to get access to any credentials provided by the remote backend.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions