Yes, partly. A validation block inside a Terraform variable lets a shared module reject unsafe or malformed inputs while the plan is being created, before anything is applied. It is a useful first guardrail, but it only sees the values passed in, not the real world.
How validation works
HashiCorp documents the validation block as a nested block in a variable that adds rules beyond the type constraint. It has two required parts:
condition: an expression. Terraform proceeds only if it evaluates to true.error_message: a string shown when the condition is false.
Terraform checks validations while creating a plan, and a failed check stops the operation. That timing is what makes it a guardrail: a bad input never reaches apply.
variable "retention_days" {
type = number
description = "Log retention in days."
validation {
condition = var.retention_days >= 30
error_message = "Retention must be at least 30 days."
}
}
Where it fits in a shared module
Shared modules are where validation pays off, because the author knows the intended use and callers may not. Typical uses:
| Input | Rule worth encoding |
|---|---|
| Retention period | Minimum number of days |
| CIDR range | Not open to the whole internet unless explicitly allowed |
| Environment name | Must be one of an allowed list |
| Name or tag | Matches a naming pattern |
| Instance or tier size | Within an approved set |
Note that "not open to the whole internet" is a rule about a value the caller passes. Validation can check that input string. It cannot see rules defined elsewhere in the configuration.
What validation does not do
Be honest about the limits so nobody mistakes it for a scanner.
- It only checks input variables, not the resources a module builds from them.
- It runs at plan time, so a person who edits the module itself can remove the rule. Review of the module repository still matters. See CODEOWNERS for release files.
- Terraform's
sensitivesetting on a variable hides values in output but, per the documentation, Terraform still records sensitive values in state.
Writing good error messages
A guardrail that confuses people gets removed. Write messages that:
- Say what was wrong with the value.
- Say what is allowed.
- Point to where to read more, such as the module README.
"Retention must be at least 30 days. See the module README for exceptions." beats "invalid value".
Pairing with tests
A validation rule is code, so it can be wrong. Pair it with module tests that pass good and bad inputs. See terraform test for shared modules.
Nullable inputs
HashiCorp notes the nullable argument defaults to true, and that when a variable is nullable and has a default, a caller can set it to null to override that default. If your rule assumes a value is present, set nullable = false so a caller cannot slip past it with null.
Where Safeguard fits
Safeguard gates and policies work on pull requests, while validation works at plan time. They are different layers. Safeguard can also keep compliance evidence of reviews and approvals around infrastructure changes.
Quick check
Does validation run at apply time?
Per HashiCorp, Terraform checks validations while creating a plan, and a failed check stops the operation.
Can a caller bypass a validation rule?
A caller cannot pass a failing value, but a nullable variable can be set to null, so set nullable to false when the rule needs a value.
Sources
Last reviewed: 19 October 2026.