Skip to main content

pre-commit

pre-commit is a framework that runs checks on the files of a commit before Git records it. Every Azure repository ships a .pre-commit-config.yaml, so the formatting, scanning and layout checks CI will run fail on the engineer's machine first.

What it does​

pre-commit install adds a Git hook; on each commit the framework runs the hooks listed in .pre-commit-config.yaml against the staged files that match each hook's pattern. Hooks come from remote repositories pinned by tag or from local scripts in the repository. pre-commit run --all-files runs every hook on the whole tree. The Baseline pins pre-commit 4.3.0.

How BuiltForProd uses it​

RepositoriesHooks
Azure Enterprise Baseline, web app and ETL infrastructurepre-commit-hooks v6.0.0 (whitespace, end of file, YAML, merge conflicts, private keys); pre-commit-opentofu v2.4.2 (tofu_fmt, tofu_validate, tofu_docs); pre-commit-terraform v1.109.1 (terragrunt_fmt, terraform_tflint, terraform_trivy); Checkov 3.3.19; the local guard scripts
Web app and ETL codepre-commit-hooks v6.0.0 with JSON checks; ruff v0.16.10 (ruff, ruff-format), the same version CI pins; Checkov 3.3.22
Secretscheck-yaml (not on the encrypted stage files), detect-private-key, end-of-file-fixer, and the local sops-encrypted hook

The generated .terragrunt-cache/ and .terragrunt-stack/ folders are excluded from every hook. The sops-encrypted hook refuses any stage file without a sops: block, so a plaintext value cannot be committed by accident; see SOPS.

Guard scripts. Local hooks run Python scripts from scripts/, the same ones the lint-and-scan job of plan.yml runs:

ScriptBlocksRepositories
check-no-hardcoded-cidrs.pyA private address range written in HCL or OpenTofu instead of coming from the address planBaseline
check-vnet-maps.pyAn invalid, overlapping or mis-nested range in either VNet map, or an Azure-reserved subnet nameBaseline
check-mock-outputs.pyA dependency without complete mock outputs, which could not be planned before it existsAll three infrastructure
check-stack-layout.pyA region folder without a stack file, an unreferenced unit definition, a hand-written unit under environments/All three
check-module-versions.pyA module versions.tf that does not repeat the pins of root.hclAll three
check-required-inputs.pyA generated unit that does not supply every required variable of its moduleAll three

The scanners these hooks call are described in Checkov, Trivy and tflint. A hook that a developer skips locally still runs in CI, so pre-commit saves a round trip rather than replacing the gate.

Terms you will see​

TermMeaning
HookOne check pre-commit runs on matching staged files.
Local hookA hook that runs a script from the repository itself.
Guard scriptA scripts/check-*.py that enforces a platform convention.
revThe pinned tag of a remote hook repository.
Address planvnet_map.yaml, the only place address ranges are written.

Where to read more​