Lambda@EdgeでSorryページを実装してみた

記事タイトルとURLをコピーする

技術4課の鎌田(裕)です。 元々プログラマーだった経歴がある私、時々コードを書きたくなる時があります。 そんな私が遭遇した問題が、「CloudFrontで429のステータスを受けた時に、エラーページを返したい」というもの。

Cloud Frontはエラーページの設定がありますが、残念ながら429のステータスコードを受けた時に限ってはエラーページの設定が出来ません。 ならば実装してしまえ、ということで試してみました。 ここで登場するのがLambda@Edgeです。

Lambda@Edgeとは

Lambda@Edgeは、Cloud Frontと組み合わせて使うサービスで、Cloud Frontに対してのリクエストやレスポンスに対し、Lambda Functionを実行して、リクエストやレスポンスを変更出来る、というものです。

AWSドキュメントにも記載がありますが、Cloud Frontの以下のリクエスト、レスポンスを変更できます。

  • CloudFront がビューワーからリクエストを受信した後 (Viewer request)
  • CloudFront がリクエストをオリジンサーバーに転送する前 (Origin request)
  • CloudFront がオリジンからレスポンスを受信した後 (Origin response)
  • CloudFront がビューワーにレスポンスを転送する前 (Viewer response)

エラーページの実装は、3つ目のOrigin responseを変更することになります。

Lambda@Edge実装上の注意

Lambda@Edgeには実装上の注意がいくつかあります。 AWSドキュメントも参考にしてください。

特に、以下の3つは把握しておかないと、実装する時に躓きますので注意しましょう。

  • 対応言語はNode.jsのみ。バージョンは6.10と8.10に対応。
  • Cloud Frontに設定するには、バージョン番号を付ける必要がある。$LATESTやALIASは不可。
  • Lambda@EdgeのLambda Functionはus-east-1(バージニア北部)で作成する必要があります。

なおLambda@EdgeをCloud Frontに設定すると、Frontに設定したタイミングの都度、Lambda Functionが実行されます。 Lambda@Edgeも通常のLambda Function同様に、スロットリングが発生します。 このため、アクセス数を考慮し、事前にLambda Functionでスロットリングが起きないよう、上限緩和申請を実施されることをお勧めします。

Lambda Functionのソースコード

実装したサンプルコードはこちらです。 Node.js 6.10で動作確認をしています。

'use strict';

let content = `

Sorry!

Service Temporarily Unavailable. Please try again later.

`; exports.handler = (event, context, callback) => { const response = event.Records[0].cf.response; if (response.status >= 400 && response.status <= 599) { response.status = 200; response.statusDescription = 'OK'; response.headers['content-type'] = [{ key: 'Content-Type', value: 'text/html' }]; response.body = content; console.log(response.headers['content-type']); } callback(null, response); };

このソースコードでは、オリジンから受け取ったレスポンスのhttpステータスコードを確認し、400番台と500番台の場合、レスポンスのステータスを200に書き換え、htmlの中身をsorryページに変更しています。 sorryページの内容は、ソースコードを書き換えていただければご利用いただけます。 簡単に実装できることがお分かりいただけるかと思います。

おわりに

Lambda@Edgeのポイント、ご理解いただけたでしょうか。 実装も、そこまで敷居が高くないことをご理解いただけたと思います。 次の記事で、実際にCloud Frontに設定する方法をご案内したいと思います。