Obter alterações de recurso

Os recursos são alterados com o uso diário, reconfiguração e até mesmo a reimplantação. A maioria das alterações é por design, mas, às vezes, não é. Você pode:

  • Localize quando foram detectadas alterações em uma propriedade Azure Resource Manager.
  • Exibir detalhes de alteração da propriedade.
  • Consulte as alterações em escala em suas assinaturas, grupo de gerenciamento ou locatário.

Neste artigo, você aprende:

  • Como é o JSON de carga.
  • Como consultar alterações de recursos por meio do Resource Graph usando a CLI, o PowerShell ou o portal do Azure.
  • Exemplos e melhores práticas para consultar alterações de recursos.
  • A análise de alteração usa funcionalidade do Ator de Alteração:
    • changedBy: quem iniciou uma alteração no recurso, como uma ID do aplicativo ou o endereço de email da pessoa autorizada.
    • clientType: qual cliente fez a alteração, como portal do Azure.
    • operation: qual operação foi chamada, como Microsoft.Compute/virtualmachines/write.

Pré-requisitos

Entender as propriedades do evento de alteração

Quando um recurso é criado, atualizado ou excluído, um novo recurso de alteração (Microsoft.Resources/changes) é criado para estender o recurso modificado e representar as propriedades alteradas. Os registros de alterações devem estar disponíveis em menos de cinco minutos. O seguinte exemplo de conteúdo JSON demonstra as propriedades do recurso de alteração:

{
  "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",
    }
  }
}

Confira o guia de referência completo para alterar as propriedades do recurso.

Executar uma consulta

Experimente uma consulta do Resource Graph baseado em locatário da tabela resourcechanges. A consulta retorna as cinco primeiras alterações mais recentes de recursos do Azure com a hora de alteração, o tipo de alteração, a ID do recurso de destino, o tipo de recurso de destino e os detalhes da alteração de cada registro de alteração.

# 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'

Você pode atualizar esta consulta para especificar um nome de coluna mais amigável para a propriedade de carimbo de data/hora.

# 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'

Para limitar os resultados da consulta às alterações mais recentes, atualize a consulta para order by a propriedade changeTime definida pelo usuário.

# 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'

Você também pode consultar por grupo de gerenciamento ou assinatura com os parâmetros -ManagementGroup ou -Subscription, respectivamente.

Observação

Se a consulta não retorna os resultados de uma assinatura à qual você já tenha acesso, o cmdlet Search-AzGraph do PowerShell usa como padrão as assinaturas no contexto padrão.

O Explorador do Resource Graph também fornece uma interface limpa para converter os resultados de algumas consultas em um gráfico que pode ser fixo em um painel do Azure.

Alterações de recurso de consulta

Com o Resource Graph, você pode consultar as tabelas resourcechanges, resourcecontainerchanges ou healthresourcechanges para filtrar ou classificar por qualquer uma das propriedades do recurso de alteração. Os exemplos a seguir consultam a tabela resourcechanges, mas também podem ser aplicados à tabela resourcecontainerchanges ou healthresourcechanges.

Observação

Saiba mais sobre os dados healthresourcechanges na documentação do Project Flash.

Exemplos

Antes de consultar e analisar alterações em seus recursos, examine as melhores práticas a seguir.

  • Consulte eventos de alteração durante uma janela de tempo específica e avalie os detalhes da alteração.
    • Essa consulta funciona melhor durante o gerenciamento de incidentes para entender as alterações potencialmente relacionadas.
  • Mantenha um banco de dados de gerenciamento de configuração (CMDB) atualizado.
    • Em vez de atualizar todos os recursos e seus conjuntos de propriedades completos em uma frequência agendada, você receberá apenas suas alterações.
  • Entenda quais outras propriedades foram alteradas quando um recurso altera oestado de conformidade.
    • A avaliação dessas propriedades adicionais pode fornecer informações sobre outras propriedades que talvez precisem ser gerenciadas por meio de uma definição de Azure Policy.
  • A ordem dos comandos de consulta é importante. Nos exemplos a seguir, o order by deve vir antes do comando limit.
    • O comando order by ordena os resultados da consulta pelo tempo de alteração.
    • Em seguida, o comando limit limita os resultados ordenados para garantir que você obtenha os cinco resultados mais recentes.
  • O que significa Desconhecido? 
    • Desconhecido é exibido quando a alteração ocorreu em um cliente que não foi reconhecido. Os clientes são reconhecidos com base no agente do usuário e na ID do aplicativo cliente associada à solicitação de alteração original.
  • O que Sistema significa?
    • O sistema é exibido como um valor changedBy quando ocorreu uma alteração em segundo plano que não estava correlacionada com nenhuma ação direta do usuário.

Todas as alterações no período de 24 horas anteriores

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

Recursos excluídos em um grupo de recursos específico

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

Alterações em um valor da propriedade específico

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

Alterações nos últimos sete dias por quem e qual cliente e ordenado por contagem

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 

Alterações no tamanho da máquina virtual

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

Contagem de alterações por tipo de alteração e nome da assinatura

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  

Alterações de recursos mais recentes para recursos criados com uma determinada marca

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

Próximas etapas