Initialization hooks

Geopoiesis allows users to inject their own custom commands before the regular Terraform workflow. Initialization hooks run after your code is fetched from the repository, but before Geopoiesis runs terraform init. They have full access to both the source code from your repo and to the scope's environment. They can modify the way the rest of the workflow behaves by acting on the input.

Use cases

There are two main use cases of initialization hooks. The first one is input validation. A great example would be running linting checks with tflint of formatting checks with terraform fmt --check. You can also write a custom script to ensure that all created resources conform to your company policy.

If any of your initialization hooks fails (exits with a code other than 0), your run or task will be marked as failed. This is usually the exact effect you're looking for, but make sure you're aware of it.

Another use case would be to work around Terraform limitations by directly modifying the source code checked out from your Git repository. You could have a script that would delete or modify certain files based on some environment variables, or the context of the run itself.

Setup

In order to add initialization hooks to your scope, please modify the configuration file accordingly. You can add as many initialization hooks as you want, though Geopoiesis will stop on the first one that fails:

config.hcl
scope "hello-world" {
domain = "localhost"
before_init = [
"echo 'Hello, Geopoiesis!'",
]
# the rest of your scope config...
}

Next time a run or task is triggered, you will see your command in the initialization phase logs:

Run context

Each initialization hook (and in fact, every command in Geopoiesis) has access to a special environment variable called RUN_DETAILS, which is a base-64 encoded snapshot of the current state of the Geopoiesis run. It is the result of running the following GraphQL query:

query run(id: $id) {
id
command
commit {
author
branch
hash
message
timestamp
url
}
delta {
add
before
change
destroy
}
finished
history {
state
timestamp
username
}
scope {
domain
mode
name
}
startedAt
state
title
trigger {
__typename: type
... on Commit {
author
branch
hash
message
timestamp
url
}
... on ExternalTrigger {
note
timestamp
username
}
}
type
updatedAt
version
}

Please consult the GraphQL reference for more information on each of the above types and fields.