Blob Storage のファイル追加を Event Grid で受け取り、Azure Functions(Y1 Consumption)から Azure AI Search のインデクサーを実行しようとすると、ネットワーク アクセスを「すべてのネットワーク」にした場合だけ成功し、「選択した IP アドレスのみ」+「信頼済みサービスを許可」では拒否される――この“あるあるな詰まりポイント”を、なぜ起きるのかという根本原因から、確実に解消するための実装手順、設計の勘所、運用チェックリストまでまとめて解説します。
構成と症状の整理
まずは今回のユースケースを簡潔に整理します。
- 構成:Blob Storage → Event Grid → Azure Functions(Y1 Consumption、認証はマネージド ID)→ Azure AI Search(インデクサーを実行)
- 症状:
- AI Search の「ネットワーク アクセス」をすべてのネットワークにすると成功
- 選択した IP アドレスのみに切り替え、信頼済みサービスを許可をオンにするとRequest is denied as the source is not allowed…(ソース IP による拒否)
- 試した対策(効果なし):
- Functions のアウトバウンド IP を AI Search のファイアウォールへ登録
- 「信頼済みサービスを許可」を有効化
- マネージド ID に Search ロール(例:Search Index Data Contributor)を割り当て
- API アクセス制御を “Both(Key + Entra ID)” に設定
結論(先に要点)
原因はネットワーク層のミスマッチにあります。Consumption プランの Azure Functions はスケールに応じてアウトバウンド IP が頻繁に変わるうえ、「信頼済みサービス」例外の対象に含まれない外向き通信であるため、ファイアウォールでの許可に失敗します。
解決策は、Functions を Elastic Premium もしくは App Service プランへ移行し、VNet 統合 + Private Endpoint で AI Search にプライベート到達させることです。これにより、AI Search 側は「選択したネットワーク(または公開アクセス無効)」のままでも安全かつ確実に到達できます。
なぜ失敗するのか:背景と技術的理由
| 課題 | 背景 / 原因 | 影響 |
|---|---|---|
| Consumption のアウトバウンド IP 変動 | Y1 Consumption はスケールアウト/イン時に実行ホストが変わり、アウトバウンド IP が動的。ドキュメント上の「可能性のある IP 一覧」を登録しても、実機で使われる IP は状況により変わる。 | AI Search のファイアウォールに登録した静的 IP で追従できず、到達元 IP 不一致で拒否される。 |
| 「信頼済みサービス」例外の誤解 | この例外は主に Microsoft バックボーン上の基盤サービス間通信を想定。 Consumption の Functions からの外向き通信はマルチテナントな公共エッジを経由するため、例外対象外となる。 | 「信頼済みサービスを許可」をオンにしても効果がない。 |
| 認証とネットワークの層分離 | RBAC や API アクセス制御は認証・認可層の話。 しかし今回の拒否はネットワーク層でブロックされており、認可設定をいくら直しても通らない。 | 「ロールを足したのに直らない」現象が起きる。 |
推奨アーキテクチャ:VNet + Private Endpoint による完全閉域化
対策はシンプルです。Functions を VNet に接続し、AI Search をプライベート エンドポイントで同一 VNet に“引き込む”ことで、プライベート IP のみで疎通させます。
Blob Storage ──▶ Event Grid ──▶ Azure Functions(Elastic Premium / App Service)
│ VNet 統合(送信)
└───▶ Private Endpoint(AI Search)──▶ Azure AI Search(公開アクセス制限)
| 項目 | 推奨構成 | ポイント |
|---|---|---|
| Functions のプラン | Elastic Premium(EP) または App Service | Consumption は VNet 統合非対応。EP はオートスケール可+閉域化を両立。 |
| ネットワーク接続 | Functions の VNet 統合(送信専用) | 専用サブネットを用意。WEBSITE_VNET_ROUTE_ALL=1 で全トラフィックを VNet へ。 |
| AI Search への到達 | Private Endpoint + Private DNS | privatelink.search.windows.net のゾーン連携を確認。FQDN がプライベート IP を解決すること。 |
| AI Search の公開設定 | 「選択したネットワーク」または公開アクセス無効 | パブリック IP を開けずに、PE のみで到達可能に。 |
| 認証 | マネージド ID + RBAC | 管理系 API(インデクサー起動等)は Search Service Contributor 等が必要な場合がある。 |
「信頼済みサービス」が効かない理由をもう一歩深掘り
Azure の「信頼済みサービスを許可」は、サービス内部の制御プレーン/データ プレーン間通信や特定の基盤連携を通すための例外スイッチです。Functions(Consumption)のワーカーから出ていく電文は、テナント共通の外部エッジを経由し、AI Search が想定する“信頼された到達元”に該当しません。そのため、IP ベースのファイアウォールで遮断されます。結局、IP という不安定な変数に運用を委ねる限り、スケールアウトやプラットフォーム移動のたびに失敗が発生し得ます。
実装手順(詳細)
- Functions を Elastic Premium / App Service へ移行
- 最小は EP1 から検討。スループット・待機インスタンス・コスト要件に応じてスケール設定。
- 既存の Function App をスケールアップするか、新規に Premium で作成してコードを再デプロイ。
- VNet とサブネットの設計
- 同リージョンに VNet。送信統合用サブネット(Microsoft.Web への委任)と、Private Endpoint 用サブネットを分離。
- NSG は最小許可。PE サブネットは受信を基本閉じ、必要最小限の管理トラフィックのみ。
- Functions の VNet 統合
- Functions の「ネットワーク」→「VNet 統合」で送信統合サブネットを割り当て。
- アプリ設定に
WEBSITE_VNET_ROUTE_ALL=1を追加(全送信を VNet にルーティング)。 - インターネット向けの固定送信が必要なら NAT Gateway を送信サブネットに関連付け。
- AI Search の Private Endpoint 作成
- AI Search の「ネットワーク」→「プライベート エンドポイント」を作成。
- リソースのサブリソース(グループ ID)は AI Search のデータ プレーンを指すものを選択。
- 同一 VNet の PE 用サブネットを指定。
- Private DNS の確認/構成
privatelink.search.windows.netのプライベート DNS ゾーンが自動作成され、VNet にリンクされているか確認。- ゾーン内に
<サービス名>.search.windows.net→ PE のプライベート IP(A レコード)があること。 - カスタム DNS を利用中なら、フォワーダー/ゾーン委任で同様の解決経路を構成。
- AI Search の公開アクセス制御
- 「ネットワーク アクセス」を選択したネットワーク(または公開アクセス無効)に設定。
- ファイアウォールには明示的な IP 許可を置かず、PE による閉域到達のみ許可。
- 認証と権限
- Functions のシステム割り当て/ユーザー割り当てマネージド ID を有効化。
- AI Search 側に必要な RBAC を付与。
ドキュメント書き込み主体なら Search Index Data Contributor、インデクサーの作成/実行など管理操作がある場合は Search Service Contributor 以上を検討。
- 動作確認
- Functions(Kudu/SSH コンソール)で
nslookup <サービス名>.search.windows.netを実行し、プライベート IP を返すこと。 curl -I https://<サービス名>.search.windows.netで疎通確認(401/403 が返れば到達自体は成功)。- アプリからインデクサー起動 API を叩いて実処理が通ること。
- Functions(Kudu/SSH コンソール)で
コード例(.NET / マネージド ID でインデクサー実行)
using Azure;
using Azure.Identity;
using Azure.Search.Documents.Indexes; // 要: Azure.Search.Documents
var endpoint = new Uri("https://<サービス名>.search.windows.net");
var credential = new DefaultAzureCredential();
// 管理操作用クライアント(インデクサーの作成/実行など)
var indexerClient = new SearchIndexerClient(endpoint, credential);
// インデクサー実行
await indexerClient.RunIndexerAsync("");
※ Search Service Contributor など、管理操作に必要なロールをマネージド ID に割り当ててください。
※ SDK のメジャーバージョンにより名前空間/型が異なる場合があります。
チェックリスト(設定の抜け漏れ防止)
| カテゴリ | 設定項目 | 期待値 | 確認ポイント |
|---|---|---|---|
| Functions | プラン種別 | Elastic Premium / App Service | Consumption では VNet 統合不可。 |
| Functions | VNet 統合 | 送信統合サブネットを割り当て | サブネットは Microsoft.Web に委任。 |
| Functions | アプリ設定 | WEBSITE_VNET_ROUTE_ALL=1 | 全送信を VNet にルーティング。 |
| AI Search | Private Endpoint | 同一 VNet の PE 作成 | 承認状態が Approved。 |
| DNS | Private DNS ゾーン | privatelink.search.windows.net | VNet リンク + A レコードの存在。 |
| AI Search | 公開アクセス | 選択したネットワーク or 無効 | IP 許可は空、PE のみで疎通。 |
| 認証 | RBAC | 適切なロール付与 | 管理操作には Service Contributor 等。 |
よくある落とし穴と回避策
- 落とし穴:Consumption で IP 許可を頑張る
関数ホストの出入口が動的なため、許可リスト運用は破綻しがち。アーキテクチャで解決(VNet + PE)が王道。 - 落とし穴:RBAC を足せば直ると誤解
今回はネットワーク層で落ちている。認証・認可はその先の話。 - 落とし穴:DNS を忘れる
PE を作っても FQDN がパブリックを向けば失敗。Private DNS ゾーン連携は必ず確認。 - 落とし穴:Functions のストレージや Key Vault が引き続きパブリック
サプライチェーンを閉域化するには、Blob/Queue、Key Vault にも PE導入を検討。 - 落とし穴:インデクサー権限不足
ドキュメント書き込み用ロールでは管理操作に不足。Search Service Contributor 等の付与を検討。
運用設計(スケール・コスト・SLA 観点)
| 選択肢 | 特徴 | 適合シナリオ | 注意点 |
|---|---|---|---|
| Elastic Premium(EP) | オートスケール・常時ウォーム・VNet 統合可 | スパイク吸収しつつ閉域が必要 | インスタンス常駐のため Consumption よりコスト高。最小台数とスケールルール設計が鍵。 |
| App Service プラン | VNet 統合可・価格階層が広い | 低〜中トラフィックの常時稼働 | オートスケールは可能だが EP ほどサーバーレス体験ではない。 |
| Consumption(継続) | 従量課金・簡易 | 厳格な閉域要件がない | IP 許可運用は不安定。ファイアウォールが厳しいリソースとの連携に不向き。 |
代替策(非推奨だが参考)
Consumption をどうしても継続したい場合、Functions の現在のアウトバウンド IP を定期的に取得して AI Search の許可リストへ反映するスクリプト運用は理論上可能です。しかし、IP 変化の瞬間に失敗が発生し、運用負荷とリスクが高くなります。ビジネス継続性を重視するなら、早期に Premium / App Service へ移行してください。
トラブルシューティング手順(現場で使える確認コマンド)
- 名前解決(Kudu/SSH)
nslookup <サービス名>.search.windows.net # 10.x.y.z(プライベート IP)が返ること - HTTP レイヤ
curl -I https://<サービス名>.search.windows.net # 401/403 が返れば到達はできている(ネットワークは OK) - アプリ設定の反映
echo $WEBSITE_VNET_ROUTE_ALL # 1 が表示されること - RBAC 有効性
// インデクサー起動 API 実行時のエラーを確認 // 403(権限不足)なら RBAC、 // 403/401 以前にタイムアウトならネットワークの疑い
セキュリティ強化の拡張ポイント
- 最小権限:Functions のマネージド ID に付与するロールは最小限に。
- ゼロトラスト:IP 許可に頼らず、プライベート エンドポイントと ID ベースで統制。
- 経路の一貫性:Functions → AI Search だけでなく、Functions が依存するすべての外部サービス(Blob/Queue、Key Vault、Cosmos DB など)も可能なら PE 化。
- 監査:AI Search と Functions の診断ログを有効化し、アクセス拒否や名前解決の失敗を監視。
実際の移行フロー例(プロジェクト計画の参考)
- 評価:現状のトリガー/バインディング、依存サービス、SLA/コスト要件を棚卸し。
- 設計:VNet、サブネット、NSG、DNS、PE、RBAC、スケール方針を設計。
- 構築:新規の EP/App Service で Functions を作成。CI/CD パイプラインを Premium 用に調整。
- 接続:VNet 統合、AI Search の PE、Private DNS ゾーンを構成。
- 閉域化:AI Search の公開アクセスを制限。必要なら Storage/Key Vault も PE 化。
- 検証:名前解決、疎通、RBAC、Event Grid → Functions → AI Search の E2E。
- カットオーバー:スロット/ブルーグリーンで段階的に切り替え、監視を強化。
FAQ(よくある質問)
Q. API アクセス制御を “Both” にしても失敗します。
A. “Both” は認証方式の話で、今回の拒否はネットワーク層(ファイアウォール)です。まずは VNet + PE で到達性を確保してください。
Q. 「信頼済みサービス」をオンにしているのに、なぜダメ?
A. Consumption の Functions からの外向きは対象外です。あくまで Microsoft バックボーン上の所定の到達元のみを許す例外であり、マルチテナントの公共エッジからの送信は含まれません。
Q. IP 許可を自動更新すれば運用できますか?
A. 技術的には可能でも、スケールの瞬間やプラットフォーム更新で落ちるリスクが残り、安定運用は困難です。長期的には推奨しません。
Q. インデクサーの実行にはどのロールが必要?
A. ドキュメントの読み書き中心なら Search Index Data Contributor で足りますが、インデクサーの作成/実行など管理操作を伴う場合は Search Service Contributor 以上を検討してください。
まとめ:ネットワークを“構造的に正す”のが近道
今回の問題は、Consumption プランの動的 IPと信頼済みサービス例外の適用範囲という、構造上のギャップが引き起こしています。個別対応(IP 追従、許可リスト更新)では根治できません。
Functions を Premium / App Service へ移行し、VNet 統合 + Private Endpoint + Private DNSという Azure ネイティブの閉域パターンを適用すれば、ファイアウォールを厳格に保ったまま、安定して Azure AI Search に接続できます。
コストやスケール要件に応じたプラン選択と、DNS/権限/監視まで含めた一貫設計を行い、ネットワークを“運用で頑張らない”状態に仕上げましょう。
補足:今回の課題と解決策の対比表
| 課題 | 背景 / 原因 | 対応策 |
|---|---|---|
| Consumption プランの動的 IP でファイアウォール許可が追従できない | Y1 Consumption ではスケールアウト時にアウトバウンド IP が頻繁に変わる。静的 IP を登録しても即座に無効化され得る。 | Elastic Premium か App Service にアップグレードし、VNet 統合を利用。 |
| 「信頼済みサービス」例外が効かない | 例外は基盤サービス間のバックボーン通信が対象。マルチテナントの Functions(Consumption)からの外向き送信は対象外。 | VNet + Private Endpoint を構成し、AI Search へプライベート IPでアクセス。 |
最後に:現場実装の“型”
- EP/App Service の Functions(最小 1 台ウォーム)
- 送信統合サブネット + NAT GW(必要に応じて)
- AI Search の Private Endpoint + Private DNS
- AI Search の公開アクセスは「選択したネットワーク」または無効
- マネージド ID + 最小権限 RBAC
- 診断ログとアラート(拒否/名前解決失敗/インデクサー失敗)
この“型”さえ押さえれば、ファイアウォールを締めたまま安定運用が実現します。ネットワークは設計で解決。ぜひ本記事の手順をベースに、貴社のセキュリティ標準へ落とし込んでみてください。

コメント