Route53のヘルスチェックを使ってメンテナンス画面を表示させる

# はじめに
　こんにちは。今回は担当している業務で検証した作業を紹介させていただきます。
　要件としては、webサーバを更新(再デプロイ)した際に「504 Gateway Timeout」になるため、更新中はメンテナンス中であることがわかるようなカスタムページを表示させたいという内容です。「冗長性や可用性はどうなっているんだ。。。？」というツッコミがあるかもしれませんが、そこはコストなど複雑な事情や要件がありまして。。。
　何か方法がないか調査して検証までやったのですが、うまく要件を満たすものが見つからず、検証だけして終わってしまう可能性が出てきてしまいました。
 　せっかく検証したのに活用もできず、それでおしまいではもったいない(？)気がしたので、この場を借りて記事にしようと思った次第です。
　色々検証した方法の1つである「Route53のヘルスチェック」を使ってメンテナンス画面を表示させる方法を紹介させていただきます。

# 検証環境構築
　検証を行う環境を紹介します。記載以外の設定については、基本的にデフォルト設定で問題ないです。

※Route53やS3などグローバルなリソースについては、一部の値を見えないようにしております。また、各リソース作成の基本的な部分は割愛させていただきます。ご了承ください。

 ## 構成図
　今回の構成図は下記になります。ELB、EC2を使った一般的なwebサイト構成になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513710/1aaab84a-82e6-4fbe-4a1d-286de5233a43.png)

## NW
　先ほどの構成図のようにVPC、サブネットを作成します。CIDRについては特に指定はありません。
 
　ルートテーブルは下記設定を入れてサブネットに割り当てしています。
* Publicサブネット：送信先：0.0.0.0/0、ターゲット：igw
* Privateサブネット：送信先：0.0.0.0/0、ターゲット：NAT

　sgはインバウンドルールに下記ルールを設定して各リソースに割り当てしています。(検証のため基本的に緩いルールです。ACLはデフォルトのままです。)
 * ELB用：ポート443と80、ソース「0.0.0.0/0」を許可
 * 踏み台サーバ用：ポート22、ソース「自端末のIPアドレス」を許可
 * webサーバ用：
　ポート22、ソース「自端末のIPアドレス」を許可
　ポート443と80、ソース「ELBのsg」を許可

## 踏み台サーバ(RHEL)
　踏み台はwebサーバへ接続するためのサーバです。検証のため、踏み台サーバはなくてもよいですが、一般的なwebサイト構成ということで作成しました。

## webサーバ(RHEL)
　踏み台経由でwebサーバにssh接続しましょう。その後、下記コマンドを実行してhttpサービスのインストールとindex.htmlを作成します。
```
# sudo yum update -y
# sudo yum install -y httpd
# sudo systemctl start httpd
# sudo systemctl enable httpd
# echo "<html><body><h1>web server test hellow world!!!</h1></body></html>" | sudo tee /var/www/html/index.html
```

## ELBとターゲットグループ
　ターゲットグループを作成し、webサーバを割り当てしましょう。そのあと、ALBを作成します。リスナー設定については、ポート80(http)のみ設定しました。

## S3
　S3はメンテナンス画面ネタを配置するために作成します。バケット作成後、メンテナンス画面のネタ(sorry.html)をバケット直下にアップロードします。sorry.htmlの中身はなんでもかまいません。今回作成したsorry.htmlの中身はこちらになります。
```
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>メンテナンス中</title>
    <style>
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background-color: #f4f4f4;
            margin: 0;
            padding: 0;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            text-align: center;
        }

        .maintenance-container {
            background-color: #fff;
            border-radius: 8px;
            padding: 40px;
            box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
            max-width: 80%;
        }

        h1 {
            font-size: 2em;
            color: #333;
            margin-bottom: 20px;
        }

        p {
            font-size: 1.2em;
            color: #555;
            line-height: 1.6;
        }

        /* 他のスタイルを追加する場合はここに追加してください */

        @media (max-width: 768px) {
            /* レスポンシブデザインのためのスタイル */
            .maintenance-container {
                max-width: 90%;
            }
        }
    </style>
</head>
<body>
    <div class="maintenance-container">
        <h1>申し訳ありません、メンテナンス中です。</h1>
        <p>ご迷惑をおかけして申し訳ありません。しばらくしてから再度アクセスしてください。</p>
        <!-- 他のコンテンツを追加する場合はここに追加してください -->
    </div>
</body>
</html>
```

　バケットの設定について、注意点が3つあります。
　1点目は、S3のバケット名はRoute53で登録するレコード名と同じにすることです。www.example.comがレコード名なら、S3バケット名もwww.example.comにする必要があります。
 
　2点目は、S3でパブリックアクセスをオフにすることです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513710/6bfbbc69-7fb4-42f4-18d0-8af990f5545c.png)

　3点目はバケットの「静的ウェブサイトホスティング」を有効にすることです。先ほど配置したメンテナンス画面のネタ(sorry.html)を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513710/142b20e9-1c38-00ba-f1ff-dac1c8691ecc.png)

## Route53
　今回のメインとなるRoute53です。ホストゾーンの作成だけでなく、ドメインの登録も行いましょう。今回はRoute53でドメイン登録しましたが、Route53にホストゾーンだけ作成して、ドメインはお名前ドットコムなど他サービスでドメイン登録しても問題ありません。ドメイン作成後、ヘルスチェックおよびレコードの作成を行います。

 ### ヘルスチェック
　ヘルスチェックですが、下記で設定します。画像のドメイン名は例になります。前手順で作成したドメインを設定しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513710/2559501f-288c-219d-ae3a-8ffd5348df10.png)

　「次へ」に進むとcloudwatchアラームの設定有無を確認されます。作成しても問題ありませんが、今回は検証なので「いいえ」とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513710/0279c2da-3249-1c86-873a-9ce6f2dba609.png)

### ホストゾーン
　続いて、ホストゾーンにメインとなるレコード名、メンテナンス画面用のレコード名の2つを登録します。

* プライマリレコード 設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513710/17d2a7eb-44ae-6173-f3fe-a429edd12a94.png)

* セカンダリレコード 設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513710/e0661221-3f91-a37b-4c2a-1879e1a8439e.png)

# 検証
　ブラウザを起動して登録したドメイン名を入力してみましょう！問題なく構築できていれば、下記のような画面になります。(正常系)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513710/b53d9e0f-52ba-c46c-7ca4-4162a65d9a01.png)

　続いて、webサーバを停止してみましょう。ヘルスチェックが異常になったあと、再度接続するとsorry.htmlが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2513710/3b7b87f2-c084-b56e-bee1-3a28f5a3082a.png)

　再度、webサーバを起動すると、ヘルスチェックが正常に戻って通常の画面に戻ります。

　もしも、ブラウザの4xxエラー、5xxエラーが表示される場合、webサーバまで正しく接続できていない可能性があります。sgやACLの設定を見直してみましょう。また、ターゲットグループにwebサーバが正常に登録されているかも確認してみましょう。
　また、Route53に登録したレコード名と設定した値が合っているか確認してみましょう。(私はここで値が一部間違っていてうまく出力されませんでした。。。)

# 最後に
　いかがでしたでしょうか。今回は検証なのでsg設定や各リソースの細かい設定はデフォルトで行いましたが、実業務で活用する場合は、NW要件、各リソースの設定をちゃんと設計した上で構築しましょう。色々リソースを作ったので無駄な課金を抑えるためにも、リソースの削除は忘れずに。
　他にもメンテナンス画面させるために試した方法(NG案)があるので、機会があれば紹介させていただければと思います。