Automation

Azure DevOps : valider approvals et checks avant de bypasser la production

Un runbook de production pour qualifier un déploiement Azure DevOps bloqué par approvals ou checks avec environnement, identité, logs, audit, validation et rollback avant de contourner la garde.

10 juil. 2026 azure-devopspipelinesapprovalschecksenvironmentsidentityauditobservabilityautomationrunbookrollbackproduction

Un déploiement Azure DevOps bloqué sur un approval, un check d’environnement ou une validation externe provoque souvent une pression immédiate : approuver manuellement, désactiver le check, relancer le pipeline, changer l’identité du service connection ou faire passer le correctif par un chemin parallèle. Ces actions peuvent débloquer la release, mais elles peuvent aussi supprimer la seule barrière qui empêchait un changement non qualifié d’atteindre la production.

Le cas d’usage est un pipeline Azure DevOps qui déploie une application ou une infrastructure Azure vers un environnement de production. Le run attend une approbation, un business hours check, une vérification REST, un contrôle de branche, un service connection ou une policy qui ne passe plus. L’objectif du runbook est de décider si le blocage est une protection légitime, un incident de garde-fou, une dérive d’identité ou un problème de signal avant de bypasser quoi que ce soit.

Nommer la barrière qui bloque

Commencez par isoler le type de garde et le périmètre. Un pipeline “bloqué” n’est pas un diagnostic exploitable. Il faut savoir quelle décision est attendue, par qui, avec quelle preuve et quel risque si elle est contournée.

text deployment-gate-contract.txt
Déploiement à qualifier
Projet Azure DevOps: platform-prod
Pipeline: deploy-orders-api
Run: 20260710.4
Stage bloqué: production
Environnement: prod-orders
Changement: image applicative + paramètres App Configuration
Garde active: approval manuel + check REST + contrôle de branche
Identité de déploiement: service connection sc-prod-orders
Fenêtre: correction de production planifiée

Preuves requises avant bypass
Commit, artefact et plan de changement identifiés
Raison exacte du check en attente, échoué ou expiré
Approbateur attendu et propriétaire du service confirmés
Identité réelle du service connection vérifiée
Logs du pipeline et du check externe conservés
Validation applicative et rollback documentés
Décision écrite: approuver, relancer, corriger le check, rollbacker ou bloquer

Si l’équipe ne peut pas expliquer la barrière, elle ne doit pas la retirer. Une approval gate est une partie du système de production, pas un simple obstacle administratif.

Séparer attente normale, échec et dérive de configuration

Trois situations se ressemblent dans l’urgence : le pipeline attend une approbation normale, le check a échoué parce qu’il a détecté un risque réel, ou le mécanisme de check est lui-même cassé. La réponse n’est pas la même.

text gate-state-triage.txt
Attente normale
Le run est en attente d'un approbateur connu
La fenêtre de changement n'est pas encore ouverte
Le check externe n'a pas encore retourné son verdict
Aucun timeout ni erreur technique n'est visible

Échec de garde légitime
Branche, artefact ou environnement ne respectent pas la règle
Le check détecte un test, une vulnérabilité ou une preuve manquante
Le service connection ne correspond pas au périmètre attendu
L'approbateur refuse ou demande une preuve complémentaire

Dérive ou panne du mécanisme
L'approbateur n'existe plus ou n'a plus accès
Le check REST expire sans joindre son service
Une policy pointe vers une branche ou un groupe obsolète
Le service connection a été modifié hors changement
Les logs du check ne sont plus exportés ou corrélables

Le bypass n’est envisageable que dans le troisième cas, et seulement avec un contrôle compensatoire documenté. Dans les deux premiers, il faut attendre ou corriger la cause du refus.

Capturer le run et l’artefact avant toute relance

Avant de relancer ou d’approuver, figez ce qui va réellement partir en production. Un nouveau run peut reconstruire un artefact différent, récupérer une variable changée ou utiliser un service connection modifié.

bash 01-pipeline-run-snapshot.sh
ORG="https://dev.azure.com/example"
PROJECT="platform-prod"
RUN_ID="20260710"
PIPELINE_ID="42"

az pipelines runs show --org "$ORG" --project "$PROJECT" --id "$RUN_ID" --query "{id:id,name:name,state:state,result:result,sourceBranch:sourceBranch,sourceVersion:sourceVersion,createdDate:createdDate,finishedDate:finishedDate}" --output json

az pipelines runs artifact list --org "$ORG" --project "$PROJECT" --run-id "$RUN_ID" --output table

az pipelines show --org "$ORG" --project "$PROJECT" --id "$PIPELINE_ID" --query "{id:id,name:name,folder:folder,revision:revision}" --output json

Conservez le commit SHA, l’artefact, le stage et le nom de l’environnement dans la note d’incident. Une approbation donnée sur “le dernier run” n’est pas assez précise pour la production.

Lire l’environnement et ses checks comme du code d’exploitation

Les approvals et checks attachés à un environnement Azure DevOps doivent être traités comme une configuration critique. Avant de les modifier, relisez la règle : groupe d’approbateurs, délai, approbation différée, checks de branche, requêtes externes, verrou exclusif ou business hours.

yaml environment-check-review.yml
environment: prod-orders
checks_to_review:
manual_approval:
  approvers: platform-release-managers
  timeout: 4h
  allow_self_approval: false
  required_evidence:
    - incident_or_change_id
    - artifact_version
    - rollback_owner

branch_control:
  allowed_branches:
    - refs/heads/main
    - refs/heads/hotfix/*
  verify_protection: true

external_rest_check:
  service: change-risk-api
  expected_decision: approved | rejected | retryable
  timeout: 10m
  evidence_required:
    - risk_score
    - blocking_reason
    - correlation_id

exclusive_lock:
  scope: environment
  reason: prevent_parallel_production_deployments

Si la règle est trop vague pour être relue, elle est trop vague pour être bypassée. La correction peut être une mise à jour de policy, mais seulement après avoir sauvegardé l’état initial et le motif du changement.

Vérifier l’identité qui peut réellement déployer

Un approval ne protège pas grand-chose si le service connection ou l’identité de déploiement a dérivé. Contrôlez l’identité utilisée par le stage, son scope Azure, ses permissions et les changements récents avant d’approuver.

bash 02-service-connection-identity.sh
ORG="https://dev.azure.com/example"
PROJECT="platform-prod"
SERVICE_ENDPOINT_ID="00000000-0000-0000-0000-000000000000"

az devops service-endpoint show --org "$ORG" --project "$PROJECT" --id "$SERVICE_ENDPOINT_ID" --query "{name:name,type:type,authorization:authorization.scheme,createdBy:createdBy.displayName,modifiedBy:modifiedBy.displayName,isShared:isShared,serviceEndpointProjectReferences:serviceEndpointProjectReferences[].projectReference.name}" --output json

az role assignment list --assignee "<principal-id-used-by-service-connection>" --scope "/subscriptions/<subscription-id>/resourceGroups/rg-prod-orders" --query "[].{role:roleDefinitionName,scope:scope}" --output table

La correction ne doit pas être d’élargir l’identité pour passer le déploiement. Si l’identité est trop faible, il faut prouver le rôle manquant et le limiter au scope nécessaire. Si elle est trop large, le bypass devient encore plus risqué.

Corréler le check externe avec les logs applicatifs

Quand un check REST ou une policy externe bloque, récupérez son verdict exact. Un timeout réseau, une erreur 500 et un refus métier ne portent pas la même décision.

kusto 03-gate-check-correlation.kql
let StartTime = datetime(2026-07-10T08:00:00Z);
let EndTime = datetime(2026-07-10T09:00:00Z);
let CorrelationId = "ado-prod-20260710-04";
AppRequests
| where TimeGenerated between (StartTime .. EndTime)
| where Name has "change-risk-api" or Url has "/deployment/check"
| where tostring(Properties["correlationId"]) == CorrelationId
| project TimeGenerated, Name, Url, ResultCode, DurationMs, Success, OperationId, Properties
| order by TimeGenerated asc

Si le check externe est indisponible, le contrôle compensatoire doit être explicite : qui valide le risque, avec quelles données, pour combien de temps, et comment la policy sera restaurée. Sinon, la panne du check devient un précédent permanent.

Décider approbation, relance, correction ou bypass contrôlé

La décision doit être plus précise que “débloquer le pipeline”. Gardez une matrice courte qui lie chaque action à la preuve disponible.

text approval-check-decision.txt
Approuver le déploiement
Artefact, commit et environnement sont identifiés
Les checks passent ou leur attente est normale
L'approbateur est autorisé et différent de l'auteur du changement
Le rollback applicatif ou infrastructure est prêt
La validation post-déploiement est définie

Relancer le pipeline
Le run a expiré sans changement de code ni de configuration
L'artefact peut être réutilisé ou reconstruit de façon déterministe
Le check externe est revenu disponible
La relance ne rejoue pas une action partielle non rollbackée

Corriger la garde
Approbateur, groupe, branche ou service de check est obsolète
Le correctif de policy est revu comme un changement de production
L'état initial est sauvegardé
La garde corrigée est testée sur un run non destructif

Bypass contrôlé
Le mécanisme de check est indisponible, pas le risque métier
Le propriétaire du service accepte le contrôle compensatoire
Le bypass est limité au run, au stage et à la fenêtre
Une trace d'audit et un ticket de restauration existent

Bloquer
Le check refuse pour une raison métier ou sécurité
L'artefact ou le commit n'est pas identifié
L'identité de déploiement a dérivé sans revue
Le rollback n'est pas testable
Le bypass demandé désactive la garde pour les runs futurs

La plupart des incidents de gate se résolvent par correction de configuration ou relance contrôlée, pas par suppression globale de l’approbation.

Valider après promotion et restaurer la garde

Si le déploiement est approuvé ou bypassé, la validation post-déploiement doit prouver deux choses : le service fonctionne et la garde est revenue dans l’état attendu.

text post-deployment-gate-validation.txt
Validation post-déploiement
Le stage production est terminé avec le run attendu
L'artefact déployé correspond au commit approuvé
Les probes applicatives passent avec un identifiant de corrélation
Les alertes Azure Monitor restent dans l'enveloppe attendue
Les logs d'audit Azure DevOps gardent approbation, refus, bypass ou modification
Les checks d'environnement sont réactivés ou corrigés
Le ticket contient décision, preuves, approbateur, rollback et propriétaire

Rollback ou restauration
Rollback applicatif si les probes ou métriques régressent
Restauration de la policy si un bypass temporaire a été créé
Retrait des permissions temporaires sur service connection
Relance d'un run non destructif pour prouver que la garde refonctionne
Revue post-incident si le check était indisponible trop longtemps

Un bypass sans restauration vérifiée n’est pas un contournement temporaire. C’est une baisse durable du niveau de contrôle.

Conclusion

Un approval ou un check Azure DevOps qui bloque la production n’est pas forcément un incident à contourner. C’est un signal à qualifier : run exact, artefact, environnement, règle, approbateur, identité, verdict externe, logs et rollback.

La bonne sortie est une décision traçable : approuver avec preuves, relancer sans changer l’artefact, corriger la garde, bypasser un run avec contrôle compensatoire, ou bloquer le changement. Ce cadre évite que l’urgence de déploiement transforme les garde-fous CI/CD en simples interrupteurs que l’on coupe quand ils deviennent gênants.