Terraform Contribution Flow
This guide covers the end-to-end contribution flow for AVM Terraform modules.
Whether you are a module owner or an external contributor, the core workflow is the same — the key differences are called out using tabs below.
Important
This guide MUST be used in conjunction with the Terraform specifications. All AVM modules must meet the requirements described in those specifications.
Overview
---
config:
nodeSpacing: 20
rankSpacing: 20
diagramPadding: 50
padding: 5
flowchart:
wrappingWidth: 300
padding: 5
layout: elk
elk:
mergeEdges: true
nodePlacementStrategy: LINEAR_SEGMENTS
---
flowchart TD
Z("1 - Fork [optional]")
click Z "#1-fork-optional"
A(2 - Branch)
click A "#2-branch"
B(3 - Implement your code change)
click B "#3-implement-your-code-change"
C(4 - Run avm pre-commit)
click C "#4-run-avm-pre-commit"
C2(5 - Run pr-check and e2e tests locally)
click C2 "#5-run-pr-check-and-e2e-tests-locally"
D(6 - Raise or Update PR)
click D "#6-raise-or-update-pr"
E("7 - Approve and monitor CI tests [owner]")
click E "#7-approve-and-monitor-ci-tests"
F{Tests passing?}
G(8 - Review and merge PR)
click G "#8-review-and-merge-pr"
H(9 - Cut a release)
click H "#9-cut-a-release"
Z --> A
A --> B
B --> C
C --> C2
C2 --> D
D --> E
E --> F
F -->|no| B
F -->|yes| G
G --> H
1. Fork [optional]
Note
This step is only needed if you do not have write access to the module repository. Module owners and invited collaborators can skip to step 2.
A fork is your own copy of the repository under your GitHub account. It lets you make changes without needing write access to the upstream repo. Once your changes are ready, you raise a pull request from your fork back to the original repository.
Navigate to the module repository in the
AzureGitHub organization.Click the Fork button in the top right.
Select your GitHub account (or organization) as the destination.
Click Create fork.
Clone your fork locally:
git clone https://github.com/<your-username>/terraform-azurerm-avm-res-<rp>-<modulename>.git cd terraform-azurerm-avm-res-<rp>-<modulename>
Keep your fork in sync with the upstream repository before creating a new branch. You can do this from the GitHub UI by clicking Sync fork on your fork’s main page, or locally:
git remote add upstream https://github.com/Azure/terraform-azurerm-avm-res-<rp>-<modulename>.git
git fetch upstream
git checkout main
git merge upstream/mainUse the GitHub CLI to fork and clone in one step. This automatically configures the upstream remote for you:
gh repo fork Azure/terraform-azurerm-avm-res-<rp>-<modulename> --clone
cd terraform-azurerm-avm-res-<rp>-<modulename>Verify the remotes are set up correctly:
git remote -v
# origin https://github.com/<your-username>/terraform-azurerm-avm-res-<rp>-<modulename>.git (fetch)
# upstream https://github.com/Azure/terraform-azurerm-avm-res-<rp>-<modulename>.git (fetch)2. Branch
Create a branch from main to work on your changes:
git checkout -b <your-branch-name>If this is a new module and the repository does not exist yet, module owners should first follow the Repository Creation Process.
Note
If the module repository does not exist yet, check the Terraform Resource Modules index for the module owner’s contact details (PrimaryModuleOwnerGHHandle column).
3. Implement your code change
Before writing code, review the Terraform specifications and composition guidelines to ensure your contribution complies with AVM’s design principles.
Once you’ve made your changes, stage, commit, and push them:
git add -A
git commit -m "feat: description of your change"
git push4. Run avm pre-commit
Before raising a pull request, run pre-commit to update your files:
./avm pre-commitThis automatically updates your code formatting, fixes styling issues, and regenerates documentation to meet AVM standards. If pre-commit made any changes, commit and push again:
git add -A
git commit -m "chore: pre-commit fixes"
git push5. Run pr-check and e2e tests locally
Before raising a PR (or while iterating on one), you can run the same checks that CI will run:
./avm pr-checkThis runs static analysis and linting locally so you can catch issues before CI does.
Local e2e testing
You can test your examples locally by running Terraform directly in the examples/ folders:
cd examples/default
az login
terraform init
terraform plan
terraform applyUse Azure CLI (az login) to authenticate — no environment variables or service principals are needed for local development.
When you’re done, clean up your resources:
terraform destroyThis is especially useful for external contributors, since only module owners can approve CI e2e test runs.
Terraform test (optional)
We support terraform test for unit and integration testing. Golang tests are not supported.
- Unit tests — place test files in
tests/unit. Use mocked providers to keep them fast and free of external dependencies. Run with./avm tf-test-unit. - Integration tests — place test files in
tests/integration. These deploy real resources and should be run locally. Run with./avm tf-test-integration.
6. Raise or Update PR
Tip
Raise your PR early — don’t wait until everything is perfect. An early PR lets you run pr-check and e2e tests in CI and get feedback sooner. You can continue pushing commits to the same branch.
- Navigate to the upstream repository on GitHub and click New pull request.
- Set the base repository to the upstream AVM repo and base branch to
main. - Set your head repository and compare branch to your fork and branch.
- Click Create pull request.
- Navigate to the repository on GitHub and click New pull request.
- Set the base branch to
mainand the compare branch to your branch. - Click Create pull request.
7. Approve and monitor CI tests
Note
Only module owners can approve CI test runs. External contributors should ensure they have run ./avm pr-check and tested locally before this step.
Once a PR is created, CI workflows are triggered automatically but require a module owner to approve the run. A centrally managed Azure test subscription is provided — no credential configuration is needed.
What CI runs
The pr-check.yml workflow runs two stages:
Linting — static analysis including:
- avmfix — formatting checks.
- terraform-docs — documentation is up to date.
- TFLint — AVM spec compliance.
- Conftest — checks the plan for Well-Architected Framework compliance using Conftest and OPA.
End-to-end tests — deploys and validates all module examples:
- Lists all examples in the
examples/directory. - Tests each example for idempotency (
terraform applythenterraform plan). - Destroys all resources (
terraform destroy).
If tests fail
Go back to step 3 — fix the issue, run ./avm pre-commit again, push your changes, and the CI tests will re-run automatically on the same PR.
Running e2e for external contributions
When approving a PR from an external contributor:
- Review the code for security — check for any malicious code or changes to workflow files before running tests. If found, close the PR and report the contributor.
- Create a release branch from
main(e.g.release/<description>). - Change the PR’s base branch to the release branch and merge it.
- Create a new PR from the release branch to
main— this triggers pr-check and e2e tests. - Approve the run and wait for results.
- If tests fail, send back to the contributor to fix and repeat from step 3.
Running e2e for your own contributions
For your own PRs, the tests trigger automatically — approve the run and wait for results.
8. Review and merge PR
Every PR must be reviewed and approved before merging.
| PR is submitted by a module owner | PR is submitted by anyone, other than the module owner | |
| Module has a single module owner | AVM core team or in case of Terraform only, the owner of another module approves the PR | Module owner approves the PR |
| Module has multiple module owners | Another owner of the module (other than the submitter) approves the PR | One of the owners of the module approves the PR |
- Address any review comments and push updates to your branch.
- Request a re-review once changes are made.
- The module owner will merge the PR once approved and tests pass.
For a brand new module being published for the first time, get the module reviewed by the AVM Core team by following the AVM Review Process before merging.
Owner responsibilities
- Watch PR and issue activity for your module and respond in a timely manner as per SNFR11.
- Familiarize yourself with Team Definitions & RACI and TF Issue Triage.
9. Cut a release
Note
This step is performed by the module owner only.
After the PR is merged to main, create a release via GitHub Releases:
- Go to the Releases tab and click Draft a new release.
- Set Target to the
mainbranch. - Type a new tag (e.g.
v0.1.0for first publish, or increment for subsequent releases). Tags MUST include thevprefix. - Use Generate release notes and credit external contributors.
- Click Publish release.
First module publish
For a brand new module, contact the AVM core team (e.g. via the AVM - Module Triage project) to request initial publication to the HashiCorp Registry. Subsequent releases are published automatically.
Important
Continue publishing in the v0.x.y range (e.g., v0.1.0, v0.1.1, v0.2.0) until the AVM team notifies you that v1.0.0 is allowed.
Common mistakes to avoid
- Search and update
TODOcomments that come from the template — remove them once addressed. - Do not commit
terraform.lock.hcl— it is excluded by.gitignore. - Update
_header.mdandSUPPORT.md. - Do not commit
terraform.tfvarsfiles.