はじめに
AWSの資料を読んでいると「エッジロケーション」という言葉が当たり前の顔で出てきます。リージョンとアベイラビリティーゾーンは図で説明されるのに、エッジだけは説明なしで通り過ぎていくことが多い。私はここを曖昧にしたまま何度もCloudFrontの設定画面を眺めていました。
そこで公式ドキュメントを頭から読み直し、エッジロケーションが何で、何がそこで動いていて、リージョンと何が違うのかを整理しました。
対象読者
- CloudFrontを触り始めたが、エッジロケーションの位置づけが曖昧な人
- AWS認定試験の勉強中で、リージョン・AZ・エッジの関係を整理したい人
結論を先に3行で。エッジロケーションはリージョンの外側にある配信専用の拠点で、EC2やRDSといった汎用リソースを自分で置くことはできません。CloudFrontのキャッシュは「エッジロケーション」と「Regional Edge Cache」の2段構えです。
参考文献
先に一次情報を置いておきます。この記事はここから拾って整理したものです。
エッジロケーションは「リージョンの外」にある
まず押さえるべきは、エッジロケーションがリージョンやAZとは別系統のインフラだという点です。
リージョンは「東京」「バージニア北部」のような地理的なまとまりで、その中に複数のAZがあり、AZの中にEC2やRDSが置かれます。ここは自分でリソースを配置する世界です。
一方エッジロケーションは、その外側にある配信のための拠点です。CloudFrontの公式ドキュメントでは Point of Presence、略してPOPと呼ばれます。ここにあるのはキャッシュと、リクエストを受けて捌くための仕組みだけ。EC2インスタンスを立てることはできませんし、「東京リージョンのAZは3つ」と数えるときにエッジロケーションは含まれません。
呼び名が2つあるのが地味に混乱の元です。エッジロケーションとPOPは同じものを指します。ドキュメントによって表記が揺れているだけなので、別物を探しに行かないでください。
数で見ると、エッジは圧倒的に多い
規模感を掴むと位置づけが腹落ちします。AWS公式のCloudFront機能ページによると、POPは750以上あり、100を超える都市・50を超える国に展開されています。
さらに面白いのが embedded POP と呼ばれるもので、こちらはISPのネットワークの中に直接配置されるPOPです。300を超える都市に1,140以上あるとされています。ユーザーの回線のさらに手前まで入り込んでいる、ということです。
リージョンが数十、AZがその3倍程度であることを考えると、桁がひとつ違います。この数の差が、そのまま「エッジは配信のために薄く広く、リージョンは計算とデータのために厚く狭く」という役割分担を表しています。
キャッシュは2段構えになっている
ここがこの記事の本体です。CloudFrontのキャッシュはPOPだけではありません。
リクエストの流れを追うと、こうなります。
- DNSが、そのリクエストを最も適切に処理できるPOPへ振り分ける。通常はレイテンシー的にいちばん近いPOP
- POPがキャッシュを確認する。あればそのまま返す
- 無ければ、POPは通常いちばん近い Regional Edge Cache へ取りに行く
- RECにも無ければ、そこで初めてオリジンまで取りに行く
Regional Edge Cache は世界に15拠点あり、POPとオリジンの間に挟まる中間層です。RECはPOPより大きなキャッシュを持ちます。だから、POPからは追い出されてしまうような「そこそこの人気」のコンテンツも、RECには残っている。ユーザー生成コンテンツやECの商品画像のように、時間とともに人気が落ちていくものに効きます。
そして複数のPOPが同じRECを共有するので、あるPOPが取りに行った結果を他のPOPも使えます。オリジンへのリクエストが束ねられる、と考えると分かりやすいはずです。
なおキャッシュ無効化はPOPとRECの両方に効きます。RECの存在を意識せず invalidation を打って「片方に古いのが残るのでは」と心配する必要はありません。
キャッシュ層をもう1段増やす Origin Shield というオプションもあります。有効にするとRECとオリジンの間にもう1層入り、各RECからのリクエストがそこで束ねられます。ただしオリジンと同じリージョンからのリクエストはOrigin Shieldを迂回します。標準構成のキャッシュ層はPOPとRECの2段で、3段目はOrigin Shieldを有効にしたときだけ現れる、という理解でいいはずです。
POPがRegional Edge Cacheを飛ばすケース
ここは見落としやすいところです。すべてのリクエストがRECを通るわけではありません。公式ドキュメントは、次の場合にPOPがRECを迂回してオリジンへ直行すると明記しています。
| 条件 | 挙動 |
|---|---|
PUT POST PATCH OPTIONS DELETE のプロキシメソッド |
POPからオリジンへ直行 |
| リクエスト時に動的と判定されたリクエスト | RECを通らずオリジンへ直行 |
| オリジンがS3バケットで、最適なRECが同じリージョンにある | POPがRECをスキップしてS3へ直行 |
つまりRECが効くのは、基本的にキャッシュ可能なGETとHEADの世界です。APIのようにほぼ全部が動的なワークロードでは、RECは事実上ほとんど関与しません。「RECがあるからオリジンの負荷は下がるはず」と一般化すると、ここで期待が外れます。
エッジで動いているサービス
エッジロケーションはCloudFront専用の設備ではありません。いくつかのサービスが同じ場所に同居しています。
| サービス | エッジでの役割 |
|---|---|
| CloudFront | コンテンツのキャッシュと配信 |
| Route 53 | DNSの応答を近い拠点から返す |
| AWS WAF | HTTPリクエストの検査と遮断 |
| AWS Shield | DDoS緩和 |
| CloudFront Functions | 軽量な書き換え処理 |
| CloudFront Connection Functions | mTLSハンドシェイク時のクライアント証明書検証 |
| Lambda@Edge | 重めのカスタム処理 |
WAFとShieldがここに居るのが重要です。ルールに引っかかった通信はエッジで遮断されるため、その分のトラフィックはオリジンに到達しません。防御を入口に置く、という設計がインフラの形として実装されているわけです。
ただしこれは「CloudFrontを置けば安全」という意味ではありません。オリジンがインターネットに直接公開されたままなら、攻撃者はCloudFrontを迂回してオリジンを直接叩けます。S3ならOrigin Access Control、ALBやEC2ならVPCオリジンなどで、オリジンへの直接アクセスを塞いで初めて入口が1本になります。
「CloudFrontはキャッシュのサービス」と覚えていませんか。私はそうでした。実際には、オリジンを塞ぐところまでやれば、CloudFrontを前段に置くことがそのままセキュリティ境界を前に出すことにもなります。
CloudFront Functions と Lambda@Edge の使い分け
HTTPリクエストとレスポンスを加工するエッジ関数は2種類あり、ここは混同しやすいので表で整理します。数字はすべて公式ドキュメントの比較表からの引用です。
| CloudFront Functions | Lambda@Edge | |
|---|---|---|
| 言語 | JavaScript(ECMAScript 5.1準拠) | Node.js と Python |
| トリガー | ビューワーリクエスト/レスポンス | 左記+オリジンリクエスト/レスポンス |
| 実行時間 | サブミリ秒 | 最大30秒 |
| メモリ | 2 MB | 128 MB(ビューワー側)/10,240 MB(オリジン側) |
| コードサイズ | 10 KB | 50 MB(依存ライブラリを含む圧縮済みパッケージ) |
| ネットワークアクセス | 不可 | 可 |
| ファイルシステム | 不可 | 可 |
| リクエストボディ | 参照不可 | 参照可(Include Bodyの有効化が必要) |
判断の軸は2つあります。ひとつはその場で完結する処理かどうかです。
ヘッダーの付け外し、URLのリライト、キャッシュキーの正規化、JWTの検証といった処理はCloudFront Functionsで足ります。逆にDynamoDBを引く、外部APIを叩く、リクエストボディを見る、といった処理は構造的にCloudFront Functionsでは不可能なので、Lambda@Edgeを選びます。
もうひとつがどのタイミングで動かしたいかです。ビューワー側のトリガーは原則として各リクエストで発火し、オリジン側のトリガーはキャッシュミスしたときにしか発火しません。ビューワー側にも、HTTPからHTTPSへの自動リダイレクトやカスタムエラーページのように発火しないケースはあります。認証のように毎回必ず通したい処理はビューワー側、オリジンへ投げる直前の書き換えのようにミス時だけでいい処理はオリジン側になります。メモリ上限はオリジン側のほうが大きいものの、発火タイミングが違うので「重いからオリジン側へ」と単純には移せません。
Include Body で渡されるリクエストボディはbase64エンコードされ、ビューワーリクエストでは40 KB、オリジンリクエストでは1 MBで切り詰められます。大きなボディを丸ごと検査する用途には向きません。
ハマりどころ:バージニア北部でしか作れないもの
エッジ関連でいちばん引っかかるのが、ここです。CloudFrontはグローバルなサービスなのに、それに紐づくリソースの一部はバージニア北部でしか作れません。
- Lambda@Edgeの関数。公式の制限事項に「The Lambda function must be in the US East (N. Virginia) Region.」と明記されています
- CloudFrontで使うACM証明書。ビューワーとCloudFront間のHTTPSに使う証明書は
us-east-1でリクエストまたはインポートする必要があります - CloudFrontディストリビューションに関連付けるAWS WAFのWeb ACL。グローバルスコープのWeb ACLはバージニア北部にハードコードされたリージョンを持ちます
東京リージョンで一式作ってからCloudFrontに紐づけようとして、マネジメントコンソールの選択肢に何も出てこない。この症状の原因はほぼこれです。
ACMの us-east-1 制約は、ビューワーとCloudFront間の証明書の話です。CloudFrontとオリジンの間のHTTPSでALBをオリジンにする場合、証明書は us-east-1 固定ではありません。ただしACM証明書はリージョナルなリソースなので、ALBと同じリージョンで発行またはインポートする必要があります。ここを一緒くたにすると逆に混乱します。
これらは「グローバルリソースだからバージニア北部」と一括りに説明されることがありますが、実際はサービスごとに理由が違います。Lambda@Edgeは単一リージョンに発行した関数をCloudFrontが世界へ複製する仕組みですし、ACM証明書はそもそもリージョナルなリソースです。共通しているのは、CloudFrontから参照するために us-east-1 を使うという製品固有の要件がある、という点だけです。理屈で覚えようとせず、そういう要件として覚えたほうが早いと思います。
Local Zones・Wavelength と混同しない
最後に、境界線を引いておきます。「ユーザーの近くに置く」という文脈で出てくるAWSのサービスは、エッジロケーションだけではありません。
| 置けるもの | 位置づけ | |
|---|---|---|
| エッジロケーション | キャッシュとエッジ関数のみ | リージョンの外側にある配信拠点 |
| Local Zones | EC2・EBS・データベースなど | リージョンの延長。人口密集地に置く |
| Wavelength | EC2・EBSなど | 通信事業者のネットワークのエッジ |
Local Zones の公式ドキュメントは「コンピュート、ストレージ、データベース、その他の一部のAWSリソースを大規模な人口・産業の中心地の近くに配置する」と説明しています。つまりLocal Zonesは自分のインスタンスを置ける場所であって、エッジロケーションとは性質がまったく違います。利用できるサービスはZoneごとに異なるので、使う前に対象Zoneの対応表を見る必要があります。
Wavelength も同様に、VPCを延長してEC2を動かせる場所です。公式の定義は「通信サービスプロバイダーのネットワークのエッジ」で、モバイル向けという文脈で語られることが多いものの、置けるのはあくまで通常のAWSリソースです。
試験でも実務でも、「低レイテンシー」というキーワードだけで反射的にCloudFrontを選ぶと外します。配るのがコンテンツならエッジロケーション、動かしたいのがアプリケーション本体ならLocal ZonesやWavelength、という分け方で見てください。
まとめ
整理すると、こうなります。
エッジロケーションはリージョンの外にある配信拠点で、POPとも呼ばれます。750以上あり、リージョンとは桁が違う密度で世界に散っています。そこに居るのはCloudFrontのキャッシュ、Route 53、WAF、Shield、そしてエッジ関数です。
キャッシュはPOPとRegional Edge Cacheの2段構えで、動的リクエストや更新系メソッドはRECを飛ばしてオリジンへ直行します。そしてLambda@Edge、ACM証明書、グローバルスコープのWeb ACLはバージニア北部でしか作れません。
私はこの「エッジには自分のEC2やRDSを置けない」という一点を掴んだあと、周辺のサービスの位置づけが一気に繋がりました。CloudFront Functionsのようにコードは動きますが、自分で汎用リソースを配置する場所ではない、という線引きです。もし同じところで止まっている人がいたら、まずそこから押さえてみてください。
なおエッジロケーションの拠点数は増え続けているので、数字を引用するときは公式の機能ページで最新を確認するのが確実です。
