Configuring pre-commit hooks for Terraform to ensure smooth module upgrades
This guide explains how to configure pre-commit hooks for Terraform projects, why these hooks are important, and best practices for managing Terraform lock files and modules.
Why Use Pre-commit Hooks?
Pre-commit hooks help automate checks and enforce consistency before code is committed. In the context of Terraform, they:
- Ensure lock files are up-to-date and compatible with supported architectures.
- Help avoid issues related to provider and module versions.
How to Configure Pre-commit
-
Install pre-commit (if not already installed):
pip install pre-commit -
Install the hooks: From the root of your repository, run:
pre-commit install --install-hooks -
Configure the hooks: In the
dxrepository are defined two hooks for terraform:lock_modules: Locks Terraform Registry modules and maintains hashes.terraform_providers_lock_staged: Ensures provider lock files are consistent and compatible with all supported platforms (Windows, macOS, Linux, ARM).
Example configuration in
.pre-commit-config.yaml:- repo: https://github.com/pagopa/dxrev: pre_commit_scripts@0.1.0hooks:# Ensures provider lock files are compatible with all supported architectures- id: terraform_providers_lock_staged# Locks Terraform Registry modules and maintains hashes- id: lock_modulesexclude: ^.*/(_modules|modules|\.terraform)(/.*)?$files: infra/(github_runner|identity/dev|repository|resources/dev)- repo: https://github.com/antonbabenko/pre-commit-terraformrev: v1.102.0hooks:# Format all Terraform files according to the standard style- id: terraform_fmt# Auto-generate README.md in local modules- id: terraform_docsname: terraform_docs on modulesargs:- --hook-config=--create-file-if-not-exist=true- --args=--hide providers- --args=--lockfile=falsefiles: ^infra/(?:.*/)?_?modules/.*# Auto-generate README.md for root modules (resources)- id: terraform_docsname: terraform_docs on resourcesargs:- --hook-config=--create-file-if-not-exist=trueexclude: |(?x)^(infra/modules/.*?|infra\/(?:.*\/)_?modules\/.*|providers\/.*)$# Lint Terraform code for best practices- id: terraform_tflintargs:# Versions are managed per-resource, not globally- --args=--disable-rule terraform_required_version# Providers are context-dependent- --args=--disable-rule terraform_required_providers- --args=--config=__GIT_WORKING_DIR__/.tflint.hclexclude: ^providers/.*# Validate Terraform syntax and configuration- id: terraform_validateargs:- --args=-json- --args=-no-color- --hook-config=--retry-once-with-cleanup=trueexclude: ^providers/.*|.*/examples?(/|$)# Security scan for vulnerabilities in Terraform- id: terraform_trivyargs:- --args=--skip-dirs="**/.terraform"- --args=--skip-dirs="**/tests/apps/network_access"- --args=--ignorefile=__GIT_WORKING_DIR__/.trivyignore- --args=--tf-exclude-downloaded-modules# Limit parallelism to avoid race condition errors- --hook-config=--parallelism-limit=1Note: These hooks are designed to avoid issues with lock files that are not compatible with all architectures. Do not manually delete or edit
.terraform.lock.hclfiles if is not necessary.
Best Practices
-
Do not delete lock files: Lock files ensure consistent provider versions across all environments. Deleting them can cause version mismatches and break deployments.
-
When updating modules: If you change a module version or source, run:
terraform init -upgradeThis will update the modules and lock files as needed.
-
Do not manually edit lock files: Always let Terraform and the pre-commit hooks manage them.
Troubleshooting
If you encounter issues with the pre-commit hooks or Terraform lock files:
-
Clean the Terraform cache:
rm -rf .terraformterraform init -
Re-run the provider lock (if needed):
terraform providers lock \-platform=windows_amd64 \-platform=darwin_amd64 \-platform=darwin_arm64 \-platform=linux_amd64This command is also used by the pre-commit hook to ensure compatibility across all platforms.
For support with pre-commit hooks or Registry modules, visit our support page.