### Install Pre-commit Hooks Locally Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Installs the pre-commit hooks for the current repository. This command is necessary if the repository was initialized before the global pre-commit hook installation. ```bash pre-commit install ``` -------------------------------- ### Install tfsec on Linux Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Downloads and installs the latest version of tfsec. Ensure you have curl and sudo privileges. ```bash curl -L "$(curl -s https://api.github.com/repos/aquasecurity/tfsec/releases/latest | grep -o -E -m 1 "https://.+?tfsec-linux-amd64")" > tfsec && chmod +x tfsec && sudo mv tfsec /usr/bin/ ``` -------------------------------- ### Install Infracost on Linux Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Installs Infracost, including authentication login. Requires apt, curl, tar, and sudo privileges. ```bash sudo apt install -y jq && \ curl -L "$(curl -s https://api.github.com/repos/infracost/infracost/releases/latest | grep -o -E -m 1 "https://.+?-linux-amd64.tar.gz")" > infracost.tgz && tar -xzf infracost.tgz && rm infracost.tgz && sudo mv infracost-linux-amd64 /usr/bin/infracost && infracost auth login ``` -------------------------------- ### Install Trivy on Linux Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Downloads, extracts, and installs the latest version of Trivy. Requires curl, tar, and sudo privileges. ```bash curl -L "$(curl -s https://api.github.com/repos/aquasecurity/trivy/releases/latest | grep -o -E -i -m 1 "https://.+?/trivy_.+?_Linux-64bit.tar.gz")" > trivy.tar.gz && tar -xzf trivy.tar.gz trivy && rm trivy.tar.gz && sudo mv trivy /usr/bin ``` -------------------------------- ### Install Pre-Commit Terraform Hooks Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Add this configuration to your .pre-commit-config.yaml to install and activate the hooks. Run 'pre-commit install' to enable the hooks and 'pre-commit run -a' to execute them. ```yaml # .pre-commit-config.yaml repos: - repo: https://github.com/antonbabenko/pre-commit-terraform rev: v1.105.0 # pin to a specific tag hooks: - id: terraform_fmt - id: terraform_validate - id: terraform_docs - id: terraform_tflint - id: terraform_trivy # Install and run: # pre-commit install # pre-commit run -a ``` -------------------------------- ### Infracost breakdown output example Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Example output from the infracost_breakdown hook showing cost summary and differences. ```bash Running in "env/dev" Summary: { "unsupportedResourceCounts": { "aws_sns_topic_subscription": 1 } } Total Monthly Cost: 86.83 USD Total Monthly Cost (diff): 86.83 USD ``` -------------------------------- ### Install Tools on Ubuntu 20.04+ Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Installs Python, pip, and various Terraform tools on Ubuntu 20.04+ by updating apt and downloading binaries. ```bash sudo apt update sudo apt install -y unzip software-properties-common python3 python3-pip python-is-python3 python3 -m pip install --upgrade pip pip3 install --no-cache-dir pre-commit pip3 install --no-cache-dir checkov curl -L "$(curl -s https://api.github.com/repos/terraform-docs/terraform-docs/releases/latest | grep -o -E -m 1 \"https://.+?-linux-amd64.tar.gz\")" > terraform-docs.tgz && tar -xzf terraform-docs.tgz terraform-docs && rm terraform-docs.tgz && chmod +x terraform-docs && sudo mv terraform-docs /usr/bin/ curl -L "$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E -m 1 \"https://.+?_Linux_x86_64.tar.gz\")" > terrascan.tar.gz && tar -xzf terrascan.tar.gz terrascan && rm terrascan.tar.gz && sudo mv terrascan /usr/bin/ && terrascan init curl -L "$(curl -s https://api.github.com/repos/terraform-linters/tflint/releases/latest | grep -o -E -m 1 \"https://.+?_linux_amd64.zip\")" > tflint.zip && unzip tflint.zip && rm tflint.zip && sudo mv tflint /usr/bin/ ``` -------------------------------- ### Build Docker Image with All Tools Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Builds a Docker image with the latest versions of all supported tools. No additional setup is required. ```bash docker build -t pre-commit-terraform --build-arg INSTALL_ALL=true . ``` -------------------------------- ### Install hcledit on Linux Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Downloads and installs the latest version of hcledit. Requires curl, tar, and sudo privileges. ```bash curl -L "$(curl -s https://api.github.com/repos/minamijoyo/hcledit/releases/latest | grep -o -E -m 1 "https://.+?_linux_amd64.tar.gz")" > hcledit.tar.gz && tar -xzf hcledit.tar.gz hcledit && rm hcledit.tar.gz && sudo mv hcledit /usr/bin/ ``` -------------------------------- ### Install Tools on MacOS using Homebrew Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Installs pre-commit and various Terraform ecosystem tools on macOS using the Homebrew package manager. ```bash brew install pre-commit terraform-docs tflint tfsec trivy checkov terrascan infracost tfupdate minamijoyo/hcledit/hcledit jq ``` -------------------------------- ### Install tfupdate on Linux Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Downloads and installs the latest version of tfupdate. Requires curl, tar, and sudo privileges. ```bash curl -L "$(curl -s https://api.github.com/repos/minamijoyo/tfupdate/releases/latest | grep -o -E -m 1 "https://.+?_linux_amd64.tar.gz")" > tfupdate.tar.gz && tar -xzf tfupdate.tar.gz tfupdate && rm tfupdate.tar.gz && sudo mv tfupdate /usr/bin/ ``` -------------------------------- ### Install Tools on Ubuntu 18.04 Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Installs Python, pip, and various Terraform tools on Ubuntu 18.04 by updating apt, adding PPAs, and downloading binaries. ```bash sudo apt update sudo apt install -y unzip software-properties-common sudo add-apt-repository ppa:deadsnakes/ppa sudo apt install -y python3.7 python3-pip python3 -m pip install --upgrade pip pip3 install --no-cache-dir pre-commit python3.7 -m pip install -U checkov curl -L "$(curl -s https://api.github.com/repos/terraform-docs/terraform-docs/releases/latest | grep -o -E -m 1 \"https://.+?-linux-amd64.tar.gz\")" > terraform-docs.tgz && tar -xzf terraform-docs.tgz && rm terraform-docs.tgz && chmod +x terraform-docs && sudo mv terraform-docs /usr/bin/ curl -L "$(curl -s https://api.github.com/repos/terraform-linters/tflint/releases/latest | grep -o -E -m 1 \"https://.+?_linux_amd64.zip\")" > tflint.zip && unzip tflint.zip && rm tflint.zip && sudo mv tflint /usr/bin/ curl -L "$(curl -s https://api.github.com/repos/aquasecurity/tfsec/releases/latest | grep -o -E -m 1 \"https://.+?tfsec-linux-amd64\")" > tfsec && chmod +x tfsec && sudo mv tfsec /usr/bin/ curl -L "$(curl -s https://api.github.com/repos/aquasecurity/trivy/releases/latest | grep -o -E -i -m 1 \"https://.+?/trivy_.+?_Linux-64bit.tar.gz\")" > trivy.tar.gz && tar -xzf trivy.tar.gz trivy && rm trivy.tar.gz && sudo mv trivy /usr/bin curl -L "$(curl -s https://api.github.com/repos/tenable/terrascan/releases/latest | grep -o -E -m 1 \"https://.+?_Linux_x86_64.tar.gz\")" > terrascan.tar.gz && tar -xzf terrascan.tar.gz terrascan && rm terrascan.tar.gz && sudo mv terrascan /usr/bin/ && terrascan init sudo apt install -y jq && \ curl -L "$(curl -s https://api.github.com/repos/infracost/infracost/releases/latest | grep -o -E -m 1 \"https://.+?-linux-amd64.tar.gz\")" > infracost.tgz && tar -xzf infracost.tgz && rm infracost.tgz && sudo mv infracost-linux-amd64 /usr/bin/infracost && infracost auth login curl -L "$(curl -s https://api.github.com/repos/minamijoyo/tfupdate/releases/latest | grep -o -E -m 1 \"https://.+?_linux_amd64.tar.gz\")" > tfupdate.tar.gz && tar -xzf tfupdate.tar.gz tfupdate && rm tfupdate.tar.gz && sudo mv tfupdate /usr/bin/ curl -L "$(curl -s https://api.github.com/repos/minamijoyo/hcledit/releases/latest | grep -o -E -m 1 \"https://.+?_linux_amd64.tar.gz\")" > hcledit.tar.gz && tar -xzf hcledit.tar.gz hcledit && rm hcledit.tar.gz && sudo mv hcledit /usr/bin/ ``` -------------------------------- ### Install Pre-commit Hook Globally Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Installs the pre-commit hook globally using Git templates. This is not needed if you are using the Docker image. ```bash DIR=~/.git-template git config --global init.templateDir ${DIR} pre-commit init-templatedir -t pre-commit ${DIR} ``` -------------------------------- ### Infracost breakdown output with cost constraints example Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Example output from the infracost_breakdown hook when cost constraints are applied, indicating passed and failed checks. ```bash Running in "env/dev" Passed: .totalHourlyCost|tonumber > 0.1 0.11894520547945205 > 0.1 Failed: .totalHourlyCost|tonumber > 1 0.11894520547945205 > 1 Passed: .projects[].diff.totalMonthlyCost|tonumber !=10000 86.83 != 10000 Passed: .currency == "USD" "USD" == "USD" Summary: { "unsupportedResourceCounts": { "aws_sns_topic_subscription": 1 } } Total Monthly Cost: 86.83 USD Total Monthly Cost (diff): 86.83 USD ``` -------------------------------- ### Configure terraform-docs.yml for replace mode Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Example .terraform-docs.yml configuration to replicate the functionality of the deprecated terraform_docs_replace hook, using 'replace' mode. ```yaml formatter: "markdown" output: file: "README.md" mode: replace template: |- {{/** End of file fixer */}} ``` -------------------------------- ### Run Pre-commit Hooks Using Docker Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Runs the pre-commit hooks using a Docker container. This ensures a consistent environment and avoids local installation issues. Mounts the current directory to '/lint' within the container and sets the user ID and group ID to match the host. ```bash TAG=latest docker run -e "USERID=$(id -u):$(id -g)" -v "$(pwd):/lint" -w "/lint" "ghcr.io/antonbabenko/pre-commit-terraform:$TAG" run -a ``` -------------------------------- ### Configure terraform_trivy with Custom Arguments Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Pass custom arguments to terraform_trivy for options like output format or skipping directories. This example sets JSON format and skips the '.terraform' directory. ```yaml - id: terraform_trivy args: - --args=--format=json - --args=--skip-dirs="**/.terraform" ``` -------------------------------- ### Configure terraform_trivy to Scan Specific Directories Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use the 'files' pre-commit flag with terraform_trivy to specify directories or files to scan. This example targets files within the 'prd-infra/' directory. ```yaml - id: terraform_trivy files: ^prd-infra/ ``` -------------------------------- ### Configure Environment Variables for Hook Arguments Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use environment variables within the `--args` section of your pre-commit configuration. Ensure you use the `${ENV_VAR}` syntax for expansion. This example shows how to dynamically set a configuration file path. ```yaml - id: terraform_tflint args: - --args=--config=${CONFIG_NAME}.${CONFIG_EXT} - --args=--call-module-type="all" ``` -------------------------------- ### Running pre-commit-terraform with Docker Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Execute all pre-commit-terraform hooks using a Docker container. This avoids local tool installation. You can also build custom Docker images with specific tool versions. ```bash TAG=v1.105.0 # Run all hooks against current directory docker run \ -e "USERID=$(id -u):$(id -g)" \ -v "$(pwd):/lint" \ -w "/lint" \ "ghcr.io/antonbabenko/pre-commit-terraform:$TAG" run -a # Build custom image with specific tool versions docker build -t pre-commit-terraform \ --build-arg TERRAFORM_VERSION=1.9.0 \ --build-arg TERRAFORM_DOCS_VERSION=0.18.0 \ --build-arg TFLINT_VERSION=0.51.0 \ --build-arg TRIVY_VERSION=latest \ --build-argCHECKOV_VERSION=3.2.0 \ . # Print versions of all installed tools docker run --rm --entrypoint cat \ "ghcr.io/antonbabenko/pre-commit-terraform:$TAG" \ /usr/bin/tools_versions_info # With private GitHub module sources (requires .netrc) echo "machine github.com" > ~/.netrc echo " login $GITHUB_PAT" >> ~/.netrc docker run --rm \ -e "USERID=$(id -u):$(id -g)" \ -v ~/.netrc:/root/.netrc \ -v "$(pwd):/lint" \ -w "/lint" \ "ghcr.io/antonbabenko/pre-commit-terraform:$TAG" run -a ``` -------------------------------- ### Configure terraform_tfsec to Scan Specific Directories Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use the 'files' pre-commit flag with terraform_tfsec to specify directories or files to scan. This example targets files within the 'prd-infra/' directory. ```yaml - id: terraform_tfsec files: ^prd-infra/ ``` -------------------------------- ### GitHub Actions Integration for pre-commit-terraform Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Integrate pre-commit-terraform into your GitHub Actions workflow. This example sets up a workflow that runs pre-commit checks on pull requests, utilizing a Docker container for the tool suite and caching pre-commit configurations. ```yaml # .github/workflows/pre-commit.yml name: pre-commit-terraform on: pull_request: jobs: pre-commit: runs-on: ubuntu-latest container: image: ghcr.io/antonbabenko/pre-commit-terraform:v1.105.0 defaults: run: shell: bash steps: - uses: actions/checkout@v4 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} - name: Configure git safe directory run: git config --global --add safe.directory $GITHUB_WORKSPACE - name: Get changed files id: file_changes run: | git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/* DIFF=$(git diff --name-only origin/${{ github.base_ref }} ${{ github.sha }}) echo "files=$(echo "$DIFF" | xargs echo)" >> $GITHUB_OUTPUT - name: Cache pre-commit uses: actions/cache@v4 with: path: ~/.cache/pre-commit key: pre-commit-3|${{ hashFiles('.pre-commit-config.yaml') }} - name: Run pre-commit run: | pre-commit run --color=always --show-diff-on-failure \ --files ${{ steps.file_changes.outputs.files }} ``` -------------------------------- ### Configure terraform_tfsec with Custom Arguments Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Pass custom arguments to terraform_tfsec for options like output format, disabling color, or excluding specific checks. This example sets JSON format and excludes two checks. ```yaml - id: terraform_tfsec args: - > --args=--format json --no-color -e aws-s3-enable-bucket-logging,aws-s3-specify-public-access-block ``` -------------------------------- ### Pull Docker Image for Pre-commit Terraform Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Pulls the latest Docker image containing all pre-commit hooks for Terraform. Ensure Docker is installed and configured. ```bash TAG=latest docker pull ghcr.io/antonbabenko/pre-commit-terraform:$TAG ``` -------------------------------- ### Enable Retry with Cleanup for terraform_validate Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Enable the --retry-once-with-cleanup=true flag for terraform_validate. This option deletes cached modules and providers from the .terraform directory before retrying initialization upon specific errors. Requires 'jq' to be installed. ```yaml - id: terraform_validate args: - --hook-config=--retry-once-with-cleanup=true # Boolean. true or false ``` -------------------------------- ### GitHub Actions Workflow with Docker Container Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md This workflow uses a Docker container to run pre-commit checks. It checks out the code, fetches remote branches, identifies changed files, installs necessary tools in the container, caches pre-commit dependencies, and executes pre-commit hooks on the identified files. Note that fixes are not automatically pushed back to the branch. ```yaml name: pre-commit-terraform on: pull_request: jobs: pre-commit: runs-on: ubuntu-latest container: image: ghcr.io/antonbabenko/pre-commit-terraform:latest # latest used here for simplicity, not recommended defaults: run: shell: bash steps: - uses: actions/checkout@v4 with: fetch-depth: 0 ref: ${{ github.event.pull_request.head.sha }} - run: | git config --global --add safe.directory $GITHUB_WORKSPACE git fetch --no-tags --prune --depth=1 origin +refs/heads/*:refs/remotes/origin/* - name: Get changed files id: file_changes run: | export DIFF=$(git diff --name-only origin/${{ github.base_ref }} ${{ github.sha }}) echo "Diff between ${{ github.base_ref }} and ${{ github.sha }}" echo "files=$( echo "$DIFF" | xargs echo )" >> $GITHUB_OUTPUT - name: fix tar dependency in alpine container image run: | apk --no-cache add tar # check python modules installed versions python -m pip freeze --local - name: Cache pre-commit since we use pre-commit from container uses: actions/cache@v4 with: path: ~/.cache/pre-commit key: pre-commit-3|${{ hashFiles('.pre-commit-config.yaml') }} - name: Execute pre-commit run: | pre-commit run --color=always --show-diff-on-failure --files ${{ steps.file_changes.outputs.files }} ``` -------------------------------- ### Set Parallelism Limit Relative to CPU Cores Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Configure parallelism to scale with the number of available CPU logical cores. Use a Bash arithmetic expression with 'CPU' as the reference for the number of cores. For example, 'CPU*4' will use four times the number of logical CPU cores. ```yaml - id: terraform_providers_lock args: - --hook-config=--parallelism-limit=CPU*4 ``` -------------------------------- ### Initialize Git Repository and Add Pre-commit Config Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Initializes a Git repository and adds the pre-commit configuration file (.pre-commit-config.yaml) to include the Terraform hooks. Ensure you replace with the latest release tag. ```bash git init cat < .pre-commit-config.yaml repos: - repo: https://github.com/antonbabenko/pre-commit-terraform rev: # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases hooks: - id: terraform_fmt - id: terraform_docs EOF ``` -------------------------------- ### Build Pre-commit Terraform Docker Image from Scratch Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Builds the Docker image from the source repository. Requires Docker Buildx to be enabled. Ensure you are in the cloned repository directory. ```bash git clone git@github.com:antonbabenko/pre-commit-terraform.git cd pre-commit-terraform ``` -------------------------------- ### Build Docker Image with Specific Tool Versions Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Builds a Docker image, allowing you to specify versions for individual tools using --build-arg. Set to 'latest' for the newest version. ```bash docker build -t pre-commit-terraform \ --build-arg PRE_COMMIT_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 TFUPDATE_VERSION=latest \ --build-arg TRIVY_VERSION=latest \ . ``` -------------------------------- ### Configure ~/.netrc for Private GitHub Repositories Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Create or append to the `~/.netrc` file with your GitHub Personal Access Token (PAT) and server hostname. This is required for Dockerized pre-commit to authenticate with private Git repositories. ```bash # set GH values (replace with your own values) GITHUB_PAT=ghp_bl481aBlabl481aBla GITHUB_SERVER_HOSTNAME=github.com # create .netrc file echo -e "machine $GITHUB_SERVER_HOSTNAME\n\tlogin $GITHUB_PAT" >> ~/.netrc ``` ```text machine github.com login ghp_bl481aBlabl481aBla ``` -------------------------------- ### Ignore Specific Warnings in tfsec Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Ignore specific warnings in tfsec by adding comments in the format '#tfsec:ignore:' directly in your HCL code. This example ignores AWS006. ```hcl resource "aws_security_group_rule" "my-rule" { type = "ingress" cidr_blocks = ["0.0.0.0/0"] #tfsec:ignore:AWS006 } ``` -------------------------------- ### List Tool Versions in Docker Image Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Retrieves and displays the versions of all tools included in the specified Docker image tag. This is helpful for debugging and ensuring compatibility. ```bash TAG=latest docker run --rm --entrypoint cat ghcr.io/antonbabenko/pre-commit-terraform:$TAG /usr/bin/tools_versions_info ``` -------------------------------- ### Run Pre-commit Hooks on All Files Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Executes the pre-commit hooks on all files within the repository. This is useful for a full code quality check. ```bash pre-commit run -a ``` -------------------------------- ### Run Docker with .netrc Mount for Private Repos Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Execute the pre-commit-terraform Docker container, mounting your `~/.netrc` file into the container at `/root/.netrc`. This allows authenticated access to private GitHub repositories. ```bash # run pre-commit-terraform with docker # adding volume for .netrc file # .netrc needs to be in /root/ dir docker run --rm -e "USERID=$(id -u):$(id -g)" -v ~/.netrc:/root/.netrc -v $(pwd):/lint -w /lint ghcr.io/antonbabenko/pre-commit-terraform:latest run -a ``` -------------------------------- ### Ignore Specific Warnings in Trivy Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Ignore specific warnings in Trivy by adding comments in the format '#trivy:ignore:' directly in your HCL code. This example ignores AVD-AWS-0107 and AVD-AWS-0124. ```hcl #trivy:ignore:AVD-AWS-0107 #trivy:ignore:AVD-AWS-0124 resource "aws_security_group_rule" "my-rule" { type = "ingress" cidr_blocks = ["0.0.0.0/0"] } ``` -------------------------------- ### Get Current Directory Owner IDs Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use `ls -aldn .` to inspect the owner user ID and group ID of the current directory. These IDs are used to configure the USERID environment variable for Docker. ```bash $ ls -aldn . drwxr-xr-x 9 1000 1000 4096 Sep 1 16:23 . ``` -------------------------------- ### Migrate to terraform-docs markers Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use this bash command to update existing documentation markers to the standard terraform-docs format. ```bash sed --version &> /dev/null && SED_CMD=(sed -i) || SED_CMD=(sed -i '') grep -rl --null 'BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK' . | xargs -0 "${SED_CMD[@]}" -e 's/BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK/BEGIN_TF_DOCS/' grep -rl --null 'END OF PRE-COMMIT-TERRAFORM DOCS HOOK' . | xargs -0 "${SED_CMD[@]}" -e 's/END OF PRE-COMMIT-TERRAFORM DOCS HOOK/END_TF_DOCS/' ``` -------------------------------- ### Custom Terraform/OpenTofu Binary Path Configuration Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Configure the path to the Terraform or OpenTofu binary. This can be set per-hook, via an environment variable (`PCT_TFPATH` or `TERRAGRUNT_TFPATH`), or by relying on `$PATH` discovery. ```yaml # Option 1: per-hook (highest precedence) - id: terraform_validate args: - --hook-config=--tf-path=/usr/local/bin/tofu # Option 2: environment variable (applies to all hooks in the session) # export PCT_TFPATH=/usr/local/bin/tofu # pre-commit run -a # Option 3: Terragrunt-aware env var # export TERRAGRUNT_TFPATH=/usr/local/bin/tofu ``` -------------------------------- ### Build Docker Image with GitHub Token Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Builds a Docker image and authenticates GitHub API calls for resolving release URLs by setting the GITHUB_TOKEN environment variable. ```bash docker build -t pre-commit-terraform --build-arg GITHUB_TOKEN . ``` -------------------------------- ### Delegate Directory Switching to tflint Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Delegate directory switching to the tflint binary to allow it to determine full paths for error messages. This requires tflint version 0.44.0 or higher. ```yaml - id: terraform_tflint args: - --hook-config=--delegate-chdir ``` -------------------------------- ### Configure Parallelism for CI CPU Cores Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md This configuration option, `--parallelism-ci-cpu-cores=N`, is intended for specific edge cases and is generally ignored. It's used in conjunction with CI environments to manage CPU core usage. ```yaml args: - --hook-config=--parallelism-ci-cpu-cores=N ``` -------------------------------- ### Docker usage for Infracost API key Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md When using Infracost with Docker, provide the Infracost API key as an environment variable. ```bash docker run -e INFRACOST_API_KEY= ... ``` -------------------------------- ### Use Git Working Directory Placeholder in Arguments Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Employ the `__GIT_WORKING_DIR__` placeholder in your `--args` to reference files relative to the Git repository root. This is useful for sharing configuration files across multiple Terraform directories. ```yaml - id: terraform_tflint args: - --args=--config=__GIT_WORKING_DIR__/.tflint.hcl ``` -------------------------------- ### Use terraform-docs config file Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Configure the terraform_docs hook to use an external terraform-docs configuration file. ```yaml - id: terraform_docs args: - --args=--config=.terraform-docs.yml ``` -------------------------------- ### Pass terraform-docs arguments Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Pass custom arguments directly to the terraform-docs command, such as output mode. ```yaml - id: terraform_docs args: - --args=--output-mode=replace ``` -------------------------------- ### Configure terraform_docs Hook Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Configure the terraform_docs hook to auto-generate module documentation. It wraps terraform-docs and supports custom output paths, auto-creation of README files, and arbitrary terraform-docs arguments via --args. ```yaml - id: terraform_docs args: # Hook-level config - --hook-config=--path-to-file=README.md # target file (default: README.md) - --hook-config=--add-to-existing-file=true # append markers if file exists but has none - --hook-config=--create-file-if-not-exist=true # create README.md if absent # terraform-docs arguments - --args=--config=.terraform-docs.yml # use a terraform-docs config file - --args=--output-mode=replace # replace entire file instead of inject # Example .terraform-docs.yml # formatter: "markdown table" # output: # file: "README.md" # mode: inject # sort: # enabled: true # by: required ``` -------------------------------- ### Run Docker Container with User Permissions Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Execute the Docker container, ensuring file permissions match your local user. This command sets the USERID environment variable to your current user and group IDs. ```bash TAG=latest docker run -e "USERID=$(id -u):$(id -g)" -v $(pwd):/lint -w /lint ghcr.io/antonbabenko/pre-commit-terraform:$TAG run -a ``` -------------------------------- ### Run a Single Pre-Commit Terraform Hook Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Use this command to run only a specific hook, such as 'terraform_validate', for faster iteration during development. It applies to all files. ```bash pre-commit run terraform_validate --all-files ``` -------------------------------- ### Configure terraform_fmt Hook Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Configure the terraform_fmt hook to reformat Terraform files. Supports standard terraform fmt flags like --no-color, --diff, and --write=false for dry-runs. ```yaml # .pre-commit-config.yaml - id: terraform_fmt args: - --args=-no-color # suppress ANSI colors - --args=-diff # show diff instead of silently rewriting - --args=-write=false # dry-run: report, don't modify ``` -------------------------------- ### Configure terraform_docs hook Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Configure the terraform_docs pre-commit hook with various options for documentation generation, including file paths, marker usage, and custom headers. ```yaml - id: terraform_docs args: - --hook-config=--path-to-file=README.md # Valid UNIX path. I.e. ../TFDOC.md or docs/README.md etc. - --hook-config=--add-to-existing-file=true # Boolean. true or false - --hook-config=--create-file-if-not-exist=true # Boolean. true or false - --hook-config=--use-standard-markers=true # Boolean. Defaults to true (v1.93+), false ( # String. # Set to use custom marker which helps you with using other formats like asciidoc. # For Asciidoc this could be "--hook-config=--custom-marker-begin=// BEGIN_TF_DOCS" - --hook-config=--custom-marker-end= # String. # Set to use custom marker which helps you with using other formats like asciidoc. # For Asciidoc this could be "--hook-config=--custom-marker-end=// END_TF_DOCS" - --hook-config=--custom-doc-header="# " # String. Defaults to "# " # Set to use custom marker which helps you with using other formats like asciidoc. # For Asciidoc this could be "--hook-config=--custom-marker-end=\ = " ``` -------------------------------- ### Generate Terraform Module Wrappers with for_each Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use `terraform_wrapper_module_for_each` to generate module wrappers for Terraform modules, especially useful for Terragrunt where `for_each` is not directly supported. Customize processing directories and repository details. ```yaml - id: terraform_wrapper_module_for_each args: - --args=--module-dir=. # Process only root module - --args=--dry-run # No files will be created/updated - --args=--verbose # Verbose output ``` ```yaml - id: terraform_wrapper_module_for_each args: - '--args=--module-repo-shortname=ec2-instance' ``` -------------------------------- ### Generate Terraform Module Wrappers for for_each Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt This hook generates Terraform `for_each` wrapper modules, which is useful for Terragrunt stacks. It reads module variables and outputs using `hcledit` and writes necessary files (`main.tf`, `variables.tf`, etc.) into a `wrappers/` directory. Use `--dry-run` to preview changes. ```yaml - id: terraform_wrapper_module_for_each args: - --args=--module-dir=. # generate wrapper for root module only - --args=--module-repo-org=terraform-aws-modules - --args=--module-repo-shortname=s3-bucket - --args=--module-repo-provider=aws - --args=--dry-run # preview without writing files - --args=--verbose # show temp file content ``` -------------------------------- ### Generate Aliased Providers for Terraform Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use this script with terraform-config-inspect and jq to generate a providers file for aliased providers. Save the output to 'aliased-providers.tf.json'. ```bash terraform-config-inspect --json . | jq -r \ '([.required_providers[].aliases] \ | flatten \ | del(.[] | select(. == null)) \ | reduce .[] as $entry ( \ {}; \ .provider[$entry.name] //= [] | .provider[$entry.name] += [{"alias": $entry.alias}]) \ )' | tee aliased-providers.tf.json ``` -------------------------------- ### Estimate Cloud Costs with Infracost Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt This hook runs Infracost to estimate cloud costs based on Terraform configurations and applies cost gates using jq expressions. It triggers once per run, regardless of changed files, and can be configured to always show the cost summary. ```yaml - id: infracost_breakdown args: - --args=--path=./env/dev - --args=--terraform-var-file=terraform.tfvars # Cost gate expressions (jq syntax against infracost JSON output) - --hook-config='.totalMonthlyCost|tonumber < 500' - --hook-config='.projects[].diff.totalMonthlyCost|tonumber != 10000' - --hook-config='.currency == "USD"' verbose: true # always print cost summary, even on pass ``` -------------------------------- ### Run Trivy Security Scan on Terraform Files Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt This hook runs Trivy to scan Terraform configuration files for security vulnerabilities. It supports custom output formats and directory exclusions. Configure specific files or directories to scan using the `files` argument. ```yaml - id: terraform_trivy files: ^prod-infra/ # only scan the prod-infra/ subdirectory args: - --args=--format=json - --args=--skip-dirs="**/.terraform" - --args=--severity=HIGH,CRITICAL ``` -------------------------------- ### Configure terraform_fmt hook with custom arguments Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Configure the terraform_fmt pre-commit hook to accept custom flags for formatting, such as disabling color, showing diffs, or controlling write behavior. ```yaml - id: terraform_fmt args: - --args=-no-color - --args=-diff - --args=-write=false ``` -------------------------------- ### Infracost breakdown hook with multiple terraform-var-files Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Configure the infracost_breakdown hook to use multiple terraform variable files. Note that spaces are not allowed in '--args', requiring splitting. ```yaml - id: infracost_breakdown args: - --args=--path=./env/dev - --args=--terraform-var-file="terraform.tfvars" - --args=--terraform-var-file="../terraform.tfvars" ``` -------------------------------- ### Debugging and Logging for pre-commit-terraform Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Control the logging level and output color for pre-commit runs. Set `PCT_LOG=trace` for detailed trace logging of all hooks, or `PRE_COMMIT_COLOR=never` to disable color output. ```bash # Enable full trace logging for all hooks PCT_LOG=trace pre-commit run -a # Disable color output PRE_COMMIT_COLOR=never pre-commit run -a ``` -------------------------------- ### Custom Script to Remove .terraform Directories Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md A bash script to find and remove all .terraform directories within a repository. This is an alternative to the --retry-once-with-cleanup flag but should not be used with Terraform workspaces. ```bash echo " function rm_terraform { find . \( -iname ".terraform*" ! -iname ".terraform-docs*" \) -print0 | xargs -0 rm -r } " # Reload shell and use `rm_terraform` command in the repo root ``` -------------------------------- ### Configure terraform_validate Hook Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Configure the terraform_validate hook to validate Terraform configurations. It automatically runs 'terraform init -backend=false' if needed and can retry with cleanup on errors. Use --tf-init-args to pass flags to terraform init and --hook-config for hook-specific settings. ```yaml - id: terraform_validate args: - --args=-json # machine-readable output - --args=-no-color - --tf-init-args=-upgrade # pass -upgrade to terraform init - --tf-init-args=-lockfile=readonly # keep lockfile unchanged during init - --hook-config=--retry-once-with-cleanup=true # auto-recover broken .terraform dirs (requires jq) - --env-vars=AWS_DEFAULT_REGION="us-east-1" - --env-vars=AWS_PROFILE="my-profile" ``` -------------------------------- ### Generate HCL files with terraform_docs Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use the terraform_docs hook to generate HCL files, specifying output file and arguments. ```yaml - id: terraform_docs args: - tfvars hcl --output-file terraform.tfvars.model . ``` -------------------------------- ### Set Trace Log Level for Pre-commit Hooks Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Enable detailed logging for debugging purposes by setting the `PCT_LOG` environment variable to `trace`. This is useful for diagnosing issues with hook execution. ```bash PCT_LOG=trace pre-commit run -a ``` -------------------------------- ### Perform Policy-as-Code Scan with Checkov Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt This hook uses Checkov to perform policy-as-code scans on Terraform configurations. It supports various Checkov CLI flags through the `args` parameter, such as skipping specific checks or setting the output framework. ```yaml - id: terraform_checkov args: - --args=--quiet - --args=--skip-check=CKV2_AWS_8,CKV_AWS_20 - --args=--framework=terraform - --args=--output=json ``` -------------------------------- ### Pass Logging and Color Flags to Pre-Commit Terraform Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Combine logging and color flags when running a pre-commit hook like 'terraform_docs'. 'PCT_LOG=trace' sets the logging level to trace, and 'PRE_COMMIT_COLOR=never' disables colorized output. ```bash PCT_LOG=trace PRE_COMMIT_COLOR=never pre-commit run terraform_docs -a ``` -------------------------------- ### Infracost breakdown hook for cost estimation Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md This hook executes 'infracost breakdown' to estimate costs. It supports all 'infracost breakdown' arguments. Set 'verbose: true' to always show costs. ```yaml - id: infracost_breakdown args: - --args=--path=./env/dev verbose: true ``` -------------------------------- ### Configure Pre-commit Hook for Terraform Providers Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Integrate the generated provider script as a local pre-commit hook. This hook runs before other Terraform hooks and is triggered by .tf or .tfvars files. ```yaml - repo: local hooks: - id: generate-terraform-providers name: generate-terraform-providers require_serial: true entry: .generate-providers.sh language: script files: \.tf(vars)?$ pass_filenames: false - repo: https://github.com/pre-commit/pre-commit-hooks ``` -------------------------------- ### Configure terraform_checkov with custom arguments Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use this configuration to run the terraform_checkov hook with custom arguments, such as skipping specific checks. The hook runs recursively. ```yaml - id: terraform_checkov args: - --args=--quiet - --args=--skip-check CKV2_AWS_8 ``` -------------------------------- ### Set Environment Variables for Hooks at Runtime Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Specify environment variables to be passed to a hook during its execution. Variable values are exported verbatim, and enclosing double quotes are removed. ```yaml - id: terraform_validate args: - --env-vars=AWS_DEFAULT_REGION="us-west-2" - --env-vars=AWS_PROFILE="my-aws-cli-profile" ``` -------------------------------- ### Configure Terrascan with Custom Arguments Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Configure `terrascan` to use custom arguments for scanning, such as disabling recursive scans or specifying policy types. The `--args=--verbose` parameter shows rule IDs, and `--skip-rules` can be used to ignore specific rules. ```yaml - id: terrascan args: - --args=--non-recursive # avoids scan errors on subdirectories without Terraform config files - --args=--policy-type=azure ``` ```yaml - id: terrascan args: - --args=--verbose # Useful to skip validations. ``` ```yaml - id: terrascan args: - --args=--skip-rules="ruleID1,ruleID2" ``` -------------------------------- ### Pass Custom Arguments to terraform init Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Configure terraform_validate to pass custom arguments to the terraform init command, such as -upgrade or -lockfile=readonly. ```yaml - id: terraform_validate args: - --tf-init-args=-upgrade - --tf-init-args=-lockfile=readonly ``` -------------------------------- ### Configure terraform_tflint Hook Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Configure the terraform_tflint hook to lint Terraform code with TFLint. It supports module inspection, rule enabling/disabling, and delegate-chdir mode. Use --args for TFLint flags and --hook-config for hook-specific settings like parallelism. ```yaml - id: terraform_tflint args: - --args=--module # enable module inspection - --args=--enable-rule=terraform_documented_variables - --args=--config=__GIT_WORKING_DIR__/.tflint.hcl # repo-root-relative config - --hook-config=--delegate-chdir # tflint manages chdir (requires tflint >= 0.44) - --hook-config=--parallelism-limit=4 # cap parallel dirs ``` -------------------------------- ### Terraform Providers Lock: Regenerate Lockfile if Platform Missed Mode Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md This mode ensures the lockfile has checksums for all requested platforms. If any are missing, it attempts to add them. This may fail if 'terraform init' has not been run. ```yaml - id: terraform_providers_lock args: - --hook-config=--mode=regenerate-lockfile-if-some-platform-missed ``` -------------------------------- ### Configure deprecated checkov hook Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md This configuration is for the deprecated checkov hook. Arguments must be specified separately. ```yaml - id: checkov args: [ "-d", ".", "--skip-check", "CKV2_AWS_8", ] ``` -------------------------------- ### Docker usage to skip Infracost update check Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Set the INFRACOST_SKIP_UPDATE_CHECK environment variable to true when using Infracost with Docker in CI/CD pipelines to skip update checks. ```bash docker run -e INFRACOST_SKIP_UPDATE_CHECK=true ... ``` -------------------------------- ### Environment Variables Expansion in Arguments Source: https://context7.com/antonbabenko/pre-commit-terraform/llms.txt Hooks expand `${ENV_VAR}` syntax within the `--args` parameter. Ensure environment variables are exported before running pre-commit. Note that `$ENV_VAR` without braces is not expanded. ```yaml # export CONFIG_NAME=.tflint # export CONFIG_EXT=hcl - id: terraform_tflint args: - --args=--config=${CONFIG_NAME}.${CONFIG_EXT} - --args=--call-module-type="all" # Expands to: tflint --config=.tflint.hcl --call-module-type="all" ``` -------------------------------- ### Configure terraform_tflint with Custom Arguments Source: https://github.com/antonbabenko/pre-commit-terraform/blob/master/README.md Use custom arguments with terraform_tflint to enable module inspection or specific rule sets. This allows for more granular control over linting. ```yaml - id: terraform_tflint args: - --args=--module - --args=--enable-rule=terraform_documented_variables ```