しばやん雑記

Azure Serverless とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure App Service から Private Endpoint を利用する際の設定がシンプルになった

先日 Azure App Service のゾーン冗長対応を確認していた時に気が付いたのですが Regional VNET Integration を Azure Portal から設定すると、デフォルトで App Service からの Outbound トラフィック全てを VNET にルーティングする設定が有効になっていました。

以前は App Settings から WEBSITE_VNET_ROUTE_ALL を追加する必要がありましたが、Azure Portal から 1 クリックでオンオフが切り替えられるようになりました。

f:id:shiba-yan:20210826110925p:plain

ドキュメントも 8 月の頭に大幅にアップデートされて WEBSITE_VNET_ROUTE_ALL を使った方法が綺麗さっぱりなくなり、代わりに ARM レベルで追加された vnet_route_all_enabled を使う方法に変わっています。

これまでの App Settings を使った方法も問題なく使えるようですが、どこかのタイミングで既存のリソースも ARM レベルのプロパティに移行しておいた方が良さそうな雰囲気です。

最新版の Azure CLI を使っていれば --vnet-route-all-enabled オプションで簡単に有効化出来ます。

az webapp config set --resource-group RG_NAME --name APP_NAME --vnet-route-all-enabled true

当然ながら ARM Template では設定できますし、Terraform でも v2.74.0 から vnet_route_all_enabled プロパティが site_config に追加されたので、ARM Template と同様に利用できます。

ちなみに Terraform で利用する場合のサンプルは以下のようになります。当たり前ですが VNET と Regional VNET Integration の設定も必要です。

resource "azurerm_app_service" "default" {
  name                = "app-routeall-test"
  location            = azurerm_resource_group.default.location
  resource_group_name = azurerm_resource_group.default.name
  app_service_plan_id = azurerm_app_service_plan.default.id

  site_config {
    vnet_route_all_enabled = true
  }
}

resource "azurerm_app_service_virtual_network_swift_connection" "default" {
  app_service_id = azurerm_app_service.default.id
  subnet_id      = azurerm_subnet.default.id
}

App Settings から分離されたので入力補完も効くようになり、扱いやすくなりました。出来れば App Settings にあるものは ARM レベルに移動してほしいのですが、追加は時間がかかるようなので難しそうです。

新しい設定を使って Private Endpoint を利用する

前述の通り 8 月の頭に Regional VNET Integration のドキュメントが大幅にアップデートされたのですが、このタイミングでこれまで Private Endpoint*1 を使うのに必要だった WEBSITE_DNS_SERVER に関する記述も全て消滅していました。代わりに以下の制約が追加されていました。

For Linux Apps Azure DNS private zones only works if Route All is enabled.

Integrate app with Azure Virtual Network - Azure App Service | Microsoft Docs

これまで App Service では Windows / Linux に関係なく Private Endpoint を使う際には WEBSITE_VNET_ROUTE_ALLWEBSITE_DNS_SERVER の設定が必要でしたが、最近のアップデートによって Windows の場合は設定なしで、Linux の場合は Route All 設定のみで利用可能になったようです。

以前の設定に関しては以下のエントリで紹介しているので、興味のある方は参照してください。

確認のために Windows の Azure Functions を作成して Regional VNET Integration を設定し、同時に Route All をオフにした環境を用意しました。

以前は Private Endpoint が必要とする Private DNS Zones を解決できず、エラーになっていた設定です。

f:id:shiba-yan:20210830020041p:plain

App Settings に WEBSITE_VNET_ROUTE_ALLWEBSITE_DNS_SERVER が存在していないことを確認しました。

f:id:shiba-yan:20210830020115p:plain

この状態から Kudu の Debug Console から Private Endpoint を有効化した Cosmos DB のホスト名を解決できるか確認すると、問題なく Private IP が返ってくることが確認できます。

f:id:shiba-yan:20210826112031p:plain

Cosmos DB Trigger を追加すると、問題なく lease に項目が作成されて Change Feed を読み取ることが出来ました。これで Windows の場合は Regional VNET Integration を有効化するだけで、Private Endpoint が使えることを確認出来ました。

Linux の App Service で利用する場合

一応 Linux の App Service も作成してドキュメント通り Private Endpoint が DNS サーバーの設定なしで使えるか確認しておきます。自分は知りませんでしたが、今年の頭から 1 つのリソースグループに Windows と Linux の App Service を混在出来るようになっていました。

Linux and Windows App Service plans can now share resource groups. This limitation has been lifted from the platform and existing resource groups have been updated to support this.

Overview - Azure App Service | Microsoft Docs

実際に検証用に Linux の App Service Plan を同じリソースグループに作成できました。

これまで同じ VNET に入れたい場合でも Windows と Linux を混在出来ず、リソースグループを分ける必要があったので面倒でしたが、これでかなり改善されました。

f:id:shiba-yan:20210830195301p:plain

話を戻して Linux の App Service からの Private Endpoint を使った Cosmos DB への接続ですが、まずは Route All 設定をオフにした状態で試すと、Private IP ではなく通常の Public IP が返ってきました。

f:id:shiba-yan:20210830191310p:plain

Private DNS Zones を使った名前解決が行われていないことが確認出来ました。

そして Route All 設定をオンに切り替えてから、同じように Cosmos DB の名前解決を試すと、今度は意図した通り Private IP が返ってくるようになりました。

f:id:shiba-yan:20210830191318p:plain

もちろん Azure Functions を作成して Cosmos DB Trigger を追加すると、Private Endpoint 経由で Cosmos DB の Change Feed を読み取ることが出来ています。

Windows と Linux で若干差があるので、個人的には Private Endpoint を使う場合には Route All をオンに統一するようにした方が混乱が無いかと思います。Windows / Linux の両方とも WEBSITE_DNS_SERVER の追加は必要なくなっているので、設定ミスではまることは減るかと思います。

*1:正確には Azure DNS の Private Zones