Amazon Web Services ブログ

Visitor PrioritizationソリューションをCloudFront Functionsを使って実装するための考慮点

約3年前になる2018年7月に「Visitor Prioritization on e-Commerce Websites with CloudFront and Lambda@Edge」と題してCloudFront と Lambda@Edge を利用したユーザーの優先制御、流量制御を行うためのソリューションを紹介いたしました。ここで例を上げたような、ホリデーシーズン、キャンペーン、新製品の発売などのイベント、ウェブサイトのトラフィックが急速に増加する可能性があるイベントというのはもちろん今でも存在し、その対応に苦心されているケースは多いと思います。特に最近は全世界的にインターネットのトラフィックが増えており、オンラインイベント、コンサート等のチケット予約や限定商品やゲームのダウンロード販売などトラフィックが集中するような機会は増えておりますので、このソリューションを活用できるような場面が増えてきているのではないかと考えます。

以前紹介した Lambda@Edge を利用したソリューションは今日時点でももちろん有効なのですが、先日(2021年5月)発表された CloudFront Functions を使った場合はどのように実装すればよいのか?または、どのような考慮点があるのか、などについての質問を受ける機会が増えてまいりました。これは、発表資料にもある通り、CloudFront Functions は Lambda@Edge と比べて低コストであることや低レイテンシーでの実行、スケールメリットなどの優位点があり、Visitor Prioritization のユースケースに合うことが想起されるからだと考えています。この記事では上記の Visitor Prioritization のブログの内容をベースに CloudFront Functions で実装する際の考慮点や新たに追加すべき内容などについて紹介したいと思います。

動作するイベントポイントについて

CloudFront Functions の紹介ブログにより詳細な内容が載っているのでここでは詳しく説明しませんが、Lambda@Edge とCloudFront Functions は動作するイベントポイントが異なります。以下の図のように Lambda@Edge はViewer フェーズ、Origin フェーズの双方においてリクエスト/レスポンスのイベントで利用することができますが、CloudFront Functions は Viewer フェーズのリクエスト/レスポンスのイベントでのみ使用することができます。

 

Viewer/Origin Phase CFF

 

以前のブログではオリジンを通常のオリジンから S3 に変えるために Origin Request イベントで実行させていましたが、CloudFront Functions では Viewer Request イベントで実行させる必要があります。そのため、ウェイティングルームに誘導するには以下の2つのパターンで実装するように変更する必要があります。

実装のパターン

パターン1 Origin アクセス時に別の PATH に誘導する

この方法は CloudFront Functions のシングルページアプリケーションの実装例とほぼ同じです。CloudFront Functions でリクエストが来た場合の URL をウェイティングルームに誘導するURL(/waitingRoom.htmlなど)に書き換え、動的なリソースではなく静的なリソースへの誘導を実現します。これにより、アプリケーションが動作しているオリジンに対しての負荷を低減させることができます。前回のブログでは S3 オリジンに誘導していましたが、CloudFront Functions は Viewer フェーズでしか動作しないためオリジンを変更することはできません。

Modify Path

パターン2 リダイレクトして別の URL に誘導する

もう一つの方法はリダイレクトして完全に別の URL で提供されるウェイティングルームのサイトに誘導する方法です。この方法は CloudFront Functions の国別リダイレクトの実装例とほぼ同じです。ブラウザに表示される URL が変わってしまいますが、F5 キーの連打などをしても元々のサイトに対するアクセスが発生しないという利点があります。こちらのパターンはサイトのオープン前やキャンペーン開始以前のトラフィックを誘導する目的や、何らかの理由でオリジンがアクセスに対処できない状態になった場合にすべてのトラフィックを別サイトに誘導する目的で利用できます。必要に応じて両方のパターンの実装を考慮しておくと良いでしょう
リダイレクトは同じドメイン内で行うこともできますし、別のドメインに誘導することもできます。事前準備として同じドメイン内で行う場合は CloudFront の中に別のビヘイビアを作成し、そのオリジンをS3などに設定しておく必要があります。別ドメインの場合は別の CloudFront の設定を用意し、同じくオリジンをS3に設定しておきます。新しい証明書の発行/管理は AWS Certificate Manager を利用することで容易に行うことができます。

  • リダイレクトして別のPATHに誘導

Redirect and Modify Path

  • リダイレクトして別のドメインに誘導

CloudFront Functions Waiting Room Different Domain

代表的な考慮点

言語の違い

CloudFront Functions は Lambda@Edgeと異なり ECMAScript 5.1 準拠の JavaScript を利用してコーディングすることになります。以前のブログに書かれていたように変数の宣言にconst、letが使えないため、varを使って宣言することになります。また、Lambda@Edge では行うことができた外部ライブラリを含むデプロイパッケージが使えない、などの制限があります。今回の Visitor Prioritization の実装ではそこまで複雑な処理や外部ライブラリは必要ないと思いますが、拡張される場合には違いについて留意する必要があります。CloudFront FunctionsのJavaScript ランタイムの機能については JavaScript runtime features for CloudFront Functions のドキュメントにまとまっています。

Event Modelの違い

また、CloudFront Functions はイベントストラクチャが Lambda@Edge と異なります。実装を開始される前に、CloudFront Functions event structure のドキュメントを見てイベントの内容を事前に理解していただくことをおすすめします。

今回の Visitor Prioritization を移植するという目的で説明しますと Cookie の取り扱い部分が Lambda@Edge と大きく異なる部分になります。以前のブログの中では isPremiumUser と parseCookies という名前の別の Function作って Cookie の処理と値の判別を行っていますが、CloudFront Functions ではこのような処理を行う必要がなく、event.request.cookies.[Cookie名].value とすることで直接Cookieの値にアクセスすることができます(このときは大文字小文字が判別されます)。
従いまして、CloudFront Functions では、プレミアムユーザーのクッキー値の判別は
if(Object.keys(cookies).indexOf("premium-user-cookie") && cookies["premium-user-cookie"].value === premiumUserCookieValue)
などとするだけで行うことができます。

また、以前のブログの例ではイベントのハンドリングが
exports.handler = (event, context, callback) => {
から始まっていますがCloudFront Functionsではイベントが異なるので、
function handler(event) {
のようにして始める必要があります。この event から
var request = event.request;
var uri = event.request.uri;
var cookies = event.request.cookies;
のように取得することでそれぞれの値にアクセスすることができます。イベントモデルの内容の理解はとても重要ですので、実装を始める前にイベントストラクチャのドキュメントをお読みいただくことを強くおすすめいたします。また、まだ数は少ないですが、CloudFront Functions のサンプルコードも公開してますので、こちらを利用して動かしながら内容を確認いただければより理解が深まるかと思います。

ネットワークアクセス

以前のブログではネットワークアクセスを利用することで Amazon AuroraAmazon DynamoDB を利用してより動的に値を決定することができるという紹介をさせていただきましたが、CloudFront Functions ではネットワークアクセスが利用できないのでこのような外部システム、リソースを利用した処理や判断を行うことはできません。

AWS WAF Bot Controlとの組み合わせ

AWS WAF とBot Control の組み合わせも利用を検討いただきたい構成の一つです。AWS WAF Bot Control は2021年4月にリリースした新しい機能です。特にアクセスが集中しているようなタイミングでは普段は歓迎できる検索エンジンからのアクセスも防ぎたいケースもでてくると思いますし、もちろん悪性なBotからのアクセスは遮断したくなると思います。CloudFront には地域制限の機能が元々ついていますが、AWS WAF と組み合わせることで地域ごとの制限に加えてレートコントロールを加えたアクセスコントロールもできるようになります。そして、特に新製品の発売やチケットの予約などにおいては多くの Bot からのアクセスも想定されますので、CloudFront Functions だけではなく AWS WAF, Bot Control を利用することでより堅牢かつ安全なWebサイトを構築することができるようになります。

Visitor Prioritization plus AWS WAF Bot Control

 

まとめ

CloudFront Functions は以前紹介した「Visitor Prioritization on e-Commerce Websites with CloudFront and Lambda@Edge」のソリューションと同等の内容を実現することができます。むしろ、CloudFront Functions の紹介ブログに紹介されている通り、コストや実行時間の面でメリットがあるのでこのユースケースでは CloudFront Functions のほうがより適していると言えます。冒頭に申し上げたとおり、チケットの販売や新製品の予約などでこのソリューションが利用できるケースはずっと存在しており、3年前と比べても増えていると言えるかもしれません。この記事が皆様のお役に立ち、Amazon CloudFront, CloudFront Functions,  AWS WAF,  AWS Shield などをより活用いただく機会の一助となれば幸いです。

このブログの著者

中谷 喜久 (Yoshihisa Nakatani)
Solutions Architect, Edge Services