Teams bauen dieselben Azure-Muster immer wieder? Azure Verified Modules verwenden

Veröffentlicht am:

Jedes Team kann ein eigenes Speicherkonto mit Blob-Dienst, Containern, Sicherheitseinstellungen, Diagnose und Rollenzuweisungen erstellen. Das Ergebnis ist wiederholter Bicep-Code mit unterschiedlichen Standardwerten, uneinheitlicher Sicherheit und höherem Wartungsaufwand.

Azure Verified Modules (AVM) sind versionierte, von Microsoft gepflegte Module für häufig verwendete Azure-Ressourcen und -Muster. Ersetze die Standardimplementierung des Speichers durch AVM. Der CloudTrips-Wrapper bleibt weiterhin für Namen, Tags, Umgebungseingaben, Container und Ausgaben verantwortlich.

Speichermodul finden

Öffne den Bicep-Index der Azure Verified Modules und wähle das Ressourcenmodul Storage Account. Die Seite dokumentiert unterstützte Parameter, Ausgaben, Beispiele und Versionen.

Diese Implementierung verwendet:

br/public:avm/res/storage/storage-account:0.32.1
  • br/public ist der Alias für die öffentliche Bicep-Registry von Microsoft.
  • avm/res/storage/storage-account identifiziert das Ressourcenmodul.
  • 0.32.1 fixiert die von CloudTrips getestete Version.

Gib immer eine Version an. Das Upgrade eines AVM ist eine Infrastrukturänderung, die Review und what-if durchlaufen muss; es darf nicht unbemerkt erfolgen.

Index der Azure Verified Modules mit geöffnetem Bicep-Modul für Speicherkonten

Benutzerdefinierte Ressourcenimplementierung ersetzen

Die vorhandene Datei main.bicep ruft bereits einen lokalen Wrapper unter modules/storage.bicep auf. Behalte diese Grenze bei, aber ersetze die direkten Speicherressourcen im Wrapper durch das verifizierte Modul:

param applicationName string
param containerNames array
param costCenter string
param deployAuditContainer bool
param environment string
param location string
param owner string
param storageSku string

var normalizedEnvironment = toLower(environment)
var storageAccountName = 'stct${normalizedEnvironment}${uniqueString(resourceGroup().id)}'
var commonTags = {
  Application: applicationName
  CostCenter: costCenter
  Environment: toUpper(normalizedEnvironment)
  ManagedBy: 'Bicep'
  Owner: owner
}

var appContainers = [
  for containerName in containerNames: {
    name: containerName
    defaultEncryptionScope: '$account-encryption-key'
    denyEncryptionScopeOverride: false
    publicAccess: 'None'
  }
]
var auditContainers = deployAuditContainer
  ? [
      {
        name: 'audit'
        defaultEncryptionScope: '$account-encryption-key'
        denyEncryptionScopeOverride: false
        publicAccess: 'None'
      }
    ]
  : []
var blobContainers = concat(appContainers, auditContainers)

module storageAccount 'br/public:avm/res/storage/storage-account:0.32.1' = {
  name: '${deployment().name}-avm-storage'
  params: {
    name: storageAccountName
    location: location
    tags: commonTags
    skuName: storageSku
    kind: 'StorageV2'
    allowBlobPublicAccess: false
    allowCrossTenantReplication: false
    allowSharedKeyAccess: true
    blobServices: {
      containerDeleteRetentionPolicyEnabled: true
      containerDeleteRetentionPolicyDays: 7
      deleteRetentionPolicyEnabled: true
      deleteRetentionPolicyDays: 7
      deleteRetentionPolicyAllowPermanentDelete: false
      containers: blobContainers
    }
    defaultToOAuthAuthentication: false
    enableTelemetry: false
    minimumTlsVersion: 'TLS1_2'
    networkAcls: {
      bypass: 'None'
      defaultAction: 'Allow'
    }
    requireInfrastructureEncryption: false
    supportsHttpsTrafficOnly: true
  }
}

output storageAccountName string = storageAccount.outputs.name
output storageAccountId string = storageAccount.outputs.resourceId
output blobEndpoint string = storageAccount.outputs.primaryBlobEndpoint
output containerIds array = [
  for containerName in containerNames: resourceId(
    'Microsoft.Storage/storageAccounts/blobServices/containers',
    storageAccountName,
    'default',
    containerName
  )
]
output auditContainerId string? = deployAuditContainer
  ? resourceId(
      'Microsoft.Storage/storageAccounts/blobServices/containers',
      storageAccountName,
      'default',
      'audit'
    )
  : null

Der lokale Wrapper stellt main.bicep weiterhin dieselben Parameter und Ausgaben bereit. Er wandelt die CloudTrips-Containerarrays in das AVM-Eingabeformat um und ordnet die AVM-Ausgaben dem vorhandenen Vertrag zu.

Firewall-Bypass und Containerverschlüsselung sind explizit, da diese Einstellungen bereits in TEST existieren. AVM besitzt eigene Standardwerte; ihnen während eines Refactorings zu vertrauen, könnte eine aktive Einstellung ändern. Telemetrie ist für diese Lernbereitstellung deaktiviert.

Modul wiederherstellen und validieren

Führe in cloudtrips-bicep aus:

az bicep restore \
  --file modules/storage.bicep

az bicep lint \
  --file modules/storage.bicep

az bicep build-params \
  --file environments/test.bicepparam \
  --stdout > /dev/null

restore lädt das fixierte Modul in den lokalen Bicep-Cache. Das Repository speichert nur die versionierte Modulreferenz und keine Kopie der AVM-Implementierung. Verwende in VS Code Go to Definition auf der Modulreferenz, um den wiederhergestellten Quellcode zu prüfen.

Refactoring vor der Freigabe prüfen

Der eingecheckte Snapshot beschreibt weiterhin die manuell geschriebene Implementierung. Führe zuerst die Snapshot-Validierung aus:

"$HOME/.azure/bin/bicep" snapshot environments/test.bicepparam \
  --mode validate \
  --subscription-id 00000000-0000-0000-0000-000000000000 \
  --resource-group rg-cloudtrips-bicep-test-weu \
  --location westeurope \
  --deployment-name deploy-cloudtrips-storage-test

Sie soll fehlschlagen, da AVM in eine andere verschachtelte Vorlage mit mehr expliziten Anbietereigenschaften kompiliert wird. Das ist zu erwarten, beweist aber noch nicht, dass die Änderung sicher ist.

Wähle CloudTrips TEST und vergleiche die kompilierte Vorlage mit Azure:

az account set \
  --subscription "<Name oder ID des CloudTrips-TEST-Abonnements>"

az deployment group what-if \
  --resource-group rg-cloudtrips-bicep-test-weu \
  --parameters environments/test.bicepparam \
  --validation-level Provider

Das vorhandene Speicherkonto soll Namen, Ressourcen-ID, SKU, Tags, TLS-Konfiguration, Firewallverhalten und Einstellung für öffentlichen Zugriff behalten. Die drei Container sollen NoChange melden. Speicherkonto und Blob-Dienst können Modify anzeigen, da AVM explizite Standardwerte sendet, die in der ursprünglichen Vorlage fehlten, und Azure einige optionale Eigenschaften normalisiert. Es darf keine Ressource gelöscht, erstellt oder ersetzt werden.

Bicep-What-if ohne Ersetzung und mit NoChange für alle drei CloudTrips-Container

Genehmige nach der Prüfung von what-if die neue kompilierte Baseline:

"$HOME/.azure/bin/bicep" snapshot environments/test.bicepparam \
  --mode overwrite \
  --subscription-id 00000000-0000-0000-0000-000000000000 \
  --resource-group rg-cloudtrips-bicep-test-weu \
  --location westeurope \
  --deployment-name deploy-cloudtrips-storage-test

Führe denselben Befehl nochmals mit --mode validate aus. Er sollte jetzt ohne Unterschied abgeschlossen werden.

Geprüfte Version bereitstellen

Committe Wrapper und aktualisierten Snapshot:

git add modules/storage.bicep \
  environments/test.snapshot.json

git commit -m "Use AVM for the CloudTrips storage account"

Pushe den Feature-Branch und öffne einen Pull Request. Die konfigurierte GitHub-Actions- oder Azure-DevOps-Pipeline stellt die öffentliche Abhängigkeit wieder her, validiert den Snapshot, führt Live-Preflight und what-if aus und stellt die genehmigte Version bereit.

Erfolgreiche Pipeline-Bereitstellung nach Einführung des Azure Verified Module für Speicherkonten

CloudTrips verwendet nun eine geprüfte Azure-Implementierung wieder, ohne die eigenen Standards zu verlieren. AVM reduziert wiederholten Ressourcencode; Architekturentscheidungen, Prüfung fixierter Versionen, what-if und Tests bleiben weiterhin erforderlich.