Infrastructure as Code with ARM Templates and Bicep: Part 5 – Advanced Bicep Patterns

Infrastructure as Code with ARM Templates and Bicep: Part 5 – Advanced Bicep Patterns

This entry is part 5 of 7 in the series Infrastructure as Code templates using ARM and Bicep

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.

Navigate<< Infrastructure as Code with ARM Templates and Bicep: Part 4 – Introduction to BicepInfrastructure as Code with ARM Templates and Bicep: Part 6 – CI/CD Integration and Advanced Deployment >>

Written by:

265 Posts

View All Posts
Follow Me :