Collection of git hooks for Terraform to be used with pre-commit framework
pre-commit
terraform-docs
required forterraform_docs
hooks.GNU awk
is required if usingterraform-docs
older than 0.8.0 with Terraform 0.12.TFLint
required forterraform_tflint
hook.TFSec
required forterraform_tfsec
hook.coreutils
required forterraform_validate
hook on macOS (due to use ofrealpath
).checkov
required forcheckov
hook.
brew tap liamg/tfsec
brew install pre-commit gawk terraform-docs tflint tfsec coreutils
sudo apt install python3-pip gawk &&\
pip3 install pre-commit
curl -L "$(curl -s https://api.github.com/repos/terraform-docs/terraform-docs/releases/latest | grep -o -E "https://.+?-linux-amd64")" > terraform-docs && 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 "https://.+?_linux_amd64.zip")" > tflint.zip && unzip tflint.zip && rm tflint.zip && sudo mv tflint /usr/bin/
env GO111MODULE=on go get -u github.com/liamg/tfsec/cmd/tfsec
DIR=~/.git-template
git config --global init.templateDir ${DIR}
pre-commit init-templatedir -t pre-commit ${DIR}
Step into the repository you want to have the pre-commit hooks installed and run:
git init
cat <<EOF > .pre-commit-config.yaml
repos:
- repo: git://github.com/antonbabenko/pre-commit-terraform
rev: <VERSION> # Get the latest from: https://github.com/antonbabenko/pre-commit-terraform/releases
hooks:
- id: terraform_fmt
- id: terraform_docs
EOF
After pre-commit hook has been installed you can run it manually on all files in the repository
pre-commit run -a
There are several pre-commit hooks to keep Terraform configurations (both *.tf
and *.tfvars
) and Terragrunt configurations (*.hcl
) in a good shape:
Hook name | Description |
---|---|
terraform_fmt |
Rewrites all Terraform configuration files to a canonical format. |
terraform_validate |
Validates all Terraform configuration files. |
terraform_docs |
Inserts input and output documentation into README.md . Recommended. |
terraform_docs_without_aggregate_type_defaults |
Inserts input and output documentation into README.md without aggregate type defaults. |
terraform_docs_replace |
Runs terraform-docs and pipes the output directly to README.md |
terraform_tflint |
Validates all Terraform configuration files with TFLint. |
terragrunt_fmt |
Rewrites all Terragrunt configuration files (*.hcl ) to a canonical format. |
terragrunt_validate |
Validates all Terragrunt configuration files (*.hcl ) |
terraform_tfsec |
TFSec static analysis of terraform templates to spot potential security issues. |
checkov |
checkov static analysis of terraform templates to spot potential security issues. |
Check the source file to know arguments used for each hook.
terraform_docs
andterraform_docs_without_aggregate_type_defaults
will insert/update documentation generated by terraform-docs framed by markers:
<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
if they are present in README.md
.
-
terraform_docs_replace
replaces the entire README.md rather than doing string replacement between markers. Put your additional documentation at the top of yourmain.tf
for it to be pulled in. The optional--dest
argument lets you change the name of the file that gets created/modified.- Example:
hooks: - id: terraform_docs_replace args: ['--with-aggregate-type-defaults', '--sort-inputs-by-required', '--dest=TEST.md']
-
It is possible to pass additional arguments to shell scripts when using
terraform_docs
andterraform_docs_without_aggregate_type_defaults
. Send pull-request with the new hook if there is something missing.
-
terraform_tflint
supports custom arguments so you can enable module inspection, deep check mode etc.- Example:
hooks: - id: terraform_tflint args: ['--args=--deep']
In order to pass multiple args, try the following:
- id: terraform_tflint args: - '--args=--deep' - '--args=--enable-rule=terraform_documented_variables'
-
When you have multiple directories and want to run
tflint
in all of them and share single config file it is impractical to hard-code the path to.tflint.hcl
file. The solution is to use__GIT_WORKING_DIR__
placeholder which will be replaced byterraform_tflint
hooks with Git working directory (repo root) at run time. For example:hooks: - id: terraform_tflint args: - '--args=--config=__GIT_WORKING_DIR__/.tflint.hcl'
-
terraform_tfsec
will consume modified files that pre-commit passes to it, so you can perform whitelisting of directories or files to run against via files pre-commit flag- Example:
hooks: - id: terraform_tfsec files: ^prd-infra/
The above will tell pre-commit to pass down files from the
prd-infra/
folder only such that the underlyingtfsec
tool can run against changed files in this directory, ignoring any other folders at the root level -
To ignore specific warnings, follow the convention from the documentation.
- Example:
resource "aws_security_group_rule" "my-rule" { type = "ingress" cidr_blocks = ["0.0.0.0/0"] #tfsec:ignore:AWS006 }
-
terraform_validate
supports custom arguments so you can pass supported no-color or json flags.- Example:
hooks: - id: terraform_validate args: ['--args=-json']
In order to pass multiple args, try the following:
- id: terraform_validate args: - '--args=-json' - '--args=-no-color'
-
terraform_validate
also supports custom environment variables passed to the pre-commit runtime- Example:
hooks: - id: terraform_validate args: ['--envs=AWS_DEFAULT_REGION="us-west-2"']
In order to pass multiple args, try the following:
- id: terraform_validate args: - '--envs=AWS_DEFAULT_REGION="us-west-2"' - '--envs=AWS_ACCESS_KEY_ID="anaccesskey"' - '--envs=AWS_SECRET_ACCESS_KEY="asecretkey"'
- Python hooks are supported now too. All you have to do is:
- add a line to the
console_scripts
array inentry_points
insetup.py
- Put your python script in the
pre_commit_hooks
folder
- add a line to the
Enjoy the clean and documented code!
This repository is managed by Anton Babenko with help from these awesome contributors.
MIT licensed. See LICENSE for full details.