Terraform Configuration · Topic 4 of 4
Custom Conditions and Sensitive Data
Terraform Associate 004: validation, preconditions, postconditions and check blocks, plus sensitive values, ephemeral values, state risks and Vault.
- 5 min
- Validation checks inputs; preconditions check assumptions; postconditions check results with
self. - Validation, precondition and postcondition failures are errors; check block failures are warnings.
sensitive = truehides values in CLI output only; state and plan still contain them.
What it is
Custom conditions are rules you write so Terraform reports a clear error, or a warning, when values or infrastructure are not what you expect. They come in four forms: variable validation, preconditions, postconditions and check blocks.
Sensitive data means passwords, keys and tokens. Terraform can hide such values in CLI output, keep some of them out of state, and read them from HashiCorp Vault instead of from code.
How it works
Variable validation
A validation block inside a variable checks the input before Terraform builds a plan.
variable "env" {
type = string
validation {
condition = contains(["dev", "prod"], var.env)
error_message = "env must be dev or prod."
}
}
If the condition is false, Terraform shows the error_message and stops. Since Terraform 1.9 a validation condition can also refer to other variables and objects, not only its own variable.
Preconditions and postconditions
Both go in the lifecycle block of a resource or data source. A precondition checks assumptions before Terraform acts on the block; a postcondition checks the result, using self for the object's own attributes.
resource "aws_instance" "web" {
ami = data.aws_ami.app.id
instance_type = var.instance_type
lifecycle {
postcondition {
condition = self.public_dns != ""
error_message = "The instance needs a public DNS name."
}
}
}
A failed precondition or postcondition is an error that stops the operation. A failed postcondition does not undo changes already made. Output blocks can also contain a precondition, but not a postcondition.
Check blocks
A check block validates infrastructure as a whole, outside any single resource's lifecycle. It holds one or more assert blocks and can contain one nested data source used only inside the check.
check "site_up" {
data "http" "home" {
url = "https://${aws_lb.web.dns_name}"
}
assert {
condition = data.http.home.status_code == 200
error_message = "The site did not return status 200."
}
}
Checks run at the end of plan and apply. A failed assertion is only a warning; the run continues. In HCP Terraform, checks also run during health assessments.
| Feature | Where it goes | When it runs | On failure |
|---|---|---|---|
| validation | variable block | Before the plan | Error, stops |
| precondition | lifecycle or output | Before the block is acted on | Error, stops |
| postcondition | lifecycle | After the change or read | Error, stops |
| check with assert | Top level check block | End of plan and apply | Warning, continues |
Sensitive values
Set sensitive = true on a variable or output to redact it in plan and apply output. Expressions built from a sensitive value are also treated as sensitive, and a root output that uses one must itself be marked sensitive.
The value is still stored in plain text in state and plan files. terraform output -json, terraform output -raw and terraform output NAME also print it in plain text.
Ephemeral values and write-only arguments
From Terraform 1.10, ephemeral = true on a variable or child module output, and the ephemeral resource block, give values that Terraform omits from state and plan files entirely. Root module outputs cannot be ephemeral.
From Terraform 1.11, providers can offer write-only arguments, usually ending in _wo, such as password_wo. They accept ephemeral values and are never stored, often paired with a _wo_version argument that you change to send a new value.
Secrets from Vault
The Vault provider reads secrets at run time so they never appear in code or variable files.
ephemeral "vault_kv_secret_v2" "db" {
mount = "secret"
name = "prod/db"
}
The value is referenced as ephemeral.vault_kv_secret_v2.db.data.password. A Vault data source also works but stores what it reads in state, whereas the ephemeral resource does not. Vault can also issue short-lived dynamic credentials that expire after a set lease time.
Best practices
- Never hard-code secrets in
.tffiles or commit them in.tfvarsfiles. - Pass secrets through
TF_VAR_environment variables, Vault or HCP Terraform sensitive variables. - Store state in a remote backend with encryption and access control, because state can hold secrets.
- Prefer ephemeral resources and write-only arguments where the provider supports them.
How the exam asks about this
- "True or false: a password passed through a sensitive variable ends up in plain text in the state file." True; sensitive only redacts CLI output.
- "An assertion that the website returns 200 fails during apply. What happens?" Terraform shows a warning and the apply continues.
- "Reject any region outside an approved list before planning." Add a validation block to the variable.
What to remember for the exam
- Validation checks inputs; preconditions check assumptions; postconditions check results with
self. - Validation, precondition and postcondition failures are errors; check block failures are warnings.
sensitive = truehides values in CLI output only; state and plan still contain them.- Ephemeral values and write-only arguments are kept out of state and plan files.
- Vault data sources store secrets in state; Vault ephemeral resources do not.
- Protect state with a remote backend that encrypts it and restricts access.
Marking a value sensitive is not encryption. Anyone who can read the state file can read every sensitive value in it.
Common mistakes
Believing sensitive values stay out of state. The sensitive argument only changes what the CLI prints. To keep a value out of state you need an ephemeral value or a write-only argument.
Expecting a check block to stop an apply. Check assertions only warn. Use a precondition or postcondition when a failure must block the run.
Committing tfvars files with secrets. A secrets.auto.tfvars file in version control leaks credentials to everyone with repository access. Use environment variables or Vault instead.
Check yourself
Where can a postcondition be used, and how does it refer to the object?
In the
lifecycleblock of a resource or data source, usingselfto refer to that object's attributes.Does
sensitive = truekeep a value out of the state file?No. It only redacts the value in CLI output; the value is still stored in plain text in state and plan files.
What happens when a check block assertion fails?
Terraform reports a warning and continues the plan or apply, unlike a failed precondition or postcondition, which stops the run.
Topic 4 of 4 in Terraform Configuration
Test yourself on Terraform Configuration
The full HashiCorp Terraform Associate 004 question bank has 600 questions, with timed practice exams and an explanation for every answer.
This study guide is independent and is not affiliated with, endorsed by, or sponsored by HashiCorp. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.