Skip to content

Commit

Permalink
fix #3824 add if parameter to hook block. (#3913)
Browse files Browse the repository at this point in the history
  • Loading branch information
wakeful authored Feb 21, 2025
1 parent 4ea5d08 commit 9546bb4
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 0 deletions.
5 changes: 5 additions & 0 deletions cli/commands/run/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ func processHooks(
terragruntOptions.Logger.Debugf("Detected %d Hooks", len(hooks))

for _, curHook := range hooks {
if curHook.If != nil && !*curHook.If {
terragruntOptions.Logger.Debugf("Skipping hook: %s", curHook.Name)
continue
}

allPreviousErrors := previousExecErrors.Append(errorsOccured)
if shouldRunHook(curHook, terragruntOptions, allPreviousErrors) {
err := telemetry.Telemetry(ctx, terragruntOptions, "hook_"+curHook.Name, map[string]interface{}{
Expand Down
1 change: 1 addition & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ func (deps *ModuleDependencies) String() string {
// Hook specifies terraform commands (apply/plan) and array of os commands to execute
type Hook struct {
Name string `hcl:"name,label" cty:"name"`
If *bool `hcl:"if,attr" cty:"if"`
Commands []string `hcl:"commands,attr" cty:"commands"`
Execute []string `hcl:"execute,attr" cty:"execute"`
RunOnError *bool `hcl:"run_on_error,attr" cty:"run_on_error"`
Expand Down
1 change: 1 addition & 0 deletions docs/_docs/04_reference/04-config-blocks-and-attributes.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ The `terraform` block supports the following arguments:
- `run_on_error` (optional) : If set to true, this hook will run even if a previous hook hit an error, or in the
case of "after" hooks, if the OpenTofu/Terraform command hit an error. Default is false.
- `suppress_stdout` (optional) : If set to true, the stdout output of the executed commands will be suppressed. This can be useful when there are scripts relying on OpenTofu/Terraform's output and any other output would break their parsing.
- `if` (optional) : hook will be skipped when the argument is set or evaluates to `false`.

- `after_hook` (block): Nested blocks used to specify command hooks that should be run after `tofu`/`terraform` is called.
Hooks run from the terragrunt configuration directory (the directory where `terragrunt.hcl` lives). Supports the same
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/hooks/if-parameter/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "example" {
value = "hello, world"
}
17 changes: 17 additions & 0 deletions test/fixtures/hooks/if-parameter/terragrunt.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
locals {
run_hook = true
}

terraform {
before_hook "run_this_one" {
if = local.run_hook
commands = ["apply", "plan"]
execute = ["echo", "running before hook"]
}

after_hook "skip_this_one" {
if = !local.run_hook
commands = ["apply", "plan"]
execute = ["echo", "skip after hook"]
}
}
23 changes: 23 additions & 0 deletions test/integration_hooks_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,31 @@ const (
testFixtureHooksInitOnceWithSourceNoBackend = "fixtures/hooks/init-once/with-source-no-backend"
testFixtureHooksInitOnceWithSourceNoBackendSuppressHookStdout = "fixtures/hooks/init-once/with-source-no-backend-suppress-hook-stdout"
testFixtureHooksInitOnceWithSourceWithBackend = "fixtures/hooks/init-once/with-source-with-backend"
testFixtureTerragruntHookIfParameter = "fixtures/hooks/if-parameter"
)

func TestTerragruntHookIfParameter(t *testing.T) {
t.Parallel()

helpers.CleanupTerraformFolder(t, testFixtureTerragruntHookIfParameter)
tmpEnvPath := helpers.CopyEnvironment(t, testFixtureTerragruntHookIfParameter)
rootPath := util.JoinPath(tmpEnvPath, testFixtureTerragruntHookIfParameter)

var (
stdout bytes.Buffer
stderr bytes.Buffer
)

err := helpers.RunTerragruntCommand(t, "terragrunt apply -auto-approve --terragrunt-non-interactive --terragrunt-working-dir "+rootPath, &stdout, &stderr)

require.NoError(t, err)

output := stdout.String()

assert.Contains(t, output, "running before hook")
assert.NotContains(t, output, "skip after hook")
}

func TestTerragruntBeforeHook(t *testing.T) {
t.Parallel()

Expand Down
2 changes: 2 additions & 0 deletions test/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2515,6 +2515,7 @@ func TestReadTerragruntConfigFull(t *testing.T) {
"execute": []interface{}{"touch", "before.out"},
"working_dir": nil,
"run_on_error": true,
"if": nil,
"suppress_stdout": nil,
},
},
Expand All @@ -2525,6 +2526,7 @@ func TestReadTerragruntConfigFull(t *testing.T) {
"execute": []interface{}{"touch", "after.out"},
"working_dir": nil,
"run_on_error": true,
"if": nil,
"suppress_stdout": nil,
},
},
Expand Down

0 comments on commit 9546bb4

Please sign in to comment.