2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EC2停止中にS3のSorryページへ切り替えるRoute 53フェイルオーバーを試す

2
Last updated at Posted at 2026-08-14

こんにちは

ソーイ株式会社 Webエンジニア2年目の村上です。

Webサービスを運用していると、障害によってサービスが停止してしまったり、メンテナンスのために一時的にサービスを停止したりする場面があります。

そのような場合、ユーザーにエラー画面をそのまま表示するのではなく、 現在メンテナンス中です といった案内を表示する、いわゆる Sorryページ を用意することがあります。

AWSについて調べていると、Route 53フェイルオーバールーティング を利用することで、通常のWebサイトにアクセスできなくなった際、S3に用意した静的なSorryページへアクセス先を切り替える構成が取れることを知りました。

ちょうどAWS資格の勉強を進めていることもあり、今回は実際にRoute 53S3を使ってSorryページへの切り替えを構築し、フェイルオーバールーティングがどのように動作するのか試してみます。

この記事の概要

取り扱う内容

今回は実際に環境を構築してフェイルオーバーを発生させることで、以下の内容を確認していきます。

  • Route 53のフェイルオーバールーティング
  • Route 53によるヘルスチェック
  • S3を利用した静的なSorryページ
  • Route 53を利用した独自ドメインの設定

前提条件

今回の検証では、以下を前提としています。

  • AWSアカウントを利用できること
  • 検証に使用できる独自ドメインを取得していること
  • Route 53EC2S3の基本的な操作ができること

検証にかかった料金

今回使用したRoute 53のホストゾーンやヘルスチェック、EC2など、一部のAWSリソースでは料金が発生します。

今回はネームサーバー変更後、DNSキャッシュの影響により反映まで時間がかかったため、検証環境を約1日稼働させました。
その際、今回の検証で使用したAWSサービスでは以下の料金が発生しました。

サービス 料金
Route 53 $0.50
EC2 インスタンス $0.33
VPC $0.12
EC2 その他 $0.02
S3 $0.00
合計 $0.97

今回の検証では、合計で約 $0.97 の料金が発生しました。

上記は今回の検証時に実際に発生した料金です。
利用時間やリージョン、各サービスの料金改定などによって実際の料金は異なるため、あくまで参考値としてご確認ください。

構成図

image.png

通常時はRoute 53によって通常のWebページへルーティングし、障害を検知した場合はS3に用意したSorryページへ切り替えます。

Route 53のフェイルオーバールーティングとは

Route 53のフェイルオーバールーティングは、正常時と障害時でDNSの応答先を切り替えるためのルーティングポリシーです。

フェイルオーバールーティングでは、アクセス先を主に以下の2つに分けて設定します。

  • Primary(プライマリ):通常時に利用するアクセス先
  • Secondary(セカンダリ):Primaryが利用できない場合のアクセス先

今回の構成では、通常のWebページを提供するEC2をPrimary、Sorryページを配置するS3をSecondaryとして設定します。

また、Primary側にはRoute 53のヘルスチェックを設定します。
ヘルスチェックが正常な間はPrimaryへアクセスさせ、異常と判断された場合にはSecondaryへDNSの応答先を切り替えます。

つまり今回作成する構成では、

正常時:Route 53 -> EC2(通常ページ)

障害時:Route 53 -> S3(Sorryページ)

という切り替えをRoute 53のフェイルオーバールーティングによって実現します。

公式docs

検証環境の作成

Sorryページを表示するために、ドメインやEC2S3などの環境を設定していきます。

1. Route 53へドメインを設定

まずは、今回の検証で使用するドメインをRoute 53で管理できるようにします。

今回は、お名前.comで取得した以下のドメインを使用します。

routetes.com

お名前.com

AWSマネジメントコンソールから Route 53 を開き、 ホストゾーン -> ホストゾーンの作成 を選択します。

ホストゾーンの設定では、以下の内容を入力し、 ホストゾーンの作成 を選択します。

設定
ドメイン名:routetes.com(登録するアドレス名)
タイプ:パブリックホストゾーン

説明は管理用にこのドメインが何なのか記載しておくとよいです。
タグをつけておくのも管理用としてよいですが、今回はなしです。

image.png

ホストゾーンを作成すると、Route 53によってNSレコードSOAレコードが自動的に作成されます。

image.png

この状態で生成されたNSレコードの、値/トラフィックのルーティング先 を確認すると、以下のような4つの値が確認できます。

Route 53のNSレコードでは、ネームサーバー名の末尾に . が付いています。これはDNS上で 完全修飾ドメイン名(FQDN) であることを表すものです。
お名前.comのネームサーバー設定では、末尾の . を除いた値を入力します。DNSサービスによって入力形式が異なる場合があるため、利用するサービスの仕様を確認してください。

値/トラフィックのルーティング先内要素
ns-xxxx.awsdns-xx.com 
ns-xxxx.awsdns-xx.net 
ns-xxxx.awsdns-xx.org 
ns-xxxx.awsdns-xx.co.uk

これはネームサーバーといわれるもので、そのドメインに関するDNSの問い合わせに対して、どの情報を返すかを管理するサーバーです。

今回は、お名前.comで取得したドメインのネームサーバーをこれらの値に変更することで、routetes.com のDNS管理をRoute 53に委任します。

問い合わせの流れイメージ
routetes.com 
│ 
│ DNS問い合わせ 
▼ 
Route 53

お名前.comを使っている場合は、ネームサーバー設定その他のネームサーバーを使うという設定欄に追加してください。

image.png

使っているサービスによって違うため、詳しいネームサーバー設定は割愛します。

2. EC2サーバーの準備

このセクションはサクッと行きます。
完成形としては以下の流れができる環境まで作成します。

環境図
Public Subnet
      │
      ▼
     EC2
Public IPv4あり
      │
Security Group
      │
   TCP : 80
      ▲
      │
インターネット

まず通常アクセス先(Primary)として使うためにEC2を起動します。

AWSマネジメントコンソールから EC2 -> インスタンス -> インスタンスを起動 を選択します。

今回は検証用で作成するため設定は以下で進めます。

VPCの設定
IPv4 CIDR:10.0.0.0/16
AZの数:1
パブリックサブネット:1
プライベートサブネット:0
NAT Gateway:なし
VPC Endpoint:なし
DNSホスト名:有効
DNS解決:有効

AZ数や、パブリックサブネット数などの項目は、
VPCを作成 -> 作成するリソース欄の VPCなど を選択すると、設定項目が現れます。

EC2の設定
AMI:Amazon Linux 2023
インスタンスタイプ:t2.micro
VPCは作成したものを選択
パブリックIP:有効
ストレージ:デフォルトでOK
キーペア:なし

次に後ほどRoute 53のヘルスチェックを行うため、セキュリティグループ設定からHTTP通信を許可します。

以下はインターネットにHTTPを公開する検証用の設定です。

セキュリティグループの設定
タイプ:HTTP
プロトコル:TCP
ポート:80
ソース:0.0.0.0/0

今回は、接続できることとページの表示を確認できればよいため、EC2のユーザーデータを利用してApacheと簡単なHTMLを起動時に用意して確認します。

高度な詳細 -> ユーザーデータ に以下を記入しました。

ユーザーデータはインスタンス停止中のみ編集できます。
すでに作成済みの場合は一度インスタンスを停止して確認してください。

ユーザーデータ
#!/bin/bash

dnf install -y httpd

systemctl enable httpd
systemctl start httpd

cat <<'EOF' > /var/www/html/index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>通常ページ</title>
</head>
<body>
    <h1>Webサイトは正常に稼働しています</h1>
</body>
</html>
EOF

インスタンスを起動後に、
EC2に割り当てられたパブリックIPv4アドレスを使って以下にアクセスします。

確認URL
http://<EC2のパブリックIPv4アドレス>

以下の表示が確認できれば準備完了です。

Webサイトは正常に稼働しています

3. S3にSorryページを保存

次はS3側にSorryページを登録します。
AWSコンソールから S3 -> バケットを作成 を開き、作成を行います。

S3設定
バケットタイプ:汎用
バケット名:routetes.com
オブジェクト所有者:ACL無効
パブリックアクセス:すべてオフ
デフォルトの暗号化:SSE-S3
バケットキー:デフォルトのまま

今回はS3の静的ウェブサイトホスティングを利用してSorryページを公開するため、ブロックパブリックアクセスをすべてオフにしています。

ここでポイントになるのが、バケット名です。
今回Route 53からS3の静的ウェブサイトへルーティングするため、S3バケット名をRoute 53で使用するドメイン名と同じ routetes.com にします。

AWS公式のS3へのルーティング手順でも、Route 53S3 Website EndpointAlias先として選択する場合、バケット名とルーティングするドメイン/サブドメイン名を一致させる構成になっています。

バケット作成後は、Sorryページとなる静的ファイルをアップロードしてください。

ページコードのサンプル
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>メンテナンス中</title>
  <style>
    :root {
      color-scheme: light dark;
    }
    body {
      margin: 0;
      font-family: "Segoe UI", "Noto Sans JP", sans-serif;
      background: linear-gradient(135deg, #f8fafc, #e2e8f0);
      color: #0f172a;
      display: grid;
      place-items: center;
      min-height: 100vh;
      padding: 24px;
      box-sizing: border-box;
    }
    .card {
      max-width: 640px;
      width: 100%;
      background: rgba(255,255,255,0.9);
      border: 1px solid rgba(15,23,42,0.08);
      border-radius: 20px;
      box-shadow: 0 20px 45px rgba(15,23,42,0.12);
      padding: 40px 32px;
      text-align: center;
    }
    h1 {
      margin: 0 0 12px;
      font-size: clamp(1.8rem, 2.4vw, 2.6rem);
    }
    p {
      margin: 0 0 16px;
      line-height: 1.7;
      font-size: 1rem;
      color: #334155;
    }
    .badge {
      display: inline-block;
      padding: 8px 14px;
      border-radius: 999px;
      background: #2563eb;
      color: white;
      font-weight: 700;
      margin-bottom: 20px;
    }
  </style>
</head>
<body>
  <main class="card">
    <div class="badge">メンテナンス中</div>
    <h1>現在、サービスを更新しています</h1>
    <p>ご不便をおかけして申し訳ありません。しばらくお待ちいただいたのち、再度アクセスしてください。</p>
    <p>復旧まで今しばらくお待ちください。</p>
  </main>
</body>
</html>

アップロード後に、
プロパティ -> 静的ウェブサイトホスティング -> 編集
と進み、有効にしてください。

設定時、インデックスドキュメントという項目に、アップロードした静的ファイル名を入力してください。

設定保存時に、以下のような バケットウェブサイトエンドポイント が表示されるので保存しておいてください。

発行されるエンドポイント
http://routetes.com.s3-website-ap-northeast-1.amazonaws.com

最後に、ブロックパブリックアクセスを無効にしただけでは、インターネットからS3バケット内のオブジェクトを読み取ることはできません。
そのため、追加で バケットポリシー を設定し、オブジェクトの読み取りを許可します。

バケットポリシー
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::routetes.com/*"
    }
  ]
}

これで、routetes.com バケット内のオブジェクトに対する読み取り(GetObject) だけを公開します。

ここまで設定できたら、S3単体で表示を確認します。

最後、プロパティ->静的ウェブサイトホスティングに表示されているバケットウェブサイトエンドポイントを開き、ページが確認できれば設定完了です。

4. Route 53のヘルスチェック作成

フェイルオーバーの肝になるヘルスチェックの作成を行います。

AWSコンソールから、
Route 53 -> ヘルスチェック -> ヘルスチェックの作成 を選択します。

ヘルスチェック設定
名前:自由記入
モニタリング対象:エンドポイント
エンドポイントの指定:IPアドレス
プロトコル:HTTP
IPアドレス:EC2のパブリックIPv4
ポート:80
パス:/
リクエスト間隔:30秒
失敗しきい値:3

ヘルスチェックでは、Route 53のヘルスチェッカーがEC2のパブリックIPv4アドレスへ定期的にアクセスします。

EC2側のSecurity Group
HTTP / TCP / 80 / 0.0.0.0/0
を許可しているのでRoute 53のヘルスチェッカーからもアクセスできます。

5. Primary、Secondaryレコードを作成する

ここまで作成したEC2S3Route 53のフェイルオーバールーティングに設定していきます。

まず、Primary -> EC2から作成していきます。

Primaryレコードの作成

Route 53から、
ホストゾーン -> routetes.com -> レコードを作成
と進みます。

以下の設定を行います。

Primaryレコード作成
レコード名:空欄
レコードタイプ:A
エイリアス:OFF
値:EC2のパブリックIPv4
TTL:60秒
ルーティングポリシー:フェイルオーバー
フェイルオーバーレコードタイプ:プライマリ
ヘルスチェック:先ほど作成したEC2用Health Check
レコードID:primary-ec2などで登録

Secondaryレコードを作成する

続いて、同じ routetes.com にもう1つレコードを作成します。

以下の設定を行います。

Secondaryレコード作成
レコード名:空欄
レコードタイプ:A
エイリアス:ON
トラフィックのルーティング先:S3ウェブサイトエンドポイントへのエイリアス
リージョン:S3を作成したリージョン
ルーティングポリシー:フェイルオーバー
フェイルオーバーレコードタイプ:セカンダリ
レコードID:secondary-s3などで登録

Secondary側にヘルスチェック設定は不要です。

Primary、Secondaryの設定により、以下のような状態になります。

レコード状態
routetes.com
     │
     ├── Primary
     │     A → EC2 Public IPv4
     │          ↑
     │      Health Check
     │
     └── Secondary
           Alias → S3 Website Endpoint

動作確認

検証環境の作成が終わりましたので、実際にやってみます。
今回は検証として、正常時障害発生時復旧時の3項目で確認します。

正常時

まず、Primaryとして設定したEC2が正常に稼働している場合の動作を確認します。

EC2の管理画面から、対象インスタンスが実行中になっていることを確認します。

image.png

次にRoute 53から、

ヘルスチェック -> **作成したヘルスチェック
**
を開き、ステータスが以下になっていることを確認します。

ステータス:正常(Healthy)

この状態で、実際にブラウザから以下URLにアクセスします。

URL
http://<設定したドメイン>
# 今回はhttp://routetes.com

アクセス後にEC2側の画面が表示されれば、正常時の動作確認は完了です。

ブラウザでの表示に加えて、nslookupを使用して正常時のDNS応答も確認します。
以下コマンドをコマンドプロンプトで実行してください。

確認コマンド
nslookup routetes.com

今回の環境では以下が出力されました。

結果
名前:    routetes.com
Address:  52.195.175.204

Addressに表示されたIPアドレスが、設定したEC2のパブリックIPv4アドレスと一致しているか確認してください。
一致していれば正常に接続できています。

接続できない場合

接続できない場合は、以下のコマンドを用いて接続先の確認を行ってください。 

確認コマンド
# ネームサーバーが、割り当てられた4つのNSで適用されているか
nslookup -type=NS ドメイン名

# Route 53に登録したEC2のパブリックIPv4が返ってくるか
nslookup routetes.com

なお、ネームサーバーの変更直後は、DNSキャッシュの影響により変更前の情報が返ってくる場合があります。

今回の検証でも、nslookup -type=NS を実行したところ、変更前のお名前.comのネームサーバーが返ってくる場合があり、その状態でページにアクセスしてもお名前.comのページに飛ぶのみでした。

実際に遷移したページ

image.png

設定内容に問題がない場合は、DNSの反映を待ってから再度確認しましょう。

障害発生時

では、本題に入ります。
PrimaryのEC2を意図的に停止して、SecondaryのS3 Sorryページへフェイルオーバーするかを確認しましょう。

EC2のインスタンスを停止してみましょう。
Webサーバーへアクセスできなくなり、Route 53のヘルスチェックが失敗するようになるはずです。

通信状況
EC2停止
   ↓
HTTPで応答できなくなる
   ↓
Route 53 Health Check
   ↓
Unhealthy

Route 53ヘルスチェックを開き、作成したヘルスチェックのステータスが、異常(Unhealthy) になっていることを確認しましょう。

確認したら、先ほどEC2で表示されていたページへ再度アクセスしてみましょう。
ここで、S3に配置したSorryページが表示されればフェイルオーバー成功です。

ブラウザでの表示に加えて、nslookupを使用してフェイルオーバー後のDNS応答も確認します。
以下コマンドをコマンドプロンプトで実行してください。

確認コマンド
nslookup routetes.com

今回の環境では以下が出力されました。

結果
名前:    routetes.com
Addresses:  3.5.157.233
            52.219.152.123
            52.219.200.19
            3.5.159.112
            52.219.162.163
            52.219.151.119
            52.219.137.39
            52.219.68.204

正常時はPrimaryレコードに設定したEC2のパブリックIPv4アドレスが返されていましたが、フェイルオーバー後は異なるIPアドレスが複数返されました

S3の静的ウェブサイトエンドポイントはEC2のように単一の固定IPアドレスを持つものではないため、nslookupでは複数のIPアドレスが返される場合があります

この結果から、DNSの応答先がPrimaryEC2からSecondaryS3へ切り替わったことを確認できました。

流れとしては構成図でも示しましたが、以下の流れになります。

通信の流れ
EC2を停止
   ↓
Route 53のヘルスチェッカーが
http://EC2のIP:80/ へアクセス
   ↓
応答が返ってこない
   ↓
一定回数ヘルスチェックに失敗
   ↓
Unhealthyと判定
   ↓
PrimaryをDNS応答から除外
   ↓
Secondary(S3)を返す

今回はリクエスト間隔を30秒、失敗しきい値を3回として設定しています。
実際にEC2を停止してからSorryページが表示されるまでを計測したところ、2分31秒で切り替わることを確認できました。

復旧時

S3の静的ページが表示されることを確認したら、EC2インスタンスを再度起動します。

EC2 -> インスタンス -> route53-test -> インスタンスの状態 -> インスタンスを開始

ステータスが実行中になったら再度ページへ訪問して表示を確認しましょう。

EC2側で設定したページが表示されれば復旧確認成功です。

注意:再起動時のパブリックIPv4アドレス

今回の構成では、Route 53のPrimaryレコードおよびヘルスチェックの接続先として、EC2のパブリックIPv4アドレスを直接指定しています。

EC2に自動割り当てされたパブリックIPv4アドレスは、インスタンスを停止して再度起動すると変更される場合があります

再起動時に変更を確認したら以下の設定を新しいIPアドレスへ変更してください。

Route 53のPrimary Aレコード
Route 53のヘルスチェックで指定したIPアドレス

パブリックIPv4アドレスを変更したくない場合は、Elastic IP(EIP)をEC2に割り当てることで固定のパブリックIPv4アドレスを利用できます
今回は検証用で作成したので設定していません。

まとめ

今回は、Route 53のフェイルオーバールーティングを利用して、EC2で稼働しているWebサーバーに障害が発生した際に、S3でホストしているSorryページへ切り替える構成を作成しました。

実際にEC2を停止することで、正常時はPrimaryのEC2へアクセスするものが、SecondaryのS3へフェイルオーバーするという一連の動作を確認できました。
この動作が接続の結果に応じてDNSの応答先を切り替える仕組みであることが理解できました。

今回学んだフェイルオーバーの仕組みは、業務におけるWebサービスの障害対策や可用性を考える上でも活用できる知識だと感じました。

次回の展望

今回の検証では、EC2・S3ともにHTTPでアクセスする構成としました。

しかし一般的なWebサイトではHTTPSが利用されることが一般的です。

今回使用したS3の静的ウェブサイトホスティング用エンドポイントはSSL/TLS証明書を割り当てられずHTTPSに対応していないため、今回の構成をそのままHTTPSのWebサイトに適用することはできません。

HTTPSの障害となると、証明書の期限切れやTLS関連の問題によってHTTPSで正常にアクセスできないといったケースも考えられます。

次回はCloudFrontACMを活用してHTTPSでもSorryページが表示できるか検証してみたいと考えています。

お知らせ

技術ブログを週1〜2本更新中、ソーイをフォローして最新記事をチェック!
https://qiita.com/organizations/sewii

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?