I am setting up variable validation for Kafka topic schemas for a Terraform module I am creating.
The schemas can be one of two types: AVRO or JSON. As both schema types are defined in a .json file, I use a variable called scheama_format
to determine what type the incoming schema is. The schema itself is provided by a variable called schema_path
, pointing to a .json file.
When evaluating if the file given by schema_path
is valid, I have to know what type of file it is to know what keys I must check. I have tried many variations, but my current validation condition looks like this:
variable "schema_path" {
type = string
description = "Relative path to the schema file to upload to the Schema Registry."
...
###################
# THIS IS THE VALIDATION THAT IS NOT WORKING
###################
validation {
conditions = (var.schema_format != "AVRO") || (jsondecode(file(var.schema_path)).type == "record")
error_message = "If schema_format is 'AVRO', the schema file must have a type of 'record'."
}
}
variable "schema_format" {
type = string
description = "The type of schema. Must be either 'JSON' or 'AVRO'."
...
}
No matter what I do, whenever a validation condition includes the value of a different variable, the condition will evaluate as true (and thus the validation will never trigger an error).
Is this a bug in Terraform, or is there something I am missing here?
I have tried en exhaustive number of conditions using a different variable and they all evaluate as true.
Even simple conditions such as:
variable "schema_path" {
...
validation {
conditions = (length(var.schema_format) < 0) || (length(var.schema_path) < 0)
error_message = "TEST"
}
}
variable "schema_format" {
...
}
To my mind, this condition should evaluate as false no matter what, but it evaluates as true.
If I try:
variable "schema_path" {
...
validation {
conditions = false || (length(var.schema_path) < 0)
error_message = "TEST"
}
}
variable "schema_format" {
...
}
the condition evaluates as false, but as soon as I use a different variable as part of the condition, it evaluates as true.
If this is the intended behaviour, I do not understand the point of Terraform version 1.9.0 allowing the use of different variables as part of a variable's validation. What am I missing?
For context, this is what a generic version of the schema file:
{
"type": "record",
"namespace": "com.mycorp.mynamespace",
"name": "sampleRecord",
"doc": "Sample schema to help you get started.",
"fields": [
...
]
}
After digging around some more, I ended up adding a lifecycle precondition to my schema resource.
locals {
schema = file(var.schema_path)
schemaJson = jsondecode(local.schema)
}
resource "confluent_schema" "schema" {
depends_on = [confluent_kafka_topic.topic]
subject_name = "${confluent_kafka_topic.topic.topic_name}-value"
format = var.schema_format
schema = local.schema
lifecycle {
precondition {
condition = var.schema_format != "AVRO" || jsondecode(local.schema).type == "record"
error_message = "Schema must be a valid AVRO schema. Key 'Type' must have value 'record'"
}
}
}
Using a precondition means that an error will be thrown if the condition is not met. Unfortunatley, this block will only run during terraform plan
and terraform apply
, meaning that terraform validate
will no longer run all the validation logic.
This is a workaround that will be fine for my use case, but the central question still stands:
Why does using other variables in a variable's validate block cause the condition to always evaluate to true?
I feel like I am still missing something. Either this is a bug in Terraform or I am missing something with how this functionality is intended to be used.