はじめに
CloudFront ディストリビューションを移行する機会がありましたので、実際に対応した手順と注意点を紹介します。以下を前提とします。
- DNS は Route 53
- 同一アカウント内での移行
- ユーザーからのアクセスはメンテナンスページに向いている状態
概要
方針として、CloudFront の変更と Route 53 の変更はなるべく同じタイミングでコマンドラインで実行し、不整合が発生しないようにします。
CloudFront
- CloudFront の CNAME を新旧ディストリビューションで付け替える
- CloudFront の CNAME は重複を許さないため、AssociateAlias API を使ってアトミックに付け替える (参考)
Route 53
- A レコード (エイリアスレコード) の向き先を変更する
リソースの状態
作業前の CloudFront ディストリビューションの状態です。
CNAME | 証明書 | 備考 | |
---|---|---|---|
移行元 | test.example.com | あり | Route 53 の A レコードはこちらを向いている |
移行先 | なし | あり | – |
ちなみに移行先に CNAME が設定されていない場合でも証明書は必須です。ない場合は AssociateAlias API 実行時に以下エラーが発生します。
An error occurred (InvalidArgument) when calling the AssociateAlias operation: To add an alternate domain name (CNAME) to a CloudFront distribution, you must attach a trusted certificate that validates your authorization to use the domain name. For more details, see: https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-requirements
TXT レコードの登録
AssociateAlias API を使う場合は、ドメインの所有権を検証するため事前に DNS に TXT レコードを仕込んでおく必要があります。TXT レコードにはドメインの先頭にアンダースコアを付けた値を設定します。Zone Apex の場合はプレフィックスとして _.
がつくことになります。Value は移行先ディストリビューションのドメイン名です。
Record name | Type | Value |
---|---|---|
_.test.example.com | TXT | xxxxxxxxxxxxx.cloudfront.net |
今回は test.example.com というパブリックホストゾーンで、Zone Apex である test.example.com の A レコード (エイリアスレコード) が移行元ディストリビューションに対して設定されています。上記の TXT レコードはその前提で設定しています。
これは一見正しいですが、実は失敗しました。のちほど説明します。
移行コマンド
CloudFront ディストリビューションの CNAME 付け替えと DNS レコードの向き先変更を続けて実行したいため、以下のように &&
で繋いで実行します。
aws cloudfront associate-alias --alias "test.example.com" --target-distribution-id "<新規作成したディストリビューションの ID>" && aws route53 change-resource-record-sets --hosted-zone-id "xxxxxxxxxxxxxxxxxxxx" --change-batch '{ "Comment": "Change of Domain Direction", "Changes": [ { "Action": "UPSERT", "ResourceRecordSet": { "Name": "test.example.com", "Type": "A", "AliasTarget": { "HostedZoneId": "Z2FDTNDATAQYW2", "DNSName": "<新規作成したディストリビューションのドメイン名 (xxxxxxxxxxxxxx.cloudfront.net)>", "EvaluateTargetHealth": false } } } ] }'
結果
コマンドを実行すると、以下のエラーが発生してしまいました。TXT レコードの検証に失敗しています。なぜでしょうか。
An error occurred (IllegalUpdate) when calling the AssociateAlias operation: Invalid or missing alias DNS TXT records.
トラブルシューティング
このエラーの原因ですが、TXT レコードの値として _test.example.com
を期待していたところ、実際は _.test.example.com
であったことが原因ではないかと推測しました。
test.example.com ホストゾーンは example.com ホストゾーンから DNS を委任されています。具体的には以下のようなケースです。
- example.com という Route 53 パブリックホストゾーンがある
- test.example.com という Route 53 パブリックホストゾーンがある
- example.com は test.example.com の NS レコードを持っている
今回 test.example.com のホストゾーンに以下のように TXT レコードを書きましたが、これがうまくいきませんでした。
Public hosted zone | Record name | Type | Value |
---|---|---|---|
test.example.com | _.test.example.com | TXT | xxxxxxxxxxxxx.cloudfront.net |
解決策として、委任元である example.com のホストゾーンで以下のように書く必要がありました。
Public hosted zone | Record name | Type | Value |
---|---|---|---|
example.com | _test.example.com | TXT | xxxxxxxxxxxxx.cloudfront.net |
この変更後、移行コマンドを再度実行することでうまく移行できました。
おわりに
いちばん言いたかったのはトラブルシューティングのところです。検証で再現しているので、このケースの対策として間違ってはいないはずです。が、私は DNS にさほど詳しくないので、不備などがあれば教えていただけると幸いです。
また本件のような作業については、ユーザーに対してはメンテナンスページを表示しておくなど、通常のメンテナンス状況下で実施することを強く推奨します。