Check!Azure FunctionとCosmos DBをPrivate Endpointでつないでよりセキュアに

2021/03/02に公開

Prologue

Azure App Service (Azure Function や Azure Web App) は、API やウェブアプリをホストでき、ネットワークに気を遣わず利用することができます。そして、たいていの場合、その裏でデータベースやストレージと接続しますね。

Azure が提供するデータベースやストレージは、アクセスキーを用いてセキュアにエンドポイントに接続できます。このエンドポイントは、デフォルトではパブリックIPアドレスが割り振られ、インターネットを経由して接続します。

アプリケーションによっては、データベースやストレージへの経路は、インターネットを介さず、プライベート アクセスに収めたい場合も多いですよね?

そんな時に利用できるのが、 Azure Private Endpoint です。

ほとんどの Azure PaaS サービスが Azure Private Link に対応しており、Private Endpoint を用いて接続することができます。(※)Private Endpoint を利用すると、接続された仮想ネットワークからのみの プライベート アクセス に制限することができます。

ここでは、Azure Function と Cosmos DB をの間のアクセスを Private Endpoint を利用して接続する構成をご紹介します。

※ 各 Azure PaaS サービスの Private Link 対応はサービスにより異なります。執筆時点ですでに多くのサービスが対応していますが、お使いの際は利用予定のサービスの対応状況をご確認ください。

用語解説

Azure Private Endpoint は Azure Private Link の一部で、Private Endpoint と Azure Private Link サービスを組み合わせることにより、サービスを仮想ネットワークに接続することができます。Azure PaaS サービスの場合は、Azure 側で Private Link の対応がなされており、Private Endpoint を作成することで仮想ネットワークに接続できます。

仮想ネットワークに接続された Private Endpoint へルーティングさせるには、Private DNS Zone を利用します。仮想ネットワークを経由するトラフィックは Microsoft のバックボーンネットワークを経由し、インターネットには公開されません。

また、顧客が運用するサービスも、標準の Azure Load Balancer の背後に配置することで、Azure Private Link サービスを利用でき、 Private Endpoint を介して接続できるようになります。ExpressRoute などを用いて Azure の仮想ネットワークに接続できれば、外部のネットワークからも Private Endpoint にアクセスすることができます。

用語 説明
Azure Private Link Private Link を利用すると、サービスをインターネットへ公開することなく仮想ネットワーク経由の プライベート アクセス に制限することができる。Azure PaaS サービス、または顧客の独自のサービスどちらでも構成が可能。
Azure Private Endpoint プライベート エンドポイント。Azure Private Link としてサービスが プライベートアクセス を受け付けられるようにする受け口、ネットワーク インターフェース。
Azure Private Link サービス 顧客が独自運用するサービスに対して Private Link を利用できるようにするサービス。
Azure Private DNS Zone 仮想ネットワーク内の名前解決を行う。

なお、同じ仮想ネットワーク内でも通信の制御が必要な場合は、セキュリティグループや Azure Firewall などを組み合わせます。

コスト

参考までに、価格情報を引用します。2021年 2月25日の情報です。詳細は各サービスの価格ページをご参照ください。

対象 価格
Private Link サービス Private Link サービスに料金はかかりません
Private Endpoint ¥1.12 / 時間
受信データ処理量 ¥1.12/GB
送信データ処理量 ¥1.12/GB

Azure DNS

Azure DNS の課金は、Azure でホストされている DNS ゾーンの数と、受信した DNS クエリの数に基づきます。

対象(ゾーン 2) 価格
最初の 25 件のホストされる DNS ゾーン ¥56/ゾーン/月
最初の 10 億 DNS クエリ/月 ¥44.800/百万

ゾーン 2 — 東アジア、東南アジア、オーストラリア東部、オーストラリア南東部、インド中部、インド南部、インド西部、東日本、西日本、韓国中部、韓国南部。

「Service Endpoint」と「Private Endpoint」の違い

Azure には、「Service Endpoint」と「Private Endpoint」というふたつのエンドポイントがあります。

どちらも仮想ネットワークから接続する手段として利用されますが、一番の大きな違いは、 パブリックからのアクセスを受けるけるか否か です。

Private Endpoint が設定されたリソースは、パブリックからのアクセスを受け付けません。通信は仮想ネットワーク内に閉じます。

それに対し、Service Endpoint は、仮想ネットワーク(サブネット)から Azure PaaS サービスに接続して利用するもので、その接続されたリソースへは、 Azure のバックボーン ネットワーク上で最適化されたルートを介して接続されます。このとき、Service Endpoint で接続されたリソースはパブリックからもアクセス可能です(データの読み書きにはアクセスキーが必要)。なお、Service Endpoint は追加の利用料金はかかりません。

ただし、Service Endpoint による接続でも、リソース側のネットワーク設定やセキュリティグループなどで通信を制限することが可能です。ですので、どちらを採択するかは、全体の構成やセキュリティ要件、コスト面との兼ね合いで選択することになります。

対象 説明
Private Endpoint 仮想ネットワークからのプライベート アクセスのみ。利用とデータ量などで料金が発生する。
Service Endpoint 仮想ネットワークからのアクセスは、Azure のバックボーン ネットワークを介して最適化される。パブリックからもアクセス可能。追加料金はなし。

Service Endpoint の詳細についてはドキュメントをご参照ください。

https://docs.microsoft.com/ja-jp/azure/virtual-network/virtual-network-service-endpoints-overview

Azure Function → Cosmos DB を Private Endpoint で接続する構成のポイント

さて、参考に、Azure Function から Cosmos DB への接続を Private Endpoint を使って仮想ネットワーク上のルーティングにする例をご紹介します。

ここでのポイントはこの 2つ。このうち、Azure Functions のルーティング設定が見落としがちなので要注意です。(わたし自身がかなりハマりました😳)

  • Azure Cosmos DB に対する Private Endpoint と Private DNS Zone を設定する
  • Azure Function からの送信トラフィックを仮想ネットワーク上にルーティングさせる

図にするとこのような構成です。

Connect Cosmos DB via Azure Private Endpoint

ご参考までに、Terraform によるリソース作成のコードはこちらです。

https://github.com/dzeyelid/learn-azure-functions-with-network-options/tree/main/terraform/modules/access_cosmosdb_via_private_endpoint

なお、ここでは各リソースの作成・設定手順の詳細は省きます。詳細は、それぞれに添付したリンク先のドキュメントをご参照ください。

Azure Cosmos DB に Private Endpoint と Private DNS Zone を設定する

まず、Azure Cosmos DB に Private Endpoint と Private DNS Zone を設定します。

Target: Private Endpoint and Private DNS Zone for Cosmos DB

ポータルから操作する場合は、Private Endpoint とともに Private DNS Zone の設定も併せて行うので迷いません。CLI や ARMテンプレート、Terraform(上記参照)でも簡単に構成することができます。詳細は、下記のドキュメントをご参照ください。

https://docs.microsoft.com/ja-jp/azure/cosmos-db/how-to-configure-private-endpoints

ここでのポイントは、 Cosmos DB の Private Endpoint に対する Private DNS Zone を構成するときは、ゾーン名は privatelink.documents.azure.com が設定されることです。これは対象のリソースによって決められており、Azure Functions の場合は privatelink.azurewebsites.net 、Azure Blob Storage の場合は privatelink.blob.core.windows.net となります。詳しくは下記をご参照ください。

https://docs.microsoft.com/ja-jp/azure/private-link/private-endpoint-dns

Azure Function からの送信トラフィックを仮想ネットワーク上にルーティングさせる

そして、Azure Functions から Private Endpoint を介して Cosmos DB のエンドポイントにアクセスできるよう、いくつか設定を行います。

Target: Private routing of Azure Function

ここで必要なことは、下記です。

  • Azure Functions で VNET 統合を設定する
  • Azure Functions で App settings で下記を設定する
    • WEBSITE_DNS_SERVER168.63.129.16 を設定する
    • WEBSITE_VNET_ROUTE_ALL1 を設定する

VNET 統合とは、Azure App Service (Azure Web Apps 及び Azure Functions)を仮想ネットワークのサブネットに接続する機能です。サブネット側で Microsoft.Web/serverFarms に対してデリゲーションを設定し、Azure App Service からそのサブネットに接続します。

また、App settings に設定する WEBSITE_VNET_ROUTE_ALL は、すべての送信トラフィックを仮想ネットワークにルーティングさせる設定です。そして、WEBSITE_DNS_SERVER により Private DNS Zone を参照させます。

VNET 統合及び WEBSITE_DNS_SERVERWEBSITE_VNET_ROUTE_ALL の詳細は、下記ドキュメントをご参照ください。

https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-networking-options

また、こちらの記事も参考になりました。

https://www.thebestcsharpprogrammerintheworld.com/2020/07/20/website_vnet_route_all-and-azure-functions/

以上、これらの 2つのポイントを押さえることで、Azure Function から Azure Cosmos DB への プライベート アクセス を構成することができます。

Epilogue

さて、ここまでまとめるのにかなりかかってしまいました。試行錯誤の末に実動する構成を作ることができても、なぜそれがそう動くのか、余計な設定はしていないか、サービスを正しく使えているのか、腑に落ちるまで調べないと気が済まず、やっとまとめることができました。

一度わかってしまうと、そして Infrastructure as Code(今回は Terraform)で構成していると、あとは使いたいときに該当のコードを参考に(というかほぼコピペ)するだけで構成が組めるし、設定忘れちゃってもコード読めば思い出せる。IaC は偉大!

なお、ここでは Azure Function を取り上げますが、Web App も同様です。詳しくは下記をご参照ください。

Discussion