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.

09 août 2026 azureresource-graphchange-analysisconfiguration-driftactivity-logobservabilitykqlrunbookrollbackproduction

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.

text configuration-drift-incident-scope.txt
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.

kusto 01-resource-graph-incident-changes.kql
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.

text change-causality-check.txt
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.

kusto 02-correlate-azure-activity.kql
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.

yaml configuration-drift-decision.yml
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.