This directory contains sample YAML configurations, Terraform fixtures, runnable behaviour scenarios, and maintained automation scripts.
Version numbers in these files demonstrate syntax only. They are not recommendations and may not be current releases of the referenced modules or providers.
| File | Demonstrates |
|---|---|
config-basic.yml |
A small batch of module updates |
config-advanced.yml |
Public and private registry modules and submodules |
config-multiple-from.yml |
Exact current-version allow-lists |
config-with-ignore.yml |
Module block-name exclusions |
config-terraform-providers.yml |
Terraform, provider, and module updates together |
config-production.yml |
A larger illustrative module batch |
Preview any config from the repository root:
go run . -pattern "examples/*.tf" -config examples/config-basic.yml -dry-runThe sample Terraform files do not contain every source listed by every config, so a preview can legitimately report fewer updates than the config contains.
For the YAML contract and filter precedence, see the configuration reference.
Validate the runtime YAML contract before selecting any Terraform files:
tf-version-bump -validate-config versions.ymlPreview the human-readable changes without writing:
tf-version-bump -pattern "**/*.tf" -config versions.yml -dry-runFor a CI or pre-commit gate, use -check. Status 0 means no eligible version value would change, status 2 means updates are required, and status 1 means validation or processing failed:
if tf-version-bump -pattern "**/*.tf" -config versions.yml -check; then
echo "No eligible Terraform version updates found"
else
check_status=$?
if [ "$check_status" -eq 2 ]; then
echo "Terraform version updates are required"
else
exit "$check_status"
fi
fiStatus 0 does not prove that every configured target exists or was eligible. Ignored or unmatched modules and matching modules skipped for a missing version can also produce no eligible update.
Install the maintained hook when the repository keeps its update configuration at versions.yml:
cp examples/pre-commit-hook.sh .git/hooks/pre-commit
chmod 755 .git/hooks/pre-commitThe hook materialises the staged Git index in a temporary directory, runs standalone configuration validation there, then uses -check without modifying either staged or worktree files. This means a partial commit is checked against the exact content Git will commit, not unrelated unstaged edits. It exits 0 when no eligible values would change, 2 when updates are required, and 1 when validation or processing fails. Git blocks a commit for either non-zero status while keeping the distinction visible to people and wrapper automation.
Use environment overrides when the repository uses different paths or an explicitly installed binary:
TF_VERSION_BUMP_CONFIG=.github/tf-version-bump/versions.yml \
TF_VERSION_BUMP_PATTERN='infrastructure/**/*.tf' \
TF_VERSION_BUMP_BIN=/usr/local/bin/tf-version-bump \
.git/hooks/pre-commitRun examples/pre-commit-hook.sh --help for the complete override reference. Environment variables must be available to the process that invokes Git; alternatively, set them in a small repository-specific wrapper around the maintained hook.
Apply the updates and write exact block counts independently of the human-readable summary:
tf-version-bump \
-pattern "**/*.tf" \
-config versions.yml \
-report-file update-report.json
jq '{terraform_blocks_updated, module_blocks_updated, provider_blocks_updated}' \
update-report.jsonThe report is schema version 2. It counts changed Terraform, module, and provider blocks, not files. Check the exit status before reading it: a run that changed files and then failed removes the file rather than leaving the previous run's counts in place, so jq on a missing file is the signal that the run did not finish. Dry-run reports contain zero counts because no updates were applied. Check mode rejects -report-file so it remains entirely write-free.
scenarios/force-add demonstrates the default warning for a registry module without version, followed by the same config with -force-add. scenarios/idempotency updates Terraform, provider, and module versions, then proves that applying the same config again leaves both bytes and modification time unchanged. scenarios/provider-targeting updates one existing provider constraint while preserving an unrelated provider and a targeted attribute-style provider without a version. The module-only -force-add flag does not add provider version attributes. scenarios/same-source-ranges uses two entries for the same module source to move a 5.x range and a 4.x range separately, excluding one module by name from the 4.x move and leaving a block that matches neither range alone, then proves that a second run changes nothing.
Run all scenarios against a temporary copy of their fixtures:
examples/run-scenarios.shThe runner builds the current source once, never changes the checked-in fixtures, and removes its temporary workspace when it exits.
| File | Purpose |
|---|---|
main.tf |
Basic modules and resources |
modules.tf |
Additional module examples |
complex.tf |
More involved HCL structures |
heavily_commented.tf |
Comment retention |
unusual_formatting.tf |
Formatting behaviour when a file is rewritten |
Copy fixtures to a temporary directory before running without -dry-run if you want to preserve the checked-in examples.
update-branches.sh applies one module update or YAML config across Git branches, creating a commit on each branch without pushing it. Pass --sign-commits to ask Git to sign each update commit with its configured signing key. Without the flag, the script does not request signing, which allows it to run in CI without access to a signing key.
Start with its help and a dry run:
examples/update-branches.sh --help
examples/update-branches.sh \
--repository /path/to/terraform-repository \
--branch-pattern 'release/*' \
--module 'terraform-aws-modules/vpc/aws' \
--to '5.0.0' \
--dry-runThe script refuses dirty worktrees, restores the starting branch after successful runs, can fetch remote-only branches, and never pushes. See Advanced usage before using write mode.
Contributors can run its end-to-end checks with:
examples/update-branches_test.shThe checks require ssh-keygen, build and exercise the real tf-version-bump binary in temporary Git repositories, and create an ephemeral signing key. They do not contact a remote service.
github-actions is a copyable GitHub Actions example that updates Terraform state branches on a schedule, opens a pull request for each changed branch, and reports every branch's versions against its config. Contributors can run its local harness, which uses Docker, with make test-github-actions. See Advanced usage for an overview.