Safeguard
Security Guides•

Can Terraform variable validation act as a guardrail in shared modules?

Terraform variable validation blocks can reject unsafe inputs in shared modules at plan time. What they check, what they miss, and how to write messages.

Safeguard Security Team
4 min read

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:

InputRule worth encoding
Retention periodMinimum number of days
CIDR rangeNot open to the whole internet unless explicitly allowed
Environment nameMust be one of an allowed list
Name or tagMatches a naming pattern
Instance or tier sizeWithin 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 sensitive setting 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:

  1. Say what was wrong with the value.
  2. Say what is allowed.
  3. 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.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.