APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Terraform で始める Azure Front Door ~基礎編~

こんにちは、ACS 事業部の埜下です。

みなさん Azure Front Door は使ったことがありますか? 「まだ使ったことがない」、「Azure Portal から作ったことはあるがよく分からない」というような方に向けて、今回は Terraform を使って Azure Front Door がどのような構成になっているか解説していきます。

はじめに

はじめに、Azure Front Door について軽く紹介します。

Azure Front Door とは

Azure Front Door は、Microsoft グローバル エッジ ネットワークを使用した「コンテンツ配信ネットワーク (CDN)」サービスで、世界中にあるエッジ ロケーションからコンテンツを配信することでユーザーに素早くコンテンツを提供することができます。

2023 年 9 月時点では 109 都市に 192 個のエッジ ロケーションがあるようです。 日本では東京・大阪に加えて、最近データセンター熱がアツい 印西 にもエッジ ロケーションが設けられています! (引用元:Azure Front Door の POP ロケーション (都市別)

Application Gateway との違い

Azure Front Door は Azure Application Gateway のように L7 のロードバランサとしての機能も有しています。 Azure Application Gateway との違いとしては、Azure Application Gateway はリージョン単位で動作するのでリージョン内での負荷分散になるのに対し、Azure Front Door はリージョン全体で負荷分散が可能、という点があります。

他にも、Azure には負荷分散のサービスとして Azure Load Balancer や Traffic Manager があります。 これらの負荷分散サービスのうち、どの負荷分散サービスを選択すればよいかは公式ドキュメントでデシジョン ツリーが公開されていますので、ぜひ参考にしてください。

learn.microsoft.com

SKU

Azure Front Door には「Classic」、「Standard」、「Premium」の 3 つの SKU が提供されています。

Classic は以前まで提供されていた SKU になり、ユーザ側で Azure Content Delivery Network 等と組み合わせて利用されていました。 現在は「Azure Front Door (クラシック)」と表記されています。

一方、Standard と Premium は、 Azure Front Door (クラシック) と Azure Content Delivery Network、Azure Web Application Firewall の機能が統合されて提供されています。 現在は Standard / Premium を選択するのが推奨のようです。

では Standard と Premium の違いはと言うと、Premium では Standard の機能に加えて以下のようなことができます。

  • Private Link を使った配信元への接続
  • WAF ポリシーで Microsoft 管理の ルール セット(OWASP Top 10 に基づいたルール)を利用可能
  • WAF ポリシーでボット保護 ルール セットを利用可能

主にセキュリティ面の強化ですね。 詳しくは「Azure Front Door のレベルの比較」を参照ください。 個人的には「Private Link を使った配信元への接続」が Premium の最大のメリットかと思います。

今回は Standard / Premium に依存しない Azure Front Door の構成を Terraform をベースに説明します。

Azure Front Door の最小構成

それでは、Azure Front Door を構成する Terraform コードを紹介します。 Azure Front Door を最小構成で構築するためのコードは以下のようになっています。*1

# プロファイル
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"]
}

こちらの Terraform コードから分かるように、Azure Front Door をデプロイするためには複数のリソースが必要になります。 各リソースの関係性を図で表すとこんな感じですね。 これらのリソースについて見ていきましょう。

プロファイル

「プロファイル」は Azure Front Door のメインのリソースとなり、リソースグループのリソース一覧には Azure Front Door としてこのプロファイルが表示されます。

Terraform では azurerm_cdn_frontdoor_profile というリソースが使われ、Azure Front Door で使用する SKU を選択する他は任意の項目として「配信元応答のタイムアウト」の設定しかありません。 「配信元応答のタイムアウト」は Azure Portal のここに表示されるタイムアウト値です。

エンドポイント

プロファイルにぶら下がるリソースの一つに「エンドポイント」があります。 名前の通り、Azure Front Door のエンドポイントとして利用されます。

エンドポイントを作成すると既定のドメインが割り当てられるほか、「カスタムドメイン」という形で独自のドメインをエンドポイントとして利用することも可能ですが、関連付け自体は Terraform の azurerm_cdn_frontdoor_endpoint リソースではなく後述する「ルート」で設定します。

azurerm_cdn_frontdoor_endpoint リソース自体には「エンドポイント名 name」と「関連付けるプロファイル cdn_frontdoor_profile_id」、そしてオプションとしての「エンドポイントの有効/無効 enabled」しか設定する項目がありません。 細かな挙動は「ルート」のリソース内で設定します。 さしずめ、エンドポイントはプロファイル内にルート設定するための入れ物ですね。

ちなみに、エンドポイント名はそのまま利用されるのではなく、グローバルで一意の名前となるように Azure によってランダム文字列が付与され、エンドポイントで利用する既定のドメインの生成に利用されます。 今回のエンドポイントは fde-demo-gpg9eweadxgdcsdp.z01.azurefd.net というドメインが生成されました。fde-demo が Terraform で指定した名前、-gpg9eweadxgdcsdp がランダム文字列、.z01.azurefd.net が既定のドメインになります。

Azure Portal の場合はブレードの「フロント ドア マネージャー」からエンドポイントの一覧を表示でき、エンドポイントに紐づくルート等を確認できます。

配信元グループ

エンドポイントと同じく、プロファイルにぶら下がるリソースとして「配信元グループ」があります。 エンドポイントが「ルート」の入れ物であるなら、配信元グループは「配信元」の入れ物にあたるでしょうか。

アプリケーションに対して同様のトラフィックを受信する一連の配信元を指します。 同じトラフィックを受信し、想定された動作で応答する世界中のアプリケーション インスタンスの論理的なグループとして、配信元グループを定義できます。

引用元:配信元グループ

とは言え、エンドポイントとは異なり配信元グループ自体にも設定する項目がいくつかあります。 Terraform の azurerm_cdn_frontdoor_origin_group リソースを見てみると「配信元グループ名 name」と「関連付けるプロファイル cdn_frontdoor_profile_id」の他に、必須の「負荷分散 load_balancing」ブロックと任意の「正常性プローブ health_probe」ブロックがあります。

負荷分散 load_balancing

load_balancing ブロックには以下の設定項目があります。

  • サンプル サイズ sample_size
  • 必要な成功したサンプル successful_samples_required
  • 待機時間感度 (ミリ秒) additional_latency_in_milliseconds

これらは正常性プローブで取得した結果をどのように評価するのかを定義する項目になります。 例えば「待機時間感度 (ミリ秒) additional_latency_in_milliseconds」は、設定した値より正常性プローブの応答速度が速い配信元にリクエストと振り分ける、という挙動になります。*2

正常性プローブ health_probe

health_probe ブロックでは以下の設定項目があります。

  • パス path
  • プロトコル protocol プローブ メソッド request_type
  • 間隔 (秒) interval_in_seconds

これらの設定に従い、配信元グループに関連付けられた各配信元に対して定期的にリクエストが送信されます。 もし配信元のアプリケーションで /healthz などのヘルスチェック用のパスが公開されている場合は、パスを指定して正常性プローブをおこなうのがよさそうですね。 ちなみに、Azure Front Door の正常性プローブではレスポンスの HTTP ステータスコードが 200 OK のみを正常と判断し、それ以外は失敗とみなされます。

配信元グループの仕様

そして、感の良い方はお気づきかもしれませんが、「負荷分散 load_balancing」ブロックは正常性プローブの結果を使うのに「正常性プローブ health_probe」ブロックは任意の項目となっています。 参照元が必須なのに参照先が任意なのはおかしいですよね。

これは、配信元グループに関連付けられた配信元が 1 つの場合は正常性プローブを無効にできる仕様に沿った実装だからです。 Azure Portal でも正常性プローブのみ有効/無効のチェックボックスがあります。

配信元が 1 つなら負荷分散の意味がないよね、だから正常性プローブはなくてもいいよね、ということでしょうか。 それなら負荷分散も任意でよいのでは。

配信元

このような配信元グループに紐づくリソースが「配信元」になります。 つまり、Azure Front Door から実際に配信されるコンテンツです。

2023.9 時点では以下のサービスを配信元として選択できます(表記は Azure Portal に準拠しています)。

配信元の種類
ストレージ (Azure BLOB)
Storage (クラシック)
ストレージ (静的 Web サイト
クラウド サービス
App Services
静的 Web アプリ
API Management
Application Gateway
パブリック IP アドレス
Traffic Manager
Azure Spring Apps
コンテナー インスタンス
Container Apps
カスタム

Terraform の azurerm_cdn_frontdoor_origin リソースでは host_name で配信元の IP アドレスやドメイン名を指定します。

Terraform 側では上述の「配信元の種類」を指定していないのに、Azure Portal で確認するとちゃんと配信元の種類が設定されています(今回だと App Service が設定されている)。 作成した Azure Front Door の ARM テンプレートを見ても Terraform と同じく種類の情報は入っていません。 ドキュメントによると自動的に検出しているようですが、ドメイン名などを見ているのでしょうか。

Azure の配信元の自動検出がサポートされています。 Azure 以外のバックエンドを使用する場合は、[カスタム] を選択できます。

引用元:配信元を追加する

このリソースの主な役割としては配信元の選択ですが、その他にオプションとして配信元ごとの重み付けや Private Link の設定があります。 Private Link については Premium SKU 限定のものなので別記事で紹介しようと思います。

ルート

最後に「ルート」になります。 ルートは「エンドポイント」、「配信元グループ」、「配信元」それぞれに関連付けられたリソースになっており、Terraform の azurerm_cdn_frontdoor_route リソースでもそれらの指定が必須項目となっています。

他にも「一致するパターン patterns_to_match」と「受け入れ済みのプロトコル supported_protocols」が必須項目になっています。 「一致するパターン patterns_to_match」は、エンドポイントに対するリクエストのうち、このルートで処理したい URL パスを指定し、「受け入れ済みのプロトコル supported_protocols」は処理したいプロトコル (HTTP or HTTPS) を指定します。

このように、ルートは「エンドポイントへのリクエストを配信元グループに振り分ける条件を設定する」、つまり「エンドポイントと配信元グループを紐付ける」役割を持っています。

また、ルートではカスタムドメインを使う場合の項目もあります。 カスタムドメインの使用は必須ではありませんが、Azure Front Door の運用時は多くの場合カスタムドメインを使うのではないでしょうか。

azurerm_cdn_frontdoor_route 特有の実装

既に Azure Front Door を触ったことがある方はお気づきかもしれませんが、Azure Front Door としてはルートで関連付ける対象に「配信元」は含まれていません。 「配信元グループ」さえ指定しておけば配信元への負荷分散は良しなにやってくれるからです。 ちなみに Azure Front Door の ARM テンプレートにも「配信元グループ」のパラメータはありますが「配信元」は存在しません。

では、なぜ azurerm_cdn_frontdoor_route リソースでは「配信元」の指定が必須かと言うと、Terraform が正しい順番でリソースを作成/削除するために配信元の情報が使われるからです。 Terraform 側の事情だったんですね。

この情報は azurerm_cdn_frontdoor_route リソースのソースコードにコメントで記載されています。 コメントによると、配信元の情報は API に送られないそうです。

github.com

リクエストの流れ

冒頭で各リソースの関係性をお伝えしましたが、「リソースがどのように関連付けられているか」という構築する側の目線で表したものになります。

一方、Azure Front Door に対するリクエストは以下のようなイメージで各リソースを経由します。 こちらの図はあくまでリクエストをベースにリソース間の繋がりを表現したものですので、実際の Azure 内部で発生するリクエストとは異なる点はご了承ください。

エンドポイントで受け取ったリクエストは、ルートに設定されている条件に従って配信元グループに振り分けられます。 配信元グループには配信元が 1 つ以上存在しており、それらのうち応答速度の速い配信元に対してリクエストが到達します。

この流れをベースに、カスタムドメインや WAF、Private Linkといった機能を追加することでより便利に、よりセキュアにコンテンツを配信することが可能になります。

おわりに

Terraform をベースに Azure Front Door の構成について紹介しました。 Azure Portal から作成した場合は Azure Front Door の構成が見えづらいまま使えてしまうので、Terraform 側から Azure サービスの仕様を確認するのも一つの手ではないでしょうか。

今回は最小限の構成で Azure Front Door を構築するパターンを例にしましたが、Azure Front Door (特に Premium)では多くの機能が提供されています。 特に以下の機能は重要かと思いますので、今回と同じように Terraform をベースとした構成の紹介記事を公開しようと考えています。

  • カスタムドメイン
  • WAF (Web Application Firewall)
  • Private Link

興味を持っていただけましたら、ぜひ Azure Front Door を使ってみてください。

[2023/10/05 更新]

各機能の解説記事を投稿しました。 こちらもあわせてご覧ください。

techblog.ap-com.co.jp

techblog.ap-com.co.jp

techblog.ap-com.co.jp

ACS事業部のご紹介

私達 ACS 事業部は Azure・AKS などのクラウドネイティブ技術を活用した内製化のご支援をしております。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: 埜下 太一
AKS/ACA をメインにインフラ系のご支援を担当しています。
個人ブログ

*1:こちらのコードは Azure Front Door に関連するリソースに絞っており、Azure Front Door を配置するリソースグループや Azure Front Door から配信するコンテンツの App Service は省略しています。

*2:厳密には 0 を設定すると最速の配信元に振り分け、0 以外を設定すると最速と第二位の配信元をラウンドロビンします。