Skip to content

Commit d490231

Browse files
MaxymVlasovantonbabenko
authored andcommitted
feat: Add support for set env vars inside hook runtime (#408)
1 parent c4f8251 commit d490231

15 files changed

Lines changed: 65 additions & 79 deletions

README.md

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ If you are using `pre-commit-terraform` already or want to support its developme
3737
* [Available Hooks](#available-hooks)
3838
* [Hooks usage notes and examples](#hooks-usage-notes-and-examples)
3939
* [All hooks: Usage of environment variables in `--args`](#all-hooks-usage-of-environment-variables-in---args)
40+
* [All hooks: Set env vars inside hook at runtime](#all-hooks-set-env-vars-inside-hook-at-runtime)
4041
* [checkov (deprecated) and terraform_checkov](#checkov-deprecated-and-terraform_checkov)
4142
* [infracost_breakdown](#infracost_breakdown)
4243
* [terraform_docs](#terraform_docs)
@@ -283,6 +284,22 @@ Config example:
283284
284285
If for config above set up `export CONFIG_NAME=.tflint; export CONFIG_EXT=hcl` before `pre-commit run`, args will be expanded to `--config=.tflint.hcl --module`.
285286

287+
### All hooks: Set env vars inside hook at runtime
288+
289+
> All, except deprecated hooks: `checkov`, `terraform_docs_replace`
290+
291+
You can specify environment variables that will be passed to the hook at runtime.
292+
293+
Config example:
294+
295+
```yaml
296+
- id: terraform_validate
297+
args:
298+
- --envs=AWS_DEFAULT_REGION="us-west-2"
299+
- --envs=AWS_ACCESS_KEY_ID="anaccesskey"
300+
- --envs=AWS_SECRET_ACCESS_KEY="asecretkey"
301+
```
302+
286303
### checkov (deprecated) and terraform_checkov
287304

288305
> `checkov` hook is deprecated, please use `terraform_checkov`.
@@ -614,25 +631,15 @@ Example:
614631
- --args=-no-color
615632
```
616633

617-
2. `terraform_validate` also supports custom environment variables passed to the pre-commit runtime:
618-
619-
```yaml
620-
- id: terraform_validate
621-
args:
622-
- --envs=AWS_DEFAULT_REGION="us-west-2"
623-
- --envs=AWS_ACCESS_KEY_ID="anaccesskey"
624-
- --envs=AWS_SECRET_ACCESS_KEY="asecretkey"
625-
```
626-
627-
3. `terraform_validate` also supports passing custom arguments to its `terraform init`:
634+
2. `terraform_validate` also supports passing custom arguments to its `terraform init`:
628635

629636
```yaml
630637
- id: terraform_validate
631638
args:
632639
- --tf-init-args=-lockfile=readonly
633640
```
634641

635-
4. It may happen that Terraform working directory (`.terraform`) already exists but not in the best condition (eg, not initialized modules, wrong version of Terraform, etc.). To solve this problem, you can find and delete all `.terraform` directories in your repository:
642+
3. It may happen that Terraform working directory (`.terraform`) already exists but not in the best condition (eg, not initialized modules, wrong version of Terraform, etc.). To solve this problem, you can find and delete all `.terraform` directories in your repository:
636643

637644
```bash
638645
echo "
@@ -648,7 +655,7 @@ Example:
648655

649656
**Warning:** If you use Terraform workspaces, DO NOT use this workaround ([details](https://github.com/antonbabenko/pre-commit-terraform/issues/203#issuecomment-918791847)). Wait to [`force-init`](https://github.com/antonbabenko/pre-commit-terraform/issues/224) option implementation.
650657

651-
5. `terraform_validate` in a repo with Terraform module, written using Terraform 0.15+ and which uses provider `configuration_aliases` ([Provider Aliases Within Modules](https://www.terraform.io/language/modules/develop/providers#provider-aliases-within-modules)), errors out.
658+
4. `terraform_validate` in a repo with Terraform module, written using Terraform 0.15+ and which uses provider `configuration_aliases` ([Provider Aliases Within Modules](https://www.terraform.io/language/modules/develop/providers#provider-aliases-within-modules)), errors out.
652659

653660
When running the hook against Terraform code where you have provider `configuration_aliases` defined in a `required_providers` configuration block, terraform will throw an error like:
654661
>

hooks/_common.sh

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ function common::initialize {
2626
# ARGS (array) arguments that configure wrapped tool behavior
2727
# HOOK_CONFIG (array) arguments that configure hook behavior
2828
# TF_INIT_ARGS (array) arguments for `terraform init` command
29+
# ENVS (array) environment variables will be available
30+
# for all 3rd-party tools executed by a hook.
2931
# FILES (array) filenames to check
3032
# Arguments:
3133
# $@ (array) all specified in `hooks.[].args` in
@@ -37,9 +39,11 @@ function common::parse_cmdline {
3739
ARGS=() HOOK_CONFIG=() FILES=()
3840
# Used inside `common::terraform_init` function
3941
TF_INIT_ARGS=()
42+
# Used inside `common::export_provided_env_vars` function
43+
ENVS=()
4044

4145
local argv
42-
argv=$(getopt -o a:,h:,i: --long args:,hook-config:,init-args:,tf-init-args: -- "$@") || return
46+
argv=$(getopt -o a:,h:,i:,e: --long args:,hook-config:,init-args:,tf-init-args:,envs: -- "$@") || return
4347
eval "set -- $argv"
4448

4549
for argv; do
@@ -60,6 +64,11 @@ function common::parse_cmdline {
6064
TF_INIT_ARGS+=("$1")
6165
shift
6266
;;
67+
-e | --envs)
68+
shift
69+
ENVS+=("$1")
70+
shift
71+
;;
6372
--)
6473
shift
6574
# shellcheck disable=SC2034 # Variable is used
@@ -270,3 +279,24 @@ function common::terraform_init {
270279

271280
return $exit_code
272281
}
282+
283+
#######################################################################
284+
# Export provided K/V as environment variables.
285+
# Arguments:
286+
# env_vars (array) environment variables will be available
287+
# for all 3rd-party tools executed by a hook.
288+
#######################################################################
289+
function common::export_provided_env_vars {
290+
local -a -r env_vars=("$@")
291+
292+
local var
293+
local var_name
294+
local var_value
295+
296+
for var in "${env_vars[@]}"; do
297+
var_name="${var%%=*}"
298+
var_value="${var#*=}"
299+
# shellcheck disable=SC2086
300+
export $var_name="$var_value"
301+
done
302+
}

hooks/infracost_breakdown.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
1010
function main {
1111
common::initialize "$SCRIPT_DIR"
1212
common::parse_cmdline "$@"
13+
common::export_provided_env_vars "${ENVS[@]}"
1314
common::parse_and_export_env_vars
1415
# shellcheck disable=SC2153 # False positive
1516
infracost_breakdown_ "${HOOK_CONFIG[*]}" "${ARGS[*]}"

hooks/terraform_checkov.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
1010
function main {
1111
common::initialize "$SCRIPT_DIR"
1212
common::parse_cmdline "$@"
13+
common::export_provided_env_vars "${ENVS[@]}"
1314
common::parse_and_export_env_vars
1415
# Support for setting PATH to repo root.
1516
# shellcheck disable=SC2178 # It's the simplest syntax for that case

hooks/terraform_docs.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
1313
function main {
1414
common::initialize "$SCRIPT_DIR"
1515
common::parse_cmdline "$@"
16+
common::export_provided_env_vars "${ENVS[@]}"
1617
common::parse_and_export_env_vars
1718
# Support for setting relative PATH to .terraform-docs.yml config.
1819
# shellcheck disable=SC2178 # It's the simplest syntax for that case

hooks/terraform_fmt.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
1010
function main {
1111
common::initialize "$SCRIPT_DIR"
1212
common::parse_cmdline "$@"
13+
common::export_provided_env_vars "${ENVS[@]}"
1314
common::parse_and_export_env_vars
1415
# shellcheck disable=SC2153 # False positive
1516
common::per_dir_hook "${ARGS[*]}" "$HOOK_ID" "${FILES[@]}"

hooks/terraform_providers_lock.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
1111
function main {
1212
common::initialize "$SCRIPT_DIR"
1313
common::parse_cmdline "$@"
14+
common::export_provided_env_vars "${ENVS[@]}"
1415
common::parse_and_export_env_vars
1516
# shellcheck disable=SC2153 # False positive
1617
common::per_dir_hook "${ARGS[*]}" "$HOOK_ID" "${FILES[@]}"

hooks/terraform_tflint.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
1111
function main {
1212
common::initialize "$SCRIPT_DIR"
1313
common::parse_cmdline "$@"
14+
common::export_provided_env_vars "${ENVS[@]}"
1415
common::parse_and_export_env_vars
1516
# Support for setting PATH to repo root.
1617
# shellcheck disable=SC2178 # It's the simplest syntax for that case

hooks/terraform_tfsec.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
1010
function main {
1111
common::initialize "$SCRIPT_DIR"
1212
common::parse_cmdline "$@"
13+
common::export_provided_env_vars "${ENVS[@]}"
1314
common::parse_and_export_env_vars
1415
# Support for setting PATH to repo root.
1516
# shellcheck disable=SC2178 # It's the simplest syntax for that case

hooks/terraform_validate.sh

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -12,73 +12,13 @@ export AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION:-us-east-1}
1212

1313
function main {
1414
common::initialize "$SCRIPT_DIR"
15-
parse_cmdline_ "$@"
15+
common::parse_cmdline "$@"
16+
common::export_provided_env_vars "${ENVS[@]}"
1617
common::parse_and_export_env_vars
17-
18-
# Export provided env var K/V pairs to environment
19-
local var var_name var_value
20-
for var in "${ENVS[@]}"; do
21-
var_name="${var%%=*}"
22-
var_value="${var#*=}"
23-
# shellcheck disable=SC2086
24-
export $var_name="$var_value"
25-
done
26-
2718
# shellcheck disable=SC2153 # False positive
2819
common::per_dir_hook "${ARGS[*]}" "$HOOK_ID" "${FILES[@]}"
2920
}
3021

31-
#######################################################################
32-
# Parse args and filenames passed to script and populate respective
33-
# global variables with appropriate values
34-
# Globals (init and populate):
35-
# ARGS (array) arguments that configure wrapped tool behavior
36-
# HOOK_CONFIG (array) arguments that configure hook behavior
37-
# TF_INIT_ARGS (array) arguments to `terraform init` command
38-
# ENVS (array) environment variables that will be used with
39-
# `terraform` commands
40-
# FILES (array) filenames to check
41-
# Arguments:
42-
# $@ (array) all specified in `hooks.[].args` in
43-
# `.pre-commit-config.yaml` and filenames.
44-
#######################################################################
45-
function parse_cmdline_ {
46-
declare argv
47-
argv=$(getopt -o e:i:a:h: --long envs:,tf-init-args:,init-args:,args: -- "$@") || return
48-
eval "set -- $argv"
49-
50-
for argv; do
51-
case $argv in
52-
-a | --args)
53-
shift
54-
ARGS+=("$1")
55-
shift
56-
;;
57-
-h | --hook-config)
58-
shift
59-
HOOK_CONFIG+=("$1;")
60-
shift
61-
;;
62-
# TODO: Planned breaking change: remove `--init-args` as not self-descriptive
63-
-i | --init-args | --tf-init-args)
64-
shift
65-
TF_INIT_ARGS+=("$1")
66-
shift
67-
;;
68-
-e | --envs)
69-
shift
70-
ENVS+=("$1")
71-
shift
72-
;;
73-
--)
74-
shift
75-
FILES=("$@")
76-
break
77-
;;
78-
esac
79-
done
80-
}
81-
8222
#######################################################################
8323
# Unique part of `common::per_dir_hook`. The function is executed in loop
8424
# on each provided dir path. Run wrapped tool with specified arguments
@@ -120,7 +60,4 @@ function per_dir_hook_unique_part {
12060
return $exit_code
12161
}
12262

123-
# global arrays
124-
declare -a ENVS
125-
12663
[ "${BASH_SOURCE[0]}" != "$0" ] || main "$@"

0 commit comments

Comments
 (0)