Route 53でサブドメインを別アカウントに移動するやり方

あるアカウントで運用しているドメインを別のアカウントに遷移したので、 未来の自分がまた同じ事をする際に思考を再現できるようにするまとめました。

前提条件

  • ドメイン(domain)をAWSのアカウントAのRoute 53で管理(domain.com)
  • domainのサブドメインsubもアカウントAのRoute53で管理(sub.domain.com)
  • subはEKS上でAWS Load Balancer Controllerexternal-dnsを利用して設定している
    • ALBを立ち上げてAレコードを登録するのが自動で行われる
    • subsub.sub.domain.comなどを作る可能性もある
  • subはACMで証明書を作成しており、DNSでの検証をしている
  • subのEKSやRDSを可能な限りアカウントBに移動したい
    • 理由がって残すのは(金額が高くないなら)OK

この前提条件のもとで、sub.domain.comをアカウントBに移動するかどうするかというところから考え始めました。

方法案

大まかな方針は2つありました。

  1. subのドメインをAに残してBからアクセスできるようにする
  2. subのドメインをBに移動する

というのも、Route53の料金自体は大したことがないのでEKSやRDSを移動することに比べたら小さく、そちらのほうが都合がいいのであれば動かす必要は無いと考えました。

また、ドメインが関わる部分として
a. subはACMのDNS検証を利用している
b. EKSから自動で変更される

という2点が挙げられます。 このうちaはドメインを移動すれば問題なくできますし、ドメインを残していたとしても CNAMEレコードを一回だけ登録すれば良いように読めるため、最初の一回だけ手動で登録すればよく、特に差はなさそうです。

一方でbはexternal-dnsのpodに設定したroleがsubのレコードを変更できるようにする必要があります。 ドメインを移動すれば特に問題はないのですが、ドメインを残したままやる場合、 external-dnsのIAM Policyを持ったRoleをAに作り、それをBからassume roleする必要があり、結構複雑なしくみになります。

そのため、ドメインを遷移したほうが自由度が高く、A自体でやっているterraform設定と統一できることもあり、ドメインも遷移することにしました。

ドメインを遷移する方法

アカウントAでは親となるdomainのホストゾーン内にsubのレコードが登録されています。 domainやsub以外にもapp.domain.comがいたりするので、domainのホストゾーンはAに残し、subだけを分離して管理をアカウントBで行いたいです。

DNSにはサブドメインを委任する仕組みがあり、これを利用することで実現できます。 具体的にはどのサーバがそのゾーンを管理しているかを示すNSレコードを利用し、親となるdomain.comのゾーンファイルに対して、アカウントBが変更できるNSサーバがsub.domain.comを管理しているというレコードを登録します。 これでアカウントBからAレコード等を登録するとそれが利用できるようになります。

具体的な遷移手順

Bから見るとsubは他のところで管理されているドメインを自分のアカウントに持ってくると言えるので、この「Route 53 を使用中のドメインの DNS サービスにする」の手順がほぼ使えます。

今回は一時的に止めることが許容できたのと、ALBの作成をEKSにまかせているので事前に作るのが面倒だったので、手順はやりやすいように変えています。 なお、数日前にアカウントAでsubのTTLを短く設定しておきます(60秒とか)。

Bのterraformでドメインsubのホストゾーンを作成します

resource "aws_route53_zone" "domain" {
  name = "sub.domain.com"
}

作成されたNSレコードをAのアカウントのドメインsubのNSレコードとして設定します。 また、subの他のレコードは削除します。

resource "aws_route53_record" "beta_account" {
  name    = "sub.domain.com"
  ttl     = 60
  type    = "NS"
  zone_id = aws_route53_zone.alpha.zone_id

  records = [
    "xxxx.awsdns-53.com.",
    "yyyy.awsdns-54.co.jp.",
    "zzzz.awsdns-55.ac.jp.",
    "xxxx.awsdns-56.org."
  ]
}

これで完了です。 あとは以下のように普通のzoneとしてACMを作ったりできますし、external-dnsからも変更ができるようになります。

resource "aws_acm_certificate" "domain" {
  domain_name       = "sub.domain.com"
  validation_method = "DNS"
}

resource "aws_route53_record" "domain" {
  zone_id = aws_route53_zone.domain.zone_id
  ttl     = 60
  ....