- Infrastructure as Code with ARM Templates and Bicep: Part 1 – ARM Template Fundamentals
- Infrastructure as Code with ARM Templates and Bicep: Part 2 – Building Production-Ready Infrastructure
- Infrastructure as Code with ARM Templates and Bicep: Part 3 – Advanced ARM Template Patterns
- Infrastructure as Code with ARM Templates and Bicep: Part 4 – Introduction to Bicep
- Infrastructure as Code with ARM Templates and Bicep: Part 5 – Advanced Bicep Patterns
- Infrastructure as Code with ARM Templates and Bicep: Part 6 – CI/CD Integration and Advanced Deployment
- Infrastructure as Code with ARM Templates and Bicep: Part 7 – Enterprise Governance and Compliance

This part explores advanced Bicep capabilities that enable enterprise-scale Infrastructure as Code. We’ll cover module registries, advanced patterns, testing strategies, and governance practices.
What You’ll Learn
- Bicep module registries and sharing
- Advanced deployment patterns
- Testing and validation strategies
- Security and governance practices
- Enterprise-scale architecture patterns
Module Registries
# Create Azure Container Registry for Bicep modules
az acr create \
--resource-group rg-shared \
--name acrBicepModules \
--sku Standard
# Publish module to registry
az bicep publish \
--file modules/storage.bicep \
--target br:acrbicepmodules.azurecr.io/bicep/modules/storage:v1.0.0
Enterprise Storage Module with User-Defined Types
// User-defined types
@export()
type StorageConfig = {
@description('Storage account name')
@minLength(3)
@maxLength(24)
name: string
@description('Storage account SKU')
@allowed(['Standard_LRS', 'Standard_GRS', 'Premium_LRS'])
sku: string
@description('Access tier for blob storage')
@allowed(['Hot', 'Cool'])
accessTier: string?
}
// Parameters
@description('Storage account configuration')
param storageConfig StorageConfig
@description('Environment name')
@allowed(['dev', 'staging', 'prod'])
param environment string
// Storage Account
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
name: storageConfig.name
location: resourceGroup().location
sku: {
name: storageConfig.sku
}
kind: 'StorageV2'
properties: {
accessTier: storageConfig.accessTier ?? 'Hot'
allowBlobPublicAccess: false
minimumTlsVersion: 'TLS1_2'
supportsHttpsTrafficOnly: true
}
}
Testing Framework
// Test framework for Bicep templates
param runTests bool = true
// Import the main template
module mainTemplate '../main.bicep' = if (runTests) {
name: 'test-deployment'
params: {
projectName: 'test'
environment: 'dev'
sqlAdministratorLogin: 'testadmin'
sqlAdministratorPassword: 'TestPassword123!'
}
}
// Test validation
resource testResults 'Microsoft.Resources/deploymentScripts@2023-08-01' = if (runTests) {
name: 'test-validation'
location: resourceGroup().location
kind: 'AzurePowerShell'
properties: {
azPowerShellVersion: '8.0'
scriptContent: '''
# Verify storage account security
$storageAccount = Get-AzStorageAccount -ResourceGroupName $env:RESOURCE_GROUP_NAME
if ($storageAccount.EnableHttpsTrafficOnly -ne $true) {
throw "Storage account HTTPS-only not enabled"
}
Write-Output "All tests passed"
'''
}
}
Security Patterns
// Key Vault integration
param appName string
param environment string
// User-assigned managed identity
resource appIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = {
name: 'id-${appName}-${environment}'
location: resourceGroup().location
}
// Key Vault
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
name: 'kv-${appName}-${environment}-${uniqueString(resourceGroup().id)}'
location: resourceGroup().location
properties: {
tenantId: tenant().tenantId
sku: {
family: 'A'
name: environment == 'prod' ? 'premium' : 'standard'
}
enableRbacAuthorization: true
enablePurgeProtection: environment == 'prod'
publicNetworkAccess: environment == 'prod' ? 'Disabled' : 'Enabled'
}
}
Best Practices
- Use Module Registries: Centralize and version reusable modules
- Implement User-Defined Types: Create strongly-typed interfaces
- Security by Default: Build security controls into modules
- Comprehensive Testing: Implement automated testing
- Multi-Region Design: Plan for global deployments
What’s Next?
In Part 6, we’ll explore CI/CD integration patterns, automated testing strategies, and advanced deployment scenarios including blue-green deployments and canary releases.
This is Part 5 of our 7-part series on Infrastructure as Code with ARM Templates and Bicep.