From a139b71bc722ac1d2d5ed89caeb74d66a882bb94 Mon Sep 17 00:00:00 2001 From: Josh Reichardt Date: Wed, 19 Jun 2024 08:23:03 -0500 Subject: [PATCH] feat: Add `terragrunt_validate_inputs` hook to check unused and undefined inputs (#677) --- .pre-commit-hooks.yaml | 8 ++++ README.md | 26 +++++++++- hooks/terragrunt_validate_inputs.sh | 73 +++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+), 1 deletion(-) create mode 100755 hooks/terragrunt_validate_inputs.sh diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index cbe506dd3..520c3f08a 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -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. diff --git a/README.md b/README.md index b2b7fd3ca..11267ed34 100644 --- a/README.md +++ b/README.md @@ -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) @@ -75,7 +76,7 @@ If you want to support the development of `pre-commit-terraform` and [many other

* [`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 @@ -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` | @@ -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 diff --git a/hooks/terragrunt_validate_inputs.sh b/hooks/terragrunt_validate_inputs.sh new file mode 100755 index 000000000..0c8d79e2d --- /dev/null +++ b/hooks/terragrunt_validate_inputs.sh @@ -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 "$@"