CloudFront で利用可能なプログラマブルな機能の実用例
目次
はじめに
前回の記事では、CloudFrontの署名付きCookieを利用したアクセス制御の方法をご紹介しました。しかし、CloudFrontにはその他にも多彩な機能が存在しています。特に注目すべきは、Lambda@EdgeやCloudFront Functionsを使用したエッジコンピューティング機能です。これらの機能により、CDNのエッジロケーションでユーザーのリクエストに対してリアルタイムでプログラムを実行し、より柔軟かつ高度な処理を行うことが可能となります。類似のサービスはCloudflareやAkamaiにも見られますが、今回はCloudFrontに焦点を当て、弊社での具体的な利用例を解説します。
CDNの仕組みとエッジコンピューティング
CDN(コンテンツデリバリーネットワーク)は全世界の利用者に迅速かつ効率的にコンテンツを提供するための技術です。この目的を達成するためにエッジサーバーと呼ばれるサーバーを世界中に分散配置しています。ユーザーがCDNを利用してサービスにアクセスすると、自動的に物理的に最も近いエッジサーバーに接続されます。これによりデータの転送距離が大幅に短縮され、通信のレイテンシーが低減します。その結果、通信全体のパフォーマンスが向上するのです。
これらのエッジサーバーに開発者が独自のプログラムを導入することで、通信の前後に処理を行うのがエッジコンピューティングの本質です。エッジサーバーは大量の通信を高速に処理する必要があるため、プログラムの実行時間や処理できるデータ量には一定の制限が存在します。しかし、この技術によってより柔軟かつ機能的なアプリケーションを開発できるようになります。
利用事例1: Basic認証やIP制限機能
CloudFrontと連携したS3バケットを用いることで、静的ウェブホスティングが実現できます。 S3バケットにはWinSCPなどのツールを使用してファイルをアップロードすることが可能です。これは一般に公開されるサイトに適していますが、社内専用など限定されたユーザーにのみ公開したいウェブサイトの場合は、公開を制限する必要があります。
このような場合、Lambda@EdgeやCloudFront Functionsを用いて認証機能を実装することで、許可されていないユーザーのアクセスを阻止できます。具体的には、CloudFrontのViewer RequestイベントでHTTP通信のヘッダーを検査し、許可されたユーザーでなければ401または403エラーを即座に返します。Viewer Requestは、CDNのエッジロケーションにキャッシュされたデータをフェッチする前に実行されるため、認証が失敗した場合、例えコンテンツがキャッシュされていたとしてもコンテンツへのアクセスを防ぐことができます。
なお、S3 バケットのウェブホスティング機能を利用した場合、バケットポリシーによってアクセスの IP 制限を付与することは可能ですが Basic 認証をかけることはできません。
利用事例2: パスの書き換え
通常、Webサーバーはディレクトリへのリクエストが終わると、そのディレクトリ内のデフォルトドキュメント(通常は index.html)を自動的に返します。しかし、CloudFrontとS3を組み合わせた構成では、URLのパスが / で終わるとS3はそれをリテラルなパスと解釈し、直接対応するオブジェクトを検索します。その結果、通常期待される index.html が返されず、代わりに404エラーが発生します。
この問題を Lambda@EdgeやCloudFront Functionsを活用することで解消できます。 これらのサービスを用いて、Viewer Request(ビューアリクエスト)フェーズで、CloudFrontがS3にリクエストを送信する前にURLをチェックします。リクエストのURLの末尾が / で終わっている場合、index.html を追加したリクエストに改変して後続の処理に渡します。これにより、ユーザーが望むコンテンツへのアクセスがスムーズに行えるようになります。
利用事例3: 動的なHTTPヘッダの追加
HTTPリクエストの要素を変更することにより、よりダイナミックなコンテンツ配信が可能になります。例えば、Cookieの値が特定の値の場合のみ、CloudFrontからオリジンへのリクエストに追加ヘッダを挿入する設定が可能です。
このようにヘッダを動的に追加することで、オリジンサーバーは受け取ったリクエストに基づいて特定のリソースを返したり、異なるユーザーエクスペリエンスを提供するA/Bテストを行うことができます。
弊社ではリソースのアクセス制限にこのパターンを利用することがありました。 もちろん、アクセス制限だけであれば他にも方法がありますが、実際の案件の様々な制約によってこちらの方法を採用しました。
利用事例4: DynamoDBと連携したアクセス制御
Lambda@Edgeを活用する大きな利点の一つに、他のAWSサービスとの連携が可能であることが挙げられます。この特性を利用して、CloudFrontの特定のBehaviorに対するアクセス制御をDynamoDBと組み合わせて強化する仕組みを構築しました。具体的には、Lambda@Edgeがリクエスト内容を分析し、DynamoDBに保存されたデータを基にアクセス権限を確認します。不正なアクセスの場合、そのリクエストを即座に拒否します。
ただし、このシステムを採用するにはいくつかの課題が伴います。 アクセス数が多い場合、DynamoDBのスロットルによる一時的な応答不能のリスクが生じます。また、Lambda@Edgeがグローバルに分散している一方で、DynamoDBのテーブルが限られた地域に集中していると、レイテンシーの増加が発生することがあります。
これらの問題を軽減するため、アクセス制御は重要なファイルやデータに限定して適用しています。これにより、システムの効率を維持しつつ、セキュリティを確保しています。
おわりに
CloudFrontとエッジコンピューティングのいくつかの実用例を紹介しました。これらの技術は、既存のコンテンツを大幅に変更することなくシステムの拡張性を高めることができるため、新たなシステムを構築する際や既存システムを拡張する際の選択肢として非常に価値があります。
しかし、これらの技術がもたらす挙動は時に不明瞭であり、適切に管理されないと予期せぬ振る舞いが発生する可能性があります。そのため、使用されている技術についてはチーム内でしっかりと共有し、理解を深めることが重要です。さらに、設定ミスやバグがシステム全体に大きな影響を及ぼしてしまうため、採用時には継続的なデプロイメント戦略まで含めて採用することを強く勧めます。
Lambda@EdgeのデプロイにはAWS CDKなどのツールが利用でき、CloudFront Distributionを含むインフラストラクチャの構築に有効です。