技術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 = `<\!DOCTYPE html>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に設定する方法をご案内したいと思います。