📝

Lambda@Edge でタイムアウトした際に CloudFront のカスタムエラーレスポンスでリトライページを表示する方法

に公開

クォータ - Amazon CloudFront

エンティティ ビューワーリクエストイベントとビューワーレスポンスイベント オリジンリクエストイベントとオリジンレスポンスイベント
関数タイムアウト。関数は、AWS リージョン 内の Amazon S3 バケット、DynamoDB テーブル、または Amazon EC2 インスタンスなどのリソースに対してネットワークコールを実行できます。 5 秒 30 秒

上記の通り Lambda@Edge のタイムアウトは通常の Lambda より短いため、特にビューワーリクエストイベントとビューワーレスポンスイベントで使用している場合には障害や一時的なネットワーク不良でタイムアウトが発生しやすいです。
タイムアウトが発生した場合にはクライアント側でリトライする方法が一般的ですが、今回なその一つとして CloudFront のカスタムエラーレスポンスでリトライページを表示する方法を紹介します。
カスタムエラーレスポンスを生成する - Amazon CloudFront

前提

  • S3 バケットで静的ウェブサイトのホスティングを設定済み
  • CloudFront で S3 バケットをオリジンに設定済み

各種設定方法については以下の資料もご参照ください。

Lambda@Edge 関数の作成

チュートリアル: 基本的な Lambda@Edge 関数 (コンソール) を作成する - Amazon CloudFront
意図的にタイムアウトを発生させるコードで関数を作成しました。

exports.handler = async (event) => {
  await new Promise(resolve => setTimeout(resolve, 6000));
  const response = {
    statusCode: 200,
    body: JSON.stringify('Hello from Lambda!'),
  };
  return response;
};
  • 関数のタイムアウト: 5 秒
  • トリガーのイベントタイプ: ビューワーリクエストに設定しました。

S3 バケットにエラーページをアップロード

既存の静的ウェブサイトのホスティングを行っている S3 バケットに以下の error.html をアップロードしました。

error.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>This is custom error page</h1>
    <h2>Please try again</h2>
  </body>
</html>

リトライ用のボタンは定義していませんが、必要に応じてリトライボタンなどを定義してください。

CloudFront のカスタムエラーレスポンスを設定

以下の内容で設定しました。

  • HTTP error code: 503: Service Unavailable
  • Error caching minimum TTL: 10
  • Customize error response: Yes
  • Response page path: /error.html
  • HTTP Response code: 200: OK

動作確認

CloudFront の更新完了後に CloudFront にアクセスしてエラーページが表示されれば OK です。

まとめ

今回は Lambda@Edge でタイムアウトした際に CloudFront のカスタムエラーレスポンスでリトライページを表示する方法を紹介しました。
どなたかの参考になれば幸いです。

参考資料

Discussion