内部ネットワークからのみ利用可能に構成する — Azure OpenAI リファレンスアーキテクチャ「企業内向けChatと社内文章検索」

この記事の内容

  • Azure OpenAI を活用したチャット・社内文書検索アプリを、インターネットから遮断して内部ネットワーク専用にする方法を解説します
  • Private Endpoint を各サービスに作成し、仮想ネットワーク内からのみアクセスできる構成にします
  • App Service の VNet 統合(送信トラフィック制御)を設定します
  • DNS Private Zone と DNS Private Resolver を使って名前解決を行います
  • Application Insights だけは Azure Monitor Private Link Scope という特殊な構成が必要になります

なぜネットワーク閉域化が必要なのか

アプリケーションを単純にデプロイした状態では、各 Azure サービスのエンドポイントはインターネットに公開された状態になっています。API キーなどの認証機構はあるものの、ネットワーク的にはインターネットからアクセス可能です。

「インターネットに足が出ているサービスを使うのはNG」というセキュリティポリシーを持つ企業は多く、そのような要件に対応するために Azure には Private Endpoint という仕組みが用意されています。本記事ではこの仕組みを使って、インターネットからのアクセスを完全に遮断しつつ、社内ネットワークからは引き続き利用できる構成を実現します。


アーキテクチャの全体像

閉域化された構成の概要は以下のとおりです。

  1. インターネットからのアクセスをブロック — 各サービスのパブリックネットワークアクセスを無効化します
  2. Azure 仮想ネットワーク(VNet)を作成 — 各サービスが所属するプライベートネットワークを用意します
  3. Private Endpoint を各サービスに作成 — 仮想ネットワーク内にプライベート IP アドレスを持つエンドポイントを生やします
  4. DNS Private Zone と統合 — ホスト名からプライベート IP アドレスへの名前解決を自動化します
  5. App Service の VNet 統合(送信側)を設定 — App Service がバックエンドサービスを呼び出す際も VNet 経由にします
  6. オンプレミス接続 — VPN Gateway や ExpressRoute でオンプレミスと Azure VNet を接続します
  7. DNS Private Resolver — オンプレミスの DNS から Azure のプライベート DNS を引けるようにします

Private Endpoint の仕組み

通常、Azure サービスのエンドポイントはインターネット上に存在します。Private Endpoint を作成すると、指定した仮想ネットワークのサブネット内にネットワークインターフェース(NIC)が生成され、そこにプライベート IP アドレスが割り当てられます。

仮想マシンであれば「NIC があって IP アドレスがある」のは当たり前ですが、App Service などはもともと NIC を持ちません。Private Endpoint を作成することで初めて NIC が生え、プライベート IP でアクセスできるようになります。

DNS Private Zone には、元のホスト名(例: myapp.azurewebsites.net)がプライベート IP アドレスに解決されるよう自動登録されます。パブリックなホスト名をそのまま使っても、VNet 内からであれば自動的にプライベート IP に解決されるため、アプリケーション側の設定変更は不要です。


App Service の VNet 統合(送信トラフィック)

App Service は受信トラフィックのほかに、送信トラフィック(バックエンド API への呼び出しなど)も VNet 経由にする必要があります。この設定を「VNet 統合」と呼びます。

インターネットへの送信がブロックされた状態で VNet 統合を設定しないと、App Service から Azure OpenAI や Cosmos DB への呼び出しも失敗します。

VNet 統合用のサブネットは、他のサービスから使われていない空のサブネットである必要があります。委任されていないサブネットが必要なため、専用のサブネットを新規作成します。


手順:仮想ネットワークの作成

まず、各 Private Endpoint を収容するための仮想ネットワークを作成します。

Azureポータルで「仮想ネットワーク」を検索し、以下の設定で作成します。

  • リソースグループ: 既存のリソースグループと同じものを選択
  • 名前: 例 secure-network
  • リージョン: 他のリソースと同じリージョン
  • アドレス空間: 例 10.1.0.0/16
  • デフォルトサブネット: 例 10.1.0.0/24

また、VPN Gateway を使わずに動作確認を行いたい場合は、Azure Bastion を合わせて作成しておくと便利です。Bastion を使うと、パブリック IP を持たない仮想マシンにブラウザ経由で接続できます。


手順:App Service の閉域化

インターネットアクセスを無効化する

App Service の「ネットワーク」→「受信トラフィック」→「アクセス制限」を開き、「パブリックアクセスを許可する」のチェックを外します。これでインターネットからのアクセスが完全に拒否されます(HTTP 403 が返ります)。

Private Endpoint を作成する

「ネットワーク」→「プライベートエンドポイント」→「追加」を選択します。

  • 名前: 例 private-endpoint-appservice
  • 仮想ネットワーク: secure-network
  • サブネット: default
  • プライベート DNS ゾーンと統合: はい(推奨)

DNS ゾーン名は自動的に privatelink.azurewebsites.net が選択されます。このゾーン名は変更できません。

VNet 統合(送信側)を設定する

「ネットワーク」→「送信トラフィック」→「VNet 統合」→「VNet の追加」を選択します。

  • 仮想ネットワーク: secure-network
  • サブネット: 新規作成(例: appservice-outbound、アドレス範囲 10.1.2.0/24

既存のサブネットは他のリソースに使用されているため選択できないことがあります。その場合は新規サブネットを作成してください。


手順:各サービスへの Private Endpoint 作成

App Service と同様に、以下のサービスにも Private Endpoint を作成します。手順は共通ですが、サービスごとに画面レイアウトが若干異なります。

Azure OpenAI

  1. Azure OpenAI リソースの「ネットワーク」を開く
  2. 「仮想ネットワーク」を無効に設定しパブリックアクセスをブロック
  3. 「プライベートエンドポイント接続」→「追加」
  4. 仮想ネットワーク・サブネット・DNS ゾーン統合を設定して作成

DNS ゾーン名は自動的に privatelink.openai.azure.com になります。

Azure AI Document Intelligence(旧 Form Recognizer)

手順は Azure OpenAI と同様です。パブリックアクセスを無効化してから Private Endpoint を追加します。

Azure Cosmos DB

  1. Cosmos DB の「ネットワーク」を開く
  2. パブリックアクセスを無効化
  3. 「プライベートアクセス」→「プライベートエンドポイントの追加」
  4. リソースの種類として Microsoft.AzureCosmosDB/databaseAccounts を選択し、対象サブリソースとして Sql を選択

Cosmos DB は他のサービスと異なり、リソースの種類や対象サブリソースを手動で選択する必要があります。

  1. AI Search の「ネットワーク」を開く
  2. パブリックネットワークアクセスを無効化
  3. 「プライベートエンドポイントの作成」
  4. リソースの種類 Microsoft.Search/searchServices、対象サブリソース searchService を選択して作成

手順:Application Insights の閉域化(特殊)

Application Insights は Azure Monitor 系のサービスであるため、他のサービスとは異なる方法で Private Endpoint を構成します。Azure Monitor Private Link Scope(AMPLS) を使います。

ポータルで「Azure Monitor プライベートリンクスコープ」を検索して作成します。

  • リソースグループ: 既存と同じ
  • 名前: 任意
  • クエリアクセス・インジェストアクセス: プライベートのみ

Application Insights リソースをスコープに追加

作成した AMPLS を開き、「Azure Monitor リソース」→「追加」から対象の Application Insights コンポーネントを追加します。

Private Endpoint を AMPLS に作成

AMPLS に対して Private Endpoint を追加します。リソースの種類として AMPLS のプライベートリンクスコープを選択し、仮想ネットワークと DNS ゾーンを設定します。

なぜ Application Insights だけ特殊なのか?
Cosmos DB や OpenAI のように 1 対 1 でプライベートエンドポイントを作ると、監視対象リソースが増えるたびに Private Endpoint が乱立します。AMPLS はこれを「1 つのスコープに束ねて 1 つのエンドポイントで接続する」ことで解決する仕組みです。


手順:DNS Private Resolver の作成(オンプレミス接続時)

オンプレミスから Azure の Private Endpoint に名前解決するためには、DNS Private Resolver のインバウンドエンドポイントを作成します。オンプレミスの DNS サーバーに条件付きフォワードを設定し、Azure のプライベートゾーンのドメイン(例: *.azurewebsites.net)の問い合わせをこのエンドポイントに転送します。

ポータルで「DNS プライベートリゾルバー」を検索して作成します。

  • 仮想ネットワーク: secure-network
  • インバウンドエンドポイント: 専用の新規サブネットを作成(例: 10.1.3.0/28

作成後、インバウンドエンドポイントに割り当てられた IP アドレス(例: 10.1.3.4)に対して、オンプレミスの DNS サーバーから条件付きフォワードを設定します。


動作確認

閉域化が正しく構成できているかを確認するには、VNet 内の仮想マシン(または Bastion 経由の VM)からアクセスします。

インターネットからのアクセス確認

ブラウザで App Service の URL に直接アクセスすると、HTTP 403 が返ります(意図した動作)。

VNet 内からの名前解決確認

VNet 内の VM で PowerShell または nslookup を使い、App Service のホスト名を解決します。

Resolve-DnsName myapp.azurewebsites.net

プライベート IP アドレス(例: 10.1.0.4)が返ってくれば正常です。

アプリケーションの動作確認

VM のブラウザで App Service の URL を開き、チャット機能および社内文書検索が正常に動作することを確認します。


注意点:切り替え時のダウンタイム

Private Endpoint への切り替え時には、以下の点に注意してください。

  • Cosmos DB は Private Endpoint 有効化後に約 5 分のダウンタイムが発生する場合があります
  • App Service はプライベートリンク切り替え直後にキャッシュが残ることがあるため、再起動を行ってください

ダウンタイムなしで切り替えたい場合は、以下の手順を推奨します。

  1. ファイアウォール設定に既存の IP/VNet ルールを追加し、旧経路を維持
  2. 新しい Private Endpoint を追加して疎通確認
  3. 旧経路を削除

まとめ

本記事では、Azure OpenAI を活用した企業内チャット・社内文書検索アプリをインターネットから遮断し、内部ネットワークからのみアクセス可能にする閉域化構成を解説しました。

構成のポイントは以下の 4 点です。

  • Private Endpoint を各サービス(App Service、Azure OpenAI、Cosmos DB、AI Search、Form Recognizer)に作成して、プライベート IP でのアクセスを可能にする
  • VNet 統合 を App Service に設定し、バックエンドへの送信トラフィックも VNet 経由にする
  • DNS Private Zone を活用して、既存のホスト名のままプライベート IP に解決されるようにする
  • DNS Private Resolver のインバウンドエンドポイントを作成し、オンプレミス DNS からの条件付きフォワードに対応する

各サービスの画面は細部が異なりますが、概念は共通です。「プライベートエンドポイントとは何か」を理解すれば、あとは同じ手順の繰り返しで構成できます。