Shared Specification (Bicep & Terraform)
Make sure to checkout the Module Classification Definitions first before reading further so you understand the difference between a Resource and Pattern Module in AVM.
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
This page contains the shared requirements for both Bicep and Terraform AVM modules (Resource and Pattern modules) that ALL AVM modules MUST meet. In addition to these, requirements specific to each language, defined in their respective specifications also MUST be met. See Bicep and Terraform specific requirements for more information.
The following table summarizes the category identification codes used in this specification:
Scope | Functional requirements | Non-functional requirements |
---|---|---|
Shared requirements (resource & pattern modules) | SFR | SNFR |
Resource module level requirements | RMFR | RMNFR |
Pattern module level requirements | PMFR | PMNFR |
Listed below are both functional and non-functional requirements for both classifications of AVM modules (Resource and Pattern) and all languages.
While every effort is being made to standardize requirements and implementation details across all languages, it is expected that some of the specifications will be different between their respective languages to ensure we follow the best practices and leverage features of each language.
This section includes shared, functional requirements (SFR) for Bicep an Terraform AVM modules (Resource and Pattern).
Modules MAY create/adopt public preview services and features at their discretion.
Preview API versions MAY be used when:
- The resource/service/feature is GA but the only API version available for the GA resource/service/feature is a preview version
- For example, Diagnostic Settings (
Microsoft.Insights/diagnosticSettings
) the latest version of the API available with GA features, like Category Groups etc., is2021-05-01-preview
- Otherwise the latest “non-preview” version of the API SHOULD be used
- For example, Diagnostic Settings (
Preview services and features, SHOULD NOT be promoted and exposed, unless they are supported by the respective PG, and it’s documented publicly.
However, they MAY be exposed at the module owners discretion, but the following rules MUST be followed:
- The description of each of the parameters/variables used for the preview service/feature MUST start with:
- “THIS IS A <PARAMETER/VARIABLE> USED FOR A PREVIEW SERVICE/FEATURE, MICROSOFT MAY NOT PROVIDE SUPPORT FOR THIS, PLEASE CHECK THE PRODUCT DOCS FOR CLARIFICATION”
Modules SHOULD align to Well-Architected Framework (WAF) pillar recommendations, alongside Microsoft Cloud Security Benchmark (MCSB) and Microsoft Defender for Cloud (MDFC), where appropriate and applicable.
They SHOULD NOT align to these recommendations when it requires an external dependency/resource to be deployed and configured and then associated to the resources in the module.
Alignment SHOULD prioritize best-practices and security over cost optimization, but MUST allow for these to be overridden by a module consumer easily, if desired.
Read the FAQ of What does AVM mean by “WAF Aligned”? for more detailed information and examples.
Variations from the upstream: custom telemetry ID prefixes
We will maintain a set of CSV files in the AVM Central Repo (
Azure/Azure-Verified-Modules
) with the required TelemetryId prefixes to enable checks to utilize this list to ensure the correct IDs are used.These will also be provided as a comment on the module proposal, once accepted, from the AVM core team.
Modules MUST provide the capability to collect deployment/usage telemetry, via a blank ARM deployment, as detailed in Telemetry further. Telemetry data should be collected on the “top level” main.bicep
or main.telemetry.tf
file; it is not necessary to include it in any nested files (child modules).
To highlight that AVM modules use telemetry, an information notice MUST be included in the footer of each module’s README.md
file with the below content. (See more details on this requirement, here.)
The ARM deployment name used for the telemetry MUST follow the pattern and MUST be no longer than 64 characters in length: <AVM 8 chars (alphanumeric)>.<res/ptn>.<(short) module name>.<version>.<uniqueness>
<AVM 8 chars (alphanumeric)>
<res/ptn>
== AVM Resource or Pattern Module<(short) module name>
== The AVM Module’s, possibly shortened, name including the resource provider and the resource type, without;- The prefixes:
avm-res-
orterraform-<provider>-avm-res-
- The prefixes:
avm-ptn-
orterraform-<provider>-avm-ptn-
- The prefixes:
Due to the 64-character length limit of Azure deployment names, the<(short) module name>
segment has a length limit of 36 characters, so if the module name is longer than that, it MUST be truncated to 36 characters. If any of the semantic version’s segments are longer than 1 character, it further restricts the number of characters that can be used for naming the module.
<version>
== The AVM Module’s MAJOR.MINOR version (only) with.
(periods) replaced with-
(hyphens), to allow simpler splitting of the ARM deployment name<uniqueness>
== This section of the ARM deployment name is to be used to ensure uniqueness of the deployment name.- This is to cater for the following scenarios:
- The module is deployed multiple times to the same:
- Location/Region
- Scope (Tenant, Management Group,Subscription, Resource Group)
- The module is deployed multiple times to the same:
- This is to cater for the following scenarios:
An example deployment name for the AVM Virtual Machine Resource Module would be:
- Bicep ==
12345678.res.compute-virtualmachine.1-2-3.eum3
An example deployment name for a shortened module name would be:
- Bicep ==
12345678.res.desktopvirtualization-appgroup.1-2-3.eum3
See the language specific contribution guides for detailed guidance and sample code to use in AVM modules to achieve this requirement.
The telemetry enablement MUST be on/enabled by default, however this MUST be able to be disabled by a module consumer by setting the below parameter/variable value to false
:
- Bicep:
enableTelemetry
- Terraform:
enable_telemetry
Modules that deploy zone-redundant resources MUST enable the spanning across as many zones as possible by default, typically all 3.
Modules that deploy zonal resources MUST provide the ability to specify a zone for the resources to be deployed/pinned to. However, they MUST NOT default to a particular zone by default, e.g. 1
in an effort to make the consumer aware of the zone they are selecting to suit their architecture requirements.
For both scenarios the modules MUST expose these configuration options via configurable parameters/variables.
For information on the differences between zonal and zone-redundant services, see Availability zone service and regional support
Variations from the upstream: default is regional redundancy and not global redundancy
Modules that deploy resources or patterns that support data redundancy SHOULD enable this to the regional redundancy by default, e.g. ZRS
. When a resource or pattern doesn’t provide the ability to specify data redundancy as a simple property, e.g. ZRS
etc., then the modules MUST provide the ability to enable data redundancy for the resources or pattern via parameters/variables.
For example, a Storage Account module can simply set the sku.name
property to Standard_ZRS
. Whereas a SQL DB or Cosmos DB module will need to expose more properties, via parameters/variables, to allow the specification of the regions to replicate data to as per the consumers requirements.
For information on the data redundancy options in Azure, see Cross-region replication in Azure
This section includes shared, non-functional requirements (SNFR) for Bicep an Terraform AVM modules (Resource and Pattern).
Variations from the upstream: choice of use between suffixes and prefixes
Module owners MUST set the default resource name prefix (or suffix) for child, extension, and interface resources to the associated abbreviation for the specific resource as documented in the following CAF article Abbreviation examples for Azure resources, if specified and documented. This reduces the amount of input values a module consumer MUST provide by default when using the module.
For example, a Private Endpoint that is being deployed as part of a resource module, via the mandatory interfaces, MUST set the Private Endpoint’s default name to end with (or begin with) pep
(or pep-
).
Module owners MUST also provide the ability for these default names, including the suffixes (or prefixes), to be overridden via a parameter/variable if the consumer wishes to. They MUST also provide the ability for the consumer to specify if they wish to use prefixes or suffixes for the resource abbreviations.
In case of private endpoints, module owners MUST also use the value of ‘groupId’ (prefixed with -
) from the private endpoint interface definition to append to the default name of the resource if the resource supports multiple instances of the same resource type.
Furthermore, as per RMNFR2, Resource Modules MUST not have a default value specified for the name of the primary resource and therefore the name MUST be provided and specified by the module consumer.
The name provided MAY be used by the module owner to generate the rest of the default name for child, extension, and interface resources if they wish to. For example, for the Private Endpoint mentioned above, the full default name that can be overridden by the consumer, MAY be <primary-resource-name>pep[-<endpoint-groupId>]
or pep-<primary-resource-name>[-<endpoint-groupId>]
.
If the resource does not have a documented abbreviation in Abbreviation examples for Azure resources, then the module owner is free to use a sensible prefix instead.
Variation from the upstream: changed from MUST to SHOULD
Modules SHOULD use the prescribed tooling and testing frameworks defined in the language specific specs.
Variations from the upstream: changed MUST to SHOULD with regards to choice of whether to implement testing or not
Modules SHOULD implement end-to-end (deployment) testing that create actual resources to validate that module deployments work. In Bicep tests are sourced from the directories in /tests/e2e
. In Terraform, these are in /examples
.
Each test MUST run and complete without user inputs successfully, for automation purposes.
Each test MUST also destroy/clean-up its resources and test dependencies following a run.
To see a directory and file structure for a module, see the language specific contribution guide.
It is likely that to complete E2E tests, a number of resources will be required as dependencies to enable the tests to pass successfully. Some examples:
- When testing the Diagnostic Settings interface for a Resource Module, you will need an existing Log Analytics Workspace to be able to send the logs to as a destination.
- When testing the Private Endpoints interface for a Resource Module, you will need an existing Virtual Network, Subnet and Private DNS Zone to be able to complete the Private Endpoint deployment and configuration.
Module owners MUST:
- Create the required resources that their module depends upon in the test file/directory
- They MUST either use:
- Simple/native resource declarations/definitions in their respective IaC language,
OR - Another already published AVM Module that MUST be pinned to a specific published version.
- They MUST NOT use any local directory path references or local copies of AVM modules in their own modules test directory.
- Simple/native resource declarations/definitions in their respective IaC language,
- They MUST either use:
Modules MUST pass all tests that ensure compliance to AVM specifications. These tests MUST pass before a module version can be published.
Variations from the upstream: changed approving team and removed GitHub dependency
Please note these are still under development at this time and will be published and available soon for module owners.
Module owners MUST request a manual Pull Request review, prior to their first release of version
0.1.0
of their module, from the Core Team.
Modules SHOULD implement unit testing to ensure logic and conditions within parameters/variables/locals are performing correctly. These tests MUST pass before a module version can be published.
Unit Tests test specific module functionality, without deploying resources. Used on more complex modules. In Bicep and Terraform these live in tests/unit
.
Modules SHOULD implement upgrade testing to ensure new features are implemented in a non-breaking fashion on non-major releases.
Modules MUST use static analysis, e.g., linting, security scanning (PSRule, tflint, etc.). These tests MUST pass before a module version can be published.
There may be differences between languages in linting rules standards, but the AVM core team will try to close these and bring them into alignment over time.
Modules MUST implement idempotency end-to-end (deployment) testing. E.g. deploying the module twice over the top of itself.
Modules SHOULD pass the idempotency test, as we are aware that there are some exceptions where they may fail as a false-positive or legitimate cases where a resource cannot be idempotent.
For example, Virtual Machine Image names must be unique on each resource creation/update.
Module owners MUST test that child, extension and interface resources, that are supported by their modules, are tested in E2E tests as per SNFR2 to ensure they deploy and are configured correctly.
These MAY be tested in a separate E2E test and DO NOT have to be tested in each E2E test.
Variations from the upstream: changed approving team and removed GitHub dependency
A module MUST have an owner that is defined and managed by a Core Team.
Variations from the upstream: removed restrictions on contributions by non-MSFT and removed GitHub dependency
All repositories that AVM module are published from and hosted within MUST only assign repository permissions to teams only.
Each module MUST have separate teams assigned for module owners AND module contributors respectively.
There MUST NOT be any repository permissions assigned to individual users.
The names for the teams for each approved module will be defined in the respective Module Indexes. These teams MUST be created (and used) for each module.
Variations from the upstream: changed from MUST to MAY and removed GitHub dependency
The naming convention for the teams MAY follow the below pattern:
<hyphenated module name>-module-owners-<bicep/tf>
- to be assigned as the repository’sModule Owners
team<hyphenated module name>-module-contributors-<bicep/tf>
- to be assigned as the repository’sModule Contributors
team
The naming convention for Bicep modules is slightly different than the naming convention for their respective teams.
Segments:
<hyphenated module name>
== the AVM Module’s name, with each segment separated by dashes, i.e.,avm-res-<resource provider>-<ARM resource type>
module-owners
ormodule-contributors
== the role the Team is assigned to<bicep/tf>
== the language the module is written in
Examples:
avm-res-compute-virtualmachine-module-owners-bicep
avm-res-compute-virtualmachine-module-contributors-tf
All officially documented module owner(s) MAY be added to the -module-owners-
team. The -module-owners-
team MUST NOT have any other members.
Any additional module contributors whom the module owner(s) agreed to work with MAY be added to the -module-contributors-
team.
Unless explicitly requested and agreed, members of the AVM core team or any PG teams MUST NOT be added to the -module-owners-
or -module-contributors-
teams as permissions for them are granted through the teams described in SNFR9.
In case of Bicep modules, permissions to the BRM repository (the repo of the Bicep Registry) are granted via assigning the-module-owners-
and-module-contributors-
teams to parent teams that already have the required level access configured. While it is the module owner’s responsibility to initiate the addition of their teams to the respective parents, only the AVM core team can approve this parent-child relationship.
Module owners MAY create their -module-owners-
and -module-contributors-
teams and as part of the provisioning process, they MAY request the addition of these teams to their respective parent teams (see the table below for details).
Team Name | Description | Permissions | Permissions granted through | Where to work? |
---|---|---|---|---|
<hyphenated module name>-module-owners-bicep | AVM Bicep Module Owners - <module name> | Write | Assignment to the avm-technical-reviewers-bicep parent team. | Need to work in a fork. |
<hyphenated module name>-module-contributors-bicep | AVM Bicep Module Contributors - <module name> | Triage | avm-module-contributors-bicep parent team. | Need to work in a fork. |
Examples - teams required for the Bicep resource module of Azure Virtual Network (avm/res/network/virtual-network
):
avm-res-network-virtualnetwork-module-owners-bicep
–> assign to theavm-technical-reviewers-bicep
parent team.avm-res-network-virtualnetwork-module-contributors-bicep
–> assign to theavm-module-contributors-bicep
parent team.
Variations from the upstream: in case of using GitHub
If this repository is hosted on GitHub, as part of the “initial Pull Request” (that publishes the first version of the module), module owners MUST add an entry to the CODEOWNERS
file in the BRM repository (here).
Through this approach, the AVM core team will grant review permission to module owners as part of the standard PR review process.
Every CODEOWNERS
entry (line) MUST include the following segments separated by a single whitespace character:
- Path of the module, relative to the repo’s root, e.g.:
/avm/res/network/virtual-network/
- The
-module-owners-
team, with the@<org>/
prefix, e.g.,@<org>/avm-res-network-virtualnetwork-module-owners-bicep
- The GitHub team of the AVM core team, with the
@<org>/
prefix, i.e.,@<org>/avm-core-team-technical-bicep
where<org>
is the GitHub organization name.
Example - CODEOWNERS
entry for the Bicep resource module of Azure Virtual Network (avm/res/network/virtual-network
):
/avm/res/network/virtual-network/ @<org>/avm-res-network-virtualnetwork-module-owners-bicep @<org>/avm-core-team-technical-bicep
Variations from the upstream: removed
Variations from the upstream: removed mention of the GitHub repository, making licensing an authors choice
Module owners MAY choose a license.
A module MUST be published with the correct license.
Variations from the upstream: removed fixed SLA.
A module owner MUST respond to logged issues.
Variations from the upstream: changed from MUST to SHOULD, and added clarification on the latest version being major.minor
Only the latest released major.minor version of a module SHOULD be supported.
For example, if an AVM Resource Module is used in an AVM Pattern Module that was working but now is not. The first step by the AVM Pattern Module owner should be to upgrade to the latest version of the AVM Resource Module test and then if not fixed, troubleshoot and fix forward from the that latest version of the AVM Resource Module onwards.
This avoids AVM Module owners from having to maintain multiple major release versions.
Variations from the upstream: removed
A module SHOULD use either: simple data types. e.g., string, int, bool.
OR
Complex data types (objects, arrays, maps) when the language-compliant schema is defined.
A module parameter/variable that requires a full Azure Resource ID as an input value, e.g. /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.KeyVault/vaults/{keyVaultName}
, MUST contain ResourceId/resource_id
in its parameter/variable name to assist users in knowing what value to provide at a glance of the parameter/variable name.
Example for the property workspaceId
for the Diagnostic Settings resource. In Bicep its parameter name should be workspaceResourceId
and the variable name in Terraform should be workspace_resource_id
.
workspaceId
is not descriptive enough and is ambiguous as to which ID is required to be input.
Variations from the upstream: changed from MUST to SHOULD.
README documentation SHOULD be automatically/programmatically generated. SHOULD include the sections as defined in the language specific requirements BCPNFR2, TFNFR2.
Variations from the upstream: changed from MUST to SHOULD.
An examples/e2e directory SHOULD exist to provide named scenarios for module deployment.
You cannot specify the patch version for Bicep modules in the public Bicep Registry, as this is automatically incremented by 1 each time a module is published. You can only set the Major and Minor versions.
See the Bicep Contribution Guide for more information.
Modules MUST use semantic versioning (aka semver) for their versions and releases in accordance with: Semantic Versioning 2.0.0
For example all modules should be released using a semantic version that matches this pattern: X.Y.Z
X
== Major VersionY
== Minor VersionZ
== Patch Version
Initially modules MUST be released as version
0.1.0
and incremented via Minor and Patch versions only until the AVM Core Team are confident the AVM specifications are mature enough and appropriate CI test coverage is in place, plus the module owner is happy the module has been “road tested” and is now stable enough for its first Major release of version1.0.0
.Releasing as version0.1.0
initially and only incrementing Minor and Patch versions allows the module owner to make breaking changes more easily and frequently as it’s still not an official Major/Stable release. 👍Until first Major version
1.0.0
is released, given a version numberX.Y.Z
:X
Major version MUST NOT be bumped.Y
Minor version MUST be bumped when introducing breaking changes (which would normally bump Major after1.0.0
release) or feature updates (same as it will be after1.0.0
release).Z
Patch version MUST be bumped when introducing non-breaking, backward compatible bug fixes (same as it will be after1.0.0
release).
A module SHOULD avoid breaking changes, e.g., deprecating inputs vs. removing.
Variations from the upstream: changed from MUST to SHOULD, repoved registry URL
Modules SHOULD be published to their respective language registries.
See the language specific contribution guides for detailed guidance and sample code to use in AVM modules to achieve this requirement.
When the module owners of the same Resource or Pattern AVM module are not the same individual or team for all languages, each languages team SHOULD collaborate with their sibling language team for the same module to ensure consistency where possible.
Listed below are both functional and non-functional requirements for AVM Resource Modules.
This section includes resource module level, functional requirements (RMFR) for Bicep an Terraform.
A resource module MUST only deploy a single instance of the primary resource, e.g., one virtual machine per instance.
Multiple instances of the module MUST be used to scale out.
Variations from the upstream: changed from MUST to SHOULD.
A resource module SHOULD add value by including additional features on top of the primary resource.
A resource module MUST NOT create a Resource Group for resources that require them.
In the case that a Resource Group is required, a module MUST have an input (scope or variable):
- In Bicep the
targetScope
MUST be set toresourceGroup
or not specified (which means default toresourceGroup
scope) - In Terraform the
variable
MUST be calledresource_group_name
Scopes will be covered further in the respective language specific specifications.
Resource modules support the following optional features/extension resources, as specified, if supported by the primary resource. The top-level variable/parameter names MUST be:
Optional Features/Extension Resources | Bicep Parameter Name | Terraform Variable Name | MUST/SHOULD |
---|---|---|---|
Diagnostic Settings | diagnosticSettings | diagnostic_settings | MUST |
Role Assignments | roleAssignments | role_assignments | MUST |
Resource Locks | lock | lock | MUST |
Tags | tags | tags | MUST |
Managed Identities (System / User Assigned) | managedIdentities | managed_identities | MUST |
Private Endpoints | privateEndpoints | private_endpoints | MUST |
Customer Managed Keys | customerManagedKey | customer_managed_key | MUST |
Azure Monitor Alerts | alerts | alerts | SHOULD |
Resource modules MUST NOT deploy required/dependent resources for the optional features/extension resources specified above. For example, for Diagnostic Settings the resource module MUST NOT deploy the Log Analytics Workspace, this is expected to be already in existence from the perspective of the resource module deployed via another method/module etc.
Please note that the implementation of Customer Managed Keys from an ARM API perspective is different across various RPs that implement Customer Managed Keys in their service. For that reason you may see differences between modules on how Customer Managed Keys are handled and implemented, but functionality will be as expected.
Module owners MAY choose to utilize cross repo dependencies for these “add-on” resources, or MAY chose to implement the code directly in their own repo/module. So long as the implementation and outputs are as per the specifications requirements, then this is acceptable.
Make sure to checkout the language specific specifications for more info on this:
ID: RMFR5 - Category: Composition - AVM Consistent Feature & Extension Resources Value Add Interfaces/Schemas
Resource modules MUST implement a common interface, e.g. the input’s data structures and properties within them (objects/arrays/dictionaries/maps), for the optional features/extension resources:
See:
- Diagnostic Settings Interface
- Role Assignments Interface
- Resource Locks Interface
- Tags Interface
- Managed Identities Interface
- Private Endpoints Interface
- Customer Managed Keys Interface
- Alerts Interface
A resource module MAY contain references to other resource modules, however MUST NOT contain references to non-AVM modules nor AVM pattern modules.
See BCPFR1 and TFFR1 for more information on this.
Parameters/variables that pertain to the primary resource MUST NOT use the resource type in the name.
e.g., use sku
, vs. virtualMachineSku
/virtualmachine_sku
Another example for where RPs contain some of their name within a property, leave the property unchanged. E.g. Key Vault has a property called keySize
, it is fine to leave as this and not remove the key
part from the property/parameter name.
Module owners MUST output the following outputs as a minimum in their modules:
Output | Bicep Output Name | Terraform Output Name |
---|---|---|
Resource Name | name | name |
Resource ID | resourceId | resource_id |
System Assigned Managed Identity Principal ID (if supported by module) | systemAssignedMIPrincipalId | system_assigned_mi_principal_id |
This section includes resource module level, non-functional requirements (RMNFR) for Bicep an Terraform.
We will maintain a set of CSV files in the AVM Central Repo (
Azure/Azure-Verified-Modules
) with the correct singular names for all resource types to enable checks to utilize this list to ensure repos are named correctly. To see the formatted content of these CSV files with additional information, please visit the AVM Module Indexes page.This will be updated quarterly, or ad-hoc as new RPs/ Resources are created and highlighted via a check failure.
Resource modules MUST follow the below naming conventions (all lower case):
Variations from the upstream: removed ‘avm/’ part to shorten the name
- Naming convention:
res/<hyphenated resource provider name>/<hyphenated ARM resource type>
(module name for registry) - Example:
res/compute/virtual-machine
orres/managed-identity/user-assigned-identity
- Segments:
res
defines this is a resource module<hyphenated resource provider name>
is the resource provider’s name after theMicrosoft
part, with each word starting with a capital letter separated by dashes, e.g.,Microsoft.Compute
=compute
,Microsoft.ManagedIdentity
=managed-identity
.<hyphenated ARM resource type>
is the singular version of the word after the resource provider, with each word starting with a capital letter separated by dashes, e.g.,Microsoft.Compute/virtualMachines
=virtual-machine
, BUTMicrosoft.Network/trafficmanagerprofiles
=trafficmanagerprofile
- sincetrafficmanagerprofiles
is all lower case as per the ARM API definition.
Variations from the upstream: removed ‘avm-’ part to shorten the name
- Naming convention:
res-<resource provider>-<ARM resource type>
(module name for registry)terraform-<provider>-res-<resource provider>-<ARM resource type>
(GitHub repository name to meet registry naming requirements)
- Example:
res-compute-virtualmachine
orres-managedidentity-userassignedidentity
- Segments:
<provider>
is the logical abstraction of various APIs used by Terraform. In most cases, this is going to beazurerm
orazuread
for resource modules.res
defines this is a resource module<resource provider>
is the resource provider’s name after theMicrosoft
part, e.g.,Microsoft.Compute
=compute
.<ARM resource type>
is the singular version of the word after the resource provider, e.g.,Microsoft.Compute/virtualMachines
=virtualmachine
A resource module MUST use the following standard inputs:
name
(no default)location
(if supported by the resource and not a global resource, then use Resource Group location, if resource supports Resource Groups, otherwise no default)
Variations from the upstream: removed.
Listed below are both functional and non-functional requirements for AVM Pattern Modules.
This section includes pattern module level, functional requirements (PMFR) for Bicep an Terraform.
A Pattern Module MAY create Resource Group(s).
This section includes pattern module level, non-functional requirements (PMNFR) for Bicep an Terraform.
Variations from the upstream: removed ‘avm/’ part to shorten the name
Pattern Modules MUST follow the below naming conventions (all lower case):
- Naming convention:
ptn/<hyphenated grouping/category name>/<hyphenated pattern module name>
- Example:
ptn/compute/app-tier-vmss
orptn/avd-lza/management-plane
orptn/3-tier/web-app
- Segments:
ptn
defines this as a pattern module<hyphenated grouping/category name>
is a hierarchical grouping of pattern modules by category, with each word separated by dashes, such as:- project name, e.g.,
avd-lza
, - primary resource provider, e.g.,
compute
ornetwork
, or - architecture, e.g.,
3-tier
- project name, e.g.,
<hyphenated pattern module name>
is a term describing the module’s function, with each word separated by dashes, e.g.,app-tier-vmss
= Application Tier VMSS;management-plane
= Azure Virtual Desktop Landing Zone Accelerator Management Plane
- Naming convention:
ptn-<pattern module name>
(Module name for registry)terraform-<provider>-ptn-<pattern module name>
(GitHub repository name to meet registry naming requirements)
- Example:
ptn-apptiervmss
orptn-avd-lza-managementplane
- Segments:
<provider>
is the logical abstraction of various APIs used by Terraform. In most cases, this is going to beazurerm
orazuread
for resource modules.ptn
defines this as a pattern module<pattern module name>
is a term describing the module’s function, e.g.,apptiervmss
= Application Tier VMSS;avd-lza-managementplane
= Azure Virtual Desktop Landing Zone Accelerator Management Plane
A Pattern Module SHOULD be built from AVM Resources Modules to establish a standardized code base and improve maintainability. If a valid reason exists, a pattern module MAY contain native resources (“vanilla” code) where it’s necessary. A Pattern Module MUST NOT contain references to non-AVM modules.
Valid reasons for not using a Resource Module for a resource required by a Pattern Module include but are not limited to:
- When using a Resource Module would result in hitting scaling limitations and/or would reduce the capabilities of the Pattern Module due to the limitations of Azure Resource Manager.
- Developing a Pattern Module under time constraint, without having all required Resource Modules readily available.
In the latter case, the Pattern Module SHOULD be updated to use the Resource Module when the required Resource Module becomes available, to avoid accumulating technical debt. Ideally, all required Resource Modules SHOULD be developed first, and then leveraged by the Pattern Module.
A Pattern Module MAY contain and be built using other AVM Pattern Modules. A Pattern Module MUST NOT contain references to non-AVM modules.
Variations from the upstream: changed from MUST to SHOULD
An item SHOULD be logged onto as an issue on the AVM Central Repo (Azure/Azure-Verified-Modules
) if a Resource Module does not exist for resources deployed by the pattern module.
If the Resource Module adds no value, see Resource Module functional requirement ID: RMFR2.
Parameter/variable input names SHOULD contain the resource to which they pertain. E.g., virtualMachineSku
/virtualmachine_sku