Azure Verified Modules (AVM), Bicep best practices, and MCP-powered infrastructure as code for Azure
Scanned 9/3/2026
Install to Claude Code
npx -y skills add fabioc-aloha/Alex_Skill_Mall --skill bicep-avm-mastery --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Bicep Avm Mastery?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/fabioc-aloha-bicep-avm-mastery)More formats (shields.io, HTML) on the badges page.
---
name: bicep-avm-mastery
description: "Azure Verified Modules (AVM), Bicep best practices, and MCP-powered infrastructure as code for Azure"
lastReviewed: 2026-04-30
---
# Skill: Bicep AVM Mastery
> Azure Verified Modules (AVM), Bicep best practices, and MCP-powered infrastructure as code for Azure.
> **Staleness Watch**: See `EXTERNAL-API-REGISTRY.md` for source URLs and recheck cadence
## Metadata
| Field | Value |
|-------|-------|
| **Skill ID** | bicep-avm-mastery |
| **Version** | 1.1.0 |
| **Category** | Cloud/Infrastructure |
| **Difficulty** | Advanced |
| **Prerequisites** | Basic Azure, infrastructure-as-code |
| **Related Skills** | azure-architecture-patterns, infrastructure-as-code |
| **Last Validated** | Feb 2026 |
> ⚠️ **Staleness Watch**: The AVM registry grows monthly — module counts and version numbers change frequently. Always use [`mcp_bicep_list_avm_metadata`](https://azure.github.io/Azure-Verified-Modules/) to enumerate current modules rather than relying on hardcoded counts. Watch for new module categories and `avm/res` vs `avm/ptn` naming changes.
---
## Overview
Bicep is Azure's domain-specific language for infrastructure as code. This skill covers Bicep best practices, Azure Verified Modules (AVM), and MCP tool integration for high-quality, production-ready deployments.
### Why Bicep?
| Feature | Bicep | ARM JSON | Terraform |
|---------|-------|----------|-----------|
| Syntax | Clean, readable | Verbose | HCL |
| Azure Integration | Native | Native | Provider |
| State Management | Azure-managed | Azure-managed | External |
| Learning Curve | Low | High | Medium |
| Tooling | VS Code, MCP | Limited | Extensive |
---
## Module 1: Bicep Best Practices
### General Rules
1. **Avoid setting `name` for module statements** — no longer required
2. **Use user-defined types** for grouped param/output values instead of multiple params
3. **Prefer `.bicepparam` files** over JSON parameters files
### Resource Patterns
```bicep
// ✅ CORRECT: Use parent property
resource subnet 'Microsoft.Network/virtualNetworks/subnets@2023-09-01' = {
parent: vnet // Reference parent symbolically
name: 'default'
properties: {
addressPrefix: '10.0.0.0/24'
}
}
// ❌ AVOID: Slash in name property
resource subnetBad 'Microsoft.Network/virtualNetworks/subnets@2023-09-01' = {
name: '${vnetName}/default' // Don't do this
}
```
### Type Safety
```bicep
// ✅ CORRECT: Typed user-defined type
@export()
type storageAccountConfig = {
@description('Storage account name')
name: string
@description('SKU for the storage account')
sku: 'Standard_LRS' | 'Standard_GRS' | 'Premium_LRS'
@description('Enable public access')
allowPublicAccess: bool
}
// ❌ AVOID: Open types
param config object // Too broad
```
### Symbolic References
```bicep
// ✅ CORRECT: Use symbolic references
output storageId string = storageAccount.id
output storageName string = storageAccount.name
// ❌ AVOID: resourceId() and reference()
output storageIdBad string = resourceId('Microsoft.Storage/storageAccounts', storageAccountName)
```
### Security
```bicep
// ✅ ALWAYS use @secure() for sensitive data
@secure()
param adminPassword string
@secure()
param connectionString string
```
### Null Handling
```bicep
// ✅ CORRECT: Safe dereference with coalesce
var subnetId = vnet.properties.subnets[?0].?id ?? 'default'
// ❌ AVOID: Non-null assertion or verbose ternary
var subnetIdBad = vnet!.properties.subnets[0].id
```
---
## Module 2: Azure Verified Modules (AVM)
### What is AVM?
Azure Verified Modules are **Microsoft-supported, production-ready Bicep modules** covering 328+ Azure resources. They follow best practices, are tested, and receive updates.
### AVM Categories
| Category | Count | Examples |
|----------|-------|----------|
| Compute | 50+ | VMs, AKS, App Service, Functions |
| Networking | 40+ | VNets, NSGs, Load Balancers, Front Door |
| Storage | 30+ | Storage Accounts, Cosmos DB, SQL |
| Security | 25+ | Key Vault, Managed Identities, WAF |
| Integration | 20+ | Service Bus, Event Grid, Logic Apps |
| AI/ML | 15+ | Cognitive Services, OpenAI, ML Workspaces |
### Using AVM in Bicep
```bicep
// Module from Bicep Registry (AVM)
module storageAccount 'br/public:avm/res/storage/storage-account:0.14.3' = {
name: 'storageAccountDeployment'
params: {
name: 'st${uniqueString(resourceGroup().id)}'
location: location
skuName: 'Standard_LRS'
kind: 'StorageV2'
managedIdentities: {
systemAssigned: true
}
networkAcls: {
defaultAction: 'Deny'
bypass: 'AzureServices'
}
}
}
```
### Finding AVM Modules
Use the MCP tool to discover available modules:
```
mcp_bicep_list_avm_metadata → 328 modules with:
- Module name and description
- Latest version
- Required/optional parameters
- Usage examples
```
---
## Module 3: MCP Tool Integration
### Required Extensions & MCP Servers
| Component | ID / Name | Purpose |
|-----------|-----------|--------|
| **VS Code Extension** | `ms-azuretools.vscode-bicep` | Bicep language support, IntelliSense |
| **VS Code Extension** | `ms-azuretools.vscode-azure-github-copilot` | Azure Copilot integration |
| **VS Code Extension** | `ms-vscode.azure-account` | Azure authentication |
| **MCP Server** | `bicep-mcp` | AVM lookup, schema, validation, best practices |
**Installation**:
```bash
# VS Code Extensions (required for Bicep authoring)
code --install-extension ms-azuretools.vscode-bicep
code --install-extension ms-azuretools.vscode-azure-github-copilot
code --install-extension ms-vscode.azure-account
# MCP Server enabled via VS Code MCP gallery
# Settings: chat.mcp.gallery.enabled = true
```
### Fallback Patterns (When MCP Unavailable)
If Bicep MCP tools are not available, use these alternatives:
| MCP Tool | Fallback Approach |
|----------|-------------------|
| `list_avm_metadata` | Browse <https://aka.ms/avm/modules> |
| `get_az_resource_type_schema` | Use `bicep list-api-types` CLI or ARM reference docs |
| `get_bicep_best_practices` | Reference <https://learn.microsoft.com/azure/azure-resource-manager/bicep/best-practices> |
| `get_bicep_file_diagnostics` | VS Code Bicep extension shows diagnostics automatically |
| `format_bicep_file` | Run `bicep format <file>` CLI |
| `decompile_arm_template_file` | Run `az bicep decompile --file <file>` CLI |
**Manual AVM Module Discovery**:
```bash
# Search Bicep Registry for modules
az bicep registry list --resource-group bicep-registry
# Or browse AVM directly
# https://github.com/Azure/bicep-registry-modules
```
### Available Bicep MCP Tools
| Tool | Purpose |
|------|---------|
| `mcp_bicep_list_avm_metadata` | Browse 328 Azure Verified Modules |
| `mcp_bicep_get_az_resource_type_schema` | Get resource type properties |
| `mcp_bicep_get_bicep_best_practices` | Current best practices |
| `mcp_bicep_get_bicep_file_diagnostics` | Validate Bicep files |
| `mcp_bicep_format_bicep_file` | Auto-format code |
| `mcp_bicep_decompile_arm_template_file` | Convert ARM JSON → Bicep |
| `mcp_bicep_get_file_references` | Find file dependencies |
| `mcp_bicep_get_deployment_snapshot` | Preview deployment changes |
### Common Workflows
#### Find the Right AVM Module
```
User: "I need to deploy a storage account with private endpoints"
the AI assistant → mcp_bicep_list_avm_metadata
Filter: storage
Returns: avm/res/storage/storage-account (v0.14.3)
- Supports privateEndpoints parameter
- Supports networkAcls
- Includes diagnosticSettings
```
#### Get Resource Schema
```
User: "What properties does App Service support?"
the AI assistant → mcp_bicep_get_az_resource_type_schema
provider: Microsoft.Web
resourceType: sites
Returns: Full property schema with descriptions
```
#### Validate Before Deploy
```
User: "Check my Bicep file for errors"
the AI assistant → mcp_bicep_get_bicep_file_diagnostics
filePath: main.bicep
Returns: BCP036 errors, warnings, suggestions
```
#### Convert Legacy ARM
```
User: "Convert this ARM template to Bicep"
the AI assistant → mcp_bicep_decompile_arm_template_file
filePath: azuredeploy.json
Returns: Clean Bicep code
```
---
## Module 4: Project Patterns
### Recommended Structure
```text
infrastructure/
├── main.bicep # Entry point
├── main.bicepparam # Parameters (env-specific)
├── modules/
│ ├── networking.bicep # Custom modules
│ ├── compute.bicep
│ └── data.bicep
├── types/
│ └── shared.bicep # Shared user-defined types
└── bicepconfig.json # Bicep configuration
```
### bicepconfig.json
```json
{
"analyzers": {
"core": {
"rules": {
"no-hardcoded-location": {
"level": "error"
},
"secure-parameter-default": {
"level": "error"
},
"prefer-interpolation": {
"level": "warning"
}
}
}
},
"moduleAliases": {
"br": {
"public": {
"registry": "mcr.microsoft.com/bicep"
}
}
}
}
```
### Environment-Specific Parameters
```bicep
// main.bicepparam (for dev)
using './main.bicep'
param environment = 'dev'
param skuName = 'Standard_LRS'
param instanceCount = 1
```
```bicep
// main.bicepparam (for prod)
using './main.bicep'
param environment = 'prod'
param skuName = 'Standard_GRS'
param instanceCount = 3
```
---
## Module 5: Deployment Patterns
### Azure CLI
```bash
# What-if preview
az deployment group what-if \
--resource-group myRG \
--template-file main.bicep \
--parameters main.bicepparam
# Deploy
az deployment group create \
--resource-group myRG \
--template-file main.bicep \
--parameters main.bicepparam
```
### GitHub Actions
```yaml
- name: Deploy Bicep
uses: azure/arm-deploy@v2
with:
resourceGroupName: ${{ env.RESOURCE_GROUP }}
template: ./infrastructure/main.bicep
parameters: ./infrastructure/main.bicepparam
deploymentMode: Incremental
```
### Azure DevOps
```yaml
- task: AzureCLI@2
inputs:
azureSubscription: 'AzureConnection'
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group create \
--resource-group $(resourceGroup) \
--template-file infrastructure/main.bicep \
--parameters infrastructure/main.bicepparam
```
---
## Common Diagnostic Codes
| Code | Meaning | Fix |
|------|---------|-----|
| BCP036 | Invalid property | Check resource schema |
| BCP037 | Invalid property value | Verify allowed values |
| BCP081 | Hallucinated resource/property | Use schema lookup |
| BCP035 | Missing required property | Add required params |
| BCP334 | Expected literal value | Use string/number directly |
---
## Activation Patterns
| Trigger | Response |
|---------|----------|
| "Bicep", "infrastructure as code Azure" | Full skill activation |
| "AVM", "Azure Verified Modules" | Module 2 |
| "Bicep MCP", "validate Bicep" | Module 3 |
| "Bicep project structure" | Module 4 |
| "deploy Bicep", "CI/CD Bicep" | Module 5 |
| "BCP error", "Bicep diagnostic" | Common Diagnostic Codes |
---
*Skill created: 2026-02-14 | Category: Cloud/Infrastructure | Status: Active | MCP-Enhanced: Yes*
---
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!