Obtenir les changements des ressources

Les ressources évoluent au fil de leur utilisation quotidienne, de leur reconfiguration, voire de leur redéploiement. La plupart des modifications sont normales, mais ce n’est parfois pas le cas. Vous pouvez :

  • Savoir à quel moment des changements ont été détectés sur une propriété Azure Resource Manager.
  • Afficher les détails des modifications de propriété.
  • Interroger les modifications à grande échelle dans vos abonnements, groupes d’administration ou locataires.

Dans cet article, vous apprenez :

  • À quoi ressemble le JSON de la charge utile.
  • Comment interroger les modifications des ressources via Resource Graph en utilisant l’interface CLI, PowerShell ou le portail Azure.
  • Exemples de requêtes et meilleures pratiques pour interroger les modifications des ressources.

Prérequis

Comprendre les propriétés de l’événement de modification

Lorsqu’une ressource est créée, mise à jour ou supprimée, une nouvelle ressource de modifications (Microsoft.Resources/changes) est créée pour étendre la ressource modifiée et représenter les propriétés modifiées. Les enregistrements de modifications doivent être disponibles en moins de cinq minutes. L’exemple suivant de charge utile JSON illustre les propriétés de modification des ressources :

{
  "targetResourceId": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/microsoft.compute/virtualmachines/myVM",
  "targetResourceType": "microsoft.compute/virtualmachines",
  "changeType": "Update",
  "changeAttributes": {
    "previousResourceSnapshotId": "08584889383111245807_37592049-3996-ece7-c583-3008aef9e0e1_4043682982_1712668574",
    "newResourceSnapshotId": "08584889377081305807_38788020-eeee-ffff-028f-6121bdac9cfe_4213468768_1712669177",
    "correlationId": "04ff69b3-e162-4583-9cd7-1a14a1ec2c61",
    "changedByType": "User",
    "changesCount": 2,
    "clientType": "ARM Template",
    "changedBy": "john@contoso.com",
    "operation": "microsoft.compute/virtualmachines/write",
    "timestamp": "2024-04-09T13:26:17.347+00:00"
  },
  "changes": {
    "properties.provisioningState": {
      "newValue": "Succeeded",
      "previousValue": "Updating",
      "changeCategory": "System",
      "propertyChangeType": "Update",
      "isTruncated": "true"
    },
    "tags.key1": {
      "newValue": "NewTagValue",
      "previousValue": "null",
      "changeCategory": "User",
      "propertyChangeType": "Insert"
    }
  }
}

Consultez le guide de référence complet pour les propriétés de modification des ressources.

Exécuter une requête

Tester une requête Resource Graph basée sur un locataire en interrogeant la table resourcechanges. La requête retourne les cinq modifications de ressources Azure les plus récentes, en indiquant l’heure de modification, le type de modification, l’ID de ressource cible, le type de ressource cible et les détails de chaque enregistrement de modification.

# Login first with az login if not using Cloud Shell
 
# Run Azure Resource Graph query
az graph query -q 'resourcechanges | project properties.changeAttributes.timestamp, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5'

Vous pouvez modifier cette requête pour spécifier un nom de colonne plus convivial pour la propriété timestamp.

# Run Azure Resource Graph query with 'extend'
az graph query -q 'resourcechanges | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5'

Pour limiter les résultats de la requête aux modifications les plus récentes, mettez à jour la requête order by pour trier par la propriété changeTime définie par l’utilisateur.

# Run Azure Resource Graph query with 'order by'
az graph query -q 'resourcechanges | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | order by changeTime desc | limit 5'

Vous pouvez également interroger par groupe d’administration ou par abonnement avec les paramètres -ManagementGroupou -Subscription respectivement.

Remarque

Si la requête ne retourne aucun résultat à partir d’un abonnement auquel vous avez déjà accès, alors l’applet de commande PowerShell Search-AzGraph porte par défaut sur les abonnements du contexte par défaut.

L’Explorateur Resource Graph fournit également une interface simple qui vous permet de convertir les résultats de certaines requêtes sous forme de graphique, que vous pouvez ensuite épingler à un tableau de bord Azure.

Modifications apportées aux ressources de requête

Avec Resource Graph, vous pouvez interroger les tables resourcechanges, resourcecontainerchangesou healthresourcechanges pour filtrer ou trier par n'importe quelle propriété de modification de ressource. Les exemples suivants interrogent la table resourcechanges, mais peuvent également être appliqués à la table resourcecontainerchanges ou healthresourcechanges.

Remarque

En savoir plus sur les données healthresourcechanges dans la documentation Project Flash.

Exemples

Avant d’interroger et d’analyser les modifications apportées à vos ressources, passez en revue les meilleures pratiques suivantes.

  • Interrogez les événements de modification dans une fenêtre de temps spécifique et évaluez les détails des modifications.
    • Cette requête fonctionne mieux pendant la gestion des incidents pour comprendre des modifications potentiellement liées.
  • Gardez à jour une base de données de gestion de la configuration (CMDB).
    • Au lieu d’actualiser toutes les ressources et leurs ensembles de propriétés complètes sur une fréquence planifiée, vous recevrez uniquement leurs modifications.
  • Comprendre quelles autres propriétés sont modifiées lorsqu’une ressource change « d’état de conformité ».
    • L’évaluation de ces propriétés supplémentaires peut fournir des insights sur les autres propriétés susceptibles de nécessiter une gestion par le biais d’une définition Azure Policy.
  • L’ordre des commandes de requête est important. Dans les exemples suivants, order by doit précéder la commande limit.
    • La commande order by trie les résultats de la requête par heure de modification.
    • La commande limit limite ensuite les résultats ordonnés pour vous assurer d’obtenir les cinq résultats les plus récents.

Toutes les modifications apportées au cours des dernières 24 heures

resourcechanges 
| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),
changeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId, 
changedProperties = properties.changes, changeCount = properties.changeAttributes.changesCount
| where changeTime > ago(1d)
| order by changeTime desc
| project changeTime, targetResourceId, changeType, correlationId, changeCount, changedProperties

Ressources supprimées dans un groupe de ressources spécifique

resourcechanges
| where resourceGroup == "myResourceGroup"
| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),
changeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId
| where changeType == "Delete"
| order by changeTime desc
| project changeTime, resourceGroup, targetResourceId, changeType, correlationId

Modifications apportées à une valeur de propriété spécifique

resourcechanges
| extend provisioningStateChange = properties.changes["properties.provisioningState"], changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType)
| where isnotempty(provisioningStateChange)and provisioningStateChange.newValue == "Succeeded"
| order by changeTime desc
| project changeTime, targetResourceId, changeType, provisioningStateChange.previousValue, provisioningStateChange.newValue

Dernières modifications de ressources pour les ressources créées au cours des sept derniers jours

resourcechanges
| extend targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType), changeTime = todatetime(properties.changeAttributes.timestamp)
| where changeTime > ago(7d) and changeType == "Create"
| project  targetResourceId, changeType, changeTime
| join ( Resources | extend targetResourceId=id) on targetResourceId
| order by changeTime desc
| project changeTime, changeType, id, resourceGroup, type, properties

Modifications apportées à la taille de la machine virtuelle

resourcechanges
|extend vmSize = properties.changes["properties.hardwareProfile.vmSize"], changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType) 
| where isnotempty(vmSize) 
| order by changeTime desc 
| project changeTime, targetResourceId, changeType, properties.changes, previousSize = vmSize.previousValue, newSize = vmSize.newValue

Nombre de modifications par type de modification et nom d’abonnement

resourcechanges  
|extend changeType = tostring(properties.changeType), changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceType=tostring(properties.targetResourceType)  
| summarize count() by changeType, subscriptionId 
| join (resourcecontainers | where type=='microsoft.resources/subscriptions' | project SubscriptionName=name, subscriptionId) on subscriptionId 
| project-away subscriptionId, subscriptionId1
| order by count_ desc  

Dernières modifications de ressources pour les ressources créées avec une certaine balise

resourcechanges 
|extend targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType), createTime = todatetime(properties.changeAttributes.timestamp) 
| where createTime > ago(7d) and changeType == "Create" or changeType == "Update" or changeType == "Delete"
| project  targetResourceId, changeType, createTime 
| join ( resources | extend targetResourceId=id) on targetResourceId
| where tags ['Environment'] =~ 'prod' 
| order by createTime desc 
| project createTime, id, resourceGroup, type

Étapes suivantes