CloudFrontのCNAMEAlreadyExistsエラーを回避しつつCNAMEを付け替える

CloudFrontディストリビューションはCNAMEが重複するとCNAMEAlreadyExistsエラーが発生します。 このエラーを回避しながら、ディストリビューション間でCNAMEを付け替える方法を紹介します。
2020.11.29

Amazon CloudFrontのディストリビューションはCNAMEの重複が許可されていません。

CNAMEAlreadyExists:CNAMEAlreadyExistsException: One or more of the CNAMEs you provided are already associated with a different resource.

本記事では、CloudFrontディストリビューションのCNAMEの重複エラーを回避しつつ、ディストリビューション間でCNAMEを付け替える方法を紹介します。

付け替えパターンは2種類

CNAMEの付け替え方法は2パターンあります。

  1. (ユーザーの操作で完結)サブドメインを同一AWSアカウントの別ディストリビューションに付け替える場合
  2. (AWSと連携)apexドメインの付け替えやサブドメインを別AWSアカウントのディストリビューションに付け替える場合

要件に合わせて使い分けてください。

サブドメインを同一AWSアカウントの別ディストリビューションに付け替える場合

サブドメインを同一AWSアカウントの別ディストリビューションに付け替える場合、ユーザーの操作で完結します。

ポイントは以下です。

  • CNAME が www.example.com と *.example.com のディストリビューションを一時的に共存させる
  • ディストリビューションのCNAMEがオーバーラップしている場合、エッジではCNAMEがより一致するディストリビューションにトラフィックが流れる(DNSは関係無し)

詳細手順は以下を参照してください

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-move-subdomain

初期状態

ディストリビューション(d123.cloudfront.net)を www.example.com のALIASレコードでアクセスしているものとします。

DNSの付け替え

DNS レコードを新しいディストリビューションに変更します。

  1. 新規ディストリビューションを「CNAME:*.example.com」で追加(完全一致は許可されないが、オーバーラップは可能)
  2. Route 53 の ALIAS レコードを新しいディストリビューションのドメイン名に変更

dig を実行すると、新しいディストリビューションに向いています。

一見すると、新ディストリビューションにトラフィックが流れそうですが、エッジでは DNS レコードに関係なく CNAME がより一致するディストリビューションにトラフィックが流れます。 Route 53 の加重レコードを作成し、2つのディストリビューション間でトラフィックを振り分けるといったこともできません。

Overlapping alternate domain names can be in the same distribution or in separate distributions as long as both distributions were created by using the same AWS account. If you have overlapping alternate domain names in two distributions, CloudFront sends the request to the distribution with the more specific name match, regardless of the distribution that the DNS record points to. For example, marketing.domain.com is more specific than *.domain.com. Using Custom URLs for Files by Adding Alternate Domain Names (CNAMEs) - Amazon CloudFront https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/CNAMEs.html#alternate-domain-names-move

CNAMEの付け替え

最後にディストリビューションのCNAMEsの付け替えを行います。

  1. 旧ディストリビューションのCNAME をブランクに変更
  2. トラフィックが新ディストリビューションに流れる
  3. 新ディストリビューションのCNAMEを非ワイルドカード形式に変更

以上で完了です。

注意

既存のディストリビューションのCNAMEがワイルドカード形式の場合、事前に非ワイルドカード形式に変更して後続の処理を進めてください。

また、ワイルドーカードCNAMEは便利な一方で、様々な弊害があります。必要がない限り、使わないようにしましょう。

apexドメインの付け替えやサブドメインを別AWSアカウントのディストリビューションに付け替える場合

この場合、AWSと連携しながらCNAMEの付け替えを行います。

ポイントは以下です。

  • ユーザーがDNS TXTレコードを作成し、ドメインと移行先ディストリビューションの所有者であることを示す。
  • AWSがディストリビューション間のCNAMEの付け替えを行う
  • CNAME付け替え直後からトラフィックは新しいディストリビューションに流れる(DNSは関係無し)

詳細手順は以下を参照してください

初期状態

AWSアカウント:123で管理されるディストリビューション(d123.cloudfront.net)を www.example.com のALIASレコードでアクセスしているものとします。

以下では、www.example.com をAWSアカウント:456で管理されるディストリビューション(d456.cloudfront.net)に付け替えます。

ディストリビューションの追加

  1. 新規ディストリビューションを「CNAME:ブランク」で追加
  2. Route 53 の TXT レコードで新ディストリビューションのドメイン名を参照(www.example.com TXT d456.cloudfront.net)

AWS がCNAMEを付け替え

AWSにディストリビューションのCNAMEsの付け替えを依頼します。

  1. AWSサポートケースを起票し、CNAME移行を依頼
  2. AWS担当部署で移行作業を実施

移行作業が終わると、DNSは旧ディストリビューションを向いているにも関わらず、トラフィックは新しいディストリビューションに流れます。

DNS の付け替え

最後にDNSレコードを調整します。

  1. www の向き先を新ディストリビューションに変更
  2. TXT レコードを削除

以上で完了です。

まとめ

CloudFrontディストリビューションはCNAMEが重複するとCNAMEAlreadyExistsエラーが発生します。 このエラーを回避しながら、ディストリビューション間でCNAMEを付け替える方法を2つ紹介しました。

いずれのケースでも、DNSが指しているディストリビューションとトラフィックが流れるディストリビューションが一致しないタイミングが発生するのが面白いですね。

ディストリビューションがCNAMEを利用している場合、エッジではリクエストヘッダーのHOSTフィールドとディストリビューションのCNAMEを元に適切なディストリビューションにルーティングされるためです。

それでは。

参考