チュートリアル: Azure CLI を使用してポリシー状態変更イベントを Event Grid にルーティングする

この記事では、Azure Policy イベント サブスクリプションの設定を通じて Web エンドポイントにポリシー状態変更イベントを送信する方法について説明します。 Azure Policy ユーザーは、リソースでポリシーの状態が変化したときに生成されるイベントをサブスクライブできます。 これらのイベントは、Web hook、Azure FunctionsAzure Storage キュー、または Azure Event Grid でサポートされている他の任意のイベント ハンドラーをトリガーできます。 通常は、イベント データを処理し、アクションを実行するエンドポイントにイベントを送信します。 ただし、このチュートリアルでは、単純化するために、メッセージを収集して表示する Web アプリにイベントを送信します。

前提条件

  • Azure サブスクリプションをお持ちでない場合は、開始する前に無料アカウントを作成してください。

  • このクイックスタートでは、Azure CLI バージョン 2.0.76 以降を実行する必要があります。 バージョンを確認するには、az --version を実行します。 インストールまたはアップグレードする必要がある場合は、Azure CLI のインストールに関するページを参照してください。

Azure Cloud Shell

Azure では、ブラウザーを介して使用できる対話型のシェル環境、Azure Cloud Shell がホストされています。 Cloud Shell で Bash または PowerShell を使用して、Azure サービスを操作できます。 ローカル環境に何もインストールしなくても、Cloud Shell にプレインストールされているコマンドを使用して、この記事のコードを実行できます。

Azure Cloud Shell を開始するには、以下のようにします。

オプション 例とリンク
コードまたはコマンド ブロックの右上隅にある [使ってみる] を選択します。 [使ってみる] を選択しても、コードまたはコマンドは Cloud Shell に自動的にはコピーされません。 Screenshot that shows an example of Try It for Azure Cloud Shell.
https://shell.azure.com に移動するか、[Cloud Shell を起動する] ボタンを選択して、ブラウザーで Cloud Shell を開きます。 Button to launch Azure Cloud Shell.
Azure portal の右上にあるメニュー バーの [Cloud Shell] ボタンを選択します。 Screenshot that shows the Cloud Shell button in the Azure portal

Azure Cloud Shell を使用するには、以下のようにします。

  1. Cloud Shell を開始します。

  2. コード ブロック (またはコマンド ブロック) の [コピー] ボタンを選択し、コードまたはコマンドをコピーします。

  3. Windows と Linux では Ctrl+Shift+V キーを選択し、macOS では Cmd+Shift+V キーを選択して、コードまたはコマンドを Cloud Shell セッションに貼り付けます。

  4. Enter キーを選択して、コードまたはコマンドを実行します。

リソース グループを作成する

Event Grid のトピックは Azure リソースであり、Azure リソース グループに配置する必要があります。 リソース グループは、Azure リソースをまとめてデプロイして管理するための論理上のコレクションです。

az group create コマンドを使用して、リソース グループを作成します。

次の例では、<resource_group_name> という名前のリソース グループを westus の場所に作成します。 <resource_group_name> を、リソース グループの一意の名前に置き換えます。

# Log in first with az login if you're not using Cloud Shell

az group create --name <resource_group_name> --location westus

Event Grid のシステム トピックを作成する

リソース グループを作成したら、システム トピックを作成します。 Event Grid でのシステム トピックは、Azure Policy や Azure Event Hubs などの Azure サービスによって発行された 1 つ以上のイベントを表します。 Azure Policy の状態の変更に関して、このシステム トピックでは Microsoft.PolicyInsights.PolicyStates という種類のトピックを使用します。

まず、PolicyInsights と、EventGrid のリソース プロバイダー (RP) を適切な管理スコープで登録する必要があります。 初めて呼び出した RP はすべて、Azure portal では自動登録されますが、Azure CLI ではされません。

# Log in first with az login if you're not using Cloud Shell

# Register the required RPs at the management group scope
az provider register --namespace Microsoft.PolicyInsights -m <managementGroupId>
az provider register --namespace Microsoft.EventGrid -m <managementGroupId>

# Alternatively, register the required RPs at the subscription scope (defaults to current subscription context)
az provider register --namespace Microsoft.PolicyInsights
az provider register --namespace Microsoft.EventGrid

次に、scope パラメーターの <subscriptionId> を実際のサブスクリプションの ID に、また resource-group パラメーターの <resource_group_name> を先ほど作成したリソース グループに置き換えます。

az eventgrid system-topic create --name PolicyStateChanges --location global --topic-type Microsoft.PolicyInsights.PolicyStates --source "/subscriptions/<subscriptionId>" --resource-group "<resource_group_name>"

Event Grid システム トピックが管理グループ スコープに適用される場合、Azure CLI --source パラメーターの構文は少し異なります。 次に例を示します。

az eventgrid system-topic create --name PolicyStateChanges --location global --topic-type Microsoft.PolicyInsights.PolicyStates --source "/tenants/<tenantID>/providers/Microsoft.Management/managementGroups/<management_group_name>" --resource-group "<resource_group_name>"

メッセージ エンドポイントの作成

トピックをサブスクライブする前に、イベント メッセージ用のエンドポイントを作成しましょう。 通常、エンドポイントは、イベント データに基づくアクションを実行します。 このクイック スタートを簡素化するために、イベント メッセージを表示する構築済みの Web アプリをデプロしします。 デプロイされたソリューションには、App Service プラン、App Service Web アプリ、および GitHub からのソース コードが含まれています。

<your-site-name> は、Web アプリの一意の名前に置き換えてください。 Web アプリ名は、DNS エントリの一部であるため、一意である必要があります。

# Log in first with az login if you're not using Cloud Shell

az deployment group create \
  --resource-group <resource_group_name> \
  --template-uri "https://raw.githubusercontent.com/Azure-Samples/azure-event-grid-viewer/master/azuredeploy.json" \
  --parameters siteName=<your-site-name> hostingPlanName=viewerhost

デプロイが完了するまでに数分かかる場合があります。 デプロイが成功した後で、Web アプリを表示して、実行されていることを確認します。 Web ブラウザーで https://<your-site-name>.azurewebsites.net にアクセスします

現在表示されているメッセージがないサイトが表示されます。

システム トピックをサブスクライブする

どのイベントを追跡し、どこにイベントを送信するかは、トピックをサブスクライブすることによって Event Grid に伝えます。 次の例では、作成したシステム トピックをサブスクライブし、イベント通知を受信するためのエンドポイントとして Web アプリの URL を渡しています。 <event_subscription_name> をイベント サブスクリプションの名前に置き換えます。 <resource_group_name><your-site-name> には、先ほど作成した値を使用します。

Web アプリのエンドポイントには、サフィックス /api/updates/ が含まれている必要があります。

# Log in first with az login if you're not using Cloud Shell

# Create the subscription
az eventgrid system-topic event-subscription create \
  --name <event_subscription_name> \
  --resource-group <resource_group_name> \
  --system-topic-name PolicyStateChanges \
  --endpoint https://<your-site-name>.azurewebsites.net/api/updates

Web アプリをもう一度表示し、その Web アプリにサブスクリプションの検証イベントが送信されたことに注目します。 目のアイコンを選択してイベント データを展開します。 Event Grid は検証イベントを送信するので、エンドポイントはイベント データを受信することを確認できます。 Web アプリには、サブスクリプションを検証するコードが含まれています。

Screenshot of the Event Grid subscription validation event in the pre-built web app.

ポリシー割り当てを作成する

このクイックスタートでは、ポリシーの割り当てを作成し、"リソース グループでタグを必須にする" 定義を割り当てます。 このポリシーの定義は、ポリシーの割り当て中に構成されたタグが存在しないリソース グループを特定します。

Event Grid トピックを保持するために作成したリソース グループを対象にポリシーの割り当てを作成するには、次のコマンドを実行します。

# Log in first with az login if you're not using Cloud Shell

az policy assignment create --name 'requiredtags-events' --display-name 'Require tag on RG' --scope '<resourceGroupScope>' --policy '<policy definition ID>' --params '{ \"tagName\": { \"value\": \"EventTest\" } }'

上記のコマンドでは次の情報を使用します。

  • Name - 割り当ての実際の名前。 この例では、requiredtags-events を使用しています。
  • DisplayName - ポリシーの割り当てに使用する表示名。 このケースでは、"Require tag on RG" を使用しています。
  • Scope - スコープによって、ポリシーの割り当てを強制するリソースまたはリソースのグループが決まります。 サブスクリプションからリソース グループまで、適用対象は多岐にわたります。 <scope> は、実際のリソース グループの名前に置き換えてください。 リソース グループのスコープの形式は /subscriptions/<subscriptionId>/resourceGroups/<resourceGroup> です。
  • Policy - 割り当ての作成に使用するポリシー定義 ID。 ここでは、"リソース グループでタグを必須にする" というポリシー定義の ID です。 ポリシー定義 ID を取得するには、次のコマンドを実行します。az policy definition list --query "[?displayName=='Require a tag on resource groups']"

ポリシーの割り当て後、Microsoft.PolicyInsights.PolicyStateCreated イベント通知が Web アプリに表示されるのを待ちます。 作成したリソース グループに関して最初に表示される data.complianceState の値は NonCompliant です。

Screenshot of the Event Grid subscription Policy State Created event for the resource group in the pre-built web app.

Note

リソース グループがサブスクリプションまたは管理グループの階層から他のポリシーの割り当てを継承している場合、それぞれのイベントも表示されます。 data.policyDefinitionId プロパティを評価してこのチュートリアルでの割り当てに関するイベントであることを確認してください。

リソース グループの変更をトリガーする

リソース グループを準拠状態にするためには、EventTest という名前のタグが必要です。 リソース グループにタグを追加するには次のコマンドを使用します。<subscriptionId> は実際のサブスクリプション ID に、また <resourceGroup> はリソース グループの名前に置き換えてください。

# Log in first with az login if you're not using Cloud Shell

az tag create --resource-id '/subscriptions/<SubscriptionID>/resourceGroups/<resourceGroup>' --tags EventTest=true

必要なタグをリソース グループに追加した後、Web アプリに Microsoft.PolicyInsights.PolicyStateChanged イベント通知が表示されるのを待ちます。 イベントを展開すると、今度は data.complianceState の値が Compliant になっていることがわかります。

トラブルシューティング

次のいずれかのようなエラーが表示された場合は、サブスクライブしているスコープ (管理グループまたはサブスクリプション) で両方のリソース プロバイダーが登録されていることを確認してください。

  • Deployment has failed with the following error: {"code":"Publisher Notification Error","message":"Failed to enable publisher notifications.","details":[{"code":"Publisher Provider Error","message":"GET request for <uri> failed with status code: Forbidden, code: AuthorizationFailed and message: The client '<identifier>' with object id '<identifier>' does not have authorization to perform action 'microsoft.policyinsights/eventGridFilters/read' over scope '<scope>/providers/microsoft.policyinsights/eventGridFilters/_default' or the scope is invalid. If access was recently granted, please refresh your credentials.."}]}
  • Deployment has failed with the following error: {'code':'Publisher Notification Error','message':'Failed to enable publisher notifications.','details':[{'code':'ApiVersionNotSupported','message':'Event Grid notifications are currently not supported by microsoft.policyinsights in global. Try re-registering Microsoft.EventGrid provider if this is your first event subscription in this region.'}]}

リソースをクリーンアップする

引き続きこの Web アプリと Azure Policy イベント サブスクリプションを使用する場合は、この記事で作成したリソースをクリーンアップしないでください。 引き続き使用する予定がない場合は、次のコマンドを使用して、この記事で作成したリソースを削除します。

<resource_group_name> は、先ほど作成したリソース グループに置き換えます。

az group delete --name <resource_group_name>

次のステップ

Azure Policy に使用するトピックとイベント サブスクリプションの作成方法がわかったら、ポリシー状態変更イベントについて、また Event Grid でできることについてさらに情報を収集しましょう。