What are `precondition` and `postcondition` custom conditions, and how do they differ from variable validation?

5 minadvancedterraformpreconditionpostcondition

Quick Answer

precondition/postcondition blocks (nested inside a resource's, data source's, or output's lifecycle/definition) assert conditions at a different point than variable validation: a precondition checks an assumption before a resource is evaluated (e.g., "this AMI must be tagged as approved"), and a postcondition checks the result after (e.g., "the resulting EC2 instance must actually be in the expected availability zone"). Unlike variable validation, which only ever sees the raw input variable, these can reference other resources' computed attributes, values only known after planning/applying, making them suited to cross-resource invariants rather than simple input shape-checking.

Detailed Answer

Variable validation blocks (the previous question) only ever see the raw variable a caller passed in. They can't reason about anything computed later, like another resource's attributes. precondition/postcondition fill that gap.

Precondition — checking an assumption before evaluating a resource

data "aws_ami" "app" {
  most_recent = true
  owners      = ["self"]

  filter {
    name   = "tag:approved"
    values = ["true"]
  }

  lifecycle {
    postcondition {
      condition     = self.tags["approved"] == "true"
      error_message = "Selected AMI is not tagged as approved for use."
    }
  }
}

resource "aws_instance" "web" {
  ami = data.aws_ami.app.id

  lifecycle {
    precondition {
      condition     = data.aws_ami.app.architecture == "x86_64"
      error_message = "Selected AMI must be x86_64; got ${data.aws_ami.app.architecture}."
    }
  }
}

A precondition on aws_instance.web runs before Terraform attempts to create/update it, checking an assumption about something it depends on (here, the AMI's architecture). It catches a mismatch before any API call is made, with a message pointing at exactly what's wrong.

Postcondition — checking the result after

A postcondition (shown above on the data source) runs after the resource/data source is evaluated, asserting something about the actual resulting values. It's useful for confirming a data source actually returned what you expected (e.g., "the AMI it found really is tagged approved," catching a filter that's too loose).

Key difference from variable validation

Variable validationprecondition/postcondition
ScopeThe variable's own raw value onlyAny expression, including other resources' computed attributes
TimingImmediately, at variable assignmentBefore (precondition) or after (postcondition) the specific resource/data source/output is evaluated
Typical use"Is this input shaped correctly?""Does this cross-resource assumption/invariant actually hold?"

Interview-ready summary

Variable validation guards the inputs to a module. precondition/postcondition guard invariants between resources that can only be checked once real values (potentially only known after planning) are available. Both exist to surface a broken assumption as an early, clear error instead of a confusing downstream failure or, worse, a successful apply that silently violates an assumption the configuration depended on.

Related Resources