skip to Main Content

I want to validate a pure object that is the output of a Terraform source (used by other modules). Specifically I want to validate it in the output declaration, rather than the parent module. My understanding is that precondition expressions are allowed in output blocks, but I can’t find a way to actually reference the output variable in-line:

output "this" {
  value = {
    foo = {
      bar = true
    }
  }

  # Doesn't work
  precondition {
    condition     = self.foo.bar != false
    error_message = "bar is false."
  }
}

The error I get is:

Error: Invalid "self" reference: The "self" object is not available in this context. This object can be used only in resource provisioner, connection, and postcondition blocks.

I tried other methods for referencing the output’s "self" but they incur similar error message. Is there a syntax that can achieve this?

2

Answers


  1. The documentation for custom conditions is clear:

    Each precondition and postcondition requires a condition argument. This is an expression that must return true if the conditition is fufilled or false if it is invalid. The expression can refer to any other objects in the same module, as long as the references do not create cyclic dependencies. Resource postconditions can also use the self object to refer to attributes of each instance of the resource where they are configured.

    emphasis mine. An output must refer to another object (and thus cannot use self).

    Login or Signup to reply.
  2. The self behavior only applies to postconditions, because they get checked after the the evaluation of the object they are associated with. A precondition cannot refer to self because that value hasn’t been evaluated yet; the purpose of a precondition is to prevent evaluating the object if some prerequisite isn’t met, so that the returned error can be about whatever the precondition was checking instead of about the expression that failed as a result of it.

    Output values don’t have postconditions because they don’t have any inherent side-effects to react to. Output values have preconditions primarily to prevent an incorrect value from being exported from a configuration that might then be consumed using terraform_remote_state or tfe_outputs, and might therefore break the consumer of that information.


    The example you shared seems contrived because the hypothetical postcondition you wrote could never fail; the value it would be checking is hard-coded right above and is set to a value that passes the condition.

    However, in a more realistic scenario where the output value is built from something else you can use a precondition to check whatever other objects the value expression refers to. For example:

    output "public_ip" {
      value = aws_instance.example.public_ip
    
      precondition {
        condition     = aws_instance.example.public_ip != ""
        error_message = "EC2 instance does not have a public IP address."
      }
    }
    

    This will prevent the evaluation of the value expression, and therefore the exporting of the output value, if the value would end up being the empty string.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search