Home > Mobile >  Is it possible to write Terraform pre-condition and post-condition in shell?
Is it possible to write Terraform pre-condition and post-condition in shell?

Time:07-06

I'd like to execute a postcondition validation check within a resource via shell script. Is this technically possible? How?

CodePudding user response:

Terraform's postcondition block allows you to check conditions based on data Terraform already has in memory as a result of its other work, but it cannot request new data itself in order to make a decision.

Therefore in order to consult an external source like a shell script to decide a decision result you will need to find a suitable data source in an existing provider that knows how to execute a shell script and return results from it.

The hashicorp/external provider includes a data source simply called external that can run an external program that prints a JSON object with string properties to its stdout, and then expose that result into Terraform for use elsewhere. You could in principle use that data source to run a script in an external interpreter, as long as the script prints a valid JSON object to its stdout.

data "external" "example" {
  program = ["bash", "${path.module}/example.sh"]

  query = {
    # arbitrary map from strings to strings, passed
    # to the external program as the data query, so
    # that the external program can react to data
    # from elsewhere in this Terraform module.
    foo = "a"
    baz = "b"
  }

  lifecycle {
    postcondition {
      condition     = self.result.foobaz == "a b"
      error_message = "foobaz should be \"a b\"."
    }
  }
}

In the above I used the query arguments and result attribute used by the Processing JSON in shell scripts example, which I'll reproduce here just in case the documentation I'm linking to changes in future:

#!/bin/bash

# Exit if any of the intermediate steps fail
set -e

# Extract "foo" and "baz" arguments from the input into
# FOO and BAZ shell variables.
# jq will ensure that the values are properly quoted
# and escaped for consumption by the shell.
eval "$(jq -r '@sh "FOO=\(.foo) BAZ=\(.baz)"')"

# Placeholder for whatever data-fetching logic your script implements
FOOBAZ="$FOO $BAZ"

# Safely produce a JSON object containing the result value.
# jq will ensure that the value is properly quoted
# and escaped to produce a valid JSON string.
jq -n --arg foobaz "$FOOBAZ" '{"foobaz":$foobaz}'

This is just a contrived script to show how to use jq to parse and then produce JSON, but I've used it here primarily just to have an initial baseline working example to start with, which you can then hopefully adapt to solve whatever real problem you are trying to solve with this shell script check.

  • Related