Durable FunctionsのAzure Event Gridへの発行を構成する

オーケストレーション ライフサイクル イベントを Azure Event Grid に発行すると、DevOps の自動化 (青/緑のデプロイなど)、リアルタイムの監視ダッシュボード、実行時間の長いバックグラウンド プロセスの追跡が可能になります。

このガイドでは.NET例を使用しますが、概念とAzure CLIコマンドは、サポートされているすべてのDurable Functions言語に適用されます。

ヒント

Event Grid カスタム トピックとマネージド ID が既に構成されている場合は、「 Durable Functions パブリッシャー アプリを構成する」に進>。

前提条件

カスタム Event Grid トピックを作成する

Durable Functionsからイベントを送信するための Event Grid トピックを作成するには、Azure CLIPowerShell、または Azure ポータルを使用します。

このガイドでは、Azure CLIを使用します。

リソース グループを作成します

az group create コマンドでリソース グループを作成します。 Event Grid をサポートし、リソースをデプロイする場所と一致する場所を選択します。

現時点では、Azure Event Gridはすべてのリージョンをサポートしているわけではありません。 サポートされているリージョンの詳細については、 Azure Event Grid の概要を参照してください。

az group create --name <resource-group-name> --location <location>

Event Grid リソース プロバイダーを有効にする

  1. Azure サブスクリプションで Event Grid を初めて使用する場合は、Event Grid リソース プロバイダーの登録が必要になることがあります。 以下のプロバイダーを登録するコマンドを実行します。

    az provider register --namespace Microsoft.EventGrid
    
  2. 登録完了まで少し時間がかかることがあります。 状態を確認するには、次のコマンドを実行します。

    az provider show --namespace Microsoft.EventGrid --query "registrationState"
    

    registrationStateRegistered になったら、次に進めることができます。

カスタム トピックの作成

Event Grid トピックには、イベントを投稿するユーザー定義エンドポイントが用意されています。 次のコマンドの <topic-name> を、トピックの一意の名前に置き換えます。 トピック名は DNS エントリになるため、一意である必要があります。

az eventgrid topic create --name <topic-name> --location <location> --resource-group <resource-group-name>

トピック エンドポイントを取得する

トピックのエンドポイントを取得します。 次のコマンドの <topic-name> を、選択した名前に置き換えます。

az eventgrid topic show --name <topic-name> --resource-group <resource-group-name> --query "endpoint" --output tsv

後で使用するために、このエンドポイントを保存します。

Azure のマネージド ID を使用すると、リソースは資格情報を格納せずに Azure サービスに対して認証を行うことができ、セキュリティと ID の管理が簡素化されます。 Durable Function アプリに関連付けられているマネージド ID を Event Grid カスタム トピックに割り当てます。

Durable Functions パブリッシャー アプリを構成する

Durable Functions アプリはオーケストレーション ライフサイクル イベントを Event Grid に自動的に発行しますが、接続設定を構成する必要があります。 extensions.durableTaskhost.json セクションに次のコードを追加します。

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "eventGridTopicEndpoint": "%EventGrid__topicEndpoint%",
      "eventGridKeySettingName": "EventGrid__credential"
    }
  }
}

eventGridTopicEndpoint設定は、前に保存した Event Grid カスタム トピック エンドポイントを参照します。 資格情報の設定は、マネージド ID と接続文字列の両方のシナリオを処理します。

Event Grid データ送信者ロールの割り当て

Event Grid トピックにイベントを発行するアクセス許可を マネージド ID に付与します。

az role assignment create \
  --assignee <client-id-of-managed-identity> \
  --assignee-principal-type ServicePrincipal \
  --role "EventGrid Data Sender" \
  --scope /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.EventGrid/topics/<topic-name>

次の値を置き換えます。

  • <client-id-of-managed-identity>: 使用中のユーザー割り当てマネージド ID のクライアント ID。
  • <subscription-id>: Azure サブスクリプション ID
  • <resource-group-name>: Event Grid トピックを含むリソース グループの名前
  • <topic-name>: Event Grid トピックの名前

ロールの割り当てが反映されるまでに 5 ~ 10 分かかる場合があります。 割り当ての直後に続行すると、認証エラーが表示されることがあります。

アプリケーションの設定の構成

関数アプリとトピックのマネージド ID を有効にしたら、Durable Functions関数アプリで Event Grid アプリの設定を構成します。

次のアプリ設定を追加します。

  • EventGrid__topicEndpoint — Event Grid トピック エンドポイント。
  • EventGrid__credentialmanagedidentityに設定されます。
  • EventGrid__clientId — ユーザー割り当てマネージド ID クライアント ID。
az functionapp config appsettings set --name <function app name> --resource-group <resource group name> --settings EventGrid__topicEndpoint="<topic endpoint>" EventGrid__credential="managedidentity" EventGrid__clientId="<client id>"

イベントを登録する

発行されたライフサイクル イベントを受信するには、カスタム トピックからサブスクライバーにイベントをルーティングする Event Grid サブスクリプション を作成します。 一般的なサブスクライバーの種類には、Azure Functions (Event Grid トリガー付き)、Logic Apps、Webhook があります。

次の例では、Azure CLIを使用して Event Grid トリガーを使用してサブスクライバー関数アプリを作成します。 既にサブスクライバーがある場合は、「 Event Grid サブスクリプションの作成」に進みます。

リスナー関数アプリを作成する

Event Grid トリガーをホストする関数アプリを作成します。 リスナーは、Event Grid トピックと同じリージョンにある必要があります。

# Create a resource group
az group create --name <listener-resource-group-name> --location <location>

# Create a storage account
az storage account create \
  --name <storage-account-name> \
  --resource-group <listener-resource-group-name> \
  --location <location> \
  --sku Standard_LRS \
  --allow-blob-public-access false

# Create the function app
az functionapp create \
  --resource-group <listener-resource-group-name> \
  --consumption-plan-location <location> \
  --runtime <preferred-runtime> \
  --functions-version 4 \
  --name <listener-function-app-name> \
  --storage-account <storage-account-name>

Event Grid トリガー関数を作成してデプロイする

ローカル プロジェクトをスキャフォールディングし、Event Grid トリガーを追加して発行します。

mkdir EventGridListenerFunction && cd EventGridListenerFunction
func init --name EventGridListener --runtime dotnet-isolated
func new --template "Event Grid trigger" --name EventGridTrigger
func azure functionapp publish <listener-function-app-name>

dotnet-isolatedを任意のランタイム (nodepythonjava、またはpowershell) に置き換えます。 詳細なデプロイ手順については、「Publish to Azure」を参照してください。

Event Grid のサブスクリプションを作成する

azurefunction エンドポイントの種類を使用してサブスクリプションを作成します。これは、webhook の検証を自動的に処理します。

az eventgrid event-subscription create \
  --name <subscription-name> \
  --source-resource-id /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.EventGrid/topics/<topic-name> \
  --endpoint /subscriptions/<subscription-id>/resourceGroups/<listener-resource-group-name>/providers/Microsoft.Web/sites/<listener-function-app-name>/functions/EventGridTrigger \
  --endpoint-type azurefunction

ヒント

関数のリソース ID で --endpoint-type azurefunction を使用することをお勧めします。 Webhook 検証が自動的に処理され、URL で --endpoint-type webhook を使用するよりも信頼性が高くなります。

イベント スキーマ

オーケストレーションの状態が変更されると、Durable Functions ランタイムは次の構造のイベントを発行します。 イベントは状態遷移ごとに自動的に生成されます。コードを追加する必要はありません。

フィールド 説明
id Event Grid イベントの一意識別子。
subject durable/orchestrator/{orchestrationRuntimeStatus} — 状態は、 RunningCompletedFailed、または Terminatedにすることができます。
eventType 常に orchestratorEvent です。
eventTime イベント時間 (UTC)。
data.hubName TaskHub の名前。
data.functionName オーケストレーター関数名。
data.instanceId 一意のオーケストレーションインスタンスID。
data.runtimeStatus RunningCompletedFailed、または Canceled
data.reason その他の追跡データ。 詳細については、「Diagnostics in Durable Functions」を参照してください。

Event Grid では、少なくとも 1 回の配信が保証されるため、まれな障害シナリオで重複するイベントが発生する可能性があります。 必要に応じて、 instanceId を使用して重複除去ロジックを追加することを検討してください。

イベント配信の確認

エンド ツー エンドのセットアップを確認するには、Durable Functions アプリを展開し、オーケストレーションをトリガーします。

  1. 関数コードをAzureAzure ポータルで関数アプリに "実行中" と表示されていることを確認します。

  2. Azure ポータルで、Settings>Environment 変数EventGrid__topicEndpoint と (マネージド ID を使用する場合) EventGrid__credential が含まれているアプリ設定を確認します。

  3. HTTP クライアントを使用してオーケストレーションをトリガーします。

    curl -X POST https://<function_app_name>.azurewebsites.net/api/HelloOrchestration_HttpStart
    
  4. Azure ポータルで、listener 関数アプリ>EventGridTrigger>Monitor に移動して、受信したイベントを表示します。 durable/orchestrator/Runningdurable/orchestrator/Completedなどの件名のイベントが表示されます。

Application Insights で確認する (省略可能)

より包括的なビューを表示するには、関数アプリの Application Insights ログで次の KQL クエリを実行します。

traces
| where message contains "Event type" or message contains "Event subject"
| project timestamp, message
| order by timestamp desc

Troubleshooting

イベントが Event Grid に発行されていない

問題: リスナー関数がイベントを受信していません。

解決策:

  • Durable Functions関数アプリに正しいアプリ設定があることを確認します。
    • EventGrid__topicEndpoint カスタム トピック エンドポイントを指す必要があります
    • EventGrid__credentialmanagedidentity に設定されている必要があります
    • EventGrid__clientId ユーザー割り当て ID を使用する場合は設定する必要があります
  • マネージド ID に EventGrid データ送信者 ロールが Event Grid カスタム トピックに割り当てられているかどうかを確認します。
  • Application Insights のDurable Functions関数アプリ ログでエラーを確認します。
  • Event Grid トピックが存在し、同じサブスクリプションでアクセス可能であることを確認します。

リスナー関数がトリガーされていない

問題: リスナー関数は存在しますが、イベントが発行されるときには実行されません。

解決策:

  • Event Grid サブスクリプションが作成され、有効になっていることを確認します。
    • Azure ポータルで、Event Grid トピック → Subscriptions
    • リスナー関数のサブスクリプションが状態が [有効] と一覧表示されていることを確認する
  • Event Grid サブスクリプションで正しいエンドポイントの種類が使用されていることを確認します。
    • Azure Functionsの場合は、関数のリソース ID --endpoint-type azurefunction を使用します
    • --endpoint-type webhook使用した場合は、webhook URL が正しい形式であることを確認します。https://<function-app>.azurewebsites.net/runtime/webhooks/eventgrid?functionName=<function-name>&code=<system-key>
  • リスナー関数アプリのログでエラーや配信の問題を確認します。
  • Event Grid トピック → メトリックで、配信エラーを示す可能性がある 破棄されたイベント を確認します。

ログにおける「禁止」または認証エラー

問題: Event Grid に発行するときの認証エラー。

解決策:

  • Durable Functions関数アプリでマネージド ID が正しく構成され、有効になっていることを確認します。
    • Azure ポータルで、関数アプリ → Identity
    • システム割り当て ID またはユーザー割り当て ID の [状態] が [オン ] と表示されていることを確認する
  • ロールの割り当てが正しいことを確認します。
    • Event Grid トピックのAccess Control (IAM) に移動します
    • マネージド ID に EventGrid データ送信者 ロールがあることを確認します (注: "Event" と "Grid" の間にスペースがありません)
    • ロールの割り当てが反映されるまでに 5 ~ 10 分かかる場合があります

"接続が拒否されました" または "エンドポイントが見つかりません" エラー

問題: Event Grid トピックへの接続エラー。

解決策:

  • アプリ設定の Event Grid トピック エンドポイントが正しく、完全な URL ( https://my-topic.eventgrid.azure.net/api/events など) が含まれていることを確認します
  • Event Grid トピック リソースが同じサブスクリプションとリージョンに存在するかどうかを確認する
  • Durable Functions アプリが Event Grid エンドポイントへのネットワーク アクセス権を持っていることを確認する

ローカルでテストする

ローカルでテストするには、 ビューアー Web アプリを使用したローカル テストに関するページを参照してください。 マネージド ID を使用してローカルでテストする場合は、開発者の資格情報を使用して Event Grid トピックに対する認証を行います。 詳細については、「マネージド ID を使用したDurable Functionsの構成 - ローカル開発」を参照してください。

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

このチュートリアルで作成したリソースを引き続き使用しない場合は、料金が発生しないように削除してください。

リソース グループを削除する

リソース グループとその含まれるすべてのリソースの両方を削除します。

az group delete --name <resource-group-name> --yes
az group delete --name <listener-resource-group-name> --yes

個々のリソースを削除する

一部のリソースを保持する場合は、それらを個別に削除できます。

  1. Event Grid サブスクリプションを削除します。

    az eventgrid event-subscription delete \
      --name <subscription-name> \
      --source-resource-id /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.EventGrid/topics/<topic-name>
    
  2. Event Grid トピックを削除します。

    az eventgrid topic delete --name <topic-name> --resource-group <resource-group-name>
    
  3. 関数アプリを削除します。

    az functionapp delete --name <publisher-function-app-name> --resource-group <resource-group-name>
    az functionapp delete --name <listener-function-app-name> --resource-group <listener-resource-group-name>
    
  4. ストレージ アカウントを削除します。

    az storage account delete --name <storage-account-name> --resource-group <resource-group-name> --yes
    az storage account delete --name <listener-storage-account-name> --resource-group <listener-resource-group-name> --yes
    

次のステップ

詳細については、以下をご覧ください。