获取资源更改Get resource changes

在日常使用、重新配置甚至是重新部署的过程中,资源都会发生更改。Resources get changed through the course of daily use, reconfiguration, and even redeployment. 更改可能是个人或者自动化过程做出的。Change can come from an individual or by an automated process. 大部分更改是依设计做出的,但有时并非如此。Most change is by design, but sometimes it isn't. Azure Resource Graph 提供过去 14 天的更改历史记录,可让你:With the last 14 days of change history, Azure Resource Graph enables you to:

  • 查找在 Azure 资源管理器属性中检测到更改的时间Find when changes were detected on an Azure Resource Manager property
  • 对于每个资源更改,请参阅属性更改详细信息For each resource change, see property change details
  • 查看检测到的更改之前和之后的资源的完整比较See a full comparison of the resource before and after the detected change

对于以下示例场景,更改检测和详细信息很有用:Change detection and details are valuable for the following example scenarios:

  • 在事件管理期间了解可能相关的更改。During incident management to understand potentially related changes. 查询特定时段内的更改事件,并评估更改详细信息。Query for change events during a specific window of time and evaluate the change details.
  • 使配置管理数据库(称为 CMDB)保持最新。Keeping a Configuration Management Database, known as a CMDB, up-to-date. 无需按计划的频率刷新所有资源及其完整的属性集,只获取更改的内容。Instead of refreshing all resources and their full property sets on a scheduled frequency, only get what changed.
  • 了解当某个资源更改了符合性状态时可能已更改的其他属性。Understanding what other properties may have been changed when a resource changed compliance state. 评估这些附加属性可以洞察可能需要通过 Azure Policy 定义进行管理的其他属性。Evaluation of these additional properties can provide insights into other properties that may need to be managed via an Azure Policy definition.

本文介绍如何通过 Resource Graph 的 SDK 收集此信息。This article shows how to gather this information through Resource Graph's SDK. 若要在 Azure 门户中查看此信息,请参阅 Azure 活动日志更改历史记录To see this information in the Azure portal, see Azure Activity Log Change history.

备注

Resource Graph 中的更改详细信息适用于资源管理器属性。Change details in Resource Graph are for Resource Manager properties. 若要跟踪虚拟机内部的更改,请参阅 Azure Policy 的 VM 的来宾配置For tracking changes inside a virtual machine, see Azure Policy's Guest Configuration for VMs.

查找检测到的更改事件并查看更改详细信息Find detected change events and view change details

查看资源发生的更改的第一步是查找某个时段内与该资源相关的更改事件。The first step in seeing what changed on a resource is to find the change events related to that resource within a window of time. 每个更改事件还包含有关资源的哪些信息发生更改的详细信息。Each change event also includes details about what changed on the resource. 此步骤通过 resourceChanges REST 终结点完成。This step is done through the resourceChanges REST endpoint.

resourceChanges 终结点接受请求正文中的以下参数:The resourceChanges endpoint accepts the following parameters in the request body:

  • resourceId [必需]:要在其上查找更改的 Azure 资源。resourceId [required]: The Azure resource to look for changes on.
  • interval [必需]:具有使用“祖鲁语时区 (Z)”检查更改事件的 start 和 end 日期的属性。interval [required]: A property with start and end dates for when to check for a change event using the Zulu Time Zone (Z).
  • fetchPropertyChanges(可选):一个布尔属性,设置响应对象是否包括属性更改。fetchPropertyChanges (optional): A Boolean property that sets if the response object includes property changes.

示例请求正文:Example request body:

{
    "resourceId": "/subscriptions/{subscriptionId}/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount",
    "interval": {
        "start": "2019-09-28T00:00:00.000Z",
        "end": "2019-09-29T00:00:00.000Z"
    },
    "fetchPropertyChanges": true
}

对于上述请求正文,resourceChanges 的 REST API URI 为:With the above request body, the REST API URI for resourceChanges is:

POST https://management.chinacloudapi.cn/providers/Microsoft.ResourceGraph/resourceChanges?api-version=2018-09-01-preview

响应如以下示例所示:The response looks similar to this example:

{
    "changes": [
        {
            "changeId": "{\"beforeId\":\"3262e382-9f73-4866-a2e9-9d9dbee6a796\",\"beforeTime\":\"2019-09-28T00:45:35.012Z\",\"afterId\":\"6178968e-981e-4dac-ac37-340ee73eb577\",\"afterTime\":\"2019-09-28T00:52:53.371Z\"}",
            "beforeSnapshot": {
                "snapshotId": "3262e382-9f73-4866-a2e9-9d9dbee6a796",
                "timestamp": "2019-09-28T00:45:35.012Z"
            },
            "afterSnapshot": {
                "snapshotId": "6178968e-981e-4dac-ac37-340ee73eb577",
                "timestamp": "2019-09-28T00:52:53.371Z"
            },
            "changeType": "Create"
        },
        {
            "changeId": "{\"beforeId\":\"a00f5dac-86a1-4d86-a1c5-a9f7c8147b7c\",\"beforeTime\":\"2019-09-28T00:43:38.366Z\",\"afterId\":\"3262e382-9f73-4866-a2e9-9d9dbee6a796\",\"afterTime\":\"2019-09-28T00:45:35.012Z\"}",
            "beforeSnapshot": {
                "snapshotId": "a00f5dac-86a1-4d86-a1c5-a9f7c8147b7c",
                "timestamp": "2019-09-28T00:43:38.366Z"
            },
            "afterSnapshot": {
                "snapshotId": "3262e382-9f73-4866-a2e9-9d9dbee6a796",
                "timestamp": "2019-09-28T00:45:35.012Z"
            },
            "changeType": "Delete"
        },
        {
            "changeId": "{\"beforeId\":\"b37a90d1-7ebf-41cd-8766-eb95e7ee4f1c\",\"beforeTime\":\"2019-09-28T00:43:15.518Z\",\"afterId\":\"a00f5dac-86a1-4d86-a1c5-a9f7c8147b7c\",\"afterTime\":\"2019-09-28T00:43:38.366Z\"}",
            "beforeSnapshot": {
                "snapshotId": "b37a90d1-7ebf-41cd-8766-eb95e7ee4f1c",
                "timestamp": "2019-09-28T00:43:15.518Z"
            },
            "afterSnapshot": {
                "snapshotId": "a00f5dac-86a1-4d86-a1c5-a9f7c8147b7c",
                "timestamp": "2019-09-28T00:43:38.366Z"
            },
            "propertyChanges": [
                {
                    "propertyName": "tags.org",
                    "afterValue": "compute",
                    "changeCategory": "User",
                    "changeType": "Insert"
                },
                {
                    "propertyName": "tags.team",
                    "afterValue": "ARG",
                    "changeCategory": "User",
                    "changeType": "Insert"
                }
            ],
            "changeType": "Update"
        },
        {
            "changeId": "{\"beforeId\":\"19d12ab1-6ac6-4cd7-a2fe-d453a8e5b268\",\"beforeTime\":\"2019-09-28T00:42:46.839Z\",\"afterId\":\"b37a90d1-7ebf-41cd-8766-eb95e7ee4f1c\",\"afterTime\":\"2019-09-28T00:43:15.518Z\"}",
            "beforeSnapshot": {
                "snapshotId": "19d12ab1-6ac6-4cd7-a2fe-d453a8e5b268",
                "timestamp": "2019-09-28T00:42:46.839Z"
            },
            "afterSnapshot": {
                "snapshotId": "b37a90d1-7ebf-41cd-8766-eb95e7ee4f1c",
                "timestamp": "2019-09-28T00:43:15.518Z"
            },
            "propertyChanges": [{
                "propertyName": "tags.cgtest",
                "afterValue": "hello",
                "changeCategory": "User",
                "changeType": "Insert"
            }],
            "changeType": "Update"
        }
    ]
}

resourceId 的每个检测到的更改事件都具有以下属性:Each detected change event for the resourceId has the following properties:

  • changeId - 此值对于该资源是唯一的。changeId - This value is unique to that resource. changeId 字符串有时可能包含其他属性,但只能保证它是唯一的。While the changeId string may sometimes contain other properties, it's only guaranteed to be unique.

  • beforeSnapshot - 包含检测到更改之前创建的资源快照的 snapshotId 和 timestamp。beforeSnapshot - Contains the snapshotId and timestamp of the resource snapshot that was taken before a change was detected.

  • afterSnapshot - 包含检测到更改之后创建的资源快照的 snapshotId 和 timestamp。afterSnapshot - Contains the snapshotId and timestamp of the resource snapshot that was taken after a change was detected.

  • changeType - 描述已针对 beforeSnapshot 和 afterSnapshot 之间的完整更改记录检测到的更改的类型。changeType - Describes the type of change detected for the entire change record between the beforeSnapshot and afterSnapshot. 值为:Create、Update 和 Delete。 Values are: Create, Update, and Delete. 仅当 changeType 为 Update 时,才包括 propertyChanges 属性数组。The propertyChanges property array is only included when changeType is Update.

    重要

    Create 仅可用于以前存在并且在过去 14 天内删除的资源。Create is only available on resources that previously existed and were deleted within the last 14 days.

  • propertyChanges - 此属性数组提供了 beforeSnapshot 和 afterSnapshot 之间已更新的所有资源属性的详细信息:propertyChanges - This array of properties details all of the resource properties that were updated between the beforeSnapshot and the afterSnapshot:

    • propertyName - 已更改的资源属性的名称。propertyName - The name of the resource property that was altered.
    • changeCategory - 描述更改者类别。changeCategory - Describes what made the change. 值为:System 和 User。Values are: System and User.
    • changeType - 描述已为单个资源属性检测到的更改的类型。changeType - Describes the type of change detected for the individual resource property. 值为:Insert、Update、Remove。 Values are: Insert, Update, Remove.
    • beforeValue - beforeSnapshot 中资源属性的值。beforeValue - The value of the resource property in the beforeSnapshot. 当 changeType 为 Insert 时,不会显示。Isn't displayed when changeType is Insert.
    • afterValue - afterSnapshot 中资源属性的值。afterValue - The value of the resource property in the afterSnapshot. 当 changeType 为 Remove 时,不会显示。Isn't displayed when changeType is Remove.

比较资源更改Compare resource changes

有了来自 resourceChanges 终结点的 changeId 后,就可以使用 resourceChangeDetails REST 终结点获取资源更改之前和之后的快照。 With the changeId from the resourceChanges endpoint, the resourceChangeDetails REST endpoint is then used to get the before and after snapshots of the resource that was changed.

resourceChangeDetails 终结点要求在请求正文中使用两个参数:The resourceChangeDetails endpoint requires two parameters in the request body:

  • resourceId:要比较其更改的 Azure 资源。resourceId: The Azure resource to compare changes on.
  • changeId:从 resourceChanges 收集的 resourceId 的唯一更改事件。 changeId: The unique change event for the resourceId gathered from resourceChanges.

示例请求正文:Example request body:

{
    "resourceId": "/subscriptions/{subscriptionId}/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount",
    "changeId": "{\"beforeId\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\"beforeTime\":'2019-05-09T00:00:00.000Z\",\"afterId\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\"afterTime\":'2019-05-10T00:00:00.000Z\"}"
}

对于上述请求正文,resourceChangeDetails 的 REST API URI 是:With the above request body, the REST API URI for resourceChangeDetails is:

POST https://management.chinacloudapi.cn/providers/Microsoft.ResourceGraph/resourceChangeDetails?api-version=2018-09-01-preview

响应如以下示例所示:The response looks similar to this example:

{
    "changeId": "{\"beforeId\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\"beforeTime\":'2019-05-09T00:00:00.000Z\",\"afterId\":\"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\",\"beforeTime\":'2019-05-10T00:00:00.000Z\"}",
    "beforeSnapshot": {
        "timestamp": "2019-03-29T01:32:05.993Z",
        "content": {
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "kind": "Storage",
            "id": "/subscriptions/{subscriptionId}/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount",
            "name": "mystorageaccount",
            "type": "Microsoft.Storage/storageAccounts",
            "location": "chinanorth",
            "tags": {},
            "properties": {
                "networkAcls": {
                    "bypass": "AzureServices",
                    "virtualNetworkRules": [],
                    "ipRules": [],
                    "defaultAction": "Allow"
                },
                "supportsHttpsTrafficOnly": false,
                "encryption": {
                    "services": {
                        "file": {
                            "enabled": true,
                            "lastEnabledTime": "2018-07-27T18:37:21.8333895Z"
                        },
                        "blob": {
                            "enabled": true,
                            "lastEnabledTime": "2018-07-27T18:37:21.8333895Z"
                        }
                    },
                    "keySource": "Microsoft.Storage"
                },
                "provisioningState": "Succeeded",
                "creationTime": "2018-07-27T18:37:21.7708872Z",
                "primaryEndpoints": {
                    "blob": "https://mystorageaccount.blob.core.chinacloudapi.cn/",
                    "queue": "https://mystorageaccount.queue.core.chinacloudapi.cn/",
                    "table": "https://mystorageaccount.table.core.chinacloudapi.cn/",
                    "file": "https://mystorageaccount.file.core.chinacloudapi.cn/"
                },
                "primaryLocation": "chinanorth",
                "statusOfPrimary": "available"
            }
        }
    },
    "afterSnapshot": {
        "timestamp": "2019-03-29T01:54:24.42Z",
        "content": {
            "sku": {
                "name": "Standard_LRS",
                "tier": "Standard"
            },
            "kind": "Storage",
            "id": "/subscriptions/{subscriptionId}/resourceGroups/MyResourceGroup/providers/Microsoft.Storage/storageAccounts/mystorageaccount",
            "name": "mystorageaccount",
            "type": "Microsoft.Storage/storageAccounts",
            "location": "chinanorth",
            "tags": {},
            "properties": {
                "networkAcls": {
                    "bypass": "AzureServices",
                    "virtualNetworkRules": [],
                    "ipRules": [],
                    "defaultAction": "Allow"
                },
                "supportsHttpsTrafficOnly": true,
                "encryption": {
                    "services": {
                        "file": {
                            "enabled": true,
                            "lastEnabledTime": "2018-07-27T18:37:21.8333895Z"
                        },
                        "blob": {
                            "enabled": true,
                            "lastEnabledTime": "2018-07-27T18:37:21.8333895Z"
                        }
                    },
                    "keySource": "Microsoft.Storage"
                },
                "provisioningState": "Succeeded",
                "creationTime": "2018-07-27T18:37:21.7708872Z",
                "primaryEndpoints": {
                    "blob": "https://mystorageaccount.blob.core.chinacloudapi.cn/",
                    "queue": "https://mystorageaccount.queue.core.chinacloudapi.cn/",
                    "table": "https://mystorageaccount.table.core.chinacloudapi.cn/",
                    "file": "https://mystorageaccount.file.core.chinacloudapi.cn/"
                },
                "primaryLocation": "chinanorth",
                "statusOfPrimary": "available"
            }
        }
    }
}

beforeSnapshot 和 afterSnapshot 分别提供快照创建时间以及当时的属性。beforeSnapshot and afterSnapshot each give the time the snapshot was taken and the properties at that time. 更改是在这些快照之间的某个时间点发生的。The change happened at some point between these snapshots. 在以上示例中我们可以看到,更改的属性是 supportsHttpsTrafficOnly。Looking at the previous example, we can see that the property that changed was supportsHttpsTrafficOnly.

若要对结果进行比较,请使用 resourceChanges 中的 changes 属性,或评估 resourceChangeDetails 中每个快照的 content 部分,以确定差异。 To compare the results, either use the changes property in resourceChanges or evaluate the content portion of each snapshot in resourceChangeDetails to determine the difference. 如果对快照进行比较,timestamp 始终会显示为差异,不过这符合预期。If you compare the snapshots, the timestamp always shows as a difference despite being expected.

后续步骤Next steps