Unexpected Behavior of Variable Validation Against Data Blocks and Resources on First Apply
Terraform Version
1.9.7
Terraform Configuration Files
variable "unused_variable" {
description = "This variable is not used in the configuration"
type = string
default = "unused"
validation {
condition = var.unused_variable != null && startswith(data.aws_s3_bucket.example_bucket_data.bucket, "zzz")
error_message = "test"
}
}
resource "random_string" "bucket_suffix" {
length = 6
special = false
upper = false
}
resource "aws_s3_bucket" "example_bucket" {
bucket = "kz-${random_string.bucket_suffix.result}"
}
data "aws_s3_bucket" "example_bucket_data" {
bucket = aws_s3_bucket.example_bucket.bucket
}
Debug Output
first apply success: https://gist.github.com/konradzagozda/cd5f98261795ece6561fac8a1f29723a second apply fails: https://gist.github.com/konradzagozda/65a77d4d6228fef75f3043bcc9a8c1ca destroy fails: https://gist.github.com/konradzagozda/d42619fe01c7536e5e4772508c9c4346
Expected Behavior
Variable validation could occur after it can reference the attributes of a resource.
Actual Behavior
- Validation passes every time when the resource was not present before the apply.
- After that, it works as expected.
Steps to Reproduce
terraform initterraform apply- successterraform destroy|apply- fail
Additional Context
A relatively new feature for variable validation was released in 1.9: "Input variable validation rules can refer to other objects."
While I find this super useful for referencing other variables, it behaves strangely when I try to reference resource or data blocks.
For example, let's say I have a feature for my app that has external infrastructure dependencies. I'd like to use a data block to fetch that information to validate whether the feature can be enabled successfully.
validation {
condition = var.unused_variable != null && startswith(data.aws_s3_bucket.example_bucket_data.bucket, "zzz")
error_message = "test"
}
I would expect this to fail every time because the prefix doesn't match the expected name.
However, the behavior is as follows:
First apply: passes without issues. Second apply: actually validates against the data block and produces the error message. Destroy: blocks the destroy operation due to the validation.
I can see this being useful if validation that includes references to resources and blocks were moved to the final stage of the apply process, perhaps with the ability to roll back on failure.
References
No response