Skip to content

Commit 9dbe672

Browse files
authored
Merge pull request #278141 from davidsmatlak/ds-updates-arg-changeanalysis-20240612
Updates ARG Change Analysis docs
2 parents 425f90c + 4dfdfef commit 9dbe672

File tree

4 files changed

+113
-99
lines changed

4 files changed

+113
-99
lines changed

articles/governance/includes/resource-graph/preview/change-analysis.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ ms.service: resource-graph
33
author: iancarter-msft
44
ms.author: iancarter
55
ms.topic: include
6-
ms.date: 03/12/2024
6+
ms.date: 06/14/2024
77
---
88

99
> [!IMPORTANT]
10-
> The Change Analysis experience in the Azure portal is in preview and migrating from Azure Monitor to Azure Resource Graph. Previews are partially covered by customer support on a best-effort basis. As such, these features aren't meant for production use.
10+
> The Change Analysis experience in the Azure portal is in preview and migrating from Azure Monitor to Azure Resource Graph. Previews are partially covered by customer support on a best-effort basis. As such, these features aren't meant for production use.

articles/governance/resource-graph/changes/get-resource-changes.md

Lines changed: 67 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
---
22
title: Get resource changes
3-
description: Get resource changes at scale using Azure Resource Graph queries.
3+
description: Get resource changes at scale using Change Analysis and Azure Resource Graph queries.
44
author: iancarter-msft
55
ms.author: iancarter
6-
ms.date: 03/11/2024
6+
ms.date: 06/14/2024
77
ms.topic: how-to
88
---
99

@@ -19,6 +19,10 @@ In this article, you learn:
1919
- What the payload JSON looks like.
2020
- How to query resource changes through Resource Graph using either the CLI, PowerShell, or the Azure portal.
2121
- Query examples and best practices for querying resource changes.
22+
- Change analysis uses _Change Actor_ functionality:
23+
- `changedBy`: Who initiated a change in your resource, like an app ID or authorized person's email address.
24+
- `clientType`: Which client made the change, like _Azure portal_.
25+
- `operation`: Which [operation](../../../role-based-access-control/resource-provider-operations.md) was called, like `Microsoft.Compute/virtualmachines/write`.
2226

2327
## Prerequisites
2428

@@ -27,23 +31,23 @@ In this article, you learn:
2731

2832
## Understand change event properties
2933

30-
When a resource is created, updated, or deleted, a new change resource (Microsoft.Resources/changes) is created to extend the modified resource and represent the changed properties. Change records should be available in less than five minutes. The following example JSON payload demonstrates the change resource properties:
34+
When a resource is created, updated, or deleted, a new change resource (`Microsoft.Resources/changes`) is created to extend the modified resource and represent the changed properties. Change records should be available in less than five minutes. The following example JSON payload demonstrates the change resource properties:
3135

3236
```json
3337
{
34-
"targetResourceId": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/microsoft.compute/virtualmachines/myVM",
38+
"targetResourceId": "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/myResourceGroup/providers/microsoft.compute/virtualmachines/myVM",
3539
"targetResourceType": "microsoft.compute/virtualmachines",
3640
"changeType": "Update",
3741
"changeAttributes": {
38-
"previousResourceSnapshotId": "08584889383111245807_37592049-3996-ece7-c583-3008aef9e0e1_4043682982_1712668574",
39-
"newResourceSnapshotId": "08584889377081305807_38788020-eeee-ffff-028f-6121bdac9cfe_4213468768_1712669177",
40-
"correlationId": "04ff69b3-e162-4583-9cd7-1a14a1ec2c61",
42+
"previousResourceSnapshotId": "11111111111111111111_22222222-3333-aaaa-bbbb-444444444444_5555555555_6666666666",
43+
"newResourceSnapshotId": "33333333333333333333_44444444-5555-ffff-gggg-666666666666_7777777777_8888888888",
44+
"correlationId": "11111111-1111-1111-1111-111111111111",
4145
"changedByType": "User",
4246
"changesCount": 2,
43-
"clientType": "ARM Template",
47+
"clientType": "Azure Portal",
4448
"changedBy": "[email protected]",
4549
"operation": "microsoft.compute/virtualmachines/write",
46-
"timestamp": "2024-04-09T13:26:17.347+00:00"
50+
"timestamp": "2024-06-12T13:26:17.347+00:00"
4751
},
4852
"changes": {
4953
"properties.provisioningState": {
@@ -67,30 +71,30 @@ When a resource is created, updated, or deleted, a new change resource (Microsof
6771

6872
## Run a query
6973

70-
Try out a tenant-based Resource Graph query of the `resourcechanges` table. The query returns the first five most recent Azure resource changes with the change time, change type, target resource ID, target resource type, and change details of each change record.
74+
Try out a tenant-based Resource Graph query of the `resourcechanges` table. The query returns the first five most recent Azure resource changes with the change time, change type, target resource ID, target resource type, and change details of each change record.
7175

7276
# [Azure CLI](#tab/azure-cli)
73-
```azurecli
77+
```azurecli-interactive
7478
# Login first with az login if not using Cloud Shell
75-
79+
7680
# Run Azure Resource Graph query
7781
az graph query -q 'resourcechanges | project properties.changeAttributes.timestamp, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5'
7882
```
79-
83+
8084
# [PowerShell](#tab/azure-powershell)
8185
```azurepowershell-interactive
8286
# Login first with Connect-AzAccount if not using Cloud Shell
83-
87+
8488
# Run Azure Resource Graph query
8589
Search-AzGraph -Query 'resourcechanges | project properties.changeAttributes.timestamp, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5'
8690
```
87-
91+
8892
# [Portal](#tab/azure-portal)
8993
1. Open the [Azure portal](https://portal.azure.com).
90-
94+
9195
1. Select **All services** in the left pane. Search for and select **Resource Graph Explorer**.
92-
93-
:::image type="content" source="./media/get-resource-changes/resource-graph-explorer.png" alt-text="Screenshot of the searching for the Resource Graph Explorer in the All Services blade.":::
96+
97+
:::image type="content" source="./media/get-resource-changes/resource-graph-explorer.png" alt-text="Screenshot of the search for the Resource Graph Explorer in All Services.":::
9498

9599

96100
1. In the **Query 1** portion of the window, enter the following query.
@@ -103,29 +107,29 @@ Try out a tenant-based Resource Graph query of the `resourcechanges` table. The
103107
1. Select **Run query**.
104108
105109
:::image type="content" source="./media/get-resource-changes/change-query-resource-explorer.png" alt-text="Screenshot of how to run the query in Resource Graph Explorer and then view results.":::
106-
107-
1. Review the query response in the **Results** tab.
108-
110+
111+
1. Review the query response in the **Results** tab.
112+
109113
1. Select the **Messages** tab to see details about the query, including the count of results and duration of the query. Any errors are displayed under this tab.
110114
111115
:::image type="content" source="./media/get-resource-changes/messages-tab-query.png" alt-text="Screenshot of the search results for Change Analysis in the Azure portal.":::
112-
116+
113117
---
114118
115119
You can update this query to specify a more user-friendly column name for the **timestamp** property.
116120
117121
# [Azure CLI](#tab/azure-cli)
118-
```azurecli
122+
```azurecli-interactive
119123
# Run Azure Resource Graph query with 'extend'
120124
az graph query -q 'resourcechanges | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5'
121125
```
122-
126+
123127
# [PowerShell](#tab/azure-powershell)
124128
```azurepowershell-interactive
125129
# Run Azure Resource Graph query with 'extend' to define a user-friendly name for properties.changeAttributes.timestamp
126130
Search-AzGraph -Query 'resourcechanges | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5'
127131
```
128-
132+
129133
# [Portal](#tab/azure-portal)
130134
```kusto
131135
resourcechanges
@@ -135,23 +139,23 @@ You can update this query to specify a more user-friendly column name for the **
135139
```
136140

137141
Then select **Run query**.
138-
142+
139143
---
140144

141-
To limit query results to the most recent changes, update the query to `order by` the user-defined **changeTime** property.
145+
To limit query results to the most recent changes, update the query to `order by` the user-defined `changeTime` property.
142146

143147
# [Azure CLI](#tab/azure-cli)
144-
```azurecli
148+
```azurecli-interactive
145149
# Run Azure Resource Graph query with 'order by'
146150
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'
147151
```
148-
152+
149153
# [PowerShell](#tab/azure-powershell)
150154
```azurepowershell-interactive
151155
# Run Azure Resource Graph query with 'order by'
152156
Search-AzGraph -Query 'resourcechanges | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | order by changeTime desc | limit 5'
153157
```
154-
158+
155159
# [Portal](#tab/azure-portal)
156160
```kusto
157161
resourcechanges
@@ -160,9 +164,9 @@ To limit query results to the most recent changes, update the query to `order by
160164
| order by changeTime desc
161165
| limit 5
162166
```
163-
167+
164168
Then select **Run query**.
165-
169+
166170
---
167171

168172
You can also query by [management group](../../management-groups/overview.md) or subscription with the `-ManagementGroup` or `-Subscription` parameters, respectively.
@@ -172,7 +176,7 @@ You can also query by [management group](../../management-groups/overview.md) or
172176
173177
Resource Graph Explorer also provides a clean interface for converting the results of some queries into a chart that can be pinned to an Azure dashboard.
174178

175-
## Query resource changes
179+
## Query resource changes
176180

177181
With Resource Graph, you can query either the `resourcechanges`, `resourcecontainerchanges`, or `healthresourcechanges` tables to filter or sort by any of the change resource properties. The following examples query the `resourcechanges` table, but can also be applied to the `resourcecontainerchanges` or `healthresourcechanges` table.
178182

@@ -183,20 +187,24 @@ With Resource Graph, you can query either the `resourcechanges`, `resourcecontai
183187

184188
Before querying and analyzing changes in your resources, review the following best practices.
185189

186-
- Query for change events during a specific window of time and evaluate the change details.
190+
- Query for change events during a specific window of time and evaluate the change details.
187191
- This query works best during incident management to understand _potentially_ related changes.
188-
- Keep an up-to-date Configuration Management Database (CMDB).
189-
- Instead of refreshing all resources and their full property sets on a scheduled frequency, you'll only receive their changes.
190-
- Understand what other properties may have been changed when a resource changes "compliance state".
191-
- Evaluation of these extra properties can provide insights into other properties that may need to be managed via an Azure Policy definition.
192+
- Keep an up-to-date Configuration Management Database (CMDB).
193+
- Instead of refreshing all resources and their full property sets on a scheduled frequency, you only receive their changes.
194+
- Understand which other properties were changed when a resource changes _compliance state_.
195+
- Evaluation of these extra properties can provide insights into other properties that might need to be managed via an Azure Policy definition.
192196
- The order of query commands is important. In the following examples, the `order by` must come before the `limit` command.
193197
- The `order by` command orders the query results by the change time.
194198
- The `limit` command then limits the ordered results to ensure that you get the five most recent results.
199+
- What does **Unknown** mean? 
200+
- Unknown is displayed when the change happened on a client that's unrecognized. Clients are recognized based on the user agent and client application ID associated with the original change request.
201+
- What does **System** mean?
202+
- System is displayed as a `changedBy` value when a background change occurred that wasn't correlated with any direct user action.
195203

196204
#### All changes in the past 24-hour period
197205

198206
```kusto
199-
resourcechanges
207+
resourcechanges
200208
| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),
201209
changeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId, 
202210
changedProperties = properties.changes, changeCount = properties.changeAttributes.changesCount
@@ -206,17 +214,19 @@ changedProperties = properties.changes, changeCount = properties.changeAttr
206214
```
207215

208216
#### Resources deleted in a specific resource group
217+
209218
```kusto
210219
resourcechanges
211220
| where resourceGroup == "myResourceGroup"
212221
| extend changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId),
213-
changeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId
222+
changeType = tostring(properties.changeType), correlationId = properties.changeAttributes.correlationId
214223
| where changeType == "Delete"
215224
| order by changeTime desc
216225
| project changeTime, resourceGroup, targetResourceId, changeType, correlationId
217226
```
218227

219228
#### Changes to a specific property value
229+
220230
```kusto
221231
resourcechanges
222232
| extend provisioningStateChange = properties.changes["properties.provisioningState"], changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType)
@@ -225,37 +235,44 @@ resourcechanges
225235
| project changeTime, targetResourceId, changeType, provisioningStateChange.previousValue, provisioningStateChange.newValue
226236
```
227237

228-
#### Latest resource changes for resources created in the last seven days
238+
#### Changes in past seven days by who and which client and ordered by count
239+
229240
```kusto
230-
resourcechanges
231-
| extend targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType), changeTime = todatetime(properties.changeAttributes.timestamp)
232-
| where changeTime > ago(7d) and changeType == "Create"
233-
| project targetResourceId, changeType, changeTime
234-
| join ( Resources | extend targetResourceId=id) on targetResourceId
235-
| order by changeTime desc
236-
| project changeTime, changeType, id, resourceGroup, type, properties
241+
resourcechanges 
242+
| extend changeTime = todatetime(properties.changeAttributes.timestamp), 
243+
targetResourceId = tostring(properties.targetResourceId), 
244+
changeType = tostring(properties.changeType), changedBy = tostring(properties.changeAttributes.changedBy), 
245+
changedByType = properties.changeAttributes.changedByType, 
246+
clientType = tostring(properties.changeAttributes.clientType) 
247+
| where changeTime > ago(7d) 
248+
| project changeType, changedBy, changedByType, clientType 
249+
| summarize count() by changedBy, changeType, clientType 
250+
| order by count_ desc 
237251
```
238252

239253
#### Changes in virtual machine size 
254+
240255
```kusto
241256
resourcechanges
242-
|extend vmSize = properties.changes["properties.hardwareProfile.vmSize"], changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType) 
257+
| extend vmSize = properties.changes["properties.hardwareProfile.vmSize"], changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType) 
243258
| where isnotempty(vmSize) 
244259
| order by changeTime desc 
245260
| project changeTime, targetResourceId, changeType, properties.changes, previousSize = vmSize.previousValue, newSize = vmSize.newValue
246261
```
247262

248263
#### Count of changes by change type and subscription name
264+
249265
```kusto
250266
resourcechanges  
251-
|extend changeType = tostring(properties.changeType), changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceType=tostring(properties.targetResourceType)  
267+
| extend changeType = tostring(properties.changeType), changeTime = todatetime(properties.changeAttributes.timestamp), targetResourceType=tostring(properties.targetResourceType)  
252268
| summarize count() by changeType, subscriptionId 
253269
| join (resourcecontainers | where type=='microsoft.resources/subscriptions' | project SubscriptionName=name, subscriptionId) on subscriptionId 
254270
| project-away subscriptionId, subscriptionId1
255271
| order by count_ desc  
256272
```
257273

258274
#### Latest resource changes for resources created with a certain tag
275+
259276
```kusto
260277
resourcechanges 
261278
|extend targetResourceId = tostring(properties.targetResourceId), changeType = tostring(properties.changeType), createTime = todatetime(properties.changeAttributes.timestamp) 

0 commit comments

Comments
 (0)