NRIネットコム Blog

NRIネットコム社員が様々な視点で、日々の気づきやナレッジを発信するメディアです

Route53のフェイルオーバールーティングを使用したSorryページの配信

本記事は 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にアクセスできるようにする

  1. S3バケットとコンテンツの配置
    新規でS3バケットを作成し、SorryページのコンテンツをS3バケットにアップロードしておきます。今回はS3の静的ホスティングではなく、CloudFrontからREST APIでの取得となります。S3バケットには、sorry.htmlをアップロードしています。
    設定項目

    • S3バケット名は「ドメインと同じ(blog-failover.example.com)」
  2. CloudFrontディストリビューションの作成
    CloudFront経由でS3にアクセスできるようにディストリビューションを作成します。CloudFrontからS3オリジンへのアクセス制御はOACを利用します。 aws.amazon.com
    設定項目

    • オリジンドメインは「1.で作成したS3バケット(blog-failover.example.com)」
    • S3バケットアクセスは「OAC」を選択し、コントロール設定を作成する
    • 代替ドメイン名(CNAME)に「設定したいドメイン名(blog-failover.example.com)」
    • SSL証明書は用意したものを選択
  3. S3バケットポリシーの変更
    CloudFrontからS3にアクセスできるようにバケットポリシーを更新します。作成したディストリビューションのオリジン編集画面で、OAC用のS3のバケットポリシーをコピーすることができます。S3バケットアクセスに移動し、バケットポリシーを更新します。

これらの設定でCloudFront経由でS3のコンテンツにアクセスできるようになります。 CloudFrontディストリビューションの最終変更日がデプロイから日時に変わり、「ディストリビューションドメイン名/コンテンツファイル名」にアクセスするとS3のコンテンツを見れることを確認します。異常系の準備は完了です。

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

  1. シンプルルーティングをフェイルオーバールーティングに変更
    現在の構成では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

  2. CloudFrontをフェイルオーバールーティングに登録
    正常系の登録は完了したので、次に異常系のセカンダリをフェイルオーバールーティングに登録します。レコードタイプでセカンダリを登録することで、異常系として設定できます。Route53のレコード作成画面で
    設定項目

    • レコード名は「ドメイン名(blog-failover.example.com)」
    • トラフィックのルーティング先は「CloudFrontディストリビューション」
    • 作成したCloudFrontディストリビューションを選択
    • レコードタイプは「セカンダリ」
    • レコードIDは任意の識別子
      この設定が完了すると、フェイルオーバールーティングできる状態なので、ターゲットグループが異常なターゲットのみになると、CloudFrontにフェイルオーバーされます。
      ですが、blog-failover.example.com/にアクセスしてもS3にコンテンツが存在しないので、403エラーが返されてしまいます。 オリジンから返された403エラーをCloudFrontのカスタムエラーレスポンスを使用することで、動作の変更が可能です。
  3. カスタムエラーレスポンスの設定
    ディストリビューションのページのエラーページタブからカスタムエラーレスポンスを作成します。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のターゲットグループの変更など、フェイルオーバールーティングより時間がかからない方法もあります。

いかがでしたでしょうか。少しでもお役に立てたら幸いに思います。

執筆者: 梅原 航 インフラエンジニア。 主にAWSを使ってます。