Skip to content

Latest commit

 

History

History
148 lines (102 loc) · 7.58 KB

README.md

File metadata and controls

148 lines (102 loc) · 7.58 KB

Examples

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.

YAML configurations

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-run

The 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.

Automation cookbook

Validate the runtime YAML contract before selecting any Terraform files:

tf-version-bump -validate-config versions.yml

Preview the human-readable changes without writing:

tf-version-bump -pattern "**/*.tf" -config versions.yml -dry-run

For 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
fi

Status 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.

Pre-commit hook

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-commit

The 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-commit

Run 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.json

The 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.

Runnable scenarios

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.sh

The runner builds the current source once, never changes the checked-in fixtures, and removes its temporary workspace when it exits.

Terraform files

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.

Branch automation

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-run

The 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.sh

The 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 automation

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.