Infrastructure
Azure Resource Graph : reconstruire une dérive de configuration avant rollback
Un runbook de production pour retrouver un changement Azure avec Resource Graph Change Analysis, le relier à son acteur et à son impact, puis valider ou rollbacker sans revenir à l’aveugle.
Une API Azure ralentit juste après une fenêtre de déploiement. Le code n’a pas changé, les probes restent vertes et aucun incident de plateforme n’est déclaré. Pourtant, une route, une règle réseau, un paramètre de service ou un tag piloté par l’automatisation a pu dériver. Réappliquer le template complet ou restaurer la dernière release applicative donnerait un résultat, mais pas une preuve.
Le cas d’usage est un environnement de production composé de plusieurs ressources Azure, modifiées par IaC, portail et automatisation. Le runbook utilise Azure Resource Graph Change Analysis pour isoler la propriété modifiée, puis l’Activity Log exporté vers Log Analytics pour retrouver l’opération et l’identité. La décision finale est volontairement étroite : conserver le changement, corriger une seule propriété, revenir à la version IaC précédente ou suspendre l’automatisation responsable.
Figer le symptôme et la fenêtre de changement
Commencez par un impact observable, pas par une liste de ressources suspectes. Retenez un test reproductible, son heure UTC, les composants touchés et un composant témoin non touché. Cette comparaison évite d’attribuer au dernier déploiement une panne plus large ou plus ancienne.
Incident: inc-20260809-014
Symptôme: latence et timeouts sur orders-api
Début observé: 2026-08-09T15:18:00Z
Dernier test sain: 2026-08-09T15:04:00Z
Fenêtre de recherche: 14:45Z à 15:30Z
Ressource principale
/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-orders-prod/providers/Microsoft.Web/sites/orders-api
Dépendances à comparer
VNet Integration et subnet
route table et NSG
App Configuration et Key Vault
plan App Service
Preuves attendues
propriété avant et après
heure du changement
identité ou application à l’origine
corrélation avec le début du symptôme
test de validation et chemin de rollback Change Analysis conserve une fenêtre de données limitée. Lancez la collecte pendant l’incident et exportez le résultat utile dans le dossier de preuves ; l’outil sert à retrouver un changement récent, pas à remplacer un historique de configuration durable.
Interroger les changements à l’échelle utile
La table resourcechanges permet de rechercher les créations, mises à jour et suppressions sur plusieurs subscriptions. Limitez d’abord par temps et par resource group, puis projetez les attributs d’acteur et le dictionnaire des propriétés modifiées. Les enregistrements arrivent généralement en quelques minutes : une absence immédiate n’est donc pas encore une preuve d’absence.
resourcechanges
| extend changeTime = todatetime(properties.changeAttributes.timestamp),
targetResourceId = tolower(tostring(properties.targetResourceId)),
targetResourceType = tostring(properties.targetResourceType),
changeType = tostring(properties.changeType),
changedBy = tostring(properties.changeAttributes.changedBy),
changedByType = tostring(properties.changeAttributes.changedByType),
clientType = tostring(properties.changeAttributes.clientType),
operation = tostring(properties.changeAttributes.operation),
correlationId = tostring(properties.changeAttributes.correlationId),
changeCount = toint(properties.changeAttributes.changesCount),
changedProperties = properties.changes
| where changeTime between (datetime(2026-08-09T14:45:00Z) .. datetime(2026-08-09T15:30:00Z))
| where targetResourceId contains "/resourcegroups/rg-orders-prod/"
| project changeTime, targetResourceId, targetResourceType, changeType,
changedBy, changedByType, clientType, operation, correlationId,
changeCount, changedProperties
| order by changeTime desc Ne filtrez pas trop tôt sur le seul App Service. Une modification de route table, NSG, subnet ou identité peut produire le symptôme sans changer la ressource applicative. À l’inverse, une longue liste de tags modifiés n’explique pas un timeout : classez les deltas par capacité à modifier le chemin d’exécution.
Lire le delta, pas seulement l’acteur
Le champ changedProperties contient les valeurs précédentes et nouvelles disponibles. Exportez le résultat JSON et examinez les chemins de propriétés qui touchent le runtime : intégration réseau, règles, références, identité, taille, options TLS ou configuration applicative. Une valeur différente n’est pas automatiquement la cause ; elle devient candidate lorsqu’elle précède le symptôme et modifie un chemin réel.
Pour une suppression, les snapshots de propriété ne sont pas toujours disponibles. Pour une création, le détail complet de chaque propriété serait trop bruyant et n’est pas exposé comme pour une mise à jour. Dans ces cas, complétez avec le template IaC, l’état courant et l’Activity Log.
Pour chaque delta candidat
Le changement précède-t-il le premier échec ?
La propriété peut-elle modifier le chemin de la requête ?
Le même delta existe-t-il sur le composant témoin ?
L’état actuel correspond-il au dépôt IaC approuvé ?
Une automation a-t-elle réécrit la valeur après le déploiement ?
Un test borné peut-il confirmer l'effet sans autre changement ?
Classer
causal confirmé
causal plausible à tester
bruit sans effet opérationnel
changement de plateforme ou acteur non déterminé
preuve incomplète changedBy ou clientType peut être vide, non déterminé ou renseigné comme System. Cela ne signifie pas que la plateforme est coupable. Cela signifie seulement que Change Analysis n’a pas attribué l’événement à un acteur exploitable ; il faut alors croiser d’autres journaux.
Relier le changement à l’Activity Log
Si l’Activity Log est exporté vers Log Analytics, utilisez le correlationId, la ressource et la fenêtre UTC pour retrouver l’opération ARM, l’appelant et son statut. Le champ operation de Change Analysis représente une action d’autorisation telle que Microsoft.Web/sites/write ; il aide à chercher, mais ne décrit pas toujours la modification exacte.
let StartTime = datetime(2026-08-09T14:45:00Z);
let EndTime = datetime(2026-08-09T15:30:00Z);
let TargetResource = "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-orders-prod/providers/Microsoft.Web/sites/orders-api";
let ChangeCorrelationId = "00000000-0000-0000-0000-000000000000";
AzureActivity
| where TimeGenerated between (StartTime .. EndTime)
| where tolower(ResourceId) == tolower(TargetResource)
or tostring(CorrelationId) == ChangeCorrelationId
| project TimeGenerated,
OperationNameValue,
ActivityStatusValue,
Caller,
CallerIpAddress,
CorrelationId,
ResourceId,
Properties
| order by TimeGenerated asc Cherchez ensuite le run CI, le job d’automatisation ou la demande de changement portant le même horodatage. Le but n’est pas seulement de trouver une personne : il faut identifier l’autorité qui peut réécrire la configuration. Corriger dans le portail une valeur gérée par Terraform ou par une policy ne tiendra que jusqu’à la prochaine exécution.
Comparer l’état courant à l’intention déclarée
Une fois le delta isolé, comparez trois états : valeur avant incident, valeur actuelle et valeur déclarée dans IaC. Cette triangulation distingue une dérive manuelle, un déploiement attendu qui a eu un effet inattendu, et une convergence automatique vers une mauvaise valeur source.
N’utilisez pas un apply complet comme outil de diagnostic. Générez d’abord un plan sur le même commit, le même backend et les mêmes variables que la production. Si le plan veut modifier des dizaines de ressources, il n’est pas un rollback borné. Préparez une correction ciblée ou revenez au commit connu, puis relisez le plan avant exécution.
Choisir correction, rollback ou maintien
La chronologie seule ne suffit pas. Le changement retenu doit expliquer le symptôme et un test contrôlé doit confirmer la restauration. Documentez la décision avant d’exécuter le retour arrière.
incident: inc-20260809-014
candidate_change:
resource: orders-api
property: properties.siteConfig.vnetRouteAllEnabled
previous: false
current: true
changed_at: 2026-08-09T15:11:42Z
authority: terraform-pipeline-prod
evidence:
- change precedes first timeout by 6 minutes
- dependency path follows the forced route
- control application without the change remains healthy
decision: rollback_iac_commit
validation:
- same synthetic request succeeds 5 times
- dependency latency returns to baseline range
- Resource Graph shows the expected reverse change
- no unrelated resource changes are introduced
stop_conditions:
- plan touches resources outside orders-api scope
- route behavior remains unchanged
- error rate increases during canary
rollback_of_rollback:
- restore the incident commit
- stop the pipeline
- escalate to network and application owners La propriété ci-dessus est un exemple de dossier de décision, pas une recommandation de configuration. Le bon état dépend de l’architecture. Conservez le changement si les tests prouvent qu’il est sain ; rollbackez seulement lorsqu’un delta précis explique l’impact et que le retour est lui-même observable.
Valider le retour et fermer la boucle
Après correction, rejouez exactement le test initial. Vérifiez le symptôme, la télémétrie applicative, la dépendance et la nouvelle entrée resourcechanges. Une réponse HTTP verte ne suffit pas si le routage, l’identité ou le volume d’erreurs reste dégradé.
Fermez ensuite la cause de dérive : verrouiller le chemin manuel, corriger le module IaC, borner l’identité d’automatisation ou ajouter une alerte sur une propriété critique. Pour un historique supérieur à la rétention Change Analysis, exportez régulièrement les changements utiles vers Log Analytics ou un stockage gouverné.
Conclusion
Une dérive Azure se traite mieux comme une chaîne de preuves que comme une intuition de déploiement. Resource Graph localise le delta, l’Activity Log retrouve l’opération, l’IaC expose l’intention et un canary valide l’effet.
La décision devient alors exploitable : maintenir un changement sain, corriger une propriété fautive ou rollbacker l’autorité qui l’a introduite. Si la causalité reste incomplète, suspendez l’automatisation concernée et conservez l’état courant plutôt que de lancer un retour arrière large sans preuve.