Define the requirement and decision time
A fictional release has two different requirements: the change window must be open before creation, and the application must be ready before receiving traffic. The first value may be known during planning; the second may depend on a later observation. For each requirement, record the value source, when it becomes available, failure behavior, and who can authorize an exception. This table exposes a common error: choosing a mechanism by its name without checking whether it blocks the intended action. The following exercises use local pending and ready values; they do not probe a real service’s health.
Test a known precondition
In the first lab, variable window_open defaults to false. Resource terraform_data.gate includes lifecycle with a precondition whose condition is var.window_open and whose message explains that the exercise window is closed. Plan exited 1 and created no state file. This observation shows rejection before creation, not rollback. In a project, a useful message should identify the requirement and corrective action without exposing secrets. If the required value were still unknown, the team would need to record deferred evaluation; it could not classify the requirement as satisfied merely because planning finished.
Read a still-unknown result
In the second lab, terraform_data.producer receives input="pending" and its postcondition requires self.output == "ready". A consumer uses producer.output. Before first creation, plan JSON showed output in after_unknown; the plan was saved successfully. The team’s report should say “pending evaluation,” not “passed” or “absent.” This distinction matters to anyone building dashboards from JSON: reading only after loses information. Ask the learner to draw the producer→consumer dependency and identify the first phase when the comparison can be decided. Configured input and still-computed output play different roles in the observed plan.
Inspect what remained after failure
Applying the saved plan failed its postcondition and the command exited 1. State contained producer with output=pending; consumer had not been created. Thus failure blocked the dependent and left an earlier persistent change. In a real incident, retain logs, execution context, and current observations before resuming. Confirm resources and bindings, identify the cause of the failed requirement, and review the new full plan. Restoring old state does not undo infrastructure. Nor should the condition be removed just to obtain a green result without addressing its requirement. The manager should communicate partial state and the next decision rather than promise an unobserved rollback.
Separate warning from promotion authorization
The third lab uses a check comparing signal.output with ready. The resource received pending; apply exited 0, displayed an assertion-failure warning, and left the resource in state. This creates an operational question: the exercise rule requires ready=true before opening traffic; which part of the pipeline enforces that rule? A warning stored in a log is not that control. Keep promotion pending and obtain the required evidence or an authorized exception where policy permits it. A local check also describes an observation at that time. A morning result does not establish afternoon status without a new observation or actually configured monitoring.
Operational handover exercise and summary
Give a colleague three records: known precondition with plan=1 and no creation; deferred postcondition with apply=1 and a persistent producer; false check with apply=0 and a warning. Ask them to explain what happened, what is still missing, and who should decide the next step. The local runner records these observations, version, and artifact hash in evidence.json. Results do not validate cloud providers, import, remote locking, or database recovery. Before transferring the pattern to a real application, add those tests in the authorized environment. Summary: unknown is not passed; failure does not guarantee reversal; command success does not replace functional acceptance. Connect this lesson with plans, secrets, observability, and incidents.
Plan=0 with unknown output; apply=1 after creating producer; consumer blocked by the postcondition.
Common pitfalls
Unknown as passed; error as rollback; check as blocking; old log as current readiness.
Related topics: Plans and validation · Modules and identity · Adoption and recovery
Choose the control according to the action and when its condition can be evaluated.
Reference: Validate your configuration · Terraform v1.16 concepts; official documentation consulted 2026-09-30; provider and backend capabilities must be confirmed