While this page describes and summarizes important aspects of contributing to AVM, it only references some of the shared and language specific requirements.
Therefore, this contribution guide MUST be used in conjunction with the Terraform specifications. ALL AVM modules (Resource and Pattern modules) MUST meet the respective requirements described in these specifications!
Summary
This section lists AVM’s Terraform-specific contribution guidance.
Repository Setup — creating a new module repository (owners only)
Subsections of Terraform Modules
Prerequisites
GitHub Account
To contribute, you need a GitHub account. If you are a Microsoft employee, your account must be linked to your corporate identity and you must be a member of the Azure organization.
Required Tooling
Tip
We recommend Linux, macOS, or Windows Subsystem for Linux (WSL) for your development environment.
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 Azure GitHub 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:
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).
Once you’ve made your changes, stage, commit, and push them:
git add -A
git commit -m "feat: description of your change"git push
4. Run avm pre-commit
Before raising a pull request, run pre-commit to update your files:
Important
You need Docker (or Podman) installed and running.
./avm pre-commit
This 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 push
5. 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-check
This 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 apply
Use 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 destroy
This 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 main and 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 apply then terraform 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.
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 main branch.
Type a new tag (e.g. v0.1.0 for first publish, or increment for subsequent releases). Tags MUST include the v prefix.
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 TODO comments that come from the template — remove them once addressed.
Do not commit terraform.lock.hcl — it is excluded by .gitignore.
Update _header.md and SUPPORT.md.
Do not commit terraform.tfvars files.
Terraform Composition
Important
This guide MUST be used in conjunction with the Terraform specifications. ALL AVM modules (Resource and Pattern modules) MUST meet the respective requirements described in these specifications!
This section is only relevant for contributions to resource modules.
To meet RMFR4 and RMFR5 AVM resource modules must leverage consistent interfaces for all the optional features/extension resources supported by the AVM module primary resource.
To meet the requirements of SFR3 & SFR4, we use the modtm telemetry provider. This lightweight telemetry provider sends telemetry data to Azure Application Insights via a HTTP POST front end service.
The modtm telemetry provider is included in all Terraform modules and is enabled by default through the main.telemetry.tf file being automatically distributed from the template repo. You do not need to change this configuration.
Make sure that the modtm provider is listed under the required_providers section in the module’s terraform.tf file using the following entry. This is also validated by the linter.
The AVM module review is a critical step before an AVM Terraform module gets published to the Terraform Registry and made publicly available for customers, partners and wider community to consume and contribute to. It serves as a quality assurance step to ensure that the AVM Terraform module complies with the Terraform specifications of AVM. The below process outlines the steps that both the module owner and module reviewer need to follow.
The module owner completes the development of the module in their branch or fork.
The module owner submits a pull request (PR) titled AVM-Review-PR and ensures that all checks are passing on that PR as that is a pre-requisite to request a review.
The module owner assigns the avm-core-team-technical-terraform GitHub team as reviewer on the PR.
The module owner leaves the following comment as it is on the module proposal in the AVM - Module Triage project by searching for their module proposal by name there.
➕ AVM Terraform Module Review Request
I have completed my initial development of the module and I would like to request a review of my module before publishing it to the Terraform Registry. The latest code is in a PR titled [AVM-Review-PR](REPLACE WITH URL TO YOUR PR) on the module repo and all checks on that PR are passing.
The AVM team moves the module proposal from “In Development” to “In Review” in the AVM - Module Triage project.
The AVM team will assign a module reviewer who will open a blank issue on the module titled “AVM-Review” and populate it with the below mark down. This template already marks the specs as compliant which are covered by the checks that run on the PR. There are some specs which don’t need to be checked at the time of publishing the module therefore they are marked as NA.
➕ AVM Terraform Module Review Issue
Dear module owner,
As per the module ownership requirements and responsibilities at the time of [assignment](REPLACE WITH THE LINK TO THE AVM MODULE PROPOSAL), the AVM Team is opening this issue, requesting you to validate your module against the below AVM specifications and confirm its compliance.
Please don’t close this issue and merge your AVM-Review-PR until advised to do so. This review is a prerequisite for publishing your module’s v0.1.0 in the Terraform Registry. The AVM team is happy to assist with any questions you might have.
Requested Actions
Complete the below task list by ticking off the tasks.
Complete the below table by updating the Compliant column with Yes, No or NA as possible values.
Please use the comments columns to provide additional details especially if the Compliant column is updated to No or NA.
Tasks
Address comments on AVM-Review-PR if any
Ensure that all checks on AVM-Review-PR are passing
The module reviewer can update the Compliance column for specs in line 42 to 47 to NA, in case the module being reviewed isn’t a pattern module.
The module reviewer reviews the code in the PR and leaves comments to request any necessary updates.
The module reviewer assigns the AVM-Review issue to the module owner and links the AVM-Review Issue to the AVM-Review-PR so that once the module reviewer approves the PR and the module owner merges the AVM-Review-PR, the AMV-Review issue is automatically closed. The module reviews responds to the module owner’s comment on the Module Proposal in AVM Repo with the following
➕ AVM Terraform Module Review Initiation Message
Thank you for requesting a review of your module. The AVM module review process has been initiated, please perform the **Requested Actions** on the AVM-Review issue on the module repo.
The module owner updates the check list and the table in the AVM-Review issue and notifies the module reviewer in a comment.
The module reviewer performs the final review and ensures that all checks in the checklist are complete and the specifications table has been updated with no requirements having compliance as ‘No’.
The module reviewer approves the AVM-Review-PR, and leaves the following comment on the AVM-Review issue with the following comment.
➕ AVM Terraform Module Review Completion Message
Thank you for contributing this module and completing the review process per AVM specs. The AVM-Review-PR has been approved and once you merge it that will close this AVM-Review issue. Please create a release with an initial minor version of `v0.1.0` (tags **MUST** include the `v` prefix) and then contact the AVM core team to publish this module to the HashiCorp Terraform Registry via HCP Terraform. Please continue publishing future versions in the v0.x.y minor range (e.g., `v0.1.0`, `v0.1.1`, `v0.2.0`, etc.) until the AVM team notifies you that publishing `v1.0.0` is allowed.
**Requested Action**: Once the AVM core team has published the module, please update your [module proposal](REPLACE WITH THE LINK TO THE MODULE PROPOSAL) with the following comment.
"The initial review of this module is complete, and the module has been published to the registry by the AVM core team. Requesting AVM team to close this module proposal and mark the module available in the module index.
Terraform Registry Link: <REPLACEWITHTHELINKOFTHEMODULEINTERRAFORMREGISTRY>
GitHub Repo Link: <REPLACEWITHTHELINKOFTHEMODULEINGITHUB>"
Once the module owner perform the requested action in the previous step, the module reviewer updates the module proposal by performing the following steps:
Assign label Status: Module Available :green_circle: to the module proposal.
Update the module index excel file and CSV file by creating a PR to update the module index and links the module proposal as an issue that gets closed once the PR is merged which will move the module proposal from “In Review” to “Done” in the AVM - Module Triage project.
Advanced Topics & FAQ
This page covers advanced scenarios and frequently asked questions that go beyond the standard contribution flow.
Using a custom Azure test subscription
By default, CI end-to-end tests run against a centrally managed Azure subscription. If your module requires a different environment (e.g. due to quota limits or tenant-level deployments), you can override the defaults.
Create a user-assigned managed identity in your target Azure environment.
Create GitHub federated credentials for the managed identity, using the module’s GitHub organization and repository. Select entity type environment and set the name to test.
To override a rule, create one of the following HCL files in the root of your module:
File
Scope
avm.tflint.override.hcl
Root module
avm.tflint_module.override.hcl
Submodules
avm.tflint_example.override.hcl
Examples
Example:
# Disable the required resource id output rule — this is a pattern module.
rule"required_output_rmfr7" {
enabled =false}
Include a comment explaining why the rule is disabled.
Excluding examples from end-to-end testing
Create a file called .e2eignore in the example directory. Its contents should explain why the example is excluded from tests.
Global test setup and teardown
If your module requires setup/teardown across all examples, create:
examples/setup.sh — (optional) — runs before all examples.
examples/teardown.sh (optional) — runs after all examples.
These scripts are authorized with the same credentials as the examples.
Per-example pre and post scripts
For example-specific setup/teardown:
examples/<example_name>/pre.sh (optional) — runs before the example.
examples/<example_name>/post.sh (optional) — runs after the example.
These run in the context of the example directory, so relative paths work.
Repository governance PRs
A weekly workflow checks repository contents creates a PR if new files or updates are available. The PR is automatically merged, so there is no action required. Module owners will be informed if there are any one off PRs that require intervention.
These PRs do not change module code, so no new release is needed.
Eventual consistency
The Azure Resource Manager API can be eventually consistent. For example, data plane role assignments may not be available immediately after creation.
Use the AzAPI provider’s retry functionality to handle eventual consistency instead of arbitrary time_sleep delays. The AzAPI provider supports configurable retry with retry blocks that can match on specific error codes, providing a more reliable and efficient approach.
Repository Creation Process
Important
This page is for module owners only. If you are an external contributor, skip to the contribution flow.
Important
If this process is not followed exactly, it may result in your repository and any in-progress code being permanently deleted.
1. Add yourself to the Module Owners Team and Open Source orgs
If you have already completed these steps, skip to step 2.
Open the Open Source Portal and ensure your GitHub account is linked to your Microsoft account.
Open the Open Source Portal and ensure you are a member of the Azure and Microsoft organizations.
Navigate to Core Identity and request access to the Azure Verified Module Owners Terraform entitlement.
Info
Until your entitlement request is approved, you can contribute by using JIT elevation.
2. Gather repository information
You’ll need the following from the module request issue: