リソースの変更の取得

リソースは、日々の使用や再構成を通じて、また再デプロイによっても変更されます。 変更は、個別のプロセスで行われることもあれば、自動プロセスによって行われることもあります。 多くの変更は目的を持って行われますが、そうでないものもあります。 直近 14 日間の変更について、リソースの構成変更から次のことが可能になります。

  • Azure Resource Manager プロパティでいつ変更が検出されたかを見つける
  • 各リソースの変更について、プロパティ変更の詳細を参照する
  • サブスクリプション、管理グループ、またはテナントでの大規模な変更を照会する

次のサンプル シナリオにとって、変更の検出と詳細は貴重です。

  • インシデント管理中に、潜在的に関連している変更を把握する。 特定の時間枠の間の変更イベントのクエリを実行し、変更の詳細を評価する。
  • CMDB (Configuration Management Database) を最新状態に保つ。 スケジュールされた頻度ですべてのリソースとそれらの全プロパティ セットを更新する代わりに、変更されたものだけを取得します。
  • リソースがコンプライアンス状態を変更したときに他のどのプロパティが変更された可能性があるかを把握する。 これらの追加プロパティを評価することにより、Azure Policy 定義による管理が必要な可能性がある他のプロパティの分析情報を得ることができます。

この記事では、Resource Graph を使用してリソース構成の変更を照会する方法について説明します。 Azure portal でこの情報を表示するには、Azure Resource Graph エクスプローラー、Azure Policy の変更履歴、または Azure アクティビティ ログの変更履歴を参照してください。 インフラストラクチャ レイヤーからアプリケーションのデプロイまで、アプリケーションに対する変更の詳細については、Azure Monitor でのアプリケーション変更分析の使用 (プレビュー)に関するページをご覧ください。

注意

リソース構成の変更は、Azure Resource Manager のプロパティに対するものです。 仮想マシン内で変更を追跡するには、Azure Automation の変更の追跡または Azure Policy の VM のゲスト構成を参照してください。 Resource Graph でゲスト構成リソースに対してクエリを実行する方法の例を表示するには、カテゴリ別の Azure Resource Graph サンプル クエリ - Azure Policy ゲスト構成に関する記事を参照してください。

重要

リソース構成の変更では、Resource Graph のリソース テーブルからのリソースの種類への変更のみがサポートされます。 これには、サブスクリプション、リソース グループなどのリソース コンテナー リソースへの変更はまだ含まれていません。 変更は 14 日間照会可能です。 保持期間を長くするには、Resource Graph クエリを Azure Logic Apps と統合し、必要な保持期間の Azure データ ストア (Log Analytics など) にクエリ結果をエクスポートします。

検出された変更イベントの検索と変更の詳細の表示

リソースが作成、更新、または削除されると、変更されたリソースを拡張し、変更されたプロパティを表す新しい変更リソース (Microsoft.Resources/changes) が作成されます。 変更レコードは、5 分以内に利用できるようになります。

変更リソースのプロパティ バッグの例:

{
  "targetResourceId": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myResourceGroup/providers/microsoft.compute/virtualmachines/myVM",
  "targetResourceType": "microsoft.compute/virtualmachines",
  "changeType": "Update",
  "changeAttributes": {
    "changesCount": 2,
    "correlationId": "88420d5d-8d0e-471f-9115-10d34750c617",
    "timestamp": "2021-12-07T09:25:41.756Z",
    "previousResourceSnapshotId": "ed90e35a-1661-42cc-a44c-e27f508005be",
    "newResourceSnapshotId": "6eac9d0f-63b4-4e7f-97a5-740c73757efb"
  },
  "changes": {
    "properties.provisioningState": {
      "newValue": "Succeeded",
      "previousValue": "Updating",
      "changeCategory": "System",
      "propertyChangeType": "Update"
    },
    "tags.key1": {
      "newValue": "NewTagValue",
      "previousValue": "null",
      "changeCategory": "User",
      "propertyChangeType": "Insert"
    }
  }
}

各変更リソースには、次のプロパティがあります。

  • targetResourceId - 変更が発生したリソースの resourceID。

  • targetResourceType - 変更が発生したリソースの種類。

  • changeType - 変更レコード全体で検出された変更の種類を示します。 値は次のとおりです。CreateUpdateDeletechanges プロパティ辞書は、changeTypeUpdate の場合にのみ含められます。 削除の場合、リソース グループ全体が削除されていても、変更リソースは削除されたリソースの延長として 14 日間維持されます。 変更リソースによって、削除がブロックされたり、既存の削除動作に影響したりすることはありません。

  • changes - 変更の一部として更新されたリソース プロパティ (プロパティ名がキー) の辞書。

    • propertyChangeType - 個々のリソース プロパティに対して検出された変更の種類が示されます。 値は次のとおりです。InsertUpdateRemove
    • previousValue - 以前のスナップショットのリソース プロパティの値。 changeTypeInsert の場合、値は null になります。
    • newValue - 新しいスナップショットのリソース プロパティの値。 changeTypeRemove の場合、値は null になります。
    • changeCategory - プロパティの変更が、値 (User) の変更の結果、または参照される API バージョン (System) の相違の結果のいずれであるかを示します。 値は次のとおりです。SystemUser
  • changeAttributes - 変更に関連するメタデータの配列。

    • changesCount - この変更レコードの一部として変更されたプロパティの数。
    • correlationId - 関連するイベントを追跡するための ID が含まれています。 各デプロイには 1 つの相関 ID があり、1 つのテンプレート内のすべてのアクションでは同じ相関 ID が共有されます。
    • timestamp - 変更が検出された日時。
    • previousResourceSnapshotId - リソースの以前の状態として使用されたリソース スナップショットの ID が含まれています。
    • newResourceSnapshotId - リソースの新しい状態として使用されたリソース スナップショットの ID が含まれています。

Resource Graph を使用して変更を照会する方法

前提条件

Resource Graph クエリを実行する

それでは、resourcechanges テーブルに対してテナントベースの Resource Graph クエリを実行してみましょう。 このクエリは、Azure リソースの変更のうち最新の 5 つを、変更の時刻、変更の種類、ターゲット リソース ID、ターゲット リソースの種類、各変更レコードの変更の詳細と共に返します。 管理グループまたはサブスクリプションでクエリするには、 または -Subscription パラメーターを使用します。

  1. 最初の Azure Resource Graph クエリを実行します。
# 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'

Note

このクエリ例では、order by などの並べ替え修飾子を指定していません。そのため、このクエリを複数回実行すると、要求ごとに、得られる一連のリソースが異なる可能性があります。

  1. timestamp プロパティに、よりわかりやすい列名を指定するために、クエリを更新します。
# Run Azure Resource Graph query with 'extend' to define a user-friendly name for properties.changeAttributes.timestamp 
az graph query -q 'resourcechanges | extend changeTime=todatetime(properties.changeAttributes.timestamp) | project changeTime, properties.changeType, properties.targetResourceId, properties.targetResourceType, properties.changes | limit 5'
  1. 最新の変更を取得するには、ユーザー定義の 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'

Note

クエリ コマンドの順序が重要です。 この例では、order bylimit コマンドよりも前に指定する必要があります。 この順序でコマンドを指定することにより、クエリの結果が最初は変更時刻で並べ替えられ、そのうえで、"直近" 5 つの結果だけを返すようにそれらが制限されます。

最後のクエリを複数回実行した場合、環境内で何も変更がないと仮定すると、返される結果は変わらず、properties.changeAttributes.timestamp (または changeTime のユーザー定義名) プロパティで並べ替えられますが、引き続き上位 5 件の結果に制限されます。

注意

既にアクセスできているサブスクリプションからクエリの結果が返されなかった場合、Search-AzGraph PowerShell コマンドレットでは既定コンテキストのサブスクリプションが既定で使用されることに注意してください。 既定のコンテキストの一部であるサブスクリプション ID の一覧を表示するには、この (Get-AzContext).Account.ExtendedProperties.Subscriptions を実行します。アクセスできるすべてのサブスクリプション全体を検索する場合は、$PSDefaultParameterValues=@{"Search-AzGraph:Subscription"= $(Get-AzSubscription).ID} を実行して Search-AzGraph コマンドレットの PSDefaultParameterValues を設定できます

また、Resource Graph エクスプローラーには、整然としたインターフェイスが備わっていて、いくつかのクエリの結果をグラフに変換して Azure ダッシュボードにピン留めすることもできます。

Resource Graph のクエリのサンプル

Resource Graph では、resourcechanges テーブルに対してクエリを実行して、変更リソース プロパティによってフィルター処理または並べ替えを行うことができます。

過去 1 日のすべての変更

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

次のステップ