Infrastructure

Azure IaC : valider un plan de changement avant l'apply en production

Un runbook de production pour qualifier un plan Terraform, Bicep ou ARM avant apply avec dérive, identité CI, Azure Policy, suppressions, dépendances, validation et rollback.

08 juil. 2026 azureiacterraformbicepwhat-ifazure-policyci-cdidentityobservabilityrunbookrollbackproduction

Un plan IaC qui passe en CI n’est pas forcément un changement prêt pour la production. Il peut masquer une dérive manuelle, remplacer une ressource critique, modifier une identité, recréer un endpoint, supprimer un diagnostic setting ou contourner une contrainte Azure Policy. Sous pression, l’équipe peut cliquer sur apply parce que le pipeline est vert, puis découvrir que le plan était techniquement valide mais opérationnellement dangereux.

Le cas d’usage est une plateforme Azure gérée avec Terraform, Bicep ou ARM depuis un pipeline CI/CD. Le changement touche un réseau, une identité managée, un Key Vault, une App Service, un diagnostic setting ou une policy assignment. L’objectif du runbook est de décider si l’apply peut partir, si le plan doit être corrigé, si une dérive doit être traitée avant déploiement, ou si le changement doit être rollbacké sans improviser.

Figer le périmètre du changement

Commencez par transformer le plan en contrat d’exploitation. Un diff IaC n’est pas seulement une liste de ressources : c’est une promesse sur ce qui sera créé, modifié, remplacé, supprimé et validé après coup.

text iac-change-contract.txt
Changement a qualifier
Environnement: production
Scope Azure: subscription, resource group ou management group
Outil: Terraform, Bicep ou ARM
Pipeline: platform-iac-prod
Identite d'execution: workload identity federation ou managed identity
Ressources sensibles: reseau, identite, secrets, diagnostic settings, policies
Fenetre d'application: approuvee et reversible

Preuves requises avant apply
Plan ou what-if attache au changement
Liste des suppressions et remplacements
Derive manuelle connue ou exclue
Identite CI et permissions verifiees
Impact Azure Policy compris
Validation applicative prevue
Rollback ou chemin de mitigation documente

Si le plan ne dit pas clairement ce qui peut être détruit ou remplacé, l’apply doit attendre. Le premier garde-fou est la lisibilité de la décision.

Séparer plan, dérive et intention

Un plan peut contenir trois réalités différentes : le changement voulu, la dérive existante, et les effets de bord du provider ou du module. Les mélanger produit des apply trop larges.

text plan-classification.txt
Classer chaque diff
Intentionnel
  Ressource ou propriete demandee par la PR
  Impact attendu dans la note de changement
  Validation post-apply definie

Derive a qualifier
  Valeur modifiee hors IaC
  Tag, diagnostic setting, role assignment ou configuration reseau differente
  Changement non lie a la PR

Risque a bloquer
  Replacement d'une ressource stateful
  Suppression de private DNS link, diagnostic setting, lock ou role assignment
  Changement d'identite d'execution
  Modification Azure Policy ou exemption trop large
  Diffrence non expliquee par la PR

Le bon réflexe n’est pas de faire rentrer toute la dérive dans le même apply. Corrigez ou acceptez explicitement la dérive avant de livrer le changement fonctionnel.

Contrôler l’identité du pipeline

Avant de croire le plan, prouvez l’identité qui l’a produit. Une erreur de fédération OIDC, de service connection ou de rôle Azure peut produire un plan incomplet, ou réussir avec des droits trop larges.

bash 01-ci-identity-scope.sh
SUBSCRIPTION="00000000-0000-0000-0000-000000000000"
PRINCIPAL_ID="11111111-1111-1111-1111-111111111111"

az account set --subscription "$SUBSCRIPTION"

az role assignment list --assignee "$PRINCIPAL_ID" --all --query "[].{role:roleDefinitionName,scope:scope,condition:condition}" --output table

az ad sp show --id "$PRINCIPAL_ID" --query "{appId:appId,displayName:displayName,servicePrincipalType:servicePrincipalType}" --output json

La question n’est pas seulement “le pipeline a-t-il le droit ?”. Elle est aussi “a-t-il uniquement les droits nécessaires au scope attendu ?”. Un apply de production exécuté avec un rôle trop large rend le rollback plus difficile à raisonner.

Lire le plan comme une liste de risques

Pour Terraform, extrayez les actions du plan au lieu de relire toute la sortie console. Pour Bicep ou ARM, utilisez le what-if et isolez les suppressions, remplacements et modifications de ressources sensibles.

bash 02-terraform-plan-risk-summary.sh
terraform plan -out=tfplan
terraform show -json tfplan > tfplan.json

jq -r '
.resource_changes[]
| {
    address: .address,
    type: .type,
    name: .name,
    actions: .change.actions
  }
| select(.actions | index("delete") or index("replace"))
' tfplan.json
bash 03-bicep-what-if-risk-summary.sh
RESOURCE_GROUP="rg-prod-platform"
TEMPLATE="main.bicep"
PARAMETERS="main.prod.bicepparam"

az deployment group what-if --resource-group "$RESOURCE_GROUP" --template-file "$TEMPLATE" --parameters "$PARAMETERS" --result-format FullResourcePayloads --output json > what-if.json

jq -r '
.changes[]
| select(.changeType == "Delete" or .changeType == "Modify")
| {resourceId: .resourceId, changeType: .changeType}
' what-if.json

Un remplacement d’App Service Plan, de subnet, de Private DNS Zone link, de Key Vault access model ou de diagnostic setting n’a pas le même poids qu’un tag. Mettez les risques en haut de la revue.

Vérifier Azure Policy avant l’apply

Azure Policy peut bloquer l’apply, modifier des ressources via deployIfNotExists, ou masquer une dérive tant que la remediation n’a pas tourné. Le plan doit inclure cette contrainte.

bash 04-policy-state-before-apply.sh
SCOPE="/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-prod-platform"

az policy state list --resource "$SCOPE" --query "[].{policy:policyDefinitionName,assignment:policyAssignmentName,compliance:complianceState,resourceId:resourceId}" --output table

az policy assignment list --scope "$SCOPE" --query "[].{name:name,displayName:displayName,enforcementMode:enforcementMode}" --output table

Bloquez l’apply si le changement nécessite de désactiver une policy sans owner, d’élargir une exemption sans date de retrait, ou d’ignorer une non-conformité qui touche la ressource modifiée.

Préparer une validation post-apply exploitable

Un apply réussi n’est pas une validation. Il prouve seulement que le moteur IaC a terminé. La validation doit partir des chemins réellement consommés : requête applicative, résolution DNS, identité, logs, métriques et contrôles de sécurité.

yaml post-apply-validation.yml
validation:
infrastructure:
  - resource_exists_with_expected_sku_and_location
  - no_unplanned_delete_or_replace
  - diagnostic_settings_still_enabled
  - locks_and_tags_preserved_when_required

network:
  - private_dns_resolution_from_workload_network
  - effective_routes_match_expected_path
  - nsg_or_firewall_logs_show_expected_flow

identity:
  - managed_identity_or_federated_principal_unchanged
  - key_vault_or_api_access_validated_with_real_identity
  - no_broad_role_added_for_apply_convenience

application:
  - synthetic_probe_passes
  - logs_visible_with_correlation_id
  - user_path_or_health_endpoint_validated

decision:
  - promote_change
  - hold_and_fix
  - rollback_or_mitigate

La validation doit être écrite avant l’apply. Sinon l’équipe risque de chercher après coup ce qu’elle aurait dû prouver.

Décider apply, correction ou rollback

Gardez une décision courte et défendable. Le plan peut être techniquement valide et rester trop risqué pour une fenêtre de production.

text iac-apply-decision.txt
Autoriser apply
Les suppressions et remplacements sont attendus ou absents
La derive est comprise et separee du changement
L'identite CI est bornee au scope attendu
Azure Policy est conforme ou l'ecart est approuve
La validation post-apply est prete

Corriger avant apply
Le plan contient une derive non liee a la PR
Une ressource stateful serait remplacee
Une identite ou un role assignment change sans justification
Une policy serait contournee pour faire passer le deploiement
Les probes ou logs de validation ne sont pas disponibles

Rollbacker ou mitiger
L'apply a supprime un chemin de diagnostic ou d'acces
La validation applicative echoue apres changement
Une ressource a ete remplacee au lieu d'etre modifiee
Le plan precedent peut etre reapplique avec un scope reduit
Une mitigation temporaire a un owner et une date de retrait

Le rollback IaC doit rester borné. Revenir à un ancien commit sans relire le plan peut réintroduire d’autres changements. Produisez un plan de rollback, relisez ses suppressions, puis validez comme un changement normal.

Garder les preuves dans la PR

La PR doit contenir assez d’éléments pour que l’exploitation puisse comprendre la décision plus tard : plan, résumé des risques, identité, policy, validation et rollback.

markdown pull-request-evidence.md
## Infrastructure change evidence

- Plan artifact: attached to CI run
- Risk summary: no unplanned delete or replace
- Drift: tag drift accepted separately, no network drift included
- CI identity: workload identity federation, scoped to rg-prod-platform
- Azure Policy: no new exemption, current non-compliance not touched
- Validation: private probe, Key Vault read, diagnostic logs
- Rollback: previous module version with targeted plan reviewed
- Decision: apply approved for production window

Cette trace évite de rejouer l’enquête au prochain incident. Elle transforme l’IaC en interface d’exploitation, pas seulement en mécanisme de déploiement.

Conclusion

Un plan IaC de production doit être relu comme un runbook de changement. La bonne décision ne repose pas sur un statut CI vert, mais sur une preuve : intention séparée de la dérive, suppressions visibles, identité bornée, Azure Policy comprise, validation prête et rollback relu.

L’apply peut partir quand le plan est explicable et que l’équipe sait quoi vérifier après. Il doit attendre quand le diff mélange changement, dérive et effets de bord. C’est cette discipline qui rend l’infrastructure automatisée réellement exploitable.