Abrufen von Ressourcenänderungen

Ressourcen werden während der alltäglichen Verwendung, Neukonfiguration und sogar der erneuten Bereitstellung geändert. Die meisten, jedoch nicht alle Änderungen sind beabsichtigt. Ihre Möglichkeiten:

  • Ermitteln, wann Änderungen an einer Azure Resource Manager-Eigenschaft festgestellt wurden
  • Anzeigen von Eigenschaftenänderungsdetails.
  • Abfragen von Änderungen im großen Stil für Ihre Abonnements, Ihre Verwaltungsgruppe oder Ihren Mandanten.

In diesem Artikel wird Folgendes behandelt:

  • Informationen zu den JSON-Nutzdaten
  • Abfragen von Ressourcenänderungen über Resource Graph mithilfe von PowerShell, der CLI oder des Azure-Portals
  • Abfragebeispiele und Best Practices zum Abfragen von Ressourcenänderungen

Voraussetzungen

Grundlegendes zu Änderungsereigniseigenschaften

Wenn eine Ressource erstellt, aktualisiert oder gelöscht wird, wird eine neue Änderungsressource (Microsoft.Resources/changes) erstellt, um die geänderte Ressource zu erweitern und die geänderten Eigenschaften zu darstellen. Änderungsdatensätze sollten in weniger als fünf Minuten verfügbar sein. Die folgenden JSON-Beispielnutzdaten veranschaulichen die Änderungsressourceneigenschaften:

{
  "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"
    }
  }
}

Hier finden Sie den vollständigen Referenzleitfaden für Änderungsressourceneigenschaften.

Ausführen einer Abfrage

Probieren Sie eine mandantenbasierte Resource Graph-Abfrage der resourcechanges-Tabelle auszuprobieren. Die Abfrage gibt die ersten fünf jüngsten Azure-Ressourcenänderungen mit Änderungszeit, Änderungstyp, Zielressourcen-ID, Zielressourcentyp und Änderungsdetails jedes Änderungsdatensatzes zurück.

# 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'

Sie können diese Abfrage aktualisieren, um einen benutzerfreundlicheren Spaltennamen für die timestamp-Eigenschaft anzugeben.

# 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'

Um die Abfrageergebnisse auf die neuesten Änderungen zu beschränken, aktualisieren Sie die Abfrage so, dass die Ergebnisse nach der benutzerdefinierten changeTime-Eigenschaft sortiert werden (order by).

# 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'

Mit den Parametern -ManagementGroup und -Subscription können Sie auch nach Verwaltungsgruppe bzw. Abonnement abfragen.

Hinweis

Das PowerShell-Cmdlet Search-AzGraph verwendet standardmäßig Abonnements im Standardkontext, wenn die Abfrage keine Ergebnisse aus einem Abonnement zurückgibt, auf das Sie bereits Zugriff haben.

Der Resource Graph-Explorer bietet auch eine übersichtliche Oberfläche, auf der Sie die Ergebnisse mancher Abfragen in ein Diagramm umwandeln können, das Sie anschließend an ein Azure-Dashboard anheften können.

Abfragen von Ressourcenänderungen

Mit Resource Graph können Sie die Tabellen resourcechanges, resourcecontainerchanges oder healthresourcechanges abfragen, um nach einer der Änderungsressourceneigenschaften zu filtern oder zu sortieren. In den folgenden Beispielen wird die resourcechanges-Tabelle abfragt, aber das Beispiel kann auch auf die resourcecontainerchanges- und healthresourcechanges-Tabellen übertragen werden.

Hinweis

Weitere Informationen zu den healthresourcechanges-Daten finden Sie in der Project Flash-Dokumentation.

Beispiele

Informieren Sie sich vor dem Abfragen und Analysieren von Änderungen in Ihren Ressourcen über die folgenden Best Practices.

  • Sie können Änderungsereignisse in einem bestimmten Zeitfenster abfragen und die Änderungsdetails auswerten.
    • Diese Abfrage funktioniert am besten bei der Verwaltung von Incidents zum Suchen potenziell ähnlicher Änderungen.
  • Halten Sie eine Datenbank für die Konfigurationsverwaltung (Configuration Management Database, CMDB) auf dem neuesten Stand.
    • Anstatt alle Ressourcen und ihre vollständigen Eigenschaftensätze in festgelegten Intervallen zu aktualisieren, erhalten Sie nur deren Änderungen.
  • Überprüfen Sie, welche anderen Eigenschaften sich unter Umständen geändert haben, wenn der Konformitätszustand einer Ressource geändert wurde.
    • Die Auswertung dieser zusätzlichen Eigenschaften kann Einblicke in andere Eigenschaften bieten, die möglicherweise über eine Azure Policy-Definition verwaltet werden müssen.
  • Die Reihenfolge der Abfragebefehle ist wichtig. In den folgenden Beispielen muss der order by-Befehl vor dem limit-Befehl stehen.
    • Der order by-Befehl sortiert die Abfrageergebnisse nach der Änderungszeit.
    • Der limit-Befehl grenzt dann die sortierten Ergebnisse ein, um sicherzustellen, dass Sie die fünf neuesten Ergebnisse erhalten.

Alle Änderungen im letzten 24-Stunden-Zeitraum

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

In einer bestimmten Ressourcengruppe gelöschte Ressourcen

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

Änderungen an einem bestimmten Eigenschaftswert

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

Neueste Ressourcenänderungen für Ressourcen, die in den letzten sieben Tagen erstellt wurden

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

VM-Größenänderungen

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

Anzahl von Änderungen nach Änderungstyp und Abonnementname

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  

Neueste Ressourcenänderungen für Ressourcen, die mit einem bestimmten Tag erstellt wurden

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

Nächste Schritte