리소스 변경 내용 가져오기
리소스는 일상적인 사용, 다시 구성 및 재배치 과정을 통해 변경됩니다. 대부분의 변경은 의도적이지만 때로는 그렇지 않습니다. 마케팅 목록의 구성원을 관리할 수 있습니다.
- Azure Resource Manager 속성에서 변경이 탐지된 시기를 확인합니다.
- 속성 변경 세부 정보 보기
- 구독, 관리 그룹 또는 테넌트 전반에 걸쳐 대규모로 변경 내용 쿼리
이 문서에서는 다음에 대해 알아봅니다.
- 페이로드 JSON의 모양입니다.
- CLI, PowerShell 또는 Azure Portal을 사용하여 Resource Graph를 통해 리소스 변경 내용을 쿼리하는 방법입니다.
- 리소스 변경 내용을 쿼리하기 위한 쿼리 예 및 모범 사례입니다.
- 변경 분석은 변경 행위자 기능을 사용합니다.
changedBy
: 앱 ID 또는 권한 있는 사용자의 아메일 주소와 같은 리소스 변경을 시작한 사용자입니다.clientType
: 변경 작업을 수행한 클라이언트입니다(예: Azure Portal).operation
: 호출된 작업입니다(예:Microsoft.Compute/virtualmachines/write
).
필수 조건
- Azure PowerShell을 사용하여 Azure Resource Graph를 쿼리하려면 모듈을 추가합니다.
- Azure CLI를 사용하여 Azure Resource Graph를 쿼리하려면 확장을 추가합니다.
변경 이벤트 속성 이해
리소스를 만들거나 업데이트하거나 삭제하면 수정된 리소스를 확장하고 변경된 속성을 나타내는 새 변경 리소스(Microsoft.Resources/changes
)가 만들어집니다. 변경 기록은 5분 이내에 사용할 수 있어야 합니다. 다음 예 JSON 페이로드는 변경 리소스 속성을 보여 줍니다.
{
"targetResourceId": "/subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/myResourceGroup/providers/microsoft.compute/virtualmachines/myVM",
"targetResourceType": "microsoft.compute/virtualmachines",
"changeType": "Update",
"changeAttributes": {
"previousResourceSnapshotId": "11111111111111111111_22222222-3333-aaaa-bbbb-444444444444_5555555555_6666666666",
"newResourceSnapshotId": "33333333333333333333_44444444-5555-ffff-gggg-666666666666_7777777777_8888888888",
"correlationId": "11111111-1111-1111-1111-111111111111",
"changedByType": "User",
"changesCount": 2,
"clientType": "Azure Portal",
"changedBy": "john@contoso.com",
"operation": "microsoft.compute/virtualmachines/write",
"timestamp": "2024-06-12T13:26:17.347+00:00"
},
"changes": {
"properties.provisioningState": {
"newValue": "Succeeded",
"previousValue": "Updating",
"isTruncated": "true"
},
"tags.key1": {
"newValue": "NewTagValue",
"previousValue": "null",
}
}
}
변경 리소스 속성에 대한 전체 참조 가이드를 참조하세요.
쿼리 실행
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개를 가져올 수 있도록 합니다.
- 알 수 없음은 무엇을 의미하나요?
- 인식할 수 없는 클라이언트에서 변경이 발생하면 알 수 없음이 표시됩니다. 클라이언트는 원래 변경 요청과 연결된 사용자 에이전트 및 클라이언트 애플리케이션 ID를 기반으로 인식됩니다.
- 시스템은 무엇을 의미하나요?
- 직접 사용자 작업과 상관 관계가 없는 백그라운드 변경이 발생한 경우 시스템은
changedBy
값으로 표시됩니다.
- 직접 사용자 작업과 상관 관계가 없는 백그라운드 변경이 발생한 경우 시스템은
지난 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 changeTime = todatetime(properties.changeAttributes.timestamp),
targetResourceId = tostring(properties.targetResourceId),
changeType = tostring(properties.changeType), changedBy = tostring(properties.changeAttributes.changedBy),
changedByType = properties.changeAttributes.changedByType,
clientType = tostring(properties.changeAttributes.clientType)
| where changeTime > ago(7d)
| project changeType, changedBy, changedByType, clientType
| summarize count() by changedBy, changeType, clientType
| order by count_ desc
가상 머신 크기 변경
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