Skip to content

feat: Add terragrunt_validate_inputs hook to check unused and undefined inputs #677

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .pre-commit-hooks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@
files: (\.hcl)$
exclude: \.terraform/.*$

- id: terragrunt_validate_inputs
name: Terragrunt validate inputs
description: Validates Terragrunt unused and undefined inputs.
entry: hooks/terragrunt_validate_inputs.sh
language: script
files: (\.hcl)$
exclude: \.terraform/.*$

- id: terragrunt_providers_lock
name: Terragrunt providers lock
description: Updates provider signatures in dependency lock files using terragrunt.
Expand Down
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ If you want to support the development of `pre-commit-terraform` and [many other
* [terrascan](#terrascan)
* [tfupdate](#tfupdate)
* [terragrunt\_providers\_lock](#terragrunt_providers_lock)
* [terragrunt\_validate\_inputs](#terragrunt_validate_inputs)
* [Docker Usage](#docker-usage)
* [File Permissions](#file-permissions)
* [Download Terraform modules from private GitHub repositories](#download-terraform-modules-from-private-github-repositories)
Expand All @@ -75,7 +76,7 @@ If you want to support the development of `pre-commit-terraform` and [many other
</sup></sub></sup></sub></sup></sub></sup></sub></sup></sub></sup></sub></sup></sub></sup></sub></sup></sub><br><br>
* [`checkov`](https://github.com/bridgecrewio/checkov) required for `terraform_checkov` hook
* [`terraform-docs`](https://github.com/terraform-docs/terraform-docs) required for `terraform_docs` hook
* [`terragrunt`](https://terragrunt.gruntwork.io/docs/getting-started/install/) required for `terragrunt_validate` hook
* [`terragrunt`](https://terragrunt.gruntwork.io/docs/getting-started/install/) required for `terragrunt_validate` and `terragrunt_valid_inputs` hooks
* [`terrascan`](https://github.com/tenable/terrascan) required for `terrascan` hook
* [`TFLint`](https://github.com/terraform-linters/tflint) required for `terraform_tflint` hook
* [`TFSec`](https://github.com/liamg/tfsec) required for `terraform_tfsec` hook
Expand Down Expand Up @@ -295,6 +296,7 @@ There are several [pre-commit](https://pre-commit.com/) hooks to keep Terraform
| `terraform_validate` | Validates all Terraform configuration files. [Hook notes](#terraform_validate) | `jq`, only for `--retry-once-with-cleanup` flag |
| `terragrunt_fmt` | Reformat all [Terragrunt](https://github.com/gruntwork-io/terragrunt) configuration files (`*.hcl`) to a canonical format. | `terragrunt` |
| `terragrunt_validate` | Validates all [Terragrunt](https://github.com/gruntwork-io/terragrunt) configuration files (`*.hcl`) | `terragrunt` |
| `terragrunt_validate_inputs` | Validates [Terragrunt](https://github.com/gruntwork-io/terragrunt) unused and undefined inputs (`*.hcl`)
| `terragrunt_providers_lock` | Generates `.terraform.lock.hcl` files using [Terragrunt](https://github.com/gruntwork-io/terragrunt). | `terragrunt` |
| `terraform_wrapper_module_for_each` | Generates Terraform wrappers with `for_each` in module. [Hook notes](#terraform_wrapper_module_for_each) | `hcledit` |
| `terrascan` | [terrascan](https://github.com/tenable/terrascan) Detect compliance and security violations. [Hook notes](#terrascan) | `terrascan` |
Expand Down Expand Up @@ -1121,6 +1123,28 @@ It invokes `terragrunt providers lock` under the hood and terragrunt [does its'
- --args=-platform=linux_amd64
```

### terragrunt_validate_inputs

Validates Terragrunt unused and undefined inputs. This is useful for keeping
configs clean when module versions change or if configs are copied.

See the [Terragrunt docs](https://terragrunt.gruntwork.io/docs/reference/cli-options/#validate-inputs) for more details.

Example:

```yaml
- id: terragrunt_validate_inputs
name: Terragrunt validate inputs
args:
# Optionally check for unused inputs
- --args=--terragrunt-strict-validate
```

> [!NOTE]
> This hook requires authentication to a given account if defined by config to work properly. For example, if you use a third-party tool to store AWS credentials like `aws-vault` you must be authenticated first.
>
> See docs for the [iam_role](https://terragrunt.gruntwork.io/docs/reference/config-blocks-and-attributes/#iam_role) attribute and [--terragrunt-iam-role](https://terragrunt.gruntwork.io/docs/reference/cli-options/#terragrunt-iam-role) flag for more.

## Docker Usage

### File Permissions
Expand Down
73 changes: 73 additions & 0 deletions hooks/terragrunt_validate_inputs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -eo pipefail

# globals variables
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
readonly SCRIPT_DIR
# shellcheck source=_common.sh
. "$SCRIPT_DIR/_common.sh"

function main {
common::initialize "$SCRIPT_DIR"
common::parse_cmdline "$@"
common::export_provided_env_vars "${ENV_VARS[@]}"
common::parse_and_export_env_vars
# JFYI: terragrunt validate color already suppressed via PRE_COMMIT_COLOR=never

# shellcheck disable=SC2153 # False positive
common::per_dir_hook "$HOOK_ID" "${#ARGS[@]}" "${ARGS[@]}" "${FILES[@]}"
}

#######################################################################
# Unique part of `common::per_dir_hook`. The function is executed in loop
# on each provided dir path. Run wrapped tool with specified arguments
# Arguments:
# dir_path (string) PATH to dir relative to git repo root.
# Can be used in error logging
# change_dir_in_unique_part (string/false) Modifier which creates
# possibilities to use non-common chdir strategies.
# Availability depends on hook.
# parallelism_disabled (bool) if true - skip lock mechanism
# args (array) arguments that configure wrapped tool behavior
# tf_path (string) PATH to Terraform/OpenTofu binary
# Outputs:
# If failed - print out hook checks status
#######################################################################
function per_dir_hook_unique_part {
# shellcheck disable=SC2034 # Unused var.
local -r dir_path="$1"
# shellcheck disable=SC2034 # Unused var.
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
# shellcheck disable=SC2034 # Unused var.
local -r tf_path="$4"
shift 4
local -a -r args=("$@")

# pass the arguments to hook
terragrunt validate-inputs "${args[@]}"

# return exit code to common::per_dir_hook
local exit_code=$?
return $exit_code
}

#######################################################################
# Unique part of `common::per_dir_hook`. The function is executed one time
# in the root git repo
# Arguments:
# args (array) arguments that configure wrapped tool behavior
#######################################################################
function run_hook_on_whole_repo {
local -a -r args=("$@")

# pass the arguments to hook
terragrunt run-all validate-inputs "${args[@]}"

# return exit code to common::per_dir_hook
local exit_code=$?
return $exit_code
}

[ "${BASH_SOURCE[0]}" != "$0" ] || main "$@"