Allow terraform validate to check reusable modules with deprecated outputs
We rely on terraform validate as a quick check for reusable modules and their submodules before publishing them. Adding deprecated to an output now makes that check fail, even though the output is valid when the module is called by another module.
Could validate take an option that tells it we're checking a reusable module rather than a deployment root? We'd like to keep running validation directly against each module without removing deprecation declarations or building a wrapper just to make the check run.
This is related to hashicorp/terraform#39207, which covers the same restriction during terraform test. This request is specifically about keeping the standalone terraform validate check available.
Terraform version
Terraform v1.16.2
on windows_amd64
No providers, credentials or cloud resources are needed for this example.
Reproduction
main.tf:
terraform {
required_version = ">= 1.15.0"
}
variable "name" {
type = string
default = "example"
deprecated = "This input is kept for compatibility."
}
output "old_name" {
value = var.name
deprecated = "This output is kept for compatibility."
}
Run from the module directory:
terraform init -backend=false
terraform validate
Validation exits with code 1:
Error: Root module output deprecated
on main.tf line 13, in output "old_name":
13: deprecated = "This output is kept for compatibility."
Root module outputs cannot be deprecated, as there is no higher-level module to inform of the deprecation.
Removing only the output's deprecated line makes validation pass. The input variable can remain deprecated. The hard failure here is the root-only restriction on the output, not an error caused by the deprecated input variable.
Requested behavior
An explicit option such as terraform validate -reusable-module would let us say that this directory is intended to be called as a child module. The flag name is just a suggestion; a narrower option for the deprecated-output restriction would also help.
With that option, validate should accept deprecated outputs that are valid in a reusable module, retain any applicable deprecation warnings, and still fail on invalid syntax, bad references, type errors, invalid arguments and other genuine validation errors. The existing behavior should remain the default for normal root configurations, and this should not change plan or apply.
This isn't a request for a general "ignore errors" switch. We want the validation checks, without a failure that comes solely from treating a reusable module as a deployment root.
Why this matters
The documentation describes validate as being "primarily useful for general verification of reusable modules": https://developer.hashicorp.com/terraform/cli/commands/validate
Validating examples is useful too, but it only checks modules that those examples actually reference. A separate check against each module directory is valuable, including for submodules that don't yet have an example. Writing wrappers also means supplying inputs and provider wiring just to run a static check.
I understand from hashicorp/terraform#38309 that validate currently expects a complete root configuration, and that changing this may involve more than one output validation rule. That issue covers the similar problem with ephemeral outputs. An explicit reusable-module option would make the intended context clear without quietly changing how existing configurations are checked.
Source: hashicorp/terraform