Your first contribution to Azure Verified Modules

If you are using Azure Verified Modules, either the Bicep or Terraform modules, you have likely encountered scenarios where you wished for additional features. This blog is a practical guide to help you make your first contribution to Azure Verified Modules, enabling you to turn those additional features into reality. This blog will focus on the Bicep side of AVM, but can also be used when contributing to the Terraform AVM modules!

What are Azure Verified Modules?

Azure Verified Modules (AVM) is a Microsoft initiative aimed at establishing a benchmark for Infrastructure as Code (IaC) standards mainly for Azure Bicep and Terraform. The modules in this repository adhere to these IaC standards and are maintained by Microsoft’s product groups, while also benefiting from community contributions.

Contributing to AVM

The reason to contribute to Azure Verified Modules typically involves one of the following:

  • Implementing a solution for an identified issue.
  • Fixing a bug in a template.
  • Adding an improvement to the existing modules.

The AVM team has made contributions very easy. When making a contribution, you only need to write Bicep code because everything else is automated (tests, generation of documentation, etc.). For contributing to Bicep modules, the repository used will be bicep-modules-registry: https://github.com/Azure/bicep-registry-modules.

Prerequisites

Before we go to the contributing part there are some things to take into account:

  • A GitHub account is required to contribute to AVM.
  • Have git, Bicep CLI, and the Bicep VSCode extension installed.
  • Be familiar with writing Bicep templates and using git.
  • Review the contribution guidelines at CONTRIBUTING.md.

In the next blog post section, we will look at a GitHub Issue (https://github.com/Azure/bicep-registry-modules/issues/1436) reported by a community member. The issue has a request to improve the virtual machine module to support a custom osDisk and dataDisk name. Letโ€™s start with the implementation!

Step-by-step contribution guide to AVM

There are five stages required to make a contribution to Azure Verified Modules:

  1. Fork and clone the bicep-registry-modules repository.
  2. Implement changes.
  3. Update the documentation.
  4. Run the tests.
  5. Submit the pull request.

Let’s start with step 1. by forking the bicep-registry-modules repository.

1. Fork and clone the bicep-registry-modules repository

A fork is a copy of a repository. Forking a repository allows you to experiment with changes without affecting the original project. Once you have forked the repository, it will appear under your GitHub repositories. This repository can then be cloned locally to implement changes.

You can fork the repository by either visiting the GitHub repository and clicking on the Fork button or by going to the following URL: https://github.com/Azure/bicep-registry-modules/fork.

Azure/bicep-registry-modules repository
johnlokerse/bicep-registry-modules forked from Azure/bicep-registry-modules

2. Implement changes

Now you have isolated the repository from the main repository by forking it, and you have cloned it locally on your computer. In your editor (in this blog, I use Visual Studio Code), open the source control panel, create a branch from main, and give your branch a name.

I normally create a branch with the name of my GitHub username followed by what I am contributing to. For example, in this case, it would be johnlokerse/issue1436.

Creating a branch in Visual Studio Code

When an issue is logged it is required to specify which module has an issue. In this case, the module that has an issue is the avm/res/compute/virtual-machine module. The request is to add the ability to give osDisk and dataDisk a custom name.

In the snippet below you see the virtual machine main.bicep with two user-defined types. I added these types to give the complex object parameters osDisk and dataDisk a strongly typed value and constraints on what properties the object requires and what is optional.

Also, the name property is optional (due to string?), this is because the name is either custom by the user or a default name is used.

User-defined type definition for the disks in virtual-machine/main.bicep

Also below, we added the reference to the user-defined types placed on the corresponding parameter. This parameter will now use the types osDiskType and dataDiskType.

Added the user-defined type for osDisk and dataDisks

In the image below, you see the implementation of the osDisk?.name property. This property is nullable, and not required, so we need to implement a fallback value if the property is null. To handle this, we implemented a coalesce check by using the ?? operator, which returns the first non-null value. So, when osDisk?.name is equal to null, it checks the next value. In this case, it will use the string interpolated value ${name}-disk-os-01.

Coalesce null check for the osDisk name

Now that we have implemented the change we wanted, there is another important step. The next step is to update the test Bicep templates to correspond with the changes you have made. These test templates can be found in the test folder. These tests are important for a later stage of the contribution.

3. Update the documentation

After you have implemented the changes in the Bicep template files, it is important to update the documentation. The documentation is semi-automated and generated via a PowerShell script: Set-AVMModule.ps1. This script is located in the folder bicep-registry-modules/avm/utilities/tools/.

This script updates the existing README documentation based on the changes made, builds the main.bicep template file, and fails when there are errors. The script contains a PowerShell function that you must dot source by executing . bicep-registry-modules/avm/utilities/tools/Set-AVMModules.ps1.

After the function has been dot-sourced, it is loaded into the PowerShell environment and can be called with Set-AVMModules. Navigate to the folder where the changes are located, in this case, the folder virtual-machine, and run the command as seen below:

Running the Set-AVMModule function in the virtual-machine folder to generate documentation

The outputs of the script are an updated README file and the Bicep template that has been built.

4. Running the tests

Running tests and having a successful GitHub Actions workflow is really important as it shows the maintainers that the changes you have implemented work.

This step requires an Azure environment where the Action can be deployed. If you donโ€™t have an environment available, proceed to step 5 and ask for help in the pull request. If you have an environment available, two one-time configurations need to be made:

  1. A service principal must be created with Contributor permissions on the subscription where the tests will be deployed.
  2. You will need to set up some GitHub Actions variables before running a test deployment:
    • ARM_MGMTGROUP_ID: The GUID (Tenant Root Group) or the name of the management group.
    • ARM_SUBSCRIPTION_ID: The GUID of the subscription where the tests will be deployed.
    • ARM_TENANT_ID: The GUID of the tenant.
    • AZURE_CREDENTIALS: Connection credentials. See the exact format in the snippet below.

The clientId and the clientSecret from the service principal must be included in the AZURE_CREDENTIALS variable for a successful connection to Azure:

{
	"clientId": "<client ID from the service principal>",
	"clientSecret": "<secret generated from the service principal>",
	"subscriptionId": "22222222-2222-2222-2222-222222222222",
	"tenantId": "33333333-3333-3333-3333-333333333333" 
}
GitHub Actions secret configuration

The GitHub Actions variables can be set in the repository’s settings. To do this, follow these steps:

  1. Navigate to the forked GitHub repository and go to Settings
  2. On the left sidebar, click on ‘Secrets and variables.โ€™
  3. On the left sidebar, then go to Actions
  4. Add the repository secret by clicking on the green New Repository Secret button. After saving the secret it will be available in the GitHub Action workflows.

It is time to run the tests! As seen in the image below, under the Actions tab, you can see all the available workflows. Find the workflow that you need to run the tests for. To run the workflow, it is important to select the branch that you are working on. Also, as seen in the image below, it is possible to select specific jobs to run in the workflow:

  • Execute static validation

This job runs Pester tests and checks whether the folders contain a README, if the description decorator is written following a standard, includes PSRule checks, and so on.

  • Execute deployment validation

This job deploys the test Bicep templates.

  • Remove deployed module

This job removes the deployed test resources from your Azure environment. I would highly recommend enabling this job; otherwise, the resources will remain in your environment, potentially costing you a lot of money.

The avm.res.compute.virtual-machine workflow with job options
Workflow virtual-machine running jobs

When all jobs are green and have been successfully executed, copy the workflow status badge. See the image below to locate the status badge. This badge is required in the last step.

Status badge retrieved from the workflow

5. The pull request

The last step is to open a pull request to the main branch of the Azure/bicep-registry-modules repository. The easiest way to do this is by navigating to the forked repository and selecting your branch. As seen in the image below, a green Compare & pull request button will appear. Click on this button to open the pull request. Then, fill in the title and description.

Opening the PR via the forked repository johnlokerse/bicep-registry-modules

Tips

I want to share some tips that I have learned while contributing to Azure Verified Modules:

  • Donโ€™t be afraid to ask for help or to ask questions. The maintainers are happy to help, and they see value in your contribution!
  • Scope your contributions to small changes rather than large ones.
  • Avoid unexpected costs by disabling GitHub workflows to prevent unintended deployments. When synchronising the main branch with your development branch, it can happen that changed modules are deployed to your environment. To enable or disable the workflows run the workflow avm.platform.toggle-avm-workflows.yml.

Conclusion

This is how to contribute to AVM, whether to resolve an issue, fix a bug in a template, or make an improvement, as detailed in the step-by-step guide. The AVM team has made it easy for us, the community, to contribute to the Bicep or Terraform modules. The bicep-registry-modules repository is a fast-evolving and growing repository so steps in my practical guide can be subject to change, so this blog will be frequently updated.

There are many contribution workflows; this guide represents just one of those. If this is your first contribution, this workflow can be easy to pick up. Either way, contributing to Microsoft Open Source repositories is a win for Microsoft, the community and yourself!

External Links

Some links on the Azure Verified Modules topic:

2 thoughts on “Your first contribution to Azure Verified Modules

  1. Hey John,

    this helped me alot for the first PR to the repo. Thanks!

    Just want to mention, that some workflows need more environment variables. In my case (using `avm.res.web.site`) I needed to add the TOKEN_NAMEPREFIX with a lowercase short value. Was used within Resource Group Names and Storage Accounts (therefore lowercase)

    Hope it helps the next one when he tries to run the workflows.

    Cheers,
    Christoph.

    Liked by 1 person

Leave a comment