리소스 변경 내용 가져오기
리소스는 일상적인 사용, 다시 구성 및 재배치 과정을 통해 변경됩니다. 대부분의 변경은 의도적이지만 때로는 그렇지 않습니다. 마케팅 목록의 구성원을 관리할 수 있습니다.
- 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