Terraform module versioning
This guidance is in preview and subject to change. The versioned approach described here has not been fully agreed yet, although it is the direction we expect to adopt. Check back before making large-scale changes based on it.
Shared Terraform modules are versioned with semantic version Git tags of the
form vMAJOR.MINOR.PATCH (for example v2.0.1).
cpp-module-terraform-azurerm-key-vault
is the reference example of the full pattern — versioned releases, label-driven
release automation, and automated consumer updates.
Consume a pinned version
Reference the module with an explicit ?ref= pointing at a version tag:
module "key_vault" {
source = "git@github.com:hmcts/cpp-module-terraform-azurerm-key-vault.git?ref=v2.0.1"
# ... see the module's variables.tf for the full list of inputs
}
Never point ?ref= at a branch. A branch moves underneath every consumer with
no commit in the consuming repository to show it, and deleting the branch
breaks terraform init for everyone still referencing it. A tag is immutable:
what you plan against today is what you apply tomorrow.
What the versions mean
| Segment | Increments when | Action for consumers |
|---|---|---|
| MAJOR | A backwards-incompatible change: renamed or removed inputs or outputs, or behaviour that forces resource replacement | Review the release notes before upgrading; may need state changes |
| MINOR | New backwards-compatible functionality, such as a new optional input | Safe to adopt |
| PATCH | A backwards-compatible bug fix or maintenance change | Safe to adopt |
Upgrade path
Renovate’s Terraform manager detects new module tags and raises update pull requests, so consumers do not need to watch module repositories. For the key-vault module there is a ready-made preset, cpp-terraform-azurerm-key-vault, which automerges minor and patch updates once CI passes and raises major updates as pull requests for review. See the Renovate guide for how to enable it.
When taking a major update, read the release notes first — a major bump can mean changed inputs or resource replacement, so always review the Terraform plan before applying.
Releasing a module
Module releases are automated with Release Drafter and pull request labels, as described in the release automation section:
- Every pull request must carry one of the standard labels
(
breaking-change,enhancement,bug,dependencies,documentation,chore) — enforced by the label check workflow. - On merge, Release Drafter creates or updates a draft release, resolving the next version from the labels of the merged pull requests.
- Publishing the release creates the
vX.Y.Ztag that consumers pin, and the changelog workflow records it inCHANGELOG.md.
The workflows are reusable — see the GitHub Actions library guide and the key-vault module’s workflow definitions for a working setup to copy.