タグ: Route53

Route53 で S3 バケットへ alias レコードを作った際のリダイレクトのふるまい

 Amazon S3 は、全てのリクエストをリダイレクトや、パスに応じたリダイレクトを設定できる機能を持っています。これは Static Web Hosting という設定を入れることにより実現可能です。実際の技術詳細については以下の公式ドキュメントを参照してください。

  • 公式ドキュメント: https://docs.aws.amazon.com/AmazonS3/latest/dev/how-to-page-redirect.html

リダイレクト設定

gochiusa.53ningen.com に対して gochiusa.com へのリダイレクト設定作業は以下の 3 STEP です

  1. S3 バケットを gochiusa.53ningen.com という名前で作成する
  2. Static Web Hosting 機能を有効にして、すべてのリクエストを gochiusa.com にリダイレクトする設定を入れる
  3. Route 53 に gochiusa.53ningen.com に対して先ほど作ったバケットへのエイリアスを張る A レコードを作成する

動作確認

作業後、設定を dig で確認します

解決される 52.219.68.26 は S3 の静的配信サーバーの IP の模様で、振る舞い的には Host ヘッダと同じ名前を持つ S3 バケットへリダイレクトをかけるという形のようです。それを確認するために次のようなリクエストを送ってみます。

x-amz-error-message: Request does not contain a bucket name. というメッセージからわかるようにバケットネームの指定がないというエラーで AWS S3 のトップページに飛ばされます。次に Host ヘッダをつけるとどうなるか試してみましょう。

The specified bucket does not exist というエラーメッセージに変わりました。ではそろそろ真面目に先ほど作った gochiusa.53ningen.com という値を Host ヘッダにつけて叩いてみましょう。

正常に 301 で http://gochiusa.com/ にリダイレクトされていることが確認できました。

実験からわかること

  1. S3 バケットへの alias レコードセットの制約の理由が推測できる
    • Route53 で S3 static web hosting しているバケットに alias を張る際は、公式ドキュメントに記載されているように Record Set の Name と S3 バケット名が一致している必要がある
    • これは Host ヘッダをみて、対象の S3 静的配信コンテンツへのリダイレクトを行なっている仕組みから生まれる制約だろうということが、上記の実験から分かる
  2. S3 バケットへの alias を張っているドメインを指す CNAME を張ると正常に動作しない
    • 実際に gochiusa2.53ningen.com に対して gochiusa.53ningen.com を指すような CNAME レコードセットを作ると以下のような実験結果になる

Route53へのDNSとドメインの移行

次のものを AWS に移行しました。

  • ドメイン移管(53ningen.com): ムームードメインから Route 53 へ
  • ドメインネームサーバー移行: ムームードメインから Route 53 へ

また、もとの運用では存在しなかった、次のようなものを導入しました。

  • L7レイヤーでのヘルスチェック
  • DNSフェイルオーバー

この資料は自分向けの作業ログであるため、実際には各ステップ冒頭に記された公式ドキュメントを理解した上で読むことを強く推奨します。

手元環境

 作業は基本的には terraform を使って行いました。ただし、ドメインの移管に関しては Route 53 のマネジメントコンソールとムームードメインのコントロールパネルを操作する必要があります。

1. DNS を Route 53 へ移行

 ドメインも Route 53 に移管しますが、その際に元のレジストラ(ムームードメイン)が提供するネームサーバーからドメインが削除されてしまうので、前もって DNS を Route 53 に切り替えておきます。

1.1. ホストゾーン(Hosted Zone)の作成

公式ドキュメント: 既存ドメインの DNS サービスを Amazon Route 53 に移行する

 ホストゾーンとはドメインに紐づくリソースレコードのセットです。おおよそゾーンファイルと対応していると考えて良いと思います。実際にゾーンファイルを取り込むこともできるようです(公式ドキュメント: ゾーンファイルをインポートしてリソースレコードセットを作成する)。

 ホストゾーンには、パブリックなものとVPC向けのプライベートなものがあります。マネジメントコンソールからドメイン名を入力すれば作成が完了しますが、今回はこのリソースを terraform で管理します。

terraform plan は以下のとおり

 terraform apply してホストゾーンを作成すると SOA レコードNS レコード も自動的に作成されます。今回はドメイン名とIPアドレスを紐づけるために A レコード の追加が必要になります。そのため、その記述を追加します。メールサーバーの移行が必要であれば MX レコード、サブドメインなどの運用をやっているのであれば CNAME レコード など適当な感じに必要なものも移行しておきましょう。ひとまず今回は A レコード のみを作ります(Route 53 が対応しているDNSリソースは サポートされる DNS リソースレコードタイプ を参照)。terraform apply を実行するとレコードが作成されます。

1.2. DNSの変更

 マネジメントコンソールの NS レコード欄の DNS サーバーを、ムームードメインのコントロールパネルで指定します。反映が有効になるまで少し時間がかかるため、少し待って dig で確認すると良いとおもいます。

1.3. コストの計算

公式ドキュメント: 料金

 お仕事ならこの計算作業する前にやるべきですが、個人のお遊びサーバーなので作業後に計算しました。

  • ホストゾーン
    • 0.50 USD(ホストゾーンごと)/月 – 最初の25のホストゾーン
    • 0.10 USD(ホストゾーンごと)/月 – それ以上のホストゾーン
  • 標準的クエリ
    • 0.400 USD(100 万クエリごと) – 最初の 10 億クエリ/月
    • 0.200 USD(100 万クエリごと) – 10 億クエリ以上/月

おおよそ 1ホストゾーン + 最初の10億クエリ = 0.50 + 0.40 = 0.90 USD

1.4. ヘルスチェックの設定 (Optional)

公式ドキュメント: Amazon Route 53 ヘルスチェックの作成と DNS フェイルオーバーの設定

 ヘルスチェック(L7)とDNSフェイルオーバーが利用できます。ヘルスチェックで障害を検知した場合に Cloudwatch Alarm と連携をさせたり、DNSフェイルオーバーを利用して待機系に参照を向けたりすることが可能です。

 ひとまずベーシックなウェブサーバーのヘルスチェックは以下のように設定できます。その他諸々 terraform を利用する際にオプション記述については terraform 公式ドキュメント: aws_route53_health_check を参照してください。

ヘルスチェックに関しては、

  • AWSエンドポイント
    • ヘルスチェック 1 件につき 0.50 USD*/月
    • オプション機能 1 件につき 1.00 USD/月
  • AWS以外のエンドポイント:
    • ヘルスチェック 1 件につき 0.75 USD*/月
    • オプション機能 1 件につき 2.00 USD/月
  • 任意のヘルスチェック機能は以下の通りです。
    • HTTPS
    • 文字列マッチング
    • 短インターバル
    • レイテンシー計測

となっています。

「AWS エンドポイント」とは、AWS の中で稼働するリソース(たとえば Amazon EC2 インスタンス)のうち、ヘルスチェックと同じ AWS アカウントの中でプロビジョニングされるか、ヘルスチェックと同じアカウントが請求先となっているものを指します。計算済みヘルスチェックとメトリクスベースのヘルスチェックは AWS エンドポイントのヘルスチェックとして請求されます。Elastic Load Balancing のリソースまたは Amazon S3 ウェブサイトバケットがエンドポイントであるヘルスチェックについては、お客様への請求は発生しません。Elastic Load Balancing のリソースおよび Amazon S3 ウェブサイトバケットをエンドポイントとするヘルスチェックについては、AWS によって自動的にプロビジョニングされ、Amazon Route 53 の一部として追加料金なしでご利用いただけます。

1.5 DNSフェイルオーバーの設定 (Optional)

公式ドキュメント: DNS フェイルオーバーの設定
terraform 公式ドキュメント: aws_route53_record

 ヘルスチェックを入れたついでに、障害発生時に S3 の静的ホスティング機能 + Cloudfront によるメンテナンスページのほうへ参照を向けるようなDNSフェイルオーバー設定を入れてみます。DNSフェイルオーバー設定については無料で利用することができます。最終的な構成図は以下のような形になります。


 
 ディザスタリカバリを想定した構成として、ap-northeast-1 リージョンで稼働させるアプリケーションサーバーに対して、メンテナンスページを静的ホスティングする際の S3 リージョンは地理・物理的に違う系統の適当なリージョンを選択します。今回は us-east-1 を選択しました。

 S3 の前段に置いた Cloudfront は主に S3 からの配信をキャッシュする役割と、メンテナンスを表すステータスコード 503 でリソースを返す役割を持っています。S3 バケットの作成とファイルの配置、静的ホスティング機能の有効化および Cloudfront の設定は以下のように terraform で記述することができます。

terraform 公式ドキュメント: aws_s3_bucket
terraform 公式ドキュメント: aws_cloudfront_distribution

resources/error には、適当なメンテナンス表示 html ファイルを、 policies/maintenance.53ningen.com_s3_policy.json には以下のようにバケットのファイルの読み取りを許可するポリシーを配置します。

つづいて Route 53 ホストゾーンにフェイルオーバーの設定をします。通常時は既存の A レコードが有効になるようにしつつ、ヘルスチェックに失敗した場合にメンテナンスページを静的にホスティングしている S3 のほうに参照を向けるような設定を入れます。また ttl を最初の設定より短く 60 秒に変更します。 terraform を用いて次のように記述できます。

 最後に動作確認として、動いているウェブサーバーを停止し、きちんとメンテナンス表示に切り替わるか確認します。またウェブサーバーを起動したときに、ヘルスチェックが通るようになり、きちんとアプリケーションサーバーに参照が戻るかも合わせてチェックしておきましょう。

2. ドメインを Route 53 に移管する

公式ドキュメント: ドメインの移管

ムームードメインで購入した 53ningen.com ドメインを Route 53 に移管します。ステップとしては以下のとおりです。

  1. WHOIS 情報としてレジストラの情報を代理公開している場合は、ムームードメインのコントロールパネルから自分のものに変更する
  2. 確認のメールが飛んでくるので踏む
  3. AUTH_CODE をメモ
  4. Route 53 の Domain registration から Transfer Domain to Route 53 に進みドメイン名を入力
  5. AUTH_CODE を入力
  6. 移管後のDNSとして先ほど作った Route 53 の Hosted Zone を指定する
  7. AWSから移管確認のメールが飛んでくるので踏む
  8. そのうち移管が完了する

Waiting for the current registrar to complete the transfer (step 7 of 14)
ドメインが移管の要件を満たしているか現在のレジストラが確認しています。このステップは、ドメインの TLD に応じて最大 10 日かかる場合があります。

結構待ったりいろんな確認メールのリンクを踏んだりする必要がありますが、あまりテクニカルな手順はないはず…。