리소스 변경 내용 가져오기

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

  • 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 bylimit 명령 앞에 와야 합니다.
    • 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

다음 단계