⚠️ Staleness Watch: The AVM registry grows monthly — module counts and version numbers change frequently. Always use mcp_bicep_list_avm_metadata 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
Avoid setting name for module statements — no longer required
Use user-defined types for grouped param/output values instead of multiple params
Prefer .bicepparam files over JSON parameters files
Resource Patterns
// ✅ 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
// ✅ 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
// ✅ ALWAYS use @secure() for sensitive data
@secure()
param adminPassword string
@secure()
param connectionString string
Null Handling
// ✅ 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.
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:
# 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"
Alex → 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?"
Alex → 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"
Alex → mcp_bicep_get_bicep_file_diagnostics
filePath: main.bicep
Returns: BCP036 errors, warnings, suggestions
Convert Legacy ARM
User: "Convert this ARM template to Bicep"
Alex → mcp_bicep_decompile_arm_template_file
filePath: azuredeploy.json
Returns: Clean Bicep code