10 — Validation and sensitive values¶
Folder: none yet — paste this into a scratch root.
Two ways of constraining a variable: one rejects bad input, the other hides the value. Neither does what the other does, and the second one does less than its name suggests.
Validation — reject bad input early¶
variable "name_length" {
description = "The length of the random pet name"
type = number
default = 1
validation {
condition = var.name_length >= 1 && var.name_length <= 5
error_message = "name_length must be between 1 and 5."
}
}
Plan fails immediately with your custom message, before Terraform makes a single provider call. That's the value: the failure is instant and legible, rather than a cryptic API error thirty seconds into an apply.
Use it for constraints a teammate wouldn't know about — naming conventions, allowed regions, ranges the downstream API silently truncates.
Sensitive — masking, not encryption¶
variable "api_token" {
description = "A fake secret, for practicing sensitive handling."
type = string
default = "super-secret-value-123"
sensitive = true
}
resource "local_file" "config" {
filename = "/tmp/app-config.txt"
content = "token=${var.api_token}"
}
Terraform masks the value in plan output and marks the resource attribute as sensitive because a sensitive value flowed into it. Then:
terraform apply
cat /tmp/app-config.txt # token=super-secret-value-123, in plaintext
grep -o 'super-secret[^"]*' terraform.tfstate
The secret is sitting there in plain text in both the artifact and the state file.
sensitive = true controls one thing: whether the value is printed in CLI and plan output.
It does not encrypt the value, does not keep it out of state, and does not stop it landing
in whatever the resource writes.
What follows from that¶
- State is a secret. If any sensitive value has ever passed through your config, the state file must be treated with the same care as the secret itself. That's the real argument for a remote backend with restricted IAM and encryption at rest, covered in Theory §14 and set up in Lab 2.
sensitiveis for shoulder-surfing and CI logs, which is genuinely useful — a plan posted to a PR comment shouldn't leak a token. It is not a security boundary.- Real secrets belong in Secret Manager or Vault, referenced by a
datablock at apply time, so the value is never in the config. The sandbox does this ininfrastructure/infra/secrets.tf.
Key takeaway¶
validation moves a failure from thirty seconds into an apply to instantly at plan — a
real guarantee. sensitive keeps a value out of your terminal and nowhere else — a
courtesy. Treating the second as though it were the first is exactly how secrets end up
committed in a state file.
Theory: §7 Variables, §14 State file security · Next: Provider versions