Amazon Route 53 によるフェイルオーバーと CloudFront と S3 構成のソリーページ設定について考えてみた

ソーリーページと呼べばよいのか、メンテナンスページと呼べばよいのか。
2023.10.15

シンプルな構成で Web サービス提供している環境に Sorry ページ(メンテナンスページ)を追加方法を考えていました。よくあるケースが故に実装方法は様々あります。

本ブログは Route 53 フェイルオーバールーティングで実装した際の考慮事項の備忘録です。

Sorry ページの実装方法は様々

Sorry ページ(メンテナンスページ)の一般的な実装を社内であたってみたところ様々な方法が挙がりました。社内の皆様ありがとうございます。

ALB の前に CloudFront を入れてオリジンフェイルオーバーしたり、ALB の固定レスポンスでシンプルな Sorry ページを返すなどのよく知られた方法があります。

AWS そのものの障害を考慮し AWS ではない Google Cloud や Azure を利用する構成もあり「たしかに、それはそう」と思う構成もありました。実際に弊社が提供している一部のサービスでは Sorry ページは AWS になかったりもしました。

今回試してみた構成

今回は Route 53 のフェイルオーバールーティングを利用した構成を試してみました。Web サービス側に障害があるときに CloudFront + S3 で構成した静的サイトの Sorry ページに切り替わるわかりやすい構成です。

細かいことを考えると CloudFront には地味な設定がぼちぼちあるので手を動かしてみました。

設定してみた

基本的な構成の説明

検証用の ALB + Faragete と CloudFront + S3 構成のリソースは以下のコードから作成しました。とくに凝った設定はなくシンプルな Web サーバーと、静的サイト配信構成があればよかっただけです。

bigmuramura/test-sorry-page: Fargate and CloudFront + S3

ALB へ Web アクセスすると Fargate のタスクはサンプルの Web ページが表示されます。

ALB には ACM の証明書を設定し、Route 53 にエイリアスレコードを作成してmyweb.ohmura.classmetdhod.infoでアクセスできるようにしました。現在はシンプルルーティングの設定ですが、後にここをフェイルオーバールーティングに変更する予定です。

Sorry ページのコンテンツは S3 に保存されており CloudFront 経由で配信する構成です。CloudFront の代替ドメイン名設定でsorry.ohmura.classmetdhod.infoを設定し、Route 53 にはエイリアスレコードを設定しました。アクセス確認のために一応設定しましたが、このドメインでアクセスすることはまずありません。ALB へアクセスできないときにmyweb.〜のドメイン名でこちら Sorry ページが表示される予定です。

Sorry ページ用の CloudFront に設定しておきたい項目

カスタムエラーレスポンス作成

CloudFront 経由で配信している Sorry ページの存在しないパスにアクセスすると AccessDenied のページが表示されます。 例えば末尾に~/hogeつけてアクセスしたときはこうなります。

このときのステータスコードは 403 です。

カスタムエラーレスポンスを作成します。ステータスコードは 403 ではなく 503 を返し、存在しないパスにアクセスしても意図したページ(今回は/index.html)が表示されるようにします。

~/hogeのパスを指定しても sorry page の文字が表示されるページ(index.html)が開きました。

ステータスコードはカスタムエラーレスポンス設定で指定した 503 になっています。

ステータスコードの書き換え

Sorry ページを正常に表示できたときのステータスコードを確認します。

このときのステータスコードは 200 です。正常にコンテンツを取得できたので当然といえば当然の結果です。

メンテナンス中の適切なステータスコードは 503 と言われたり、ステータスコードが 200 だと検索エンジンの結果に載ってしまう可能性もあるため、200 ではなく Sorry ページは正常に取得できても 503 を返したいです。CloudFront Functions を利用してステータスコードを書き換えます。

CloudFront Functions で実現したかった内容は先人がサンプルコードをアップしてくれていました。ありがたく拝借します。

以下のコードを CloudFront Functions の関数として登録しました。

change-503

function handler(event) {
    var response = event.response;
    var contentType = response.headers['content-type'].value;

    if (contentType.includes('image')) {
        return response;
    }

    if (response && response.statusCode === 200) {
        response.statusCode = 503;
        response.statusDescription = 'Service Temporarily Unavailable';
    }

    return response;
}

ビヘイビアの編集からビューワーレスポンスの設定で登録した関数を指定します。

CloudFront Functions でステータスコードの書き換えているため、正常にコンテンツを取得できてもステータスコードは 503 となりました。

CloudFront の Sorry ページ用の細々とした設定は以上で完了です。

Route 53 のフェイルオーバールーティング設定

フェイルオーバールーティングの設定にはヘルスチェック設定が必須です。先に対象のドメインに対してヘルスチェック設定を作ります。

Route 53 から Web サービスを提供している ALB のエイリアスレコード設定をフェイルオーバーに変更し、ALB はプライマリ指定にします。ここで作成したヘルスチェック設定が必要になります。ALB 側の設定はこれだけです。

Sorry ページ用の CloudFront に Web サービスを提供しているドメイン名を代替ドメインに登録します。

Web サービスを提供しているドメイン名と同じ名前のレコードを新たに作成します。宛先は Sorry ページ用の CloudFront でフェイルオーバーのセカンダリを指定します。

同じレコード名でプライマリと、セカンダリの 2 つレコードが登録されている状態になります。

動作確認してみる

ALB に障害があったことを想定します。ALB のセキュリティグループのインバウンドを閉じてどこからもアクセスできなくしました。

Web サイトにアクセスできません。Sorry ページにも切り替わっていません。

ヘルスチェックはまだ正常判定でした。

スタンダード設定(デフォルト)は 30 秒間隔です。ヘルスチェック作成時に高速設定を選ぶと、10 秒間隔でチェックを行えます。

そうこうしているうちに異常と表示されました。

Web サービスを提供していたドメイン名ですが、CloudFront + S3 構成の Sorry ページの内容が表示されるようになりました。

フェイルバックもテストします。セキュリティグループを当初の設定に戻しヘルスチェックは正常に戻りました。

キャッシュの影響か、すぐには切替わりませんでした。

間もなくして元々の Web ページが開けるようになりました。

ALB 背後の Fargate のタスクを 0 個にして Web アプリケーションが起動していない場合も確認しました。 結果は同じのため省略しますが、ALB のセキュリティグループ閉じて、開けたときと同様にフェイルオーバー・バックは正常に機能しました。

おわりに

Sorry ページ用の CloudFront 設定について考えたことをまとめておきたかったという備忘録です。

Sorry ページ用の CloudFront となると一般的なコンテンツ配信とは異なるステータスコードの変更があり、試してみて勉強になりました。

参考