2026年6月8日

2026年6月8日

Route 53 のゾーン作成方法|パブリック・プライベートの選び分けとサブドメインの委任

Route 53 でゾーン(ホストゾーン)を作るときは、まず「インターネットに公開するのか、VPC の中だけで使うのか」を決め、それに合わせてパブリックかプライベートかを選びます。さらに、dev.example.com のようなサブドメインを別ゾーンに切り出す場合は、親ゾーンに NS レコードを追加して委任します。この記事では、この3種類の作り方を AWS CLI と Terraform で示し、それぞれでつまずきやすい点と、作ったゾーンが正しく使われているかの確認方法を説明します。既存ドメインをほかの DNS から Route 53 へ移す手順そのものは扱わず、「どの種類のゾーンをどう作るか」に絞っています。

作る前に決めること

Route 53 のホストゾーンは、作ったあとで種類を変えられません。パブリックで作ったゾーンを後からプライベートにすることはできないため、最初の判断が大切です。

  • パブリックホストゾーン: インターネット上のどこからでも名前解決できます。WordPress サイトの公開用ドメイン、メールの MX、各種サービスの所有権確認用 TXT などはこちらに置きます。レジストラにこのゾーンのネームサーバーを登録して、初めて外部から使われます。
  • プライベートホストゾーン: 関連付けた VPC の中からだけ名前解決できます。EC2 上の WordPress から RDS や ElastiCache を db.internal.example.com のような分かりやすい名前で参照したいときに便利です。レジストラへの登録は不要です。
  • サブドメイン用のパブリックゾーン: dev.example.com などを親とは別のゾーンで管理する方法です。開発環境の DNS を別チームや別 AWS アカウントに任せたい場合や、親ゾーンの権限を広げたくない場合に使います。

なお、ホストゾーンは作成した時点でゾーン単位の月額料金が発生します。料金体系は改定されることがあるため、AWS の料金ページで確認してください(2026年10月現在)。試しに作ったゾーンを放置しないよう、作業の最後に一覧を見直す習慣をつけておくと安心です。

パブリックホストゾーンを作る

コンソールでは Route 53 のホストゾーンの画面から作成に進み、ドメイン名を入力して公開用のタイプを選びます。画面の表記は更新で変わることがありますが、入力項目はドメイン名・説明・タイプの3つが基本です。手順を記録に残したい場合は CLI を使います。

aws route53 create-hosted-zone \
  --name example.com \
  --caller-reference "example-com-$(date +%Y%m%d%H%M%S)" \
  --hosted-zone-config Comment="public zone for WordPress"

--caller-reference は同じリクエストの二重実行を防ぐための一意な文字列で、実行のたびに違う値を渡します。作成に成功すると、出力の DelegationSet に4台のネームサーバー名が入っています。これがレジストラに登録する値で、ゾーンごとに組み合わせが違います。

ここで気をつけたいのは、同じドメイン名のパブリックゾーンを複数作れてしまうことです。作り直すたびにネームサーバーの組み合わせが違うゾーンが増え、レジストラが指しているのはそのうち1つだけになります。レコードを追加しても反映されないときは、まず次のコマンドで重複がないかを確かめます。

aws route53 list-hosted-zones-by-name --dns-name example.com

プライベートホストゾーンを作る

プライベートゾーンは、作成時に関連付ける VPC を指定します。VPC を指定するとプライベートゾーンとして作られます。

aws route53 create-hosted-zone \
  --name internal.example.com \
  --caller-reference "internal-$(date +%Y%m%d%H%M%S)" \
  --vpc VPCRegion=ap-northeast-1,VPCId=vpc-0123456789abcdef0 \
  --hosted-zone-config Comment="private zone",PrivateZone=true

作ったのに名前が引けない場合、多くは VPC 側の設定が原因です。プライベートゾーンを使うには、VPC の DNS 解決(enableDnsSupport) と DNS ホスト名(enableDnsHostnames) の両方が有効になっている必要があります。

aws ec2 describe-vpc-attribute --vpc-id vpc-0123456789abcdef0 --attribute enableDnsSupport
aws ec2 describe-vpc-attribute --vpc-id vpc-0123456789abcdef0 --attribute enableDnsHostnames

もう一つの落とし穴は、パブリックとプライベートで同じ名前のゾーンを作ったときの挙動です。たとえば example.com のプライベートゾーンを VPC に関連付けると、その VPC の中では example.com 以下の名前がすべてプライベートゾーンで解決されます。プライベートゾーンに登録していない名前は、パブリックゾーンにあっても「存在しない」と返されます。社内からだけ WordPress サイトが開けなくなる典型的な原因なので、同じ名前を使うなら、VPC 内で必要なレコードをすべてプライベート側にも登録するか、internal.example.com のように別の名前にするのが安全です。

ほかの VPC からも使いたい場合は、aws route53 associate-vpc-with-hosted-zone で関連付けを追加します。別の AWS アカウントの VPC を関連付けるときは、ゾーンを持つアカウント側で先に関連付けの許可を作成する手順が必要です。

サブドメインを別ゾーンに委任する

dev.example.com を別ゾーンで管理する場合、レジストラの設定は変更しません。親ゾーン(example.com)の中に「dev はこのネームサーバーに聞いてください」という NS レコードを置くことで委任します。

  1. dev.example.com のパブリックホストゾーンを作り、出力された4台のネームサーバー名を控えます。
  2. 親ゾーンに、名前が dev、タイプが NS、値が控えた4台のレコードを追加します。
cat > delegate-dev.json <<'EOF'
{
  "Changes": [{
    "Action": "UPSERT",
    "ResourceRecordSet": {
      "Name": "dev.example.com",
      "Type": "NS",
      "TTL": 3600,
      "ResourceRecords": [
        {"Value": "ns-111.awsdns-11.com"},
        {"Value": "ns-222.awsdns-22.net"},
        {"Value": "ns-333.awsdns-33.org"},
        {"Value": "ns-444.awsdns-44.co.uk"}
      ]
    }
  }]
}
EOF

aws route53 change-resource-record-sets \
  --hosted-zone-id Z0PARENTZONEID \
  --change-batch file://delegate-dev.json

上の4台の値は例です。実際には手順1で表示された値をそのまま使います。親ゾーンに委任の NS を置いたら、以後 dev.example.com 以下のレコードは子ゾーンにだけ登録します。親ゾーンに www.dev.example.com などを登録しても、委任した範囲の名前は子ゾーンで解決されるため使われません。

Terraform でまとめて書く

ゾーンを複数作るなら、Terraform でコード化しておくと、委任の NS を手で写す必要がなくなります。

resource "aws_route53_zone" "public" {
  name    = "example.com"
  comment = "public zone for WordPress"
}

resource "aws_route53_zone" "dev" {
  name = "dev.example.com"
}

# 子ゾーンのネームサーバーを親ゾーンに登録して委任する
resource "aws_route53_record" "dev_ns" {
  zone_id = aws_route53_zone.public.zone_id
  name    = "dev.example.com"
  type    = "NS"
  ttl     = 3600
  records = aws_route53_zone.dev.name_servers
}

resource "aws_route53_zone" "private" {
  name = "internal.example.com"

  vpc {
    vpc_id = "vpc-0123456789abcdef0"
  }
}

aws_route53_zone に vpc ブロックを書くとプライベートゾーンになります。パブリックゾーンの name_servers は出力しておき、レジストラへの登録に使います。本番のゾーンを Terraform 管理に切り替える場合は、既存ゾーンを import してから plan の差分を確認し、意図しない削除や作り直しが含まれていないことを確かめてから apply します。

作ったゾーンが使われているかを確認する

ゾーンを作っただけでは、実際の名前解決に使われているとは限りません。種類ごとに次のように確認します。

  • パブリックゾーン: dig NS example.com +short の結果が、作ったゾーンの4台と一致しているかを見ます。一致しなければ、レジストラの設定がまだか、別のゾーンを見ています。切り替え前でも dig @ns-111.awsdns-11.com www.example.com のように、ゾーンのネームサーバーへ直接問い合わせればレコードの中身は確認できます。
  • 委任したサブドメイン: dig NS dev.example.com +short で子ゾーンのネームサーバーが返るかを見ます。返らない場合は、親ゾーンの NS レコードの名前や値を見直します。
  • プライベートゾーン: VPC 内の EC2 などにログインし、dig db.internal.example.com を実行します。VPC の外から引けないのは正常な動作です。

まとめ

  • ゾーンの種類は後から変えられないため、公開用はパブリック、VPC 内専用はプライベート、サブドメインの分離は子ゾーンの委任、と用途で決めてから作ります。
  • パブリックゾーンは同名の重複に注意し、ネームサーバーの組み合わせがレジストラと一致しているかで確認します。
  • プライベートゾーンは VPC の DNS 解決と DNS ホスト名を有効にし、パブリックと同じ名前を使う場合の挙動を理解しておきます。
  • サブドメインの委任は親ゾーンに NS レコードを置くだけで、レジストラの変更は不要です。Terraform なら子ゾーンの値を参照して自動で登録できます。
  • 作成後は dig で、ゾーンが実際に使われているかを種類ごとに確かめます。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲