terraform test fails when a module output is marked deprecated
We're trying to deprecate an output without removing it or changing its value.
Adding deprecated makes our existing terraform test runs fail, even when the tests don't use that output.
The module is intended to be called by other modules. We test it directly so we can check its locals, resources and variable validation. I'd like to keep those tests while giving consumers a warning about the old output.
Terraform version
Terraform v1.16.2
on windows_amd64
This example needs no providers, credentials or cloud resources.
Reproduction
main.tf:
terraform {
required_version = ">= 1.15.0"
}
variable "name" {
type = string
validation {
condition = var.name != ""
error_message = "name must not be empty."
}
}
locals {
normalized_name = lower(var.name)
}
output "name" {
value = local.normalized_name
}
output "old_name" {
value = local.normalized_name
deprecated = "Use name instead."
}
tests/main.tftest.hcl:
run "normalizes_name" {
command = plan
variables {
name = "EXAMPLE"
}
assert {
condition = local.normalized_name == "example"
error_message = "Expected a lowercase name."
}
}
run "rejects_empty_name" {
command = plan
variables {
name = ""
}
expect_failures = [var.name]
}
Run from the directory containing main.tf:
terraform init -backend=false
terraform test
The first test fails with:
Error: Root module output deprecated
on main.tf line 24, in output "old_name":
24: deprecated = "Use name instead."
Root module outputs cannot be deprecated, as there is no higher-level module to inform of the deprecation.
The second test is skipped. Removing just the deprecated line makes both tests pass.
Expected behavior
Both tests should still pass when the output is marked deprecated.
I understand the restriction for normal root configurations. Here, the root is a reusable module being tested on its own. Could terraform test allow deprecated outputs in that context, without changing the restriction for normal root configurations?
There is already a similar exception for ephemeral outputs in tests, added through hashicorp/terraform#37805.
Why a wrapper doesn't preserve the existing tests
Calling the module from a wrapper avoids the deprecated-output error and lets us check its public outputs. It doesn't let the tests inspect the module's locals or resources.
It also changes how variable validation failures are tested. expect_failures = [module.test.var.name] is rejected, as described in
hashicorp/terraform#34951. Using the wrapper's pass-through var.name instead gives a missing expected failure, while the child's validation error still fails the run.
Copying validation rules into the wrapper would test those copies rather than the module. We'd prefer not to add test-only public outputs or reorganize the module just to mark an existing output deprecated.
Source: hashicorp/terraform