ADR-003: Azure Verified Modules (AVM) First Approach
Status
Accepted
Date
2024-01-15
Context
When generating Bicep infrastructure code, there are multiple approaches to resource definition:
- Raw Bicep resources - Define each Azure resource directly with full property specification
- Custom modules - Create reusable modules with organization-specific patterns
- Azure Verified Modules (AVM) - Use Microsoft's officially maintained module library
The Challenge
Azure resources have complex configurations with hundreds of potential properties. A single App Service
deployment might require:
- App Service Plan (with SKU, workers, zone redundancy)
- App Service (with runtime, networking, identity, slots)
- Private Endpoint (with DNS, NIC, subnet)
- Diagnostic Settings (with log categories, metrics)
- Managed Identity (with role assignments)
Writing raw Bicep for each resource is:
- Time-consuming and error-prone
- Inconsistent across teams
- Difficult to maintain as Azure APIs evolve
- Missing security best practices
Decision
We adopted an AVM-first approach where:
- Prefer AVM modules for all supported resources
- Fall back to raw Bicep only when AVM doesn't cover the resource type
- Use consistent parameter patterns across all module calls
- Document AVM versions in planning files for reproducibility
AVM Module Categories
| Category |
Registry Path |
Example Resources |
| Resource |
avm/res/<provider>/<resource> |
VNet, Storage, Key Vault, SQL |
| Pattern |
avm/ptn/<pattern-name> |
Hub-spoke network, Landing zone |
| Utility |
avm/utl/<utility-name> |
Naming, tagging utilities |
Standard Module Reference Format
module keyVault 'br/public:avm/res/key-vault/vault:0.11.0' = {
name: 'keyVaultDeployment'
params: {
name: keyVaultName
location: location
tags: tags
// AVM handles: private endpoints, RBAC, diagnostics, soft delete
enablePurgeProtection: true
enableSoftDelete: true
softDeleteRetentionInDays: 90
}
}
Why AVM?
- Microsoft maintained - Updated with latest API versions and security patches
- Well-Architected by design - Implements WAF recommendations out of the box
- Tested extensively - Unit tests, integration tests, policy compliance
- Consistent interfaces - Similar parameter patterns across all modules
- Private endpoint support - Built-in PE configuration for supported resources
Consequences
Positive
- 60-80% reduction in Bicep code volume
- Security best practices included by default (TLS 1.2, HTTPS, encryption)
- Easier maintenance as AVM handles API version updates
- Consistent module interface patterns improve learning curve
- Private endpoints and diagnostics are first-class features
Negative
- Learning curve for AVM parameter structure
- Module versions must be tracked and updated
- Some edge-case configurations may not be exposed
- Dependency on external registry (
mcr.microsoft.com)
- Raw Bicep still needed for unsupported resource types
Mitigations
- Agent prompts include common AVM patterns
- Planning files document specific versions to use
- Fallback to raw Bicep is explicitly allowed
- Shared configuration includes AVM module references
Implementation in Agents
bicep-plan Agent
Creates planning documents that specify:
- Which AVM modules to use
- Specific versions (e.g.,
0.11.0)
- Required parameters for each module
- Dependencies between modules
bicep-code Agent
Generates Bicep code that:
- References AVM modules from public registry
- Uses pinned versions from planning docs
- Follows AVM parameter naming conventions
- Includes proper outputs for module chaining
AVM Resources
Common AVM Modules Used
| Resource Type |
AVM Module Path |
Version |
| Virtual Network |
avm/res/network/virtual-network |
0.5.0 |
| NSG |
avm/res/network/network-security-group |
0.4.0 |
| Key Vault |
avm/res/key-vault/vault |
0.11.0 |
| Storage Account |
avm/res/storage/storage-account |
0.14.0 |
| SQL Server |
avm/res/sql/server |
0.10.0 |
| App Service Plan |
avm/res/web/serverfarm |
0.4.0 |
| App Service |
avm/res/web/site |
0.12.0 |
| Log Analytics |
avm/res/operational-insights/workspace |
0.9.0 |
| Application Insights |
avm/res/insights/component |
0.4.0 |
Note: Versions shown are examples. Always check AVM Index for latest.
References
1---2name: 2103-adr-003-avm-first-approach-50944ee53description: ADR-003: Azure Verified Modules (AVM) First Approach4---5# ADR-003: Azure Verified Modules (AVM) First Approach67## Status89Accepted1011## Date12132024-01-151415## Context1617When generating Bicep infrastructure code, there are multiple approaches to resource definition:18191. **Raw Bicep resources** - Define each Azure resource directly with full property specification202. **Custom modules** - Create reusable modules with organization-specific patterns213. **Azure Verified Modules (AVM)** - Use Microsoft's officially maintained module library2223### The Challenge2425Azure resources have complex configurations with hundreds of potential properties. A single App Service26deployment might require:2728- App Service Plan (with SKU, workers, zone redundancy)29- App Service (with runtime, networking, identity, slots)30- Private Endpoint (with DNS, NIC, subnet)31- Diagnostic Settings (with log categories, metrics)32- Managed Identity (with role assignments)3334Writing raw Bicep for each resource is:3536- Time-consuming and error-prone37- Inconsistent across teams38- Difficult to maintain as Azure APIs evolve39- Missing security best practices4041## Decision4243We adopted an **AVM-first approach** where:44451. **Prefer AVM modules** for all supported resources462. **Fall back to raw Bicep** only when AVM doesn't cover the resource type473. **Use consistent parameter patterns** across all module calls484. **Document AVM versions** in planning files for reproducibility4950### AVM Module Categories5152| Category | Registry Path | Example Resources |53| -------- | ------------------------------- | ------------------------------- |54| Resource | `avm/res/<provider>/<resource>` | VNet, Storage, Key Vault, SQL |55| Pattern | `avm/ptn/<pattern-name>` | Hub-spoke network, Landing zone |56| Utility | `avm/utl/<utility-name>` | Naming, tagging utilities |5758### Standard Module Reference Format5960```bicep61module keyVault 'br/public:avm/res/key-vault/vault:0.11.0' = {62 name: 'keyVaultDeployment'63 params: {64 name: keyVaultName65 location: location66 tags: tags67 // AVM handles: private endpoints, RBAC, diagnostics, soft delete68 enablePurgeProtection: true69 enableSoftDelete: true70 softDeleteRetentionInDays: 9071 }72}73```7475### Why AVM?76771. **Microsoft maintained** - Updated with latest API versions and security patches782. **Well-Architected by design** - Implements WAF recommendations out of the box793. **Tested extensively** - Unit tests, integration tests, policy compliance804. **Consistent interfaces** - Similar parameter patterns across all modules815. **Private endpoint support** - Built-in PE configuration for supported resources8283## Consequences8485### Positive8687- 60-80% reduction in Bicep code volume88- Security best practices included by default (TLS 1.2, HTTPS, encryption)89- Easier maintenance as AVM handles API version updates90- Consistent module interface patterns improve learning curve91- Private endpoints and diagnostics are first-class features9293### Negative9495- Learning curve for AVM parameter structure96- Module versions must be tracked and updated97- Some edge-case configurations may not be exposed98- Dependency on external registry (`mcr.microsoft.com`)99- Raw Bicep still needed for unsupported resource types100101### Mitigations102103- Agent prompts include common AVM patterns104- Planning files document specific versions to use105- Fallback to raw Bicep is explicitly allowed106- Shared configuration includes AVM module references107108## Implementation in Agents109110### bicep-plan Agent111112Creates planning documents that specify:113114- Which AVM modules to use115- Specific versions (e.g., `0.11.0`)116- Required parameters for each module117- Dependencies between modules118119### bicep-code Agent120121Generates Bicep code that:122123- References AVM modules from public registry124- Uses pinned versions from planning docs125- Follows AVM parameter naming conventions126- Includes proper outputs for module chaining127128## AVM Resources129130- [AVM Module Index](https://aka.ms/avm/index) - Searchable module catalog131- [AVM GitHub](https://github.com/Azure/bicep-registry-modules) - Source code132- [AVM Contribution Guide](https://aka.ms/avm/contribute) - Module development133134## Common AVM Modules Used135136| Resource Type | AVM Module Path | Version |137| -------------------- | ---------------------------------------- | ------- |138| Virtual Network | `avm/res/network/virtual-network` | 0.5.0 |139| NSG | `avm/res/network/network-security-group` | 0.4.0 |140| Key Vault | `avm/res/key-vault/vault` | 0.11.0 |141| Storage Account | `avm/res/storage/storage-account` | 0.14.0 |142| SQL Server | `avm/res/sql/server` | 0.10.0 |143| App Service Plan | `avm/res/web/serverfarm` | 0.4.0 |144| App Service | `avm/res/web/site` | 0.12.0 |145| Log Analytics | `avm/res/operational-insights/workspace` | 0.9.0 |146| Application Insights | `avm/res/insights/component` | 0.4.0 |147148> **Note**: Versions shown are examples. Always check [AVM Index](https://aka.ms/avm/index) for latest.149150## References151152- [.github/agents/\_shared/defaults.md](../../.github/agents/_shared/defaults.md) - Shared AVM references153- [.github/agents/bicep-plan.agent.md](../../.github/agents/bicep-plan.agent.md) - Planning agent154- [.github/agents/bicep-code.agent.md](../../.github/agents/bicep-code.agent.md) - Implementation agent