Automation

Azure Policy : diagnostiquer un deny avant de créer une exemption de production

Un runbook de production pour qualifier un déploiement bloqué par Azure Policy avec assignment, initiative, effet deny, conformité, exemption bornée, validation et rollback.

10 juil. 2026 azureazure-policypolicydenyexemptiongovernanceiacrbacobservabilityautomationrunbookrollbackproduction

Un déploiement Azure refusé par Azure Policy déclenche souvent une réaction trop rapide : désactiver l’assignment, créer une exemption large, changer le template pour contourner la règle, ou relancer le pipeline avec une identité plus permissive. Le message d’erreur semble administratif, mais il peut signaler une vraie dérive : région non autorisée, SKU interdit, chiffrement manquant, diagnostic absent, tag obligatoire perdu ou ressource créée hors zone de gouvernance.

Le cas d’usage est un déploiement Terraform, Bicep, ARM ou Azure DevOps qui échoue en production avec un effet deny. L’objectif du runbook est de décider si le changement doit être corrigé, exempté de façon bornée, relancé après propagation, ou bloqué. Une exemption n’est pas un raccourci : c’est une décision de production avec périmètre, expiration, preuve et rollback.

Identifier le refus exact

Commencez par figer le déploiement et l’erreur Policy. Un message RequestDisallowedByPolicy ne suffit pas : il faut l’assignment, la définition, l’initiative éventuelle, l’effet, la ressource ciblée et le champ évalué.

text policy-deny-incident.txt
Déploiement bloqué
Environnement: production
Outil: Terraform, Bicep, ARM, Azure DevOps ou GitHub Actions
Run: deploy-prod-20260710.6
Subscription: sub-prod-core
Resource group: rg-prod-app
Ressource refusée: Microsoft.Web/sites/orders-api
Opération: create ou update
Erreur: RequestDisallowedByPolicy

Preuves à collecter
policyAssignmentId
policyDefinitionId ou policySetDefinitionId
policyDefinitionReferenceId si initiative
effet réellement appliqué: deny, modify, append, audit, deployIfNotExists
champ ou alias évalué
paramètres de l'assignment
exemption existante ou absente
changement de policy récent

Si l’équipe ne peut pas relier le refus à une règle précise, elle ne doit pas créer d’exemption. Elle risquerait de contourner la mauvaise barrière.

Lire l’assignment et ses paramètres

Une policy peut être correcte dans son principe mais mal paramétrée au niveau management group, subscription ou resource group. L’incident peut venir d’une liste de régions obsolète, d’un tag obligatoire renommé, d’une initiative mise à jour ou d’une exemption expirée.

bash 01-policy-assignment-context.sh
ASSIGNMENT_ID="/providers/Microsoft.Management/managementGroups/mg-prod/providers/Microsoft.Authorization/policyAssignments/deny-unapproved-web-sku"

az policy assignment show --ids "$ASSIGNMENT_ID" --query "{name:name,scope:scope,notScopes:notScopes,enforcementMode:enforcementMode,definition:policyDefinitionId,parameters:parameters,metadata:metadata}" --output json

az policy exemption list --scope "/subscriptions/<subscription-id>/resourceGroups/rg-prod-app" --query "[].{name:name,assignment:policyAssignmentId,expires:expiresOn,category:exemptionCategory,selectors:resourceSelectors}" --output table

Vérifiez aussi si enforcementMode est Default ou DoNotEnforce. Un déploiement peut avoir passé en environnement de test parce que la règle y était auditée, puis échouer en production parce que le deny est actif.

Séparer erreur de template et règle de gouvernance

Le diagnostic doit répondre à une question simple : la policy bloque-t-elle un changement réellement non conforme, ou bloque-t-elle un cas acceptable mais non prévu ?

text policy-deny-triage.txt
Erreur de template ou de plan
Région hors liste approuvée
SKU non autorisé
Diagnostic settings absents
Public network access activé sans justification
Tag obligatoire absent ou vide
Identité managée non activée
Chiffrement ou TLS minimum non conforme

Règle trop large ou paramètre obsolète
Nouveau SKU validé mais absent des paramètres
Région ajoutée au landing zone mais pas à la policy
Alias Azure Policy ne couvre pas le nouveau mode de ressource
Initiative mise à jour sans communication d'exploitation
Exemption existante expirée sans owner

Cas à bloquer
L'exemption demandée couvrirait tout le resource group
La correction consiste à désactiver l'assignment
Le risque métier ou sécurité n'est pas documenté
Le rollback applicatif n'est pas prêt

Le bon correctif est souvent dans le template : ajouter diagnostics, tags, identité, SKU autorisé ou paramètre conforme. L’exemption doit rester l’exception, pas le mode normal de déploiement.

Retrouver la décision dans les logs

Corrélez le run avec Azure Activity et l’état Policy. Les logs permettent de distinguer une policy deny, un refus RBAC, un problème de provider ou une erreur de validation ARM.

kusto 02-policy-deny-correlation.kql
let StartTime = datetime(2026-07-10T08:00:00Z);
let EndTime = datetime(2026-07-10T09:00:00Z);
AzureActivity
| where TimeGenerated between (StartTime .. EndTime)
| where ActivityStatusValue in ("Failure", "Failed")
| where Properties has "RequestDisallowedByPolicy"
 or Properties has "policyAssignmentId"
| project TimeGenerated,
        OperationNameValue,
        ActivityStatusValue,
        Caller,
        ResourceGroup,
        ResourceProviderValue,
        ResourceId,
        CorrelationId,
        Properties
| order by TimeGenerated asc

Gardez le CorrelationId dans le ticket. Il servira à prouver que l’exemption ou la correction correspond au refus observé, et non à une hypothèse générale.

Tester la conformité avant de redéployer

Avant de relancer le pipeline, évaluez la ressource ou le scope visé. Une relance sans changement peut échouer pareil, ou pire, passer après une exemption trop large sans que personne ne voie le risque accepté.

bash 03-policy-state-check.sh
SUBSCRIPTION_ID="<subscription-id>"
RESOURCE_GROUP="rg-prod-app"

az policy state list --subscription "$SUBSCRIPTION_ID" --resource-group "$RESOURCE_GROUP" --query "[?complianceState=='NonCompliant'].{resource:resourceId,assignment:policyAssignmentName,definition:policyDefinitionName,reference:policyDefinitionReferenceId,state:complianceState,timestamp:timestamp}" --output table

az policy state summarize --subscription "$SUBSCRIPTION_ID" --resource-group "$RESOURCE_GROUP" --output json

Si l’état de conformité n’est pas encore à jour, notez-le. La décision ne doit pas dépendre d’une interface qui n’a pas encore convergé.

Encadrer l’exemption si elle est nécessaire

Une exemption de production doit être bornée par scope, ressource, assignment, durée, owner et condition de sortie. Elle ne doit pas supprimer la garde pour les futurs changements.

yaml policy-exemption-contract.yml
exemption:
reason: deploy hotfix while diagnostic settings policy parameter is corrected
assignment: deny-missing-diagnostic-settings
scope: /subscriptions/sub-prod-core/resourceGroups/rg-prod-app/providers/Microsoft.Web/sites/orders-api
category: Waiver
expires_on: 2026-07-17T18:00:00Z
owner: platform-operations
accepted_risk:
  - diagnostic setting will be added by follow-up change
  - alert coverage remains active through existing Application Insights rules
forbidden:
  - exemption at subscription scope
  - disabling assignment
  - changing policy effect from deny to audit for all resources
exit_criteria:
  - template corrected
  - compliance scan green
  - exemption removed
  - deployment validation attached to incident

Si le besoin est durable, corrigez la policy ou ses paramètres. Une exemption longue sans owner devient une nouvelle dette de gouvernance.

Décider correction, exemption ou blocage

La sortie du runbook doit être explicite. Le pipeline ne doit pas simplement passer au vert : il doit passer avec une décision compréhensible.

text policy-deny-decision.txt
Corriger le template
Le refus correspond à une exigence valide
La correction est limitée et testable
Aucun contournement de policy n'est nécessaire
Le plan montre uniquement les changements attendus

Corriger la policy ou ses paramètres
La règle est légitime mais les paramètres sont obsolètes
Le changement de gouvernance est relu comme du code
Les scopes impactés sont identifiés
Un scan de conformité valide le résultat

Créer une exemption bornée
Le besoin de production est réel et temporaire
Le risque accepté est documenté
Scope, expiration et owner sont définis
La sortie d'exemption est planifiée

Bloquer
La demande masque un risque sécurité ou conformité
Le scope d'exemption est trop large
Le déploiement a déjà produit un état partiel non qualifié
Le rollback applicatif ou infrastructure est absent

Cette matrice évite deux dérives opposées : bloquer toute livraison par rigidité, ou vider Azure Policy de son sens en créant des exceptions globales.

Valider après action et rollbacker la garde

Après correction ou exemption, relancez avec le même artefact ou un plan clairement identifié. Puis vérifiez à la fois le service et la gouvernance.

text post-policy-action-validation.txt
Validation minimale
Le déploiement concerne le run et le commit approuvés
La ressource créée ou modifiée correspond au scope prévu
Azure Activity ne montre plus de deny inattendu
Les policies non liées restent actives
L'état de conformité est relu après propagation
Les probes applicatives passent
L'exemption contient owner, expiration et justification

Rollback
Supprimer l'exemption si la validation échoue
Revenir au template précédent si la correction casse le service
Restaurer les paramètres de policy si l'initiative a été trop ouverte
Réexécuter un scan de conformité
Garder la trace du deny initial, de la décision et de la sortie

Conclusion

Un deny Azure Policy n’est pas seulement une erreur de déploiement. C’est un point de décision entre conformité, continuité de service et exploitation.

Le runbook doit donc aboutir à une décision traçable : corriger le template, ajuster la policy, créer une exemption temporaire et bornée, ou bloquer. La bonne validation n’est pas seulement un pipeline vert, mais une ressource conforme, une garde toujours active et un rollback prêt si l’exception se révèle trop risquée.