Hooks & mocks

Before/after actions and plan-time mocks.

Advanced12 min · lesson 10 of 12

Terragrunt can run actions around Terraform commands via hooks: before_hook and after_hook run a command before or after a Terraform action (init, plan, apply), and error_hook runs when one fails. Uses include running a linter or policy check before apply, formatting, sending a notification after apply, or fetching a credential. Hooks live in the terraform block of a terragrunt.hcl and can be inherited from a parent.

HOOKS AROUND A TERRAFORM COMMAND
1before_hook
e.g. conftest policy check on plan/apply
2Terraform action
init / plan / apply
3after_hook
notify on success (run_on_error=false)
4error_hook
runs when the action fails
Hooks run commands around the Terraform action and are filtered by command (e.g. notify only on apply).
terragrunt.hcl
terraform {
source = "git::...//app?ref=v1.4.0"
before_hook "policy_check" {
commands = ["apply", "plan"]
execute = ["sh", "-c", "conftest test $(pwd) --policy /policies"]
}
after_hook "notify" {
commands = ["apply"]
execute = ["sh", "-c", "./notify-slack.sh applied"]
run_on_error = false
}
}

Mocks and command filtering revisited

Alongside dependency mock_outputs (from the dependencies lesson), Terragrunt lets you scope where mocks and hooks apply by command, so a mock only feeds plan/validate and a hook only fires on apply. This precision keeps automation from firing at the wrong time — you do not want the Slack notification on every plan, or a mock value reaching an apply. Filtering hooks and mocks by command is what keeps a large automated setup predictable.

Hooks run arbitrary commands in your pipeline context
A before/after hook executes whatever command you give it with the pipeline’s credentials and access — so a compromised hook (or one pulled from an untrusted shared config) can run malicious code with your cloud permissions. Keep hook commands in reviewed version control, avoid fetching-and-executing remote scripts in hooks, and treat inherited hooks from parent configs as code you are responsible for.