こんにちは、ACS 事業部の埜下です。
先日、Terraform を元にした Azure Front Door の解説記事を投稿しました。
今回はそちらの続きで、Azure Front Door の Private Link を使ったバックエンド (App Service) への接続方法について解説していきます。 その他の記事は以下になります。
- Azure Front Door の構成(おさらい)
- App Service アクセス制限の課題
- Azure Front Door が利用する Private Link の構成
- Terraform で Private Link を構築
- おわりに
- 参照資料
- ACS事業部のご紹介
Azure Front Door の構成(おさらい)
Private Link の話の前に、前回のおさらいです。
Azure Front Door はいくつかのコンポーネントで構成されていまして、Terraform で構築する場合に最低限必要なリソースは以下になります。
- プロファイル (azurerm_cdn_frontdoor_profile)
- エンドポイント (azurerm_cdn_frontdoor_endpoint)
- 配信元グループ (azurerm_cdn_frontdoor_origin_group)
- 配信元 (azurerm_cdn_frontdoor_origin)
- ルート (azurerm_cdn_frontdoor_route)
これらのリソースを使って Azure Front Door を構築する Terraform コードは以下のようになります(バックエンドとして配置している App Service のリソースは省略)。
# プロファイル resource "azurerm_cdn_frontdoor_profile" "demo" { name = "afd-demo" resource_group_name = azurerm_resource_group.demo.name sku_name = "Premium_AzureFrontDoor" } # エンドポイント resource "azurerm_cdn_frontdoor_endpoint" "demo" { name = "fde-demo" cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.demo.id } # 配信元グループ resource "azurerm_cdn_frontdoor_origin_group" "demo" { name = "demo-origin-group" cdn_frontdoor_profile_id = azurerm_cdn_frontdoor_profile.demo.id load_balancing {} } # 配信元 resource "azurerm_cdn_frontdoor_origin" "demo" { name = "demo-origin" cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.demo.id host_name = azurerm_linux_web_app.demo.default_hostname origin_host_header = azurerm_linux_web_app.demo.default_hostname certificate_name_check_enabled = true } # ルート resource "azurerm_cdn_frontdoor_route" "demo" { name = "demo-route" cdn_frontdoor_endpoint_id = azurerm_cdn_frontdoor_endpoint.demo.id cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.demo.id cdn_frontdoor_origin_ids = [azurerm_cdn_frontdoor_origin.demo.id] patterns_to_match = ["/*"] supported_protocols = ["Http", "Https"] }
クライアントからのリクエストに対してこれらのリソースがどのように繋がっているかのイメージは以下になります。
App Service アクセス制限の課題
Azure Front Door を最小構成で構築すると、「バックエンドのパブリックアクセスをどうするか」といった課題が出てきます。
App Service をバックエンドとした場合、上記のコードで Azure Front Door を構築すると App Service のパブリックアクセスは許可されている必要があります。 これは Azure Front Door からの App Service へのアクセスもパブリックアクセス扱いとなるからです。
例えば、App Service のアクセス制限から「パブリック アクセスを許可する」のチェックを外すと、Azure Front Door のエンドポイントから App Service のコンテンツを参照できなくなります。
このような構成ではAzure Front Door を利用しているにも関わらず App Service に直接パブリックアクセスできてしまい、セキュリティ等の観点からよろしくない場合があります。 解決方法としては 2 つの案が考えられます。
- Azure Front Door が利用する IP アドレスのみパブリックアクセスを許可する
- パブリックアクセスを許可せず、Private Link を使った App Service のプライベート エンドポイント経由とする
1つ目の案は「Azure Front Door がバックエンドへのアクセス時に利用する IP アドレス」を示すサービスタグ AzureFrontDoor.Backend
を App Service のアクセス制限のルールに追加する方法です。
App Service の機能を利用するため簡単に設定でき、Azure Front Door 以外の接続元を許可することも可能な反面、そもそも「App Service のパブリックアクセスが許可されていない」場合は採用できない案になります。
そのような場合に使えるのが、2つ目の Private Link 案となります。 ちなみに Azure Front Door の Private Link は Premium SKU でしか使えません。
Azure Front Door 識別子
余談ですが、Azure Front Door のリソースは複数ユーザで共有されており、Azure Front Door で使用する IP アドレスは他者も利用する可能性があるため、 AzureFrontDoor.Backend
サービスタグのみでアクセス制限を管理すると他者のプロファイルからも App Service にアクセス可能となってしまいます。
そこで、プロファイル毎に生成される「識別子」をアクセス制限のルールの X-Azure-FDID
に追加することで、自分のプロファイルからのみ App Service へアクセスさせることができます。
Azure Front Door が利用する Private Link の構成
それでは、Azure Front Door で Private Link を使ってバックエンドにアクセスする方法についてですが、はじめに Azure Front Door が利用する Private Link の構成について説明しておきます。
「普段から Private Link (プライベート エンドポイント)は使っているから説明いらないんだけど……」と思われた人も多いかもしれません。 しかし、Azure Front Door の場合は多くの方が思い浮かべる Private Link の構成とは少し異なる部分があります。
それは何かというと、App Service に対するプライベート エンドポイントが Microsoft 管理の仮想ネットワーク内に作られるという点です。 図で表すほどでもないですが、以下のような構成になります。
Azure Portal などから App Service のプライベート エンドポイントを作成する場合、プライベート エンドポイントを作成する仮想ネットワークおよびサブネットを選択する必要があります。
Azure Front Door の場合は「配信元」の設定で Private Link の有効化ができますが、その際に仮想ネットワークなどの指定はありません。 Azure Front Door 側でプライベート エンドポイントを作成す仮想ネットワークを用意してくれるからです。 逆に言うと、ユーザ側でAzure Front Door が管理する仮想ネットワークは参照できません。
Terraform で Private Link を構築
では Azure Front Door の Private Link を Terraform で構築していきましょう。
とはいっても、以下のように azurerm_cdn_frontdoor_origin
リソースに private_link
ブロックを追加するだけです。
# 配信元 resource "azurerm_cdn_frontdoor_origin" "demo" { name = "demo-origin" cdn_frontdoor_origin_group_id = azurerm_cdn_frontdoor_origin_group.demo.id host_name = azurerm_linux_web_app.demo.default_hostname origin_host_header = azurerm_linux_web_app.demo.default_hostname certificate_name_check_enabled = true # Private Link 用に追加 private_link { private_link_target_id = azurerm_linux_web_app.demo.id location = azurerm_linux_web_app.demo.location target_type = "sites" request_message = "Request access for Private Link Origin CDN Frontdoor" } }
private_link ブロックの引数
private_link
ブロック内には以下の引数を設定します。
- private_link_target_id (必須)
- location (必須)
- target_type (任意)
- request_message (任意)
private_link_target_id
では Private Link を作成するリソース(配信元)を指定しますが、現時点では App Service と Blob Storage、Internal Load Balancer のみ対応しています。
location
はプライベート エンドポイントを配置するリージョンを指定します。
こちらは配信元の存在するリージョンか、最も近いリージョンを指定するのが推奨されています。
target_type
はプライベート エンドポイントからアクセスさせる配信元のサブリソースを選択します。
そして request_message
は「プライベート エンドポイント接続要求」をする際のメッセージになります。
「プライベート エンドポイント接続要求」については以下で説明します。
プライベート エンドポイント接続要求
前述した通り、Azure Front Door の Private Link ではプライベート エンドポイントがユーザ管理の仮想ネットワークではなく、Microsoft 管理の仮想ネットワークに作成されます。 Azure の仕様として、別テナントのリソースに対してプライベート エンドポイントを作成するためには、別テナント側に対して「プライベート エンドポイント接続要求」を作成して承認してもらう必要があります。
この仕様に従って、Azure Front Door で Private Link を設定すると自動的に「プライベート エンドポイント接続要求」が作成されます。 そしてユーザ側で「プライベート エンドポイント接続要求」を承認する必要がありますが、実はここが肝になっていて、残念ながら Terraform で「プライベート エンドポイント接続要求」の承認はできません。 Azure Portal などから [保留中の接続] を参照して、Azure Front Door からの「プライベート エンドポイント接続要求」を手動で承認してください。 承認作業を完了させるまでは Azure Front Door からバックエンドにアクセスできませんので、十分にご注意ください。
おわりに
Azure Front Door の Private Link について Terraform をベースに紹介させていただきました。 Private Link は Premium SKU 限定にはなりますが、バックエンドをパブリックアクセスさせられない環境などでは有効な機能ではないでしょうか。
また、Terraform から構築することも可能ですが、接続要求を手動で承認する必要がある点はご注意ください。
参照資料
ACS事業部のご紹介
私達 ACS 事業部は Azure・AKS などのクラウドネイティブ技術を活用した内製化のご支援をしております。
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。