diff --git a/.github/.container-structure-test-config.yaml b/.github/.container-structure-test-config.yaml
index c746d83fc..33beae533 100644
--- a/.github/.container-structure-test-config.yaml
+++ b/.github/.container-structure-test-config.yaml
@@ -10,11 +10,6 @@ commandTests:
args: ["-V"]
expectedOutput: ["^pre-commit ([0-9]+\\.){2}[0-9]+\\n$"]
- - name: "terraform"
- command: "terraform"
- args: ["-version"]
- expectedOutput: ["^Terraform v([0-9]+\\.){2}[0-9]+\\n"]
-
- name: "gcc"
command: "gcc"
args: ["--version"]
@@ -30,6 +25,16 @@ commandTests:
args: ["--version"]
expectedOutput: ["^Infracost v([0-9]+\\.){2}[0-9]+"]
+ - name: "opentofu"
+ command: "tofu"
+ args: ["-version"]
+ expectedOutput: ["^OpenTofu v([0-9]+\\.){2}[0-9]+\\n"]
+
+ - name: "terraform"
+ command: "terraform"
+ args: ["-version"]
+ expectedOutput: ["^Terraform v([0-9]+\\.){2}[0-9]+\\n"]
+
- name: "terraform-docs"
command: "terraform-docs"
args: ["--version"]
diff --git a/.github/ISSUE_TEMPLATE/bug_report_local_install.md b/.github/ISSUE_TEMPLATE/bug_report_local_install.md
index c58591c28..0ac1fb405 100644
--- a/.github/ISSUE_TEMPLATE/bug_report_local_install.md
+++ b/.github/ISSUE_TEMPLATE/bug_report_local_install.md
@@ -78,6 +78,7 @@ Linux DESKTOP-C7315EF 5.4.72-microsoft-standard-WSL2 #1 SMP Wed Oct 28 23:40:43
bash << EOF
bash --version | head -n 1 2>/dev/null || echo "bash SKIPPED"
pre-commit --version 2>/dev/null || echo "pre-commit SKIPPED"
+tofu --version | head -n 1 2>/dev/null || echo "opentofu SKIPPED"
terraform --version | head -n 1 2>/dev/null || echo "terraform SKIPPED"
python --version 2>/dev/null || echo "python SKIPPED"
python3 --version 2>/dev/null || echo "python3 SKIPPED"
diff --git a/Dockerfile b/Dockerfile
index 3822194e5..9fa4f2557 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -20,20 +20,18 @@ COPY tools/install/ /install/
# Install required tools
#
ARG PRE_COMMIT_VERSION=${PRE_COMMIT_VERSION:-latest}
-ARG TERRAFORM_VERSION=${TERRAFORM_VERSION:-latest}
-
RUN touch /.env && \
- if [ "$PRE_COMMIT_VERSION" = "false" ] || [ "$TERRAFORM_VERSION" = "false" ]; then \
+ if [ "$PRE_COMMIT_VERSION" = "false" ]; then \
echo "Vital software can't be skipped" && exit 1; \
fi
-
-
RUN /install/pre-commit.sh
-RUN /install/terraform.sh
#
# Install tools
#
+ARG OPENTOFU_VERSION=${OPENTOFU_VERSION:-false}
+ARG TERRAFORM_VERSION=${TERRAFORM_VERSION:-false}
+
ARG CHECKOV_VERSION=${CHECKOV_VERSION:-false}
ARG HCLEDIT_VERSION=${HCLEDIT_VERSION:-false}
ARG INFRACOST_VERSION=${INFRACOST_VERSION:-false}
@@ -51,6 +49,9 @@ ARG TRIVY_VERSION=${TRIVY_VERSION:-false}
# specified in step below
ARG INSTALL_ALL=${INSTALL_ALL:-false}
RUN if [ "$INSTALL_ALL" != "false" ]; then \
+ echo "OPENTOFU_VERSION=latest" >> /.env && \
+ echo "TERRAFORM_VERSION=latest" >> /.env && \
+ \
echo "CHECKOV_VERSION=latest" >> /.env && \
echo "HCLEDIT_VERSION=latest" >> /.env && \
echo "INFRACOST_VERSION=latest" >> /.env && \
@@ -63,6 +64,9 @@ RUN if [ "$INSTALL_ALL" != "false" ]; then \
echo "TRIVY_VERSION=latest" >> /.env \
; fi
+RUN /install/opentofu.sh
+RUN /install/terraform.sh
+
RUN /install/checkov.sh
RUN /install/hcledit.sh
RUN /install/infracost.sh
@@ -79,7 +83,9 @@ RUN /install/trivy.sh
RUN . /.env && \
F=tools_versions_info && \
pre-commit --version >> $F && \
- ./terraform --version | head -n 1 >> $F && \
+ (if [ "$OPENTOFU_VERSION" != "false" ]; then echo "./tofu --version | head -n 1" >> $F; else echo "opentofu SKIPPED" >> $F ; fi) && \
+ (if [ "$TERRAFORM_VERSION" != "false" ]; then echo "./terraform --version | head -n 1" >> $F; else echo "terraform SKIPPED" >> $F ; fi) && \
+ \
(if [ "$CHECKOV_VERSION" != "false" ]; then echo "checkov $(checkov --version)" >> $F; else echo "checkov SKIPPED" >> $F ; fi) && \
(if [ "$HCLEDIT_VERSION" != "false" ]; then echo "hcledit $(./hcledit version)" >> $F; else echo "hcledit SKIPPED" >> $F ; fi) && \
(if [ "$INFRACOST_VERSION" != "false" ]; then echo "$(./infracost --version)" >> $F; else echo "infracost SKIPPED" >> $F ; fi) && \
diff --git a/README.md b/README.md
index 1c58c24dc..173e525a0 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,7 @@ If you are using `pre-commit-terraform` already or want to support its developme
* [Table of content](#table-of-content)
* [How to install](#how-to-install)
* [1. Install dependencies](#1-install-dependencies)
+ * [1.1 Custom Terraform binaries and OpenTofu support](#11-custom-terraform-binaries-and-opentofu-support)
* [2. Install the pre-commit hook globally](#2-install-the-pre-commit-hook-globally)
* [3. Add configs and hooks](#3-add-configs-and-hooks)
* [4. Run](#4-run)
@@ -67,7 +68,7 @@ If you are using `pre-commit-terraform` already or want to support its developme
### 1. Install dependencies
* [`pre-commit`](https://pre-commit.com/#install),
- [`terraform`](https://www.terraform.io/downloads.html),
+ [`terraform`](https://www.terraform.io/downloads.html) or [`opentofu`](https://opentofu.org/docs/intro/install/),
[`git`](https://git-scm.com/downloads),
[BASH `3.2.57` or newer](https://www.gnu.org/software/bash/#download),
Internet connection (on first run),
@@ -77,17 +78,31 @@ If you are using `pre-commit-terraform` already or want to support its developme
Some basic physical laws,
Hope that it all will work.
-* [`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.
-* [`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.
-* [`Trivy`](https://github.com/aquasecurity/trivy) required for `terraform_trivy` hook.
-* [`infracost`](https://github.com/infracost/infracost) required for `infracost_breakdown` hook.
-* [`jq`](https://github.com/stedolan/jq) required for `terraform_validate` with `--retry-once-with-cleanup` flag, and for `infracost_breakdown` hook.
-* [`tfupdate`](https://github.com/minamijoyo/tfupdate) required for `tfupdate` hook.
-* [`hcledit`](https://github.com/minamijoyo/hcledit) required for `terraform_wrapper_module_for_each` hook.
+* [`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
+* [`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
+* [`Trivy`](https://github.com/aquasecurity/trivy) required for `terraform_trivy` hook
+* [`infracost`](https://github.com/infracost/infracost) required for `infracost_breakdown` hook
+* [`jq`](https://github.com/stedolan/jq) required for `terraform_validate` with `--retry-once-with-cleanup` flag, and for `infracost_breakdown` hook
+* [`tfupdate`](https://github.com/minamijoyo/tfupdate) required for `tfupdate` hook
+* [`hcledit`](https://github.com/minamijoyo/hcledit) required for `terraform_wrapper_module_for_each` hook
+
+
+#### 1.1 Custom Terraform binaries and OpenTofu support
+
+It is possible to set custom path to `terraform` binary.
+This makes it possible to use [OpenTofu](https://opentofu.org) binary `tofu` instead of `terraform`.
+
+How binary discovery works and how you can redefine it (first matched takes precedence):
+
+1. Check if per hook configuration `--hook-config=--tf-path=` is set
+2. Check if `PCT_TFPATH=` environment variable is set
+3. Check if `TERRAGRUNT_TFPATH=` environment variable is set
+4. Check if `terraform` binary can be found in the user's $PATH
+5. Check if `tofu` binary can be found in the user's $PATH
Docker
@@ -120,17 +135,18 @@ To install a specific version of individual tools, define it using `--build-arg`
```bash
docker build -t pre-commit-terraform \
--build-arg PRE_COMMIT_VERSION=latest \
- --build-arg TERRAFORM_VERSION=latest \
+ --build-arg OPENTOFU_VERSION=latest \
+ --build-arg TERRAFORM_VERSION=1.5.7 \
--build-arg CHECKOV_VERSION=2.0.405 \
+ --build-arg HCLEDIT_VERSION=latest \
--build-arg INFRACOST_VERSION=latest \
--build-arg TERRAFORM_DOCS_VERSION=0.15.0 \
--build-arg TERRAGRUNT_VERSION=latest \
--build-arg TERRASCAN_VERSION=1.10.0 \
--build-arg TFLINT_VERSION=0.31.0 \
--build-arg TFSEC_VERSION=latest \
- --build-arg TRIVY_VERSION=latest \
--build-arg TFUPDATE_VERSION=latest \
- --build-arg HCLEDIT_VERSION=latest \
+ --build-arg TRIVY_VERSION=latest \
.
```
diff --git a/hooks/_common.sh b/hooks/_common.sh
index 16c070c6c..c278c3a7a 100644
--- a/hooks/_common.sh
+++ b/hooks/_common.sh
@@ -283,6 +283,8 @@ function common::per_dir_hook {
# despite there's only one positional ARG left
local -a -r files=("$@")
+ local -r tf_path=$(common::get_tf_binary_path)
+
# check is (optional) function defined
if [ "$(type -t run_hook_on_whole_repo)" == function ] &&
# check is hook run via `pre-commit run --all`
@@ -383,7 +385,7 @@ function common::per_dir_hook {
pushd "$dir_path" > /dev/null
fi
- per_dir_hook_unique_part "$dir_path" "$change_dir_in_unique_part" "$parallelism_disabled" "${args[@]}"
+ per_dir_hook_unique_part "$dir_path" "$change_dir_in_unique_part" "$parallelism_disabled" "$tf_path" "${args[@]}"
} &
pids+=("$!")
@@ -445,6 +447,58 @@ function common::colorify {
echo -e "${COLOR}${TEXT}${RESET}" >&2
}
+#######################################################################
+# Get Terraform/OpenTofu binary path
+# Allows user to set the path to custom Terraform or OpenTofu binary
+# Globals (init and populate):
+# HOOK_CONFIG (array) arguments that configure hook behavior
+# PCT_TFPATH (string) user defined env var with path to Terraform/OpenTofu binary
+# TERRAGRUNT_TFPATH (string) user defined env var with path to Terraform/OpenTofu binary
+# Outputs:
+# If failed - exit 1 with error message about missing Terraform/OpenTofu binary
+#######################################################################
+function common::get_tf_binary_path {
+ local hook_config_tf_path
+
+ for config in "${HOOK_CONFIG[@]}"; do
+ if [[ $config == --tf-path=* ]]; then
+ hook_config_tf_path=${config#*=}
+ hook_config_tf_path=${hook_config_tf_path%;}
+ break
+ fi
+ done
+
+ # direct hook config, has the highest precedence
+ if [[ $hook_config_tf_path ]]; then
+ echo "$hook_config_tf_path"
+ return
+
+ # environment variable
+ elif [[ $PCT_TFPATH ]]; then
+ echo "$PCT_TFPATH"
+ return
+
+ # Maybe there is a similar setting for Terragrunt already
+ elif [[ $TERRAGRUNT_TFPATH ]]; then
+ echo "$TERRAGRUNT_TFPATH"
+ return
+
+ # check if Terraform binary is available
+ elif command -v terraform &> /dev/null; then
+ command -v terraform
+ return
+
+ # finally, check if Tofu binary is available
+ elif command -v tofu &> /dev/null; then
+ command -v tofu
+ return
+
+ else
+ common::colorify "red" "Neither Terraform nor OpenTofu binary could be found. Please either set the \"--tf-path\" hook configuration argument, or set the \"PCT_TFPATH\" environment variable, or set the \"TERRAGRUNT_TFPATH\" environment variable, or install Terraform or OpenTofu globally."
+ exit 1
+ fi
+}
+
#######################################################################
# Run terraform init command
# Arguments:
@@ -452,6 +506,7 @@ function common::colorify {
# dir_path (string) PATH to dir relative to git repo root.
# Can be used in error logging
# parallelism_disabled (bool) if true - skip lock mechanism
+# tf_path (string) PATH to Terraform/OpenTofu binary
# Globals (init and populate):
# TF_INIT_ARGS (array) arguments for `terraform init` command
# TF_PLUGIN_CACHE_DIR (string) user defined env var with name of the directory
@@ -464,6 +519,7 @@ function common::terraform_init {
local -r command_name=$1
local -r dir_path=$2
local -r parallelism_disabled=$3
+ local -r tf_path=$4
local exit_code=0
local init_output
@@ -480,13 +536,13 @@ function common::terraform_init {
# Plugin cache dir can't be written concurrently or read during write
# https://github.com/hashicorp/terraform/issues/31964
if [[ -z $TF_PLUGIN_CACHE_DIR || $parallelism_disabled == true ]]; then
- init_output=$(terraform init -backend=false "${TF_INIT_ARGS[@]}" 2>&1)
+ init_output=$($tf_path init -backend=false "${TF_INIT_ARGS[@]}" 2>&1)
exit_code=$?
else
# Locking just doesn't work, and the below works quicker instead. Details:
# https://github.com/hashicorp/terraform/issues/31964#issuecomment-1939869453
for i in {1..10}; do
- init_output=$(terraform init -backend=false "${TF_INIT_ARGS[@]}" 2>&1)
+ init_output=$($tf_path init -backend=false "${TF_INIT_ARGS[@]}" 2>&1)
exit_code=$?
if [ $exit_code -eq 0 ]; then
diff --git a/hooks/terraform_checkov.sh b/hooks/terraform_checkov.sh
index dbbdc463b..01e2f2454 100755
--- a/hooks/terraform_checkov.sh
+++ b/hooks/terraform_checkov.sh
@@ -36,6 +36,7 @@ function main {
# 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
#######################################################################
@@ -46,7 +47,9 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ # shellcheck disable=SC2034 # Unused var.
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
checkov -d . "${args[@]}"
diff --git a/hooks/terraform_fmt.sh b/hooks/terraform_fmt.sh
index 949a066a8..a39c27fc5 100755
--- a/hooks/terraform_fmt.sh
+++ b/hooks/terraform_fmt.sh
@@ -33,6 +33,7 @@ function main {
# 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
#######################################################################
@@ -43,11 +44,12 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
# pass the arguments to hook
- terraform fmt "${args[@]}"
+ $tf_path fmt "${args[@]}"
# return exit code to common::per_dir_hook
local exit_code=$?
diff --git a/hooks/terraform_providers_lock.sh b/hooks/terraform_providers_lock.sh
index 34bce58b2..1cecd1a02 100755
--- a/hooks/terraform_providers_lock.sh
+++ b/hooks/terraform_providers_lock.sh
@@ -87,6 +87,7 @@ function lockfile_contains_all_needed_sha {
# 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
#######################################################################
@@ -95,7 +96,8 @@ function per_dir_hook_unique_part {
# shellcheck disable=SC2034 # Unused var.
local -r change_dir_in_unique_part="$2"
local -r parallelism_disabled="$3"
- shift 3
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
local platforms_count=0
@@ -138,7 +140,7 @@ function per_dir_hook_unique_part {
common::colorify "yellow" "DEPRECATION NOTICE: We introduced '--mode' flag for this hook.
Check migration instructions at https://github.com/antonbabenko/pre-commit-terraform#terraform_providers_lock
"
- common::terraform_init 'terraform providers lock' "$dir_path" "$parallelism_disabled" || {
+ common::terraform_init 'terraform providers lock' "$dir_path" "$parallelism_disabled" "$tf_path" || {
exit_code=$?
return $exit_code
}
@@ -153,7 +155,7 @@ Check migration instructions at https://github.com/antonbabenko/pre-commit-terra
#? Don't require `tf init` for providers, but required `tf init` for modules
#? Mitigated by `function match_validate_errors` from terraform_validate hook
# pass the arguments to hook
- terraform providers lock "${args[@]}"
+ $tf_path providers lock "${args[@]}"
# return exit code to common::per_dir_hook
exit_code=$?
diff --git a/hooks/terraform_tflint.sh b/hooks/terraform_tflint.sh
index 211e648bc..54bcebe38 100755
--- a/hooks/terraform_tflint.sh
+++ b/hooks/terraform_tflint.sh
@@ -46,6 +46,7 @@ function main {
# 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
#######################################################################
@@ -54,7 +55,9 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ # shellcheck disable=SC2034 # Unused var.
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
if [ "$change_dir_in_unique_part" == "delegate_chdir" ]; then
diff --git a/hooks/terraform_tfsec.sh b/hooks/terraform_tfsec.sh
index 52cab2c71..dddad49a6 100755
--- a/hooks/terraform_tfsec.sh
+++ b/hooks/terraform_tfsec.sh
@@ -39,6 +39,7 @@ function main {
# 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
#######################################################################
@@ -49,7 +50,9 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ # shellcheck disable=SC2034 # Unused var.
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
# pass the arguments to hook
diff --git a/hooks/terraform_trivy.sh b/hooks/terraform_trivy.sh
index 7de40188b..fb4a529a0 100755
--- a/hooks/terraform_trivy.sh
+++ b/hooks/terraform_trivy.sh
@@ -31,6 +31,7 @@ function main {
# 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
#######################################################################
@@ -41,7 +42,9 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ # shellcheck disable=SC2034 # Unused var.
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
# pass the arguments to hook
diff --git a/hooks/terraform_validate.sh b/hooks/terraform_validate.sh
index a56e8c6db..e51b5c714 100755
--- a/hooks/terraform_validate.sh
+++ b/hooks/terraform_validate.sh
@@ -77,6 +77,7 @@ function match_validate_errors {
# 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
#######################################################################
@@ -85,7 +86,8 @@ function per_dir_hook_unique_part {
# shellcheck disable=SC2034 # Unused var.
local -r change_dir_in_unique_part="$2"
local -r parallelism_disabled="$3"
- shift 3
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
local exit_code
@@ -116,25 +118,25 @@ function per_dir_hook_unique_part {
# First try `terraform validate` with the hope that all deps are
# pre-installed. That is needed for cases when `.terraform/modules`
# or `.terraform/providers` missed AND that is expected.
- terraform validate "${args[@]}" &> /dev/null && {
+ $tf_path validate "${args[@]}" &> /dev/null && {
exit_code=$?
return $exit_code
}
# In case `terraform validate` failed to execute
# - check is simple `terraform init` will help
- common::terraform_init 'terraform validate' "$dir_path" "$parallelism_disabled" || {
+ common::terraform_init "$tf_path validate" "$dir_path" "$parallelism_disabled" "$tf_path" || {
exit_code=$?
return $exit_code
}
if [ "$retry_once_with_cleanup" != "true" ]; then
# terraform validate only
- validate_output=$(terraform validate "${args[@]}" 2>&1)
+ validate_output=$($tf_path validate "${args[@]}" 2>&1)
exit_code=$?
else
# terraform validate, plus capture possible errors
- validate_output=$(terraform validate -json "${args[@]}" 2>&1)
+ validate_output=$($tf_path validate -json "${args[@]}" 2>&1)
exit_code=$?
# Match specific validation errors
@@ -152,12 +154,12 @@ function per_dir_hook_unique_part {
common::colorify "yellow" "Re-validating: $dir_path"
- common::terraform_init 'terraform validate' "$dir_path" "$parallelism_disabled" || {
+ common::terraform_init "$tf_path validate" "$dir_path" "$parallelism_disabled" "$tf_path" || {
exit_code=$?
return $exit_code
}
- validate_output=$(terraform validate "${args[@]}" 2>&1)
+ validate_output=$($tf_path validate "${args[@]}" 2>&1)
exit_code=$?
fi
fi
diff --git a/hooks/terragrunt_fmt.sh b/hooks/terragrunt_fmt.sh
index a39c78a79..698b3843b 100755
--- a/hooks/terragrunt_fmt.sh
+++ b/hooks/terragrunt_fmt.sh
@@ -29,6 +29,7 @@ function main {
# 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
#######################################################################
@@ -39,7 +40,9 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ # shellcheck disable=SC2034 # Unused var.
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
# pass the arguments to hook
diff --git a/hooks/terragrunt_providers_lock.sh b/hooks/terragrunt_providers_lock.sh
index 059f8d1f5..9e3557aeb 100755
--- a/hooks/terragrunt_providers_lock.sh
+++ b/hooks/terragrunt_providers_lock.sh
@@ -29,6 +29,7 @@ function main {
# 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
#######################################################################
@@ -39,7 +40,9 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ # shellcheck disable=SC2034 # Unused var.
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
# pass the arguments to hook
diff --git a/hooks/terragrunt_validate.sh b/hooks/terragrunt_validate.sh
index e595329b6..5a62c3913 100755
--- a/hooks/terragrunt_validate.sh
+++ b/hooks/terragrunt_validate.sh
@@ -29,6 +29,7 @@ function main {
# 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
#######################################################################
@@ -39,7 +40,9 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ # shellcheck disable=SC2034 # Unused var.
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
# pass the arguments to hook
diff --git a/hooks/terrascan.sh b/hooks/terrascan.sh
index d7dc5f4a5..f6586ceae 100755
--- a/hooks/terrascan.sh
+++ b/hooks/terrascan.sh
@@ -29,6 +29,7 @@ function main {
# 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
#######################################################################
@@ -39,7 +40,9 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ # shellcheck disable=SC2034 # Unused var.
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
# pass the arguments to hook
diff --git a/hooks/tfupdate.sh b/hooks/tfupdate.sh
index 5c9979a47..1d474318b 100755
--- a/hooks/tfupdate.sh
+++ b/hooks/tfupdate.sh
@@ -39,6 +39,7 @@ function main {
# 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
#######################################################################
@@ -49,7 +50,9 @@ function per_dir_hook_unique_part {
local -r change_dir_in_unique_part="$2"
# shellcheck disable=SC2034 # Unused var.
local -r parallelism_disabled="$3"
- shift 3
+ # shellcheck disable=SC2034 # Unused var.
+ local -r tf_path="$4"
+ shift 4
local -a -r args=("$@")
# pass the arguments to hook
diff --git a/tools/install/opentofu.sh b/tools/install/opentofu.sh
new file mode 100755
index 000000000..bda0fe399
--- /dev/null
+++ b/tools/install/opentofu.sh
@@ -0,0 +1,21 @@
+#!/usr/bin/env bash
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd -P)"
+readonly SCRIPT_DIR
+# shellcheck source=_common.sh
+. "$SCRIPT_DIR/_common.sh"
+
+#
+# Unique part
+#
+GH_ORG="opentofu"
+GH_RELEASE_REGEX_SPECIFIC_VERSION="https://.+?v${VERSION}_${TARGETOS}_${TARGETARCH}.tar.gz"
+GH_RELEASE_REGEX_LATEST="https://.+?_${TARGETOS}_${TARGETARCH}.tar.gz"
+DISTRIBUTED_AS="tar.gz"
+UNUSUAL_TOOL_NAME_IN_PKG="tofu"
+
+common::install_from_gh_release "$GH_ORG" "$DISTRIBUTED_AS" \
+ "$GH_RELEASE_REGEX_LATEST" "$GH_RELEASE_REGEX_SPECIFIC_VERSION" \
+ "$UNUSUAL_TOOL_NAME_IN_PKG"
+
+# restore original binary name
+mv "$TOOL" "$UNUSUAL_TOOL_NAME_IN_PKG"