Azure Policy sicher ausrollen und Regeln kontrolliert aktivieren
Im Grundlagenartikel zu Azure Policy haben wir gezeigt, wofür Azure Policy geeignet ist und wie Definitionen, Initiativen, Assignments und Ausnahmen zusammenspielen. Im zweiten Teil der Reihe geht es darum, Policies mit Bicep oder Terraform als versioniertes Regelwerk zu organisieren. Dieser Artikel zeigt, wie du diese Regeln schrittweise ausrollst und kontrolliert aktivierst.
Eine neue Deny-Policy kann ein bisher unauffälliges Deployment sofort stoppen. Das passiert beispielsweise, wenn eine Regel gegen öffentlichen Storage-Zugriff auf eine Subscription mit älteren Storage Accounts trifft. Die Policy Definition kann dabei korrekt sein, problematisch sind der zu große Geltungsbereich und der ungeprüfte Bestand.
Eine solche Änderung gehört deshalb in den Release-Prozess der Plattform. In einem einzelnen Pull Request kurz vor dem Merge bleiben betroffene Teams, bestehende Ausnahmen und mögliche Treffer leicht unbemerkt. Bei einem gestuften Rollout kann das Plattformteam diese Treffer prüfen, bevor die Policy ein produktives Deployment blockiert oder Ressourcen verändert.
Was eine Policy im Betrieb tatsächlich auslösen kann
Eine Policy greift direkt in Deployments ein. Eine deny-Regel entscheidet bei Create oder Update über den Request. modify und deployIfNotExists können Konfiguration ergänzen. Eine Remediation-Aufgabe wendet die dafür vorgesehene Änderung nachträglich auf Bestandsressourcen an.
Der Test richtet sich nach diesem Effekt. Bei deny reicht das Lesen der Definition nicht. Ein absichtlich nicht konformer Request muss mit der erwarteten Fehlermeldung scheitern. Bei modify und deployIfNotExists zählt zusätzlich das Ergebnis an der Ressource. Azure muss die gewünschte Eigenschaft setzen, und dieselbe Änderung muss sich am Bestand nachvollziehbar wiederholen lassen.
Microsoft beschreibt denselben Grundsatz in den Safe-Deployment-Practices für Azure Policy. Der erste Scope sollte klein genug sein, dass ein Fehler noch keine breite Betriebsstörung auslöst.
Scopes und Ausnahmen vor dem Rollout klären
Der Speicherort einer Definition bestimmt nicht ihre Wirkung. Erst ein Assignment macht sie auf einem Management Group-, Subscription- oder Resource Group-Scope wirksam. Wenn ein Deployment blockiert wird, ist die Assignment-Hierarchie der erste Prüfpunkt. Ein weniger strenges Assignment auf Subscription-Ebene hebt eine restriktive Zuweisung vom Elternscope nicht auf.
notScopes und Exemptions lösen unterschiedliche Probleme. notScopes nehmen einen Bereich vollständig aus der Auswertung eines Assignments heraus. Das passt zu einer dauerhaften strukturellen Grenze, etwa einer getrennten Sandbox. Eine Exemption hält die Ressource dagegen im Scope und zeigt die Abweichung weiterhin im Compliance-Reporting. Damit bleibt eine zeitlich begrenzte Ausnahme eines Teams sichtbar.
Zu einer Exemption gehören ein fachlicher Grund, ein Owner und ein Review-Termin. Die Struktur einer Azure-Policy-Exemption beschreibt die dafür relevanten Felder.
Bei einer Initiative enthält policyDefinitionReferenceIds nur die stabile policyDefinitionReferenceId der betroffenen Definition, statt das gesamte Set auszunehmen. Waiver im Feld exemptionCategory kennzeichnet eine genehmigte Ausnahme. expiresOn gibt den Zeitpunkt an, bis zu dem Azure die Exemption bei der Policy-Auswertung berücksichtigt.
{
"properties": {
"policyAssignmentId": "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.Authorization/policyAssignments/platform-baseline",
"policyDefinitionReferenceIds": ["storagePublicAccess"],
"exemptionCategory": "Waiver",
"expiresOn": "2027-01-31T23:59:00Z",
"metadata": {
"ticketRef": "PLAT-1842"
}
}
}
Nach expiresOn bleibt die Exemption-Ressource zur Dokumentation bestehen, aber Azure berücksichtigt sie nicht mehr bei der Policy-Auswertung.
Solange dieser Weg nicht geklärt ist, sollte die Regel nur Verstöße melden. Direktes Durchsetzen ist erst sinnvoll, wenn Scope, Vererbung und Umgang mit Ausnahmen nachvollziehbar sind.
Einen Testscope mit absichtlichen Verstößen aufbauen
Am einfachsten lässt sich die Policy in einer isolierten Dev- oder Sandbox-Subscription prüfen. Wo das nicht möglich ist, braucht der Test wenigstens eine eigens dafür abgegrenzte Resource Group. Ein gemeinsam genutzter Dev-Scope mit alten Experimenten und Ressourcen anderer Teams liefert dagegen einen schwer interpretierbaren Compliance-Status.
Zum Test gehören mindestens zwei reproduzierbare Fälle. Einer erfüllt die Regel, der andere verstößt absichtlich dagegen. Für modify und deployIfNotExists kommt ein Bestandsobjekt hinzu, an dem sich die Remediation kontrollieren lässt. Die Hinweise zum Evaluieren des Impacts empfehlen diese Prüfung im Zielsystem.
Alias-Verhalten und Provider-Eigenheiten fallen häufig erst bei einem echten Resource-Manager-Request auf. Ein Resource-Manager-Request ist der Create- oder Update-Aufruf an Azure Resource Manager, den beispielsweise ein Bicep-Deployment auslöst. Eine JSON-Prüfung der Definition kann diesen Test nicht ersetzen.
param location string = 'westeurope'
resource compliantStorage 'Microsoft.Storage/storageAccounts@2024-01-01' = {
name: 'stpolicyokdemo01'
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
allowBlobPublicAccess: false
}
}
resource nonCompliantStorage 'Microsoft.Storage/storageAccounts@2024-01-01' = {
name: 'stpolicyfaildemo01'
location: location
sku: {
name: 'Standard_LRS'
}
kind: 'StorageV2'
properties: {
allowBlobPublicAccess: true
}
}
Das Beispiel erzeugt einen erlaubten Request und einen erwarteten Audit-Fund oder Block. Ein wiederholbarer Test räumt beide Ressourcen anschließend auf oder stellt denselben Ausgangszustand wieder her. Sonst vermischt der nächste Lauf neue Policy-Treffer mit Rückständen aus dem vorherigen Test.
Den Rollout stufenweise durchsetzen
Alle Produktivsubscriptions sind kein geeigneter Startpunkt. Für eine spätere Deny-Regel liefert audit zunächst reale Treffer, ohne den Create- oder Update-Pfad zu blockieren. Bei modify und deployIfNotExists bietet sich enforcementMode: DoNotEnforce an. Azure ermittelt dann weiterhin den Compliance-Status, führt den Effekt bei Create oder Update aber nicht aus.
Mit resourceSelectors lässt sich der erste Rollout beispielsweise nach Region oder Ressourcentyp begrenzen. Organisatorische Tiers lassen sich damit nicht immer abbilden. Wenn jede Produktgruppe eigene Subscriptions betreibt, sind getrennte Assignments oder Scopes meist verständlicher als eine indirekte Auswahl über technische Merkmale.
Das folgende Assignment testet die Regel in einer Region.
Es setzt voraus, dass die benutzerdefinierte Definition storage-public-access auf der angegebenen Management Group liegt und das Bicep-Deployment auf diesem Scope läuft.
resource stagedPolicyAssignment 'Microsoft.Authorization/policyAssignments@2026-06-01' = {
name: 'storage-public-access-rollout-stage-1'
properties: {
displayName: 'Storage Public Access Guardrail, Rollout Stage 1'
policyDefinitionId: managementGroupResourceId('Microsoft.Authorization/policyDefinitions', 'storage-public-access')
enforcementMode: 'DoNotEnforce'
resourceSelectors: [
{
name: 'rollout-stage-1-subset'
selectors: [
{
// Erster Rollout nur in einer wenig kritischen Region.
kind: 'resourceLocation'
in: [
'westeurope'
]
}
]
}
]
}
}
Nach einem erfolgreichen Lauf kann eine weitere Region in den Selector aufgenommen werden. Das Ergebnis braucht trotzdem eine neue Prüfung. Nicht jede Abweichung ist ein Policy-Fehler. Möglicherweise verwendet ein Team bewusst ein bisher geduldetes Deployment-Muster. Erst wenn alle Rollout-Stufen mit DoNotEnforce erwartbare Ergebnisse liefern, wechselt die erste Produktivsubscription zu Default.
Default ist der normale Durchsetzungsmodus. Azure wendet den Effect dann bei Create- und Update-Requests wie im Assignment vorgesehen an.
Ein Compliance-Gate muss den Rollout wirklich stoppen
Vor der nächsten Rollout-Stufe braucht der Rollout eine überprüfbare Erwartung. Im Testscope kann das genau ein bekannter non-compliant Fund sein, jedoch kein unerwarteter Deny-Fehler. Bei modify und deployIfNotExists gehört außerdem die kontrollierte Ressourceneigenschaft zum Gate. Der Status einer Remediation-Aufgabe allein beweist nicht, dass die gewünschte Konfiguration an der Ressource angekommen ist.
Die integrierten Evaluierungen und Azure Resource Graph sind dafür ein brauchbarer Ausgangspunkt. Ein Bericht ohne Konsequenz ist jedoch kein Gate. Bei einem unerwarteten Ergebnis muss die Pipeline abbrechen.
Azure Resource Graph durchsucht zentral die Ressourcen- und Policy-Daten der ausgewählten Scopes. Die Abfragen verwenden die Kusto Query Language (KQL). Dieses Kusto-Beispiel zählt non-compliant Ressourcen für das Assignment.
PolicyResources
| where type =~ 'microsoft.policyinsights/policystates'
| extend policyAssignmentName = tostring(properties.policyAssignmentName)
| extend complianceState = tostring(properties.complianceState)
| where policyAssignmentName == 'storage-public-access-rollout-stage-1'
| summarize nonCompliant = countif(complianceState == 'NonCompliant')
Stimmt die Zahl nicht mit der Erwartung überein, muss der Policy Rollout gestoppt werden. Die vorherige Assignment-Version sollte deshalb im Repository verfügbar bleiben. So lässt sich der Selector wieder verkleinern oder modify beziehungsweise deployIfNotExists auf DoNotEnforce zurückstellen, ohne die Konfiguration während einer Störung rekonstruieren zu müssen.
Remediation und Built-in-Updates getrennt behandeln
Für eine Remediation-Aufgabe brauchst du eine Managed Identity am Assignment und passende Rollen auf dem Zielscope. Azure Role-Based Access Control (Azure RBAC) steuert diese Berechtigungen über Rollenzuweisungen. Das Portal vergibt erforderliche Rollen bei einigen Abläufen automatisch. Bei Bicep oder anderem Infrastructure as Code bleibt diese Zuweisung deine Aufgabe. Die Dokumentation zur Remediation nennt die benötigten Rollen je Definition.
Eine erste Remediation sollte nur wenige bekannte Ressourcen umfassen. Nach dem Lauf werden sowohl die Ressourceneigenschaft als auch der Compliance-Status kontrolliert. Fehlen der Managed Identity die benötigten Rollen, ist der Fehler auf diesem kleinen Scope leichter zuzuordnen. Bei einer breit gestarteten Remediation entsteht dagegen dieselbe Fehlermeldung für viele Ressourcen und entsprechend viel Nacharbeit für die betroffenen Teams.
Auch ein Update einer integrierten Definition verändert die wirksame Regel. Eine neue Version läuft deshalb zuerst auf einem kleinen Selector. Ein Override im Assignment steuert für eine einzelne Policy-Definition einer Initiative gezielt den Effect oder die Version, ohne die Initiative zu ändern. Erst das geprüfte Ergebnis rechtfertigt die Übernahme in das breite Assignment.
Policy-Rollouts dürfen kein Überraschungseffekt sein
Ein sicherer Policy-Rollout beginnt mit einem kleinen Testscope, absichtlichen Verstößen und einer klaren Abbruchbedingung. Die Prüfung umfasst die Definition, vorhandene Ressourcen, Ausnahmen und Deployment-Wege.
Danach wird jeweils nur eine Variable verändert. Das Team erweitert etwa einen Selector, bewertet die neuen Treffer und gibt anschließend die nächste Stufe frei. Dieses Vorgehen dauert länger als ein globales Assignment, begrenzt aber die Auswirkungen einer falsch eingeschätzten Regel.
Welche Policy-Rollouts haben bei euch gut funktioniert und wo lagen die Stolpersteine? Teile deine Erfahrungen mit uns auf LinkedIn.
Autoren

Felix Burkhard
Felix ist Solution Architect mit Fokus auf skalierbare Azure-IoT-Lösungen, agile Entwicklungsprozesse und DevOps. Er verbindet tiefes technisches Verständnis mit pragmatischer Umsetzung und schafft so nachhaltigen Geschäftsnutzen.





