리소스 변경 내용 가져오기
리소스는 일상적인 사용, 다시 구성 및 재배치 과정을 통해 변경됩니다. 대부분의 변경은 의도적이지만 때로는 그렇지 않습니다. 마케팅 목록의 구성원을 관리할 수 있습니다.
- Azure Resource Manager 속성에서 변경이 탐지된 시기를 확인합니다.
- 속성 변경 세부 정보 보기
- 구독, 관리 그룹 또는 테넌트 전반에 걸쳐 대규모로 변경 내용 쿼리
이 문서에서는 다음에 대해 알아봅니다.
- 페이로드 JSON의 모양입니다.
- CLI, PowerShell 또는 Azure Portal을 사용하여 Resource Graph를 통해 리소스 변경 내용을 쿼리하는 방법입니다.
- 리소스 변경 내용을 쿼리하기 위한 쿼리 예 및 모범 사례입니다.
필수 조건
- Azure PowerShell을 사용하여 Azure Resource Graph를 쿼리하려면 모듈을 추가합니다.
- Azure CLI를 사용하여 Azure Resource Graph를 쿼리하려면 확장을 추가합니다.
변경 이벤트 속성 이해
리소스를 만들거나 업데이트하거나 삭제하면 수정된 리소스를 확장하고 변경된 속성을 나타내는 새 변경 리소스(Microsoft.Resources/change)가 만들어집니다. 변경 기록은 5분 이내에 사용할 수 있어야 합니다. 다음 예 JSON 페이로드는 변경 리소스 속성을 보여 줍니다.
{
"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"
}
}
}
변경 리소스 속성에 대한 전체 참조 가이드를 참조하세요.
쿼리 실행
resourcechanges
테이블의 테넌트 기반 Resource Graph 쿼리를 사용해 보세요. 쿼리는 가장 최근 Azure 리소스 변경 내용 중 처음 5개를 변경 시간, 변경 유형, 대상 리소스 ID, 대상 리소스 종류 및 각 변경 레코드의 변경 세부 정보와 함께 반환
# 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'
이 쿼리를 업데이트하여 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'
쿼리 결과를 가장 최근 변경 내용으로 제한하려면 쿼리를 사용자 정의 changeTime 속성인 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'
각각 -ManagementGroup
또는 -Subscription
매개 변수를 사용하여 관리 그룹 또는 구독별로 쿼리할 수도 있습니다.
참고 항목
사용자에게 액세스 권한이 이미 있는 구독에서 쿼리가 결과를 반환하지 않는 경우 Search-AzGraph
PowerShell cmdlet은 기본 컨텍스트에서 구독으로 기본 설정됩니다.
Resource Graph Explorer는 일부 쿼리의 결과를 Azure 대시 보드에 고정할 수 있는 차트로 변환하는 깔끔한 인터페이스도 제공합니다.
쿼리 리소스 변경
Resource Graph를 사용하면 resourcechanges
, resourcecontainerchanges
또는 healthresourcechanges
테이블을 쿼리하여 변경 리소스 속성을 기준으로 필터링하거나 정렬할 수 있습니다. 다음 예에서는 resourcechanges
테이블을 쿼리하지만 resourcecontainerchanges
또는 healthresourcechanges
테이블에도 적용될 수 있습니다.
참고 항목
Project Flash 설명서에서 healthresourcechanges
데이터에 대해 자세히 알아봅니다.
예제
리소스의 변경 내용을 쿼리하고 분석하기 전에 다음 모범 사례를 검토합니다.
- 특정 시간 창에서 변경 이벤트를 쿼리하고 변경 세부 정보 평가
- 이 쿼리는 인시던트 관리 중에 잠재적으로 관련된 변경 내용을 이해하는 데 가장 효과적입니다.
- 최신 CMDB(구성 관리 데이터베이스)를 유지합니다.
- 예약된 빈도에 따라 모든 리소스와 전체 속성 집합을 새로 고치는 대신 변경 내용만 수신하게 됩니다.
- 리소스가 "준수 상태"를 변경했을 때 변경되었을 수 있는 다른 속성을 이해합니다.
- 이러한 추가 속성을 평가하면 Azure Policy 정의를 통해 관리해야 할 수 있는 다른 속성에 대한 인사이트를 제공할 수 있습니다.
- 쿼리 명령의 순서는 중요합니다. 다음 예에서
order by
는limit
명령 앞에 와야 합니다.order by
명령은 변경 시간을 기준으로 쿼리 결과를 정렬합니다.- 그런 다음
limit
명령은 순서가 지정된 결과를 제한하여 가장 최근 결과 5개를 가져올 수 있도록 합니다.
지난 24시간 동안의 모든 변경 내용
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
특정 리소스 그룹에서 삭제된 리소스
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
특정 속성 값에 대한 변경 내용
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
지난 7일 동안 만들어진 리소스에 대한 최신 리소스 변경 내용
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
가상 머신 크기 변경
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
변경 유형 및 구독 이름별 변경 횟수
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
특정 태그로 만들어진 리소스에 대한 최신 리소스 변경 내용
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