skip to content

In Terraform, what does a `validation` block inside a `variable` block do, and which two arguments does it take?

level: juniorimportance: must knowfreq 66%

answer

  1. a rule attached to the input
  2. exactly two arguments
  3. one boolean, one message
  4. evaluated while planning, nothing built
  5. several blocks, every failure reported

basics

~20 s

A validation block makes Terraform reject an unacceptable input value at plan time. It takes condition, a boolean expression over the variable, and error_message, the text printed when the condition is false — so nothing gets created.

solid answer

~40 s

A `validation` block is nested inside a `variable` block and attaches a rule to the value that variable receives. It takes exactly two arguments: `condition`, a boolean expression that refers to the variable, and `error_message`, the string Terraform prints when that expression is false. Terraform evaluates the rule while it is preparing the plan, before it calls any provider API, so a bad value ends the run with a message a human wrote rather than a cryptic API error twenty resources in — or worse, a half-built environment. You can attach several `validation` blocks to one variable; Terraform evaluates all of them and reports every failure it finds, so the caller fixes all the problems in one pass instead of one run per mistake.

code

hcl · 14 lines
hcl
variable "environment" {
  type        = string
  description = "Deployment environment name."

  validation {
    condition     = contains(["dev", "staging", "prod"], var.environment)
    error_message = "The environment must be one of: dev, staging, prod."
  }

  validation {
    condition     = lower(var.environment) == var.environment
    error_message = "The environment must be lowercase."
  }
}

go deeper

for a junior

Be ready to write the block from memory: condition with a boolean expression using var.<name>, and error_message with a sentence explaining the rule. Say plainly that the run stops during plan, before anything is created.

for a middle

Explain why several small validation blocks beat one condition joined with && — Terraform reports every failure separately. Be able to distinguish this from the terraform validate command, which people confuse with it.

for a senior

Frame it as the cheapest layer of the testing pyramid: zero cloud calls, instant feedback, caught at the moment of the typo. An interviewer expects you to reach here before proposing scanners or integration tests.

for a principal

Own the interface contract: a shared module's validations are how you push standards onto dozens of consuming teams without a review bottleneck, and every message you write is documentation somebody reads at their most frustrated moment.

## What a validation block is A Terraform *input variable* is declared with a `variable` block, which is the public interface of a root module or a child module. The `type` argument constrains the **shape** of the value — string, number, a list of objects and so on. A `validation` block, nested inside the same `variable` block, constrains the **value**: it is a rule the incoming value must satisfy before Terraform is willing to proceed. ```hcl variable "environment" { type = string validation { condition = contains(["dev", "staging", "prod"], var.environment) error_message = "The environment must be one of: dev, staging, prod." } } ``` ## The two arguments `condition` is an expression that must evaluate to `true` or `false`. `true` means the value is acceptable; `false` means Terraform stops. The expression normally refers to the variable being validated through `var.<name>` — you write `var.environment`, not a bare `environment`. `error_message` is the string shown to whoever ran Terraform when the condition comes out `false`. It is not optional, and it is the entire point of the feature: the machine already knows the value is wrong, and the message is what turns that into something the caller can act on. Write it as a full sentence that states the rule and, where useful, the acceptable values — "The environment must be one of: dev, staging, prod" beats "invalid environment". ## When the rule runs Terraform evaluates variable validations while it is evaluating the configuration for a plan, which is before it has created or modified anything. A failure is a plan error: the command exits non-zero, no provider API calls are made for the resources you were about to build, and there is no saved plan file to apply. That is why this is described as the cheapest layer of the IaC test pyramid — it costs no cloud calls, no test harness and no minutes of CI, and it catches the mistake at the moment somebody typed it. Contrast the alternative. Without the rule, a value like `Prod` flows into a resource name, an S3 bucket name or a tag, and you find out either from a provider error partway through the apply — with some resources already created — or, much worse, not at all, because the value was merely wrong rather than illegal, and you have quietly built a fourth environment nobody meant to have. ## Several rules on one variable A variable may carry more than one `validation` block, and this is usually better than cramming several rules into one condition with `&&`. Terraform evaluates each block and reports every one that failed, each with its own `error_message`, so the caller sees "must be lowercase" and "must be at most 24 characters" together instead of discovering the second only after fixing the first. ```hcl variable "cluster_name" { type = string validation { condition = length(var.cluster_name) <= 24 error_message = "The cluster_name must be 24 characters or fewer." } validation { condition = lower(var.cluster_name) == var.cluster_name error_message = "The cluster_name must be lowercase." } } ``` One rule per block, one message per rule, is the readable form. ## What it is not It is not the `terraform validate` command. That command checks that the configuration itself is internally consistent — syntax, references, argument names — and is a different thing that happens to share the word. Variable validation is a rule you author about a value. It is also not a check on anything outside the module's input. Whether the AMI you were handed is the right architecture, or whether the instance that got built actually has a public address, are assumptions about the world rather than about the argument list, and Terraform has separate `precondition` and `postcondition` constructs for those. ## What interviewers are listening for That you know the two arguments, that the condition is a boolean and not the value itself, and above all that the check happens at plan time so a bad input costs nothing. Candidates who reach for validation first — before proposing a policy scanner or an integration test — are signalling that they know how to spend a testing budget.

  • If a variable carries three validation blocks and the supplied value fails two of them, what does the operator see?
    Both failures, each reported as its own error with its own `error_message`. Terraform evaluates every validation block rather than stopping at the first failure, which is the practical argument for one rule per block instead of a single condition joined with `&&` — the caller can fix everything in one edit.
  • Can a failing value ever slip past validation and reach apply?
    Not through the normal workflow. The rules are evaluated while Terraform builds the plan, so the plan command exits non-zero and produces no saved plan file. Since `apply` runs either from a saved plan or from its own fresh plan, there is no path where the rejected value gets as far as a provider call.
  • Can the condition reference anything other than the variable it belongs to?
    As of Terraform 1.9, yes — a validation condition may refer to other objects such as another input variable or a local value, which makes cross-field rules expressible. Before 1.9 the condition could only refer to its own variable, and anything else was a configuration error. Say which version you are assuming.

It is the guard clause at the top of a function: check the arguments and raise a clear, specific error before doing any real work.

saying these in an interview costs you the question

  • Says validation runs at apply time, after resources exist
  • Thinks the condition returns the value rather than a boolean
  • Claims a variable can carry only one validation block
  • Confuses a validation block with the terraform validate command
  • Treats error_message as optional or leaves it as 'invalid'

context