Das Entfernen von Bicep-Code entfernt nicht immer die Ressource? Deployment Stacks verwenden

Veröffentlicht am:

CloudTrips entfernt einen temporären Blob-Container aus Bicep, doch eine normale inkrementelle Bereitstellung lässt den vorhandenen Container in Azure bestehen. Code und Umgebung stimmen nicht mehr überein, und die übrig gebliebene Ressource hat keinen klaren Besitzer.

Verwende einen Azure Deployment Stack für Ressourcen, deren Lebenszyklus der Bicep-Definition folgen muss. Ein Deployment Stack ist eine Azure-Ressource, die festhält, welche Ressourcen durch ihn bereitgestellt wurden. Verschwindet eine verwaltete Ressource aus dem Template, kann der Stack sie abkoppeln oder löschen.

In diesem Lab wird absichtlich ein Blob-Container gelöscht. Verwende die dafür vorgesehene Ressourcengruppe und keine bestehende CloudTrips-Umgebung.

Dieser Trip baut auf folgendem Trip auf: Bedingungen und Schleifen verwenden. Dort siehst du, warum eine normale inkrementelle Bereitstellung eine entfernte bedingte Ressource zurücklassen kann; dieses isolierte Lab zeigt, wie ein Deployment Stack diesen Lebenszyklus verändert.

Das temporäre Lab vorbereiten

Wähle im Stammverzeichnis des Repositorys das CloudTrips-TEST-Abonnement aus und erstelle die leere Lab-Ressourcengruppe:

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

az group create \
  --name rg-cloudtrips-bicep-stack-test-weu \
  --location westeurope

Das Template cloudtrips-bicep/deployment-stacks/initial.bicep erstellt ein Speicherkonto mit zwei privaten Containern:

resource uploadsContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2025-06-01' = {
  parent: blobService
  name: 'uploads'
  properties: {
    publicAccess: 'None'
  }
}

resource temporaryContainer 'Microsoft.Storage/storageAccounts/blobServices/containers@2025-06-01' = {
  parent: blobService
  name: 'temporary'
  properties: {
    publicAccess: 'None'
  }
}

Die zweite Datei cloudtrips-bicep/deployment-stacks/without-temporary-container.bicep definiert dasselbe Speicherkonto, denselben Blob-Dienst und den Container uploads, enthält aber keine Ressource für den Container temporary.

Prüfe beide Zustände vor der Verwendung:

az bicep lint \
  --file cloudtrips-bicep/deployment-stacks/initial.bicep

az bicep lint \
  --file cloudtrips-bicep/deployment-stacks/without-temporary-container.bicep

Den Deployment Stack erstellen

Erstelle aus dem ersten Template einen Stack auf Ressourcengruppenebene:

az stack group create \
  --name stack-cloudtrips-storage-lifecycle-test \
  --resource-group rg-cloudtrips-bicep-stack-test-weu \
  --template-file cloudtrips-bicep/deployment-stacks/initial.bicep \
  --action-on-unmanage deleteResources \
  --deny-settings-mode none \
  --yes

deleteResources weist den Stack an, eine verwaltete Azure-Ressource zu löschen, wenn sie aus einem späteren Template entfernt wird. deny-settings-mode none fügt keine Deny Assignments hinzu; dieses Lab konzentriert sich ausschließlich auf die Lebenszyklusverwaltung.

Zeige den Stack und die IDs seiner verwalteten Ressourcen an:

az stack group show \
  --name stack-cloudtrips-storage-lifecycle-test \
  --resource-group rg-cloudtrips-bicep-stack-test-weu \
  --query "{state:provisioningState,managedResources:resources[].id}" \
  --output yaml

Der Status sollte succeeded sein. Die verwalteten Ressourcen sollten sowohl den Container uploads als auch temporary enthalten. Öffne im Azure-Portal die Ressourcengruppe und wähle Deployment stacks > stack-cloudtrips-storage-lifecycle-test, um dieselbe Liste anzuzeigen.

Erfolgreicher CloudTrips Deployment Stack mit dem Speicherkonto und beiden verwalteten Containern

Zeigen, warum eine normale Bereitstellung nicht ausreicht

Zeige das Template ohne den temporären Container zunächst als normale Ressourcengruppenbereitstellung in der Vorschau an:

az deployment group what-if \
  --resource-group rg-cloudtrips-bicep-stack-test-weu \
  --template-file cloudtrips-bicep/deployment-stacks/without-temporary-container.bicep

Die normale inkrementelle Vorschau schlägt keine Löschung von temporary vor. Ressourcen, die in einem inkrementellen Template fehlen, bleiben normalerweise in Azure bestehen.

Aktualisiere nun den vorhandenen Stack mit demselben Template:

az stack group create \
  --name stack-cloudtrips-storage-lifecycle-test \
  --resource-group rg-cloudtrips-bicep-stack-test-weu \
  --template-file cloudtrips-bicep/deployment-stacks/without-temporary-container.bicep \
  --action-on-unmanage deleteResources \
  --deny-settings-mode none \
  --yes

Da Stackname und Bereich bereits vorhanden sind, ist dies ein Update. Azure vergleicht die bisherige Liste verwalteter Ressourcen mit dem neuen Template. Der Container temporary ist nun nicht mehr verwaltet und wird deshalb durch deleteResources gelöscht. Das Speicherkonto, der Blob-Dienst und der Container uploads bleiben verwaltet.

Prüfe das Ergebnis:

az stack group show \
  --name stack-cloudtrips-storage-lifecycle-test \
  --resource-group rg-cloudtrips-bicep-stack-test-weu \
  --query "{state:provisioningState,deletedResources:deletedResources[].id,managedResources:resources[].id}" \
  --output yaml

Der Status sollte erneut succeeded sein. Die Liste der gelöschten Ressourcen sollte den Container temporary enthalten, während uploads weiterhin in der Liste der verwalteten Ressourcen erscheint.

Aktualisierter CloudTrips Deployment Stack mit gelöschtem temporären Container und weiterhin verwaltetem uploads-Container

Das Lebenszyklusverhalten bewusst auswählen

--action-on-unmanage steuert, was geschieht, wenn eine Ressource das Template verlässt oder der Stack selbst gelöscht wird:

Wert Ergebnis
detachAll Ressourcen in Azure behalten, aber nicht mehr mit dem Stack verwalten
deleteResources Verwaltete Ressourcen löschen, jedoch keine verwalteten Ressourcengruppen
deleteAll Verwaltete Ressourcen und Ressourcengruppen löschen, die von einem Stack mit größerem Bereich verwaltet werden

Verwende detachAll, wenn die Verantwortung ohne Löschung übertragen werden soll. Verwende eine Löschoption nur, wenn der Stack den vollständigen Lebenszyklus besitzen soll und die Löschung geprüft wurde.

Das temporäre Lab entfernen

Lösche den Stack und seine verbleibenden verwalteten Ressourcen:

az stack group delete \
  --name stack-cloudtrips-storage-lifecycle-test \
  --resource-group rg-cloudtrips-bicep-stack-test-weu \
  --action-on-unmanage deleteResources \
  --yes

Lösche anschließend die leere Lab-Ressourcengruppe:

az group delete \
  --name rg-cloudtrips-bicep-stack-test-weu \
  --yes

CloudTrips hat damit den Unterschied zwischen der Bereitstellung eines Templates und der Verwaltung eines Ressourcenlebenszyklus gezeigt. Wird eine Definition aus einer normalen inkrementellen Bereitstellung entfernt, bleibt die Ressource bestehen. Wird sie aus einem Stack mit deleteResources entfernt, wird die Ressource bewusst gelöscht.