Validation Rules
environment = "produciton" is a perfectly valid string. Crumb's configuration would happily build crumb-produciton-assets. Types check the shape of a value; validation rules check whether it makes sense.
The rule
Types check the shape; validation checks the sense.
A validation block lives inside a variable block:
variable "environment" {
type = string
description = "Deployment environment"
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "Environment must be dev, staging or prod."
}
}
variable "web_count" {
type = number
default = 1
validation {
condition = var.web_count >= 1 && var.web_count <= 4
error_message = "Web count must be between 1 and 4."
}
}conditionmust betruefor a valid value. It describes the good case.error_messageis shown when it isfalse. Write a full sentence.- A variable may have several validation blocks; each is checked.
Handy building blocks for conditions:
contains(list, value)— is it one of the allowed values?length(var.x) <= 20— size limits.can(regex("^[a-z0-9-]+$", var.x))— pattern checks.canturns an error intofalse, so a non-matching value fails validation cleanly.&&and||to combine checks.
Terraform checks validation as soon as the variable's value is known, before planning any change. A bad value stops the run at the door with your message.
Up to Terraform 1.8, a condition could refer only to the variable being validated. From 1.9 it may also refer to other variables and objects, which allows rules like "production needs at least two servers".
The shortcut
Write the rule as "a good value is …". Turn it into a condition, then write the error as the same rule said to a person.
State the good case
"A good environment is dev, staging or prod."
The trap, again, is writing the condition as the bad case, such as var.environment == "test". That rejects every value except the one you meant to forbid.
Drills
Answer fast — trust the rule.
A variable has type = string and no validation. Is "produciton" accepted?
When is a variable's validation rule checked?
Which condition accepts web counts from 1 to 4 inclusive?
Why wrap regex(...) in can(...) inside a condition?
Remember
validation { condition = ..., error_message = ... }inside a variable checks meaning.- Shortcut: "a good value is …" becomes the condition.
- Trap: the condition is the good case; types alone never catch typos.
