Azure Verified Modules
Glossary GitHub GitHub Issues Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Last updated: 27 Nov 2024

Owner Contribution Flow

This section describes the contribution flow for module owners who are responsible for creating and maintaining Bicep Modules.

This contribution flow is for Module Owners only.

As a Bicep Module Owner you need to be aware of the AVM Contribution Process Overview , Bicep specifications (including Bicep Interfaces ) as these need to be followed during pull request reviews for the modules you own. The purpose of this Owner Contribution Flow is to simplify and list the most important activities of an owner and to help you understand your responsibilities as an owner.

Additional internal content for ongoing module maintenance available for Microsoft FTEs, here .

1. Owner Activities and Responsibilities

Familiarise yourself with the responsibilities as Module Owner outlined in Team Definitions & RACI and Module Owner Responsibilities in the BRM Issue Triage .

  1. Create GitHub teams as outlined in SNFR20 and add respective parent teams:

Segments:

  • avm-res-<RP>-<modulename>-module-owners-bicep
  • avm-res-<RP>-<modulename>-module-contributors-bicep

Examples:

  • avm-res-compute-virtualmachine-module-owners-bicep and added avm-technical-reviewers-bicep as parent.
  • avm-res-compute-virtualmachine-module-contributors-bicep and added avm-module-contributors-bicep as parent.

If a secondary owner is required, add the secondary owner to the avm-res-<RP>-<modulename>-module-owners-bicep team.

Only fulltime Microsoft employees can be added at this time.

Once the teams have been created the AVM Core Team will review the team name and parent team membership for accuracy. A notification will automatically be sent to the AVM Core Team to inform them that their review needs to be completed.
  1. Add teams to CODEOWNERS file as outlined in SNFR20 .
  2. Ensure your module has been tested before raising a PR. You can do this your own or in another module contributor’s environment - if any. Also, once a PR is raised, a GitHub workflow pipeline is required to be run successfully before the PR can be merged. This is to ensure that the module is working as expected and is compliant with the AVM specifications.
    If you’re the sole owner of the module, the AVM core team must review and approve the PR. To indicate that your PR needs the core team’s attention, apply theNeeds: Core Team 🧞label on it!
  3. Ensure that the module(s) you own are compliant with the AVM Bicep specifications and are working as expected.
  4. Watch Pull Request (PR) activity for your module(s) in the BRM repository (Bicep Registry Modules repository - where all Bicep AVM modules are published) and ensure that PRs are reviewed and merged in a timely manner as outlined in SNFR11 .
  5. Watch AVM module issue and AVM question/feedback activity for your module(s) in the BRM repository.

2. Module Handover Activities

Under certain circumstances, you may find yourself unable to continue as the module owner. In such cases, it is advisable to designate a new module owner. The following steps outline this transition:

  • Leave a comment on the original module proposal, indicating that you’d like to hand the ownership over to somebody else. Mention the person who originally helped triage the issue or the @Azure/avm-core-team-technical-bicep team. You must wait for someone from the AVM Core Team to respond first, as the module index must be updated before you can continue handing over the ownership.
  • Add the new owner’s GitHub account as a “maintainer” on your modules GitHub teams.
  • Remove your GitHub account from your module’s GitHub teams.

If a new module owner cannot be identified then the module will need to be “Orphaned”. Please follow the step outlined when-a-module-becomes-orphaned .


3. Adopting an Orphaned Module

When adopting an orphaned module the when-a-new-owner-is-identified steps must be followed.


4. GitHub Notification Settings

As a module owner, it’s important that you receive notifications when any of your AVM modules experience activity or when you or any groups you belong to are explicitly mentioned (using the @ operator). This document describes how to configure your GitHub and Email settings to ensure you receive email notifications for these types of scenarios within GitHub.

Enable Global GitHub Notifications

Visit the GitHub Notifications Settings Page while logged in with your GitHub account.

GitHub Notifications Settings Page.
  1. Ensure your Default Notifications Email address is set to the email address you intend to use.
  2. (Optional) If you would like to automatically watch repositories that you are active in, ensure Automatically watch repositories is set to “On.”
  3. (Required) If you would like to automatically subscribe to team-level notifications whenever you join a new team, ensure Automatically watch teams is set to “On.”
  4. (Required) To receive notifications whenever a change is made to a repository or conversation that you are Watching, ensure the Notify Me setting has at least Email enabled.
  5. (Required)To receive notifications whenever you or a group you belong to are @mentioned, ensure the Notify Me setting has at least Email enabled.

Watch a Repository

Optionally, you may consider “watching” (following most or all activities in) an entire repository. The primary repository that owners should watch is the Bicep-Registry-Modules (BRM) repository. Notifications from this repository will notify you of issues concerning your module and any direct or team @mentions. It is important that you read and react to these messages.

To watch the BRM repository, visit Bicep-Registry-Modules , click the Watch button in the top-right of the page, then select Participating and @mentions. Optionally, if you would like to be notified for all activity within the repository, you can select All Activity.

Enabling All Activity will result in a lot of notifications! If you choose to go this route, you should set up filters within your email client. See Configure Email Inbox Notification Filters .
GitHub Notifications Page.

Configure Email Inbox Notification Filters

GitHub uses a unique email address sender for each type of notification it sends. This allows us to set up filters within our email client to sort our inboxes depending on the type of notifications that was sent. The table below lists all of the relevant email addresses that may be useful for filtering notifications from GitHub.

GitHub will use the following email addresses to Cc you if you’re subscribed to a conversation. The second Cc email address matches the notification reason.
Type of NotificationGitHub Email AddressNotification Reason
@Mentionsmention@noreply.github.comYou were mentioned on an issue or pull request.
@Team Mentionteam_mention@noreply.github.comA team you belong to was mentioned on an issue or pull request
Subscribedsubscribed@noreply.github.comThere was an update in a repository you’re watching.
Assignassign@noreply.github.comYou were assigned to an issue or pull request.
Commentcomment@noreply.github.comYou commented on an issue or pull request.

For a full list of GitHub notification types, see Filtering Email Notifications .


5. Contribution Checklist

This checklist can be used in the development of AVM Bicep Modules.

  1. Before beginning any work a new module a valid Issue: New AVM Module Proposal needs to be created. Instructions for creating the module proposal are outlined in the issue template. Pay particular attention to the questions and associated links to fill out the proposal accurately. Please do not start work on your proposed module until you receive a notification that your proposal has been accepted.

  2. Fork the bicep-registry-modules BRM repository. If you use an existing fork, ensure it’s up to date with origin/BRM.

    • Ensure all workflows are disabled by default once you forked the BRM repo, to prevent any accidental deployments into your Azure test environment resulted by an automated deployment.
  3. Create a new branch from your forked repository to develop your module.

  4. If you’re working on a new module you have to create its corresponding workflow file (see here ).

    • In order to run your e2e tests in your fork, this workflow file has to be put into the main branch first, so it can be run against your feature branch (GitHub Workflows can only be run on feature branches when they are already present in the main branch).
    • Since all workflows are disabled by default you have to enable your module’s specific GitHub workflow to run your e2e tests.
  5. Implement your contribution .

  6. Create, update, and run tests .

    • In addition to testing your module via GitHub pipeline, you can also test-locally . The following helper script facilitates local testing.
    <div class="gdoc-include"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-powershell" data-lang="powershell"><span class="line"><span class="cl"><span class="c"># Start pwsh if not started yet</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl"><span class="n">pwsh</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl"><span class="c"># Set default directory</span>
    </span></span><span class="line"><span class="cl"><span class="nv">$folder</span> <span class="p">=</span> <span class="s2">&#34;&lt;your directory&gt;/bicep-registry-modules&#34;</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl"><span class="c"># Dot source functions</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl"><span class="p">.</span> <span class="nv">$folder</span><span class="p">/</span><span class="n">utilities</span><span class="p">/</span><span class="n">tools</span><span class="p">/</span><span class="nb">Set-AVMModule</span><span class="p">.</span><span class="py">ps1</span>
    </span></span><span class="line"><span class="cl"><span class="p">.</span> <span class="nv">$folder</span><span class="p">/</span><span class="n">utilities</span><span class="p">/</span><span class="n">tools</span><span class="p">/</span><span class="nb">Test-ModuleLocally</span><span class="p">.</span><span class="py">ps1</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl"><span class="c"># Variables</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl"><span class="nv">$modules</span> <span class="p">=</span> <span class="vm">@</span><span class="p">(</span>
    </span></span><span class="line"><span class="cl">    <span class="c"># &#34;service-fabric/cluster&#34;, # Replace with your module</span>
    </span></span><span class="line"><span class="cl">    <span class="s2">&#34;network/private-endpoint&#34;</span>  <span class="c"># Replace with your module</span>
    </span></span><span class="line"><span class="cl"><span class="p">)</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl"><span class="c"># Generate Readme</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl"><span class="k">foreach</span> <span class="p">(</span><span class="nv">$module</span> <span class="k">in</span> <span class="nv">$modules</span><span class="p">)</span> <span class="p">{</span>
    </span></span><span class="line"><span class="cl">    <span class="nb">Write-Output</span> <span class="s2">&#34;Generating ReadMe for module </span><span class="nv">$module</span><span class="s2">&#34;</span>
    </span></span><span class="line"><span class="cl">    <span class="nb">Set-AVMModule</span> <span class="n">-ModuleFolderPath</span> <span class="s2">&#34;</span><span class="nv">$folder</span><span class="s2">/avm/res/</span><span class="nv">$module</span><span class="s2">&#34;</span> <span class="n">-Recurse</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl">    <span class="c"># Set up test settings</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl">    <span class="nv">$testcases</span> <span class="p">=</span> <span class="s2">&#34;waf-aligned&#34;</span><span class="p">,</span> <span class="s2">&#34;max&#34;</span><span class="p">,</span> <span class="s2">&#34;defaults&#34;</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl">    <span class="nv">$TestModuleLocallyInput</span> <span class="p">=</span> <span class="vm">@</span><span class="p">{</span>
    </span></span><span class="line"><span class="cl">        <span class="n">TemplateFilePath</span>           <span class="p">=</span> <span class="s2">&#34;</span><span class="nv">$folder</span><span class="s2">/avm/res/</span><span class="nv">$module</span><span class="s2">/main.bicep&#34;</span>
    </span></span><span class="line"><span class="cl">        <span class="n">ModuleTestFilePath</span>         <span class="p">=</span> <span class="s2">&#34;</span><span class="nv">$folder</span><span class="s2">/avm/res/</span><span class="nv">$module</span><span class="s2">/tests/e2e/max/main.test.bicep&#34;</span>
    </span></span><span class="line"><span class="cl">        <span class="n">PesterTest</span>                 <span class="p">=</span> <span class="vm">$true</span>
    </span></span><span class="line"><span class="cl">        <span class="n">ValidationTest</span>             <span class="p">=</span> <span class="vm">$false</span>
    </span></span><span class="line"><span class="cl">        <span class="n">DeploymentTest</span>             <span class="p">=</span> <span class="vm">$false</span>
    </span></span><span class="line"><span class="cl">        <span class="n">ValidateOrDeployParameters</span> <span class="p">=</span> <span class="vm">@</span><span class="p">{</span>
    </span></span><span class="line"><span class="cl">            <span class="n">Location</span>         <span class="p">=</span> <span class="s1">&#39;&lt;your location&gt;&#39;</span>
    </span></span><span class="line"><span class="cl">            <span class="n">SubscriptionId</span>   <span class="p">=</span> <span class="s1">&#39;&lt;your subscriptionId&gt;&#39;</span>
    </span></span><span class="line"><span class="cl">            <span class="n">RemoveDeployment</span> <span class="p">=</span> <span class="vm">$true</span>
    </span></span><span class="line"><span class="cl">        <span class="p">}</span>
    </span></span><span class="line"><span class="cl">        <span class="n">AdditionalTokens</span>           <span class="p">=</span> <span class="vm">@</span><span class="p">{</span>
    </span></span><span class="line"><span class="cl">            <span class="n">namePrefix</span> <span class="p">=</span> <span class="s1">&#39;&lt;your prefix&gt;&#39;</span>
    </span></span><span class="line"><span class="cl">            <span class="n">TenantId</span>   <span class="p">=</span> <span class="s1">&#39;&lt;your tenantId&gt;&#39;</span>
    </span></span><span class="line"><span class="cl">        <span class="p">}</span>
    </span></span><span class="line"><span class="cl">    <span class="p">}</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl">    <span class="c"># Run tests</span>
    </span></span><span class="line"><span class="cl">
    </span></span><span class="line"><span class="cl">    <span class="k">foreach</span> <span class="p">(</span><span class="nv">$testcase</span> <span class="k">in</span> <span class="nv">$testcases</span><span class="p">)</span> <span class="p">{</span>
    </span></span><span class="line"><span class="cl">        <span class="nb">Write-Output</span> <span class="s2">&#34;Running test case </span><span class="nv">$testcase</span><span class="s2"> on module </span><span class="nv">$module</span><span class="s2">&#34;</span>
    </span></span><span class="line"><span class="cl">        <span class="nv">$TestModuleLocallyInput</span><span class="p">.</span><span class="py">ModuleTestFilePath</span> <span class="p">=</span> <span class="s2">&#34;</span><span class="nv">$folder</span><span class="s2">/avm/res/</span><span class="nv">$module</span><span class="s2">/tests/e2e/</span><span class="nv">$testcase</span><span class="s2">/main.test.bicep&#34;</span>
    </span></span><span class="line"><span class="cl">        <span class="nb">Test-ModuleLocally</span> <span class="nv">@TestModuleLocallyInput</span>
    </span></span><span class="line"><span class="cl">    <span class="p">}</span>
    </span></span><span class="line"><span class="cl"><span class="p">}</span>
    </span></span></code></pre></div></div>
    
  7. Create a PR and reference the status badge of your pipeline run - see here .

    If you’re the sole owner of the module, the AVM core team must review and approve the PR. To indicate that your PR needs the core team’s attention, apply theNeeds: Core Team 🧞label on it!

  8. After a pull request has been created, it is important to update the AVM module proposal issue associated with your module, with a link to the pull request you created in BRM and mention the person who helped triage your module or the @Azure/avm-core-team-technical-bicep team.

  9. Once your BRM pull request has been approved and merged into main update the AVM module proposal issue associated with your module, with a Merged comment and mention the person who helped triage your module, or the @Azure/avm-core-team-technical-bicep team.