Azure Event Grid 名前空間で Push 配信のサブスクリプションを作成したら 500 エラー…。Queue モードは動くのになぜ?さらに Logic Apps(消費プラン)を Webhook 受信先にして Managed Identity で認証したい、という設計も迷いやすいポイントです。本記事では、実際のトラブル事例と回避パターンを、運用ノウハウも交えて整理します。
Azure Event Grid 名前空間の Push 配信で 500 エラーが出るときの考え方
まずは「Event Grid 名前空間」のトピックに対して、deliveryMode = Push でイベント サブスクリプションを作成しようとした際に、ポータルや API から 500 (InternalServerError) が返ってしまうケースを整理します。
よくあるパターンとしては次のようなものです。
- Queue モード(deliveryMode = Queue)は問題なく作成できる
- Push モードだけがサブスクリプション作成時の最終ステップで 500 エラー
- イベント サブスクリプションのエラー詳細を見ても「内部エラー」程度しか分からない
一見すると「Azure 側の障害?」と思いがちですが、実際には 受信側エンドポイントの設定やネットワーク制御 が原因となることが非常に多くあります。
一次原因の実例:IP 制限により Event Grid からの検証リクエストがブロック
実際のトラブル事例として、最終的な原因が 受信側エンドポイントの IP 制限 だったケースを紹介します。
構成はシンプルです。
- Event Grid 名前空間のトピック(deliveryMode = Push)
- 受信先エンドポイント:ファイアウォールや WAF で IP 制限された Web アプリ
Event Grid の Push/Webhook サブスクリプションは、作成時に サブスクリプション検証(validation)を行います。このとき Event Grid から受信 URL に対して検証リクエストが送信されますが、受信側の IP 制限が厳しすぎると、この検証リクエスト自体がブロックされてしまいます。
その結果、Event Grid サービス側から見ると「受信側が応答しない/到達できない」状態になり、呼び出し元(ポータルや CLI)には 500 InternalServerError として返ってくる、という挙動になります。
このケースでは、受信側の IP 制限を見直し、Event Grid 送信元の IP 範囲を許可リストに追加したところ、同じ設定のままでも Push サブスクリプションが正常に作成できるようになりました。
Push は失敗するのに Queue は成功する理由
なぜ Queue モードでは問題なく、Push モードだけが失敗するのでしょうか。その理由を簡単に整理すると次のとおりです。
| 項目 | Push 配信(deliveryMode = Push) | Queue モード(deliveryMode = Queue) |
|---|---|---|
| サブスクリプション作成時の検証 | 受信 URL へ 検証リクエスト を送信し、HTTP 200 などの応答を要求 | 受信 URL へのリクエストは不要(Queue に格納するだけ) |
| 受信側の即時到達性の要求 | あり(検証&配信時に到達できなければ失敗) | なし(Queue への書き込みができれば OK) |
| ネットワーク/FW 設定の影響 | WAF、FW、IP 制限で拒否されると作成時点で 500 に見える | Queue は Azure 内部のリソースなので、外部公開エンドポイントの制限に影響されにくい |
つまり、Queue モードは「とりあえず Azure 内部の Queue に突っ込むだけ」なのに対し、Push モードは「外部エンドポイントまで届いて初めて成功」となるため、ネットワーク・アプリ側の問題が顕在化しやすいのです。
500 エラー切り分けのステップ:よくある原因と確認ポイント
ここからは、実際に 500 エラーが出たときにどの順番で切り分けると効率がよいかを整理します。「とりあえず再試行」ではなく、再発しないためのチェックリストとして使えるようにしておくと便利です。
1. リソース プロバイダーの登録状態を確認する
まず確認したいのが、サブスクリプションに Microsoft.EventGrid リソース プロバイダーが正しく登録されているかです。ほとんどの環境では自動登録されていますが、セキュリティポリシーが厳しいサブスクリプションでは未登録のこともあります。
Azure CLI で確認・登録する例は次のとおりです。
# 登録状態の確認
az provider show -n Microsoft.EventGrid --query registrationState
# Registered でなければ登録
az provider register -n Microsoft.EventGrid
特に新規サブスクリプションや検証環境では見落としがちなので、最初に一度確認しておくと安心です。
2. エンドポイントの到達性と検証ハンドシェイクを確認する
Push/Webhook 配信では、サブスクリプション作成時に 検証イベント が送られます。受信側がこれに正しく応答できないと、結果として 500 エラーに見えるケースが少なくありません。
確認すべきポイントは次のとおりです。
- 受信 URL がインターネットまたは要求されるネットワークから到達可能か
- WAF・FW・IP 制限・仮想ネットワーク統合などで Event Grid の送信元をブロックしていないか
- 受信アプリが検証リクエストに対して HTTP 200 で応答できているか
- リダイレクト(3xx)や 4xx(特に 401/403/404)を返していないか
- 応答時間が 30 秒以内に収まっているか(タイムアウトを引き起こしていないか)
一時的に WAF をオフにする/IP 制限を緩めるなどして、まずは「素の状態で成功するか」を確認し、その後で徐々に制限を戻しながら許可リストやルールを整えていくのがおすすめです。
3. サービス側の一時障害の可能性も考慮する
頻度は高くありませんが、Azure 側の一時的な障害や内部エラーで 500 が返ることもあります。この場合は、数分~数十分おいてから 指数バックオフ を取り入れた再試行ロジックでリトライすると解消することがあります。
それでも失敗が続く場合は、ポータルや CLI のエラーメッセージに含まれる Correlation ID(相関 ID)と UTC 時刻 を控えて、Azure サポートに問い合わせると解析がスムーズになります。
チェック観点まとめ表:Push で 500 が出たとき
| 確認項目 | 見るべきポイント | 優先度 |
|---|---|---|
| リソース プロバイダー | Microsoft.EventGrid が Registered か | 高 |
| 受信 URL の到達性 | ブラウザ/curl/Application Insights などで到達確認 | 高 |
| WAF・FW・IP 制限 | Event Grid の送信元 IP が許可されているか | 高 |
| アプリ応答 | 検証リクエストに対して 200 を返せているか、4xx/5xx を返していないか | 中 |
| 一時障害 | 時間をおいて再試行しても再現するか | 中 |
IP 制限を続けたい場合の設計:Event Grid 送信元 IP の扱い
セキュリティ要件上、「インターネットから開けっぱなし」は避けたい場面も多いと思います。その場合は、Event Grid 送信元 IP 範囲を許可リストに登録する という設計が現実的な落としどころです。
- Event Grid はリージョンごとに送信元 IP 範囲が公開されています
- WAF / FW / NSG などにその IP 範囲を許可として追加します
- 同じリージョン内のトラフィックのみに限定したい場合、リージョンを揃えてリソースを配置することも有効です
IP 範囲の更新に追従する必要があるため、可能であれば Infrastructure as Code(ARM/Bicep/Terraform)やスクリプト化 して自動反映できるようにしておくと運用が楽になります。
Logic Apps(消費プラン)を Webhook 受信先にし、Managed Identity で認証したい問題
次のよくある相談がこちらです。
「Event Grid 名前空間の Push 配信で、受信先を Logic Apps(消費プラン)の HTTP トリガー Webhook にしたい。さらに Event Grid からは Managed Identity を使って認証したいが、Terraform の deliveryWithResourceIdentity を組み合わせるとうまくいかない。」
結論から言うと、Logic Apps(消費プラン)の HTTP トリガーと Event Grid Webhook + MI の “直結” は、現時点では実質サポート外 と考えるのが現実的です。
前提整理:Event Grid 名前空間の Webhook + Managed Identity
Event Grid 名前空間では、Push 配信において Webhook 受信先を指定する際に、deliveryWithResourceIdentity を設定することで、Event Grid 側のシステム割り当て MI などを使って Azure AD トークンを取得し、受信側に対してトークンベース認証を行うことができます。
このとき、設定としては次のような要素を指定します。
- どの Managed Identity を使うか(システム割り当て or ユーザー割り当て)
azureActiveDirectoryApplicationIdOrUriで、どのアプリケーション(API)向けのトークンを取得するか(=Audience)- 受信側アプリで、そのトークンをどのように検証するか
つまり、受信側は Azure AD / Entra ID の保護された API として振る舞えなければなりません。
Logic Apps(消費プラン)HTTP トリガーが前提としている認証方式
ここでポイントになるのが、Logic Apps(消費プラン)の HTTP トリガーの認証モデルです。既定では次のようになっています。
- トリガーには「コールバック URL」が発行される
- この URL には
sigというクエリ パラメーターを含む SAS 署名 が付与されている - 外部からの呼び出しは「正しい URL(=正しい sig)」であることをもって認証・認可とみなす
つまり、Logic Apps(消費プラン)の HTTP トリガーは、標準では「URL 内の SAS 署名」が唯一かつ十分な認証情報であり、Azure AD トークンを前提としたエンドポイントではないのです。
| 項目 | Logic Apps(消費プラン)HTTP トリガー | Event Grid Webhook + MI が期待する世界 |
|---|---|---|
| 主な認証方式 | SAS 署名付きコールバック URL(sig) | Azure AD / Entra ID トークン(Bearer トークン) |
| Audience の概念 | なし(URL さえ合っていれば呼び出し可能) | あり(アプリケーション ID / URI に対して発行) |
| Event Grid との相性 | SAS URL をそのまま endpointUrl に設定すれば◎ | MI を直接使う形では △~× |
このギャップにより、「Logic Apps(消費プラン)の HTTP トリガーに対して MI 認証で直接 Webhook を張る」という構成は、仕組み上かなり無理のある設計となります。
現実的な解決策:SAS 付きコールバック URL をそのまま endpointUrl に設定する
実務上、もっとも簡単かつ確実な方法は非常にシンプルです。
Logic Apps(消費プラン)のコールバック URL(sig 付き)を、そのまま Event Grid Webhook の endpointUrl に設定する。
この構成では、次のようなメリットがあります。
- Event Grid からの検証リクエスト/実際のイベント配信が、そのまま Logic App の HTTP トリガーに届く
- Logic App 側は「正しい SAS 署名付き URL からの呼び出し」という前提が崩れない
- 特別なカスタムコーディングや仲介レイヤーなしで、すぐに動かせる
コールバック URL の取得方法(自動化前提)
IaC や自動化を前提とする場合、ポータルからコピペではなく API でコールバック URL を取得することが多いです。代表的な方法をいくつか挙げます。
REST API で取得する場合
POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Logic/workflows/{workflowName}/triggers/{triggerName}/listCallbackUrl?api-version=2016-06-01
# レスポンス例(一部)
{
"value": "https://<region>.logic.azure.com:443/workflows/...
.../triggers/manual/paths/invoke?api-version=2016-06-01&sp=...&sv=1.0&sig=xxxxxxxx"
}
レスポンスの value が、SAS 署名付きの完全なコールバック URL です。この値を Event Grid の Webhook エンドポイント URL としてそのまま使用します。
PowerShell で取得する場合
$callback = Get-AzLogicAppTriggerCallbackUrl `
-ResourceGroupName <rg-name> `
-Name <workflow-name> `
-TriggerName <trigger-name>
$callback.Value # <= これがコールバック URL
Terraform との組み合わせ
Terraform から扱う場合は、deliveryWithResourceIdentity ブロックを外し、Webhook の endpointUrl にコールバック URL を設定するだけで十分です。概念イメージは次のようになります。
resource "azurerm_eventgrid_event_subscription" "example" {
name = "eg-to-logicapp"
scope = azurerm_eventgrid_namespace.example.id
event_delivery_schema = "EventGridSchema"
delivery_mode = "Push"
webhook_endpoint {
# listCallbackUrl 等で取得した SAS 付き URL を設定
url = var.logicapp_callback_url
}
}
ここで var.logicapp_callback_url には、前述の REST / PowerShell などで取得した値を CI/CD パイプライン経由で注入する、という構成がよく使われます。
セキュリティ上の注意点:SAS URL は「秘密情報」扱いにする
コールバック URL に含まれる sig は、実質的に 共有鍵 と同じ扱いです。そのため、次のような運用ルールを徹底することが重要です。
- Git リポジトリに 直書きしない(コードレビュー時に見える場所に置かない)
- Azure Key Vault や GitHub Actions / Azure DevOps のシークレットとして管理し、パイプライン内で環境変数として注入する
- 漏洩が疑われる場合は、トリガーのコールバック URL を再生成し、古い URL を無効化する(ローテーション手順をドキュメント化しておく)
- IP 制限や Azure Virtual Network 統合と併用し、使用可能な経路を限定する
どうしても Managed Identity で認証したい場合のアーキテクチャ
「SAS URL はあまり使いたくない」「ゼロトラストや組織ポリシーの観点から、MI/Azure AD トークンで統一したい」という要件もあります。その場合は、Logic Apps(消費プラン)を直接 MI で守るのではなく、MI を受け付けられる別コンポーネントを仲介させる構成が現実的です。
パターン 1:Azure API Management をファサードにする
構成イメージは次のとおりです。
- Event Grid 名前空間 → API Management に対して Webhook + MI でイベントを送信
- API Management 側で Azure AD トークンを検証(Audience / 発行者 / 有効期限など)
- 問題なければ、APIM が 内部的に Logic App の SAS 付きコールバック URL にフォワード
- Logic App は従来どおり HTTP トリガーで起動する
この構成では、外部から見えるエンドポイントは「MI で保護された APIM の API」となり、Logic App のコールバック URL は社内の設定・Key Vault の中だけに閉じ込めることができます。
パターン 2:Azure Functions / App Service を仲介レイヤーにする
より軽量な構成として、Functions や App Service の API を受け口にする方法もあります。
- Event Grid → Functions / App Service(Webhook + MI)
- Functions 側で受信した HTTP リクエストに含まれるトークンを検証
- 必要に応じて追加のロジック(フィルタリングや変換)を行う
- 最後に Logic App のコールバック URL にイベントを POST
ここでも、Logic App の SAS URL は内部コードまたは Key Vault 経由でのみ使用し、外部には露出しません。
Audience 設定でハマりがちなポイント
MI を利用する構成では、Event Grid の設定項目である azureActiveDirectoryApplicationIdOrUri が非常に重要です。ここに https://management.azure.com/ のような ARM 向けのリソース URI を指定してしまうと、Event Grid は「ARM API 用トークン」を取りに行ってしまい、受信側アプリケーションと Audience が不一致 になってしまいます。
受信側が APIM や Functions の場合は、それぞれのアプリ登録の アプリケーション ID URI または クライアント ID を指定する必要があります。設計時に「トークンの発行先」と「トークンの検証先」が一致しているかを必ず確認しましょう。
Logic Apps(Standard プラン)や他サービスへの移行も選択肢
もしこれから新規に構成するのであれば、Logic Apps(Standard プラン) や、Azure Functions など、Azure AD 認証を ネイティブに受けられる受信先 を選ぶという選択肢も十分に検討の価値があります。
- Standard プラン Logic Apps:App Service ベースで動作し、Azure AD 認証や VNet 統合などの機能を柔軟に使える
- Azure Functions / App Service:Azure AD での保護が豊富にドキュメント化されており、APIM との組み合わせも容易
既存環境との互換性や料金モデル(消費課金 vs 常時起動)も踏まえて、「どこで认证を終端するのが自然か」という観点でアーキテクチャを見直してみるとよいでしょう。
即使えるチェックリストと設計パターンのまとめ
Push で 500 が出たときのチェックリスト
| チェック項目 | 確認内容 | OK 条件 |
|---|---|---|
| Event Grid RP 登録 | az provider show -n Microsoft.EventGrid で状態確認 | registrationState = "Registered" |
| 受信 URL の到達性 | ブラウザや curl でアクセスしてみる | HTTP 200 など正常応答が返る |
| WAF・FW・IP 制限 | Event Grid の送信元 IP がブロックされていないか | 検証リクエストが通るように許可設定済み |
| 検証ハンドシェイク | 検証リクエストに対してアプリが 200 応答できるか | タイムアウトや 4xx を返していない |
| 一時障害 | 数分おいて再試行しても再現するか | 再試行で解消 or 相関 ID を持ってサポートにエスカレーション |
Logic App(消費プラン)に Push したいときのチェックリスト
| チェック項目 | 推奨設定 | 注意点 |
|---|---|---|
| endpointUrl | Logic App の「コールバック URL(sig 付き)」をそのまま使用 | URL は Key Vault やパイプラインのシークレットで管理 |
| deliveryWithResourceIdentity | 使用しない | Logic Apps(消費プラン)の HTTP トリガーは MI 前提ではない |
| IP 制限 | Event Grid の送信元 IP を許可 | 可能なら VNet 統合や APIM と組み合わせて多層防御 |
| SAS URL の管理 | Key Vault / シークレット ストアに保存 | 漏洩時に即ローテーションできる手順を用意 |
設計パターン早見表:どの構成を選ぶべきか
| 要件 | おすすめ構成 | 概要 |
|---|---|---|
| とにかくシンプルに Push したい | Event Grid Push → Logic Apps(消費)SAS URL 直結 | コールバック URL を endpointUrl に設定するだけの最小構成 |
| MI / AAD トークンで統一したい | Event Grid Push + MI → APIM or Functions → Logic Apps(SAS URL) | MI を仲介レイヤーで終端し、内部的に Logic Apps を呼び出す |
| 新規システムで柔軟な認証を使いたい | Event Grid Push → Logic Apps(Standard)や Functions | AAD 認証をネイティブに扱える受信先を採用する |
おわりに:Queue ではなく Push を採用しつつ、安定運用するために
Event Grid 名前空間の Push 配信で 500 エラーが発生する場合、その多くは「Azure 側の謎エラー」ではなく、受信側エンドポイントのネットワーク制御や応答挙動が原因です。特に、Queue モードでは成功するのに Push だけ失敗するケースでは、IP 制限や WAF をまず疑うのが近道です。
また、Logic Apps(消費プラン)を Webhook 受信先にする場合、「MI で直接守る」発想にこだわると設計が複雑になりがちです。実務的には、コールバック URL(SAS 署名付き)をそのまま Webhook に設定するか、どうしても MI を使いたい場合は APIM や Functions をファサードとして挟む構成が、セキュリティと運用コストのバランスが取れた選択肢になります。
本記事で紹介したチェックリストや設計パターンをテンプレート化しておけば、今後 Event Grid 名前空間で Push 配信を使う際も、トラブルシュートと設計検討の時間を大きく削減できるはずです。ぜひ自社環境向けにカスタマイズして、運用ドキュメントや IaC のコメントに組み込んでみてください。

コメント