Route53PrivateHostedZone内でマルチリージョンのDNSフェイルオーバー（Active-Active）を設定

[前回](https://qiita.com/tonkatsu_oishi/items/ebef5fd49a0d478550dc)は、Route53のPrivateHostedZoneにて単一リージョン内にDNSフェイルオーバー（Active-Active）を設定する手順をご紹介しました。

今回は、東京・大阪のマルチリージョン環境にて、Active-ActiveのDNSフェイルオーバーを設定する手順を確認していこうと思います。

### 構成の確認
現在、東京リージョン上に下記の構成が存在します。
10.0.0.0/21のVPCに対してRoute53のHostedZoneを紐づけています。
二つのWEBサーバーに対して、加重ルーティングとHealthCheckの設定を行い、単一リージョン上にてActive-Activeのフェイルオーバールーティングが設定されている状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/a2721280-4778-bf44-1725-9035e4f2d945.png)


今回は、上記環境に大阪リージョンのVPCを追加し、東京・大阪の2つのリージョン上のWEBサーバーに対して加重ルーティングの設定を行います。
さらに、東京・大阪上のWEBサーバーが全台ダウンした場合にのみ、S3バケット上のSorryページを表示するよう設定を追加していきます。

#### NW構成の確認
まずは、東京・大阪上に存在するVPC・サブネット・EC2の各リソースについて確認します。
東京・大阪にそれぞれVPCを構築し、WEBサーバーを二台ずつ配置しています。
東京と大阪間のVPCにはVPCピアリングを設定し、あらかじめ相互に通信できる状態にしておきます。
さらに、静的WEBサイトホスティングを有効化したS3バケットを作成し、sorryページを用意しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/c5874da8-b26b-f52c-38b7-ed1dae721cba.png)

#### Route53設定の確認
Route53のPrivateHostedZoneの設定内容を確認しておきます。
Route53PrivateHostedZoneは、東京・大阪リージョン上の各VPCに対して紐づけます。
この状態で、HostedZone内に各リージョン上のWEBサーバーに対する加重ルーティングのレコード設定を行います。

今回は、東京をプライマリリージョン・大阪をセカンダリリージョンとしてテストします。
東京に対して優先的にルーティングを行わせたいため、「web-test」というレコードに対して東京の加重を20、大阪の加重を10として設定をしています。
さらに、東京・大阪上のWEBサーバーが全台ダウンした場合にのみS3のSorryページにつながるよう、「web-test」というレコードに対してS3を加重0で設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/bb691f70-a110-19b2-146f-affa8053740e.png)


##### 平常時の挙動
東京リージョンの加重を20に設定しているため、平常時はプライマリの東京側サーバーへ優先的にルーティングされます。
※大阪リージョン側も加重10で設定しているため、平常時は大阪リージョンにもルーティングされる点にご注意ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/338a9dd2-e6ad-7710-bdf7-93fb816fb4c8.png)

##### 東京リージョン側が全台ダウンした場合
東京リージョン側のWEB1/WEB2が全台ダウンしヘルスチェックがUnhealthyとなった場合は、大阪リージョン側にのみルーティングが行われます。
S3バケットは加重0で設定されているため、この時はまだSorryページは表示されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/137911e5-df6a-3ec8-247a-da36db1b9299.png)

##### 東京・大阪リージョン両方のサーバーが全台ダウンした場合
東京・大阪リージョン上のWEB1/WEB2が全台ダウンし、すべてのサーバーに対するヘルスチェックがUnhealthyとなった際に、初めてS3バケットのSorryページが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/cf476b0a-6c7c-0313-e754-dfa4f04ad784.png)

### 作業の流れ
作業は下記流れで行います。
長くなるため、VPC構築・Apacheの設定・S3バケットへのSorryページ設定などの事前準備手順については本記事内ではご紹介しません。
具体的な手順は別記事にてご紹介しているため、必要に応じてご参照ください。
また、各リージョンのWEBサーバーにはそれぞれテストページを配置しています。
それぞれのサーバーに配置したテストページのhtmlは[こちら](https://qiita.com/drafts/f13ae85253f274e0eb6b/edit#web%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AB%E9%85%8D%E7%BD%AE%E3%81%97%E3%81%9Fhtml%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)となります。

#### 1.東京リージョン側作業
[VPCの作成](https://qiita.com/tonkatsu_oishi/items/ee5d7f64a43ba7deb671)
[EC2（踏み台サーバー、WEBサーバーなど）の構築](https://qiita.com/tonkatsu_oishi/items/80d86fa0145e37896147)
[EC2にApacheをインストールする](https://qiita.com/tonkatsu_oishi/items/31aa7d2c17cac4b6ca84#ec2web12%E3%81%ABapache%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%83%86%E3%82%B9%E3%83%88%E7%94%A8%E3%83%9A%E3%83%BC%E3%82%B8%E3%82%92%E9%85%8D%E7%BD%AE%E3%81%99%E3%82%8B)
#### 2.大阪リージョン側作業
[VPCの作成](https://qiita.com/tonkatsu_oishi/private/7693570c405344b8f602)
[EC2（踏み台サーバー、WEBサーバーなど）の構築](https://qiita.com/tonkatsu_oishi/private/20930488abe843d306af)
[EC2にApacheをインストールする](https://qiita.com/tonkatsu_oishi/items/31aa7d2c17cac4b6ca84#ec2web12%E3%81%ABapache%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%97%E3%83%86%E3%82%B9%E3%83%88%E7%94%A8%E3%83%9A%E3%83%BC%E3%82%B8%E3%82%92%E9%85%8D%E7%BD%AE%E3%81%99%E3%82%8B)
#### 3.東京・大阪側共通作業
[東京リージョン・大阪リージョンのVPCをVPCピアリングで接続する](https://qiita.com/tonkatsu_oishi/private/2aa9a450a77ec9f5ea17)
[S3バケットの静的WEBサイトホスティングを有効化し、Sorryページを表示する](https://qiita.com/tonkatsu_oishi/private/988bbd300de544f6a25b)
[Route53のPrivateHostedZoneを作成し、各VPCに紐づける](https://qiita.com/tonkatsu_oishi/items/26f121d25db5c9fb7163#%E6%A7%8B%E7%AF%89)
[各VPCの設定でDNSホスト名、DNS名前解決を有効化する](https://qiita.com/tonkatsu_oishi/items/26f121d25db5c9fb7163#vpc%E5%81%B4%E3%81%A7dns%E8%A7%A3%E6%B1%BAdns%E3%83%9B%E3%82%B9%E3%83%88%E5%90%8D%E3%82%92%E6%9C%89%E5%8A%B9%E5%8C%96)
ヘルスチェック対象のサーバーにCloudWatchAlarmを設定する
Route53のヘルスチェックを作成する
Route53のPrivateHostedZoneにレコードを登録する
動作確認

#### WEBサーバーに配置したhtmlについて
東京・大阪上の各サーバーには下記内容のテストページを配置しています。
<details><summary>東京側WEB１のテストページ</summary>

    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>WEB1</title>
      <style>
        body {
          font-family: Arial, sans-serif;
          margin: 20px;
          background-color: #f9f9f9;
        }
        h1 {
          color: #333;
        }
        p {
          color: #666;
        }
        a {
          color: #007BFF;
          text-decoration: none;
        }
        a:hover {
          text-decoration: underline;
        }
      </style>
    </head>
    <body>
      <h1>ここは東京のWEB1</h1>
      <p>これは東京のweb1。</p>
      <p>これは東京のWEB1のコンテンツ</p>
    </body>
    </html>

</details>

<details><summary>東京側WEB2のテストページ</summary>

    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>WEB2</title>
      <style>
        body {
          font-family: Arial, sans-serif;
          margin: 20px;
          background-color: #d7f3e3;
        }
        h1 {
          color: #006400;
        }
        p {
          color: #228B22;
        }
        a {
          color: #006400;
          text-decoration: none;
        }
        a:hover {
          text-decoration: underline;
        }
      </style>
    </head>
    <body>
      <h1>ここは東京のWEB2</h1>
      <p>これは東京のweb2。</p>
      <p>これは東京のWEB2のコンテンツ</p>
    </body>
    </html>

</details>

<details><summary>大阪側WEB1のテストページ</summary>

    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>WEB1 - Orange Theme</title>
      <style>
        body {
          font-family: Arial, sans-serif;
          margin: 20px;
          background-color: lightyellow;
          color: lightyellow;
        }
        h1 {
          color: darkorange;
        }
        p {
          color: orange;
        }
        a {
          color: orangered;
          text-decoration: none;
        }
        a:hover {
          text-decoration: underline;
        }
      </style>
    </head>
    <body>
      <h1>ここは大阪のWEB1</h1>
      <p>これは大阪のweb1。</p>
      <p>これは大阪のWEB1のコンテンツ</p>
    </body>
    </html>

</details>
<details><summary>大阪側WEB2のテストページ</summary>

    <!DOCTYPE html>
    <html lang="ja">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>WEB1 - Blue Theme</title>
      <style>
        body {
          font-family: Arial, sans-serif;
          margin: 20px;
          background-color: lightblue;
          color: blue;
        }
        h1 {
          color: darkblue;
        }
        p {
          color: blue;
        }
        a {
          color: navy;
          text-decoration: none;
        }
        a:hover {
          text-decoration: underline;
        }
      </style>
    </head>
    <body>
      <h1>ここは大阪のWEB2</h1>
      <p>これは大阪のweb2。</p>
      <p>これは大阪のWEB2のコンテンツ</p>
    </body>
    </html>

</details>

### 構築
#### ヘルスチェック対象のサーバーにCloudWatchAlarmを設定する
Route53のヘルスチェックはインターネット経由で行われます。
プライベートサブネット上のリソースに対してRoute53のヘルスチェックを使用する場合は、CloudWatchAlarmを設定し、CloudWatchAlarmに対してヘルスチェックを紐づけることになります。
まずは対象のリソースに対してCloudWatchAlarmを設定します。
今回は、東京・大阪上に2台ずつ存在するWEBサーバーに対してCloudWatchAlarmを設定していきます。

CloudWatchアラームのトップ画面を表示し、左メニューから「アラーム状態」を押下します。
画面上部の「アラームの作成」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/3276bf5b-9aef-b6a0-3a57-e4d7dc312aad.png)
アラームの作成画面が表示されます。「メトリクスの選択」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/162c2697-715a-5195-7111-ea4fd2d70505.png)
メトリクスの選択画面が表示されます。
「EC2」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/29a36a6a-bee2-1a05-c9b5-e1c6a7456b1f.png)
「インスタンス別メトリクス」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/63c88221-ffcf-92cc-f378-6d580115bed4.png)
今回は「StatusCheckFailed_System」というメトリクスに対してアラームを設定します。
検索ボックスに「StatusCheckFailed_System」を入力しメトリクスをソートしたうえで、対象のサーバーのチェックボックスにチェックを入れ、「メトリクスの選択」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/55a7a956-d0fd-a3ca-e7e7-4c237f69ceb6.png)
アラーム作成画面に戻ります。
統計は「最大」、期間は「1分」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/905df801-16a8-cdc5-97ed-50848df9923d.png)
条件を設定します。
しきい値の種類には「静的」を選択し、アラーム条件には「以上」を選択します。
しきい値には「1」と入力し、欠落データの処理には「欠落データを不正」を選択し、「次へ」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/c8bf208c-47f1-eb61-0d0a-cb3322f54bd7.png)
アクションの設定画面が表示されます。
「アラーム状態トリガー」を「アラーム状態」に設定します。
SNSトピックには「既存のSNSトピックを選択」を設定し、通知先を指定します。
他の設定は変更せず「次へ」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/da0dfb83-5899-112d-3b7c-97e4273f6a06.png)
画面上部に、「アラームが正常に作成されました」と表示されることを確認します。
同じ要領で、東京リージョン・大阪リージョンのWEBサーバーすべてに対してCloudWatchアラームを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/6113d60b-9d23-80aa-001f-482c66428dc6.png)

#### Route53のヘルスチェックを作成する
CloudWatchアラームの設定が完了したら、Route53ヘルスチェックを作成します。
Route53のサービス画面に移動し、左メニューから「ヘルスチェック」を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/9a5ccd0c-c955-459a-e046-f969feb7105c.png)

ヘルスチェックのトップ画面が表示されたら、「ヘルスチェックの作成」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/21af181d-8f32-c621-de93-daec1b1e3cbc.png)

ヘルスチェックの設定が表示されます。
ヘルスチェックの名前を入力します。
「モニタリングの対象」は「CloudWatchアラームの状態」を設定します。
「CloudWatchリージョン」を対象のサーバーが存在するリージョン（今回は東京リージョン）に設定します。
「CloudWatchAlarm」には、先ほど作成したCloudWatchAlarmを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/5b19aae6-2d66-abb7-f28e-38d64641d211.png)

下にスクロールします。
ヘルスチェックステータスについて、「アラームが不足状態にある場合、そのステータスは正常です」を選択します。
全ての設定を完了したら、「次へ」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/c2d3f5b1-f074-76de-09f7-14ab294be467.png)

ヘルスチェックが失敗した際の通知についての設定画面が表示されます。
「アラームの作成」は「いいえ」を選択し、「ヘルスチェックの作成」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/73de3770-ccb9-2ede-d76f-543775edfa40.png)

「ヘルスチェックの作成に成功しました」と表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/3172c145-cf5f-887d-1c7a-910295df3578.png)
画面を更新すると、作成したヘルスチェックが確認できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/ca9e315b-46be-fafb-6358-8d3e51844ce5.png)
同じ要領で、東京・大阪リージョンのWEBサーバー全台に対してヘルスチェックを設定します。

#### Route53のPrivateHostedZoneにレコードを登録する
ヘルスチェックの設定が完了したら、Route53HostedZoneに対してレコードの設定を行います。
まずは東京・大阪リージョンのWEBサーバーに対する設定を行います。
左メニューから「ホストゾーン」を押下し、対象のホストゾーン名のリンクを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/90600dc5-13d5-773c-2ea4-0a1ae56c767d.png)
ホストゾーンの詳細が表示されます。
「レコードを作成」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/8efd29c8-df4c-9947-b389-664c56b89380.png)
レコード作成画面が表示されます。
レコード名に「web-test」と入力し、レコードタイプは「A」とします。
値は「10.0.5.4」を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/62669c9c-3777-86c7-2080-9a65a3c47153.png)
TTLを60にします。
「ルーティングポリシー」は「加重」を設定し、重量を入力します。
ヘルスチェックを紐づけ、レコードIDを入力し、「レコードを作成」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/6ff5c8ee-2697-48c9-0b98-6b317c56ffae.png)

この工程のRoute53のレコードについて、レコード名・IPアドレス・加重・TTL・ヘルスチェックは下記内容を設定しています。
| レコード名 | レコードタイプ | 値 | TTL | 重量 | ヘルスチェック |
|:-:|:-:|:-:|:-:|:-:|:-:|
| web-test  | A  | 10.0.1.4（東京のWEB1のIP）  | 60  | 20  | 東京WEB1に対応するHealthCheckを紐づける  |
| web-test  |  A |  10.0.5.4(東京のWEB2のIP） |  60 |  20 |  東京WEB2に対応するHealthCheckを紐づける |
| web-test  |  A |  172.31.1.5(大阪のWEB1のIP） |  60 |  10 |  大阪WEB1に対応するHealthCheckを紐づける |
| web-test  |  A |  172.31.5.5（大阪のWEB2のIP） |  60 |  10 |  大阪WEB2に対応するHealthCheckを紐づける |

次に、S3バケットに対して加重0のレコード設定を行います。
Route53でS3バケットを紐づける際は、エイリアスレコードでS3のエンドポイントを指定する必要があります。
レコード作成画面で、レコードタイプを「Aレコード」にします。
「エイリアス」のチェックを入れて、トラフィックのルーティング先を「S3ウェブサイトエンドポイントへのエイリアス」に指定します。
リージョンには、S3バケットを作成時に指定したリージョンを選択します。
エンドポイント名には、「s3-website-ap-northeast-1.amazonaws.com.」と入力します。
※静的WEBサイトホスティングを有効化したS3をRoute53のレコードに紐づける場合は、S3のバケット名とRoute53のレコード名を同一の名前で作成しておく必要がある点にご注意ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/baf88a0c-58af-7856-212a-c6371e85b1e9.png)
ルーティングポリシーには「加重」を設定し、重量は「0」を入力します。
ヘルスチェックは紐づけません。レコードIDに一意のレコードIDを入力し、「レコードを作成」を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/81011ab6-ce52-a9e7-7c11-9de5cdaa6d58.png)

全てのレコード設定が完了した状態がこちらです。
東京リージョンのWEBサーバー2台の加重が20、大阪リージョンのWEBサーバー2台の加重が10、S3バケットの加重が10で設定されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/87baf5ec-e3f3-6a5f-2549-053f980168be.png)

#### 動作確認
踏み台サーバーにログインし、接続確認を行ってみます。
平常状態だと、東京リージョン・大阪リージョンのサーバーに対してルーティングが行われている状態です。
踏み台サーバーからブラウザを立ち上げドメイン名を入力すると、ランダムで東京・大阪の各ページが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/d4159bcd-2329-35dc-13fe-e1bbf7471c76.png)

digコマンドを複数回実行し、「web-test.https-demo.com」というドメイン名に対してどのIPアドレスが返ってくるか確認してみます。
下記コマンドを実行すると、digコマンドの実行結果を「RecursiveResolver_results_20241230_1.txt」というファイルに書き込みます。

    for i in {1..20000}; do domain=$(dig web-test.https-demo.com. @10.0.0.2 +short); echo -e  "$domain" >> RecursiveResolver_results_20241230_1.txt; done

下記コマンドを実行すると、「RecursiveResolver_results_20241230_1.txt」に書き込まれたIPを集計できます。

    sort RecursiveResolver_results_20241230_1.txt | uniq -c | sort -nr

結果にばらつきはありますが、東京・大阪の各IPに対して名前解決されている状態でした。

       7436 172.31.1.5
       5000 10.0.5.4
       4990 172.31.5.5
       2574 10.0.1.4


東京リージョン側のWEB1/WEB2を停止させ、ヘルスチェックのステータスをUnhealthyにした状態で再度確認してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/696d3a43-d8ef-b11d-6be1-dfe462e7a756.png)

踏み台からブラウザを立ち上げ確認してみると、今度は大阪のテストページのみが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/1d9bba42-32d4-4a5a-efb3-40aa557f43fc.png)

digコマンドで確認してみても、大阪リージョン側のIPにのみ名前解決されていることが確認できました。

    for i in {1..20000}; do domain=$(dig web-test.https-demo.com. @10.0.0.2 +short); echo -e  "$domain" >> RecursiveResolver_results_20241230_2.txt; done
    sort RecursiveResolver_results_20241230_2.txt | uniq -c | sort -nr
      17515 172.31.1.5
       2485 172.31.5.5

今度は東京・大阪のWEBサーバーを全台停止させ、Sorryページが表示されるか確認してみます。
Route53のヘルスチェックは全てUnhealthyの状態です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/f4d9ebc7-aae4-3b58-18ac-9a71145d76aa.png)

この状態で踏み台からブラウザを立ち上げ確認してみると、S3のSorryページが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2237429/df53cad3-492a-b0dc-4e67-751e7257613e.png)

今回ご紹介する手順は以上となります。
ここまでお読みいただきありがとうございました。