本記事は
NRIネットコム Advent Calendar 2022
17日目の記事です。
🎁 16日目
▶▶本記事 ▶▶
18日目
🎄
初めに
はじめまして、今年NRIネットコムに入社した梅原と申します。アドベントカレンダー17日目の記事を担当します。アドベントカレンダーも残すところ1週間ほどとなりました。2022年4月入社で4ヶ月の研修を経て、基盤デザイン事業部に配属となりました。業務ではAWSを使用したサービスのインフラ運用を担当しています。日中だけ使用するシステムで、稼働時間外にアクセスが来た際にエラー画面ではなくSorryページを配信したいことがあり、方法を考えたのでまとめます。
要件
Sorryページを表示させたいインフラ構成は図の通りで、blog-failover.example.comでWebサーバのコンテンツにアクセスできます。EC2インスタンスをEventBridgeで定刻に起動停止して、日中だけ稼働する設定にしています。稼働時間外にアクセスすると、ALBが503エラーを出してしまいます。要件としては、
- 503のエラー画面ではなくSorryページの表示
- ステータスコードを503で返す
- HTTPS通信
今回紹介するSorryページの配信方法は、Route53のフェイルオーバールーティングを使用した方法です。
フェイルオーバールーティングとは
フェイルオーバールーティングとは、Route53のルーティングポリシーの一つです。 この図のように、ドメインblog-failover.example.comのDNSをプライマリ(正常系)とセカンダリ(異常系)の2つ紐づけておきます。Route53の機能であるヘルスチェックを使用し、プライマリのエンドポイントの正常性をチェックしています。そのプライマリのエンドポイントが正常であるときは、プライマリにトラフィックが流れます。 ですが、ヘルスチェックが通らなくなり、Route53からプライマリにルーティングできない場合は、セカンダリに登録した異常系にルーティングされるようにDNSを書き換えてくれます。 このようにして、プライマリに異常が発生した場合に、セカンダリにルーティングしてくれます。プライマリのヘルスチェックが正常になった際は、再度プライマリにフェイルバックしてくれます。フェイルオーバールーティングを使用することで、万が一の障害時にも活用できます。
構成
Sorryページの配信方法は、CloudFrontとS3を使用しています。CloudFrontのオリジンをS3にすることで、サーバレス構成で、HTTPS通信も可能、またCloudFrontのカスタムエラーレスポンスを使用することで503のステータスコードで返すことができます。
実装
事前に、使用するドメインとSorryページのコンテンツ、バージニア北部にSSL証明書を用意しておきます。
CloudFrontからS3にアクセスできるようにする
S3バケットとコンテンツの配置
新規でS3バケットを作成し、SorryページのコンテンツをS3バケットにアップロードしておきます。今回はS3の静的ホスティングではなく、CloudFrontからREST APIでの取得となります。S3バケットには、sorry.htmlをアップロードしています。
設定項目- S3バケット名は「ドメインと同じ(blog-failover.example.com)」
CloudFrontディストリビューションの作成
CloudFront経由でS3にアクセスできるようにディストリビューションを作成します。CloudFrontからS3オリジンへのアクセス制御はOACを利用します。 aws.amazon.com
設定項目- オリジンドメインは「1.で作成したS3バケット(blog-failover.example.com)」
- S3バケットアクセスは「OAC」を選択し、コントロール設定を作成する
- 代替ドメイン名(CNAME)に「設定したいドメイン名(blog-failover.example.com)」
- SSL証明書は用意したものを選択
S3バケットポリシーの変更
CloudFrontからS3にアクセスできるようにバケットポリシーを更新します。作成したディストリビューションのオリジン編集画面で、OAC用のS3のバケットポリシーをコピーすることができます。S3バケットアクセスに移動し、バケットポリシーを更新します。
これらの設定でCloudFront経由でS3のコンテンツにアクセスできるようになります。 CloudFrontディストリビューションの最終変更日がデプロイから日時に変わり、「ディストリビューションドメイン名/コンテンツファイル名」にアクセスするとS3のコンテンツを見れることを確認します。異常系の準備は完了です。
Route53のフェイルオーバールーティングの設定
シンプルルーティングをフェイルオーバールーティングに変更
現在の構成ではblog-failover.example.comはシンプルルーティングでALBに紐づけています。これをフェイルオーバールーティングに変更します。対象レコードの編集画面にて
設定項目- ルーティングポリシーを「フェイルオーバールーティング」に変更
- フェイルオーバーレコードタイプを「プライマリ」
- ターゲットのヘルスを評価を「はい」
- レコードIDは任意の識別子
この設定で正常系のレコード登録が完了します。なお、レコードでAliasレコードを登録する際は、自作でヘルスチェックを作成する必要がなく、ロードバランサーに関連付けられているターゲットグループの正常性に基づいて判定してくれます。ターゲットグループに異常なターゲットのみが含まれている場合、ロードバランサーは異常であるとみなされ、Route 53 はクエリを他のリソースにルーティングします。 https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/resource-record-sets-values-failover-alias.html
CloudFrontをフェイルオーバールーティングに登録
正常系の登録は完了したので、次に異常系のセカンダリをフェイルオーバールーティングに登録します。レコードタイプでセカンダリを登録することで、異常系として設定できます。Route53のレコード作成画面で
設定項目- レコード名は「ドメイン名(blog-failover.example.com)」
- トラフィックのルーティング先は「CloudFrontディストリビューション」
- 作成したCloudFrontディストリビューションを選択
- レコードタイプは「セカンダリ」
- レコードIDは任意の識別子
この設定が完了すると、フェイルオーバールーティングできる状態なので、ターゲットグループが異常なターゲットのみになると、CloudFrontにフェイルオーバーされます。
ですが、blog-failover.example.com/にアクセスしてもS3にコンテンツが存在しないので、403エラーが返されてしまいます。 オリジンから返された403エラーをCloudFrontのカスタムエラーレスポンスを使用することで、動作の変更が可能です。
カスタムエラーレスポンスの設定
ディストリビューションのページのエラーページタブからカスタムエラーレスポンスを作成します。403で受け取ったステータスコードを503に変更して、返すコンテンツのパスを指定します。
設定項目- HTTP エラーコードは「403 Forbidden」
- エラーレスポンスをカスタマイズを「はい」
- レスポンスページのパスは「コンテンツのパスを記載」
- HTTP レスポンスコードを「503: service Unavailable 」 このように設定するとCloudFrontがS3オリジンから403を受け取った際に、クライアントにコンテンツを表示し、503で返すことができます。
以上で設定が完了しました。 試しにフェイルオーバーされるか確認してみます。 正常時にドメインにアクセスするとWebサーバからのレスポンスが返されます。
インスタンスをターゲットグループから外すと、CloudFront側にフェイルオーバーされ、S3に置いたコンテンツが503で返されてることがわかります。
まとめ
今回はRoute53のフェイルオーバールーティングを使用したSorryページの配信方法を紹介しました。この構成だと常時Sorryサーバを起動させる必要もなく、ランニングコストや管理コストを安価に済ませることができます。またS3バケットにコンテンツを置くので、コンテンツのカスタマイズも可能です。
ですが、ELBのヘルスチェックやRoute53によるDNSの切り替えを実施しているので、切り替えまでに多少の時間がかかります。
他の方法としては、LambdaでRoute53の荷重ルーティングの重み変更や、ALBのlistenerルールの優先度変更、ALBのターゲットグループの変更など、フェイルオーバールーティングより時間がかからない方法もあります。
いかがでしたでしょうか。少しでもお役に立てたら幸いに思います。
2024 Japan AWS Jr. Champions