Failing early with a clear message beats a half-applied plan or a silently wrong deployment.
Terraform has several assertion mechanisms, each for a different moment:
- Variable validation: inside a
variable, one or morevalidation { condition = ... error_message = "..." }blocks. Evaluated at plan time. Since 1.9 conditions may also refer to other variables and objects, not only the variable itself. - precondition (in a resource's, data source's or output's
lifecycle): checked before that object is planned or applied. Good for assumptions about inputs or data sources ("the AMI must be x86_64"). - postcondition: checked after the object is created or read, with
selfreferring to it ("the instance must have received a public IP"). - check blocks: top-level
check "name" { assert {...} }, optionally with a scoped data source, run on every plan and apply. A failure is a warning, not an error, so checks suit continuous health assertions like "the website returns 200".
Write error messages for the person who will hit them: say what's wrong and what to do.
Use can() in conditions to turn errors into booleans: can(regex("^[a-z0-9-]+$", var.name)). Keep conditions simple; complex logic hides mistakes.
These checks complement, and don't replace, terraform test and policy tools (OPA/conftest, Sentinel) that judge the plan as a whole.
Example
variable "env" {
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.env)
error_message = "env must be dev, staging or prod."
}
}
variable "bucket_name" {
type = string
validation {
condition = can(regex("^[a-z0-9.-]{3,63}$", var.bucket_name))
error_message = "Bucket names: 3-63 chars of a-z, 0-9, dots and hyphens."
}
}
resource "terraform_data" "bucket" {
input = var.bucket_name
lifecycle {
postcondition {
condition = startswith(self.output, var.env)
error_message = "Bucket name must start with the environment name."
}
}
}Remember
- validation for inputs; pre/postconditions for assumptions about objects
- check blocks warn on every run without blocking
- can() turns failing expressions into false
Watch out for
- Vague error messages like 'invalid input' that don't tell users how to fix it.