- AWS
Route53とは|料金・ホストゾーン・Aliasをモックとdigで確認
結論
Amazon Route 53 は AWS の DNS サービスで、「ドメインの登録」「DNS ルーティング(ホストゾーンに置いたレコードで名前を IP アドレスなどに変える)」「ヘルスチェック」の3つの機能を、組み合わせて使えます。料金はホストゾーン1つにつき月0.50ドル、標準の問い合わせ100万件ごとに0.40ドルからで、AWS のリソースを指す Alias レコードへの問い合わせは無料です(2026年10月29日時点)。
この記事でわかること
- 料金・ホストゾーン・Alias・ルーティングポリシー8種類の要点と選び方
- AWS に接続せず moto で動かした CLI・boto3 の出力と、エラーの原文
- dnsmasq と dig で測った「変更が反映されない」時間(TTL・ネガティブキャッシュ)
ブラウザが www.example.com を開くとき、最初に「この名前の IP アドレスは何か」を DNS に問い合わせます。Route 53 は、その問い合わせに最終的な答えを返す側(権威 DNS サーバー)を AWS が運用してくれるサービスです。
flowchart TD
B[ブラウザ] --> R[リゾルバー<br>答えをキャッシュ]
R -->|1 名前を聞く| P[.com の<br>ネームサーバー]
P -->|2 担当は awsdns-xx| R
R -->|3 もう一度聞く| Z[Route 53<br>ホストゾーン]
Z -->|4 A の値| R
R -->|5 TTL の間は再利用| B
よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| Route 53とは | AWS の DNS サービス。ドメイン登録・DNS ルーティング・ヘルスチェックの3機能 | Route 53とは |
| route53 料金 | ゾーン月0.50ドル、標準クエリ100万件0.40ドル、AWS 宛ての Alias は無料 | Route 53の料金 |
| ホストゾーンとは | 1つのドメインのレコードを入れる入れ物。作ると NS と SOA が自動でできる | ホストゾーンとは |
| Alias と CNAME の違い | Alias はドメインの頂点(example.com)に置け、dig では A に見える | Aliasレコードとは |
| ルーティングポリシーの種類 | シンプル・加重・フェイルオーバー・レイテンシーなど公式で8種類 | ルーティングポリシー |
| 他社で取ったドメインを使う | ホストゾーンを作り、レジストラのネームサーバーを4つの awsdns に変える | 他社のドメインを使う手順 |
| 変更が反映されない | Route 53 側はすぐ変わる。キャッシュは TTL が切れるまで以前の値を返す | 反映されない理由 |
| InvalidChangeBatch が出た | 重複の作成・頂点の CNAME・削除の値違いが多い | よくあるエラー |
| AWS に接続せずに試したい | moto で Route 53 の API をモックし、CLI と boto3 を向ける | boto3とmotoでテスト |
確認環境:Ubuntu 24.04.5 LTS の上で、Python 3.13.18 の venv(作業用のフォルダー)に moto 5.2.5(server 版)・boto3 1.43.121・AWS CLI 1.46.2(pip 版)・pytest 9.2.0 を入れ、moto のサーバーを 127.0.0.1 のポートに起動して、AWS CLI と boto3 をそこへ向けました。AWS には一度も接続していません。認証情報は環境変数のダミーの値(testing)だけで、~/.aws の設定も読ませていません。dig の確認は、ip netns で作った専用のネットワーク空間の中で dnsmasq 2.91 を動かし、moto に作ったゾーンの中身を変換して読み込ませ、BIND 9.18.39 の dig で問い合わせました。dnsmasq は Route 53 そのものではなく、ゾーンの中身と DNS の動き(TTL・キャッシュ)を確かめるための代わりです。料金・ルーティングポリシー・ヘルスチェックの判定条件・クォータ・他社ドメインの移行手順は、AWS の公式ドキュメント・料金ページ・API リファレンスと AWS re:Post のナレッジセンターで確かめました。図は mermaid 11.16.0 で描画を確かめています(確認日 2026年10月29日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Route 53とは|料金・ホストゾーン・Aliasをモックとdigで確認」
Route 53とは(AWSのDNSサービスと3つの機能)
この節では、Route 53 が何をするサービスで、DNS のどの役割を受け持つのかが分かります。
Amazon Route 53 は、可用性と拡張性に優れた DNS(ドメインネームシステム)のウェブサービスです。公式ドキュメントは、主な機能を「ドメイン登録」「DNS ルーティング」「ヘルスチェック」の3つとし、どれか1つだけでも、組み合わせても使えると説明しています。DNS の問い合わせは通常 53 番ポートを使い、サービス名の「53」はこの番号と同じ数字です。
1ドメインの登録
example.com のような名前を Route 53 で買って更新する。料金はトップレベルドメイン(.com・.jp など)ごとに年単位。
2DNS ルーティング
ホストゾーンにレコードを置き、www.example.com などへの問い合わせに IP アドレスや別名で答える。いちばんよく使う機能。
3ヘルスチェック
Web サーバーなどにインターネット経由で定期的にリクエストを送り、異常なら通知したり、DNS の答えから外したりする。
権威 DNS とリゾルバーの違い
DNS には、答えを持っている「権威 DNS サーバー」と、利用者の代わりに聞いて回り、答えを一定時間覚えておく「リゾルバー(キャッシュ DNS サーバー)」があります。Route 53 のホストゾーンは権威 DNS サーバーの役です。家庭の回線や会社のネットワーク、パブリック DNS は、リゾルバーの役です。冒頭の図の 5 のとおり、リゾルバーは答えを TTL(生存時間)の秒数だけ覚えるため、Route 53 でレコードを変えても、利用者に届くまで時間差が出ます。この時間差は後の節で実測しています。
DNS ルーティング以外の機能
公式ドキュメントでは、次の機能も Route 53 の一部として紹介されています。どれも AWS の中のネットワーク(VPC)や大きな構成で使うもので、ドメインを AWS で使い始める段階では、ホストゾーンとレコードを先に覚えれば困りません。
- VPC リゾルバー:VPC の中の名前解決。条件付き転送のルールで、社内(オンプレミス)の DNS とつなげる。
- リゾルバー DNS ファイアウォール:VPC から外へ出る DNS の問い合わせを、ドメインのリストで絞る。
- トラフィックフロー:位置・レイテンシー・正常性などを組み合わせたルーティングを、図のような形で作る。
- Route 53 プロファイル:DNS の設定を、複数の VPC やアカウントにまとめて当てる。
AWS 全体の主要サービスの位置づけは、関連記事「AWSとは|初心者向けに主要サービス・料金・始め方を解説」で扱っています。
Route 53の料金(2026年10月29日時点)
この節では、Route 53 の料金の内訳と、よくある使い方で月にいくらになるかが分かります。
Route 53 の料金は「ホストゾーンの月額」と「問い合わせ(クエリ)の件数」が中心で、ヘルスチェックやドメイン登録は使った分だけ加わります。次の値は、AWS の料金ページ(日本語)で 2026年10月29日時点に確かめたものです。税は含みません。
| 項目 | 料金(標準リージョン) | 補足 |
|---|---|---|
| ホストゾーン | 0.50ドル/月(26ゾーン目から0.10ドル) | 日割りなし。作成から12時間以内に消したゾーンは課金されない |
| レコード | 1ゾーン10,000件まで追加料金なし | 超えた分は1件0.0015ドル/月 |
| 標準クエリ | 100万件0.40ドル(10億件超は0.20ドル) | 存在しない名前(NXDOMAIN)への問い合わせも対象 |
| レイテンシーベースのクエリ | 100万件0.60ドル(10億件超は0.30ドル) | レイテンシールーティングのレコード |
| 位置情報・地理的近接性のクエリ | 100万件0.70ドル(10億件超は0.35ドル) | IP ベースは0.80ドル(超過分0.40ドル) |
| Alias のクエリ | 無料 | ELB・CloudFront・S3 ウェブサイトエンドポイント・API Gateway など AWS リソースを指す A/AAAA |
| プライベートホストゾーンへのクエリ | 無料 | ゾーンの月額はかかる |
| トラフィックフロー | ポリシーレコード1つ50.00ドル/月 | ドメインに関連付けていないポリシーは無料 |
ヘルスチェックの料金
| 項目 | AWS のエンドポイント | AWS 以外のエンドポイント |
|---|---|---|
| 基本(1件/月) | 0.50ドル | 0.75ドル |
| オプション(HTTPS・文字列一致・高速間隔・レイテンシー測定。1機能ごと) | 1.00ドル | 2.00ドル |
| 無料の範囲 | 同じアカウントの AWS エンドポイント宛てで50件まで | なし |
よくある使い方での月額の試算
料金ページの単価で計算しました。ドメイン登録料と税は含みません。
| 使い方 | 内訳 | 月額 |
|---|---|---|
| 個人のサイト(1ゾーン・月50万件) | 0.50+0.40×0.5 | 約0.70ドル |
| 小さなサービス(3ゾーン・月1,000万件のうち800万件が ALB・CloudFront 宛ての Alias) | 0.50×3+0.40×2(Alias 分は0) | 約2.30ドル |
| フェイルオーバー(1ゾーン・月500万件・AWS 以外のサーバーに HTTPS+文字列一致のヘルスチェック1件) | 0.50+0.40×5+0.75+2.00×2 | 約7.25ドル |
- ホストゾーンは作った月に1か月分がかかります(日割りなし)。試しに作るなら、12時間以内に消すと課金されません。ただし、その間に来たクエリは課金されます。
- ドメイン登録の料金はトップレベルドメインごとに違い、年単位です。公式の「開始方法」には、年会費はドメインによって9ドルから数百ドルまで幅があり、返金されないと書かれています。最新の額は料金ページの TLD 別の表で確かめます。
- 料金ページに、Route 53 全体の「無料利用枠」の記載はありません。無料と明記されているのは、AWS リソース宛ての Alias のクエリ、条件つきのヘルスチェック50件、12時間以内に消したゾーンなどです。
- DNSSEC の署名は Route 53 では無料ですが、鍵を置く AWS KMS の料金がかかります。
ホストゾーンとは(パブリックとプライベートの違い)
この節では、ホストゾーンの意味と、作ったときに自動でできる NS・SOA レコードの中身が、moto で作った実物で分かります。
ホストゾーンは、1つのドメイン(example.com など)とそのサブドメインのレコードを入れておく入れ物です。API リファレンスは「パブリックホストゾーンでは、Route 53 が SOA レコード1つと NS レコード4つを自動で作る」としています。moto に作らせた結果も同じ形でした。
$ aws $E route53 create-hosted-zone --name example.com \
--caller-reference demo-2026-10-29-1 --hosted-zone-config Comment="RJC demo"
{
"Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/SI54EGLRYR37XECF1M653N",
"HostedZone": {
"Id": "/hostedzone/SI54EGLRYR37XECF1M653N",
"Name": "example.com.",
"CallerReference": "demo-2026-10-29-1",
"Config": {
"Comment": "RJC demo",
"PrivateZone": false
},
"ResourceRecordSetCount": 2
},
"ChangeInfo": {
"Id": "/change/C1PA6795UKMFR9",
"Status": "INSYNC",
"SubmittedAt": "2026-10-29T18:07:50.645110Z"
},
"DelegationSet": {
"NameServers": [
"ns-2048.awsdns-64.com",
"ns-2049.awsdns-65.net",
"ns-2050.awsdns-66.org",
"ns-2051.awsdns-67.co.uk"
]
}
}
$E は --endpoint-url http://127.0.0.1:45841(手元の moto)を入れたシェル変数です。DelegationSet.NameServers の4つが、このゾーンを担当するネームサーバーです。他社のレジストラで取ったドメインを Route 53 で使うときは、この4つをレジストラに登録します。本物の Route 53 では、ゾーンごとに違う4つが割り当てられます(上の名前は公式ドキュメントの例と同じで、レジストラに登録してはいけない例として書かれているものです)。
$ aws $E route53 list-resource-record-sets --hosted-zone-id $ZID \
--query 'ResourceRecordSets[].[Name,Type,TTL]' --output text
example.com. NS 172800
example.com. SOA 900
SOA レコードの値の意味は、公式ドキュメントの例で次のとおりです。
| 順 | 値(公式の例) | 意味 |
|---|---|---|
| 1 | ns-2048.awsdns-64.net. | SOA を作った Route 53 のネームサーバー |
| 2 | hostmaster.example.com. | 管理者のメールアドレス(@ をピリオドに置き換えた形) |
| 3 | 1 | シリアル番号。Route 53 は自動では増やさない |
| 4・5・6 | 7200・900・1209600 | セカンダリ DNS 向けの更新・再試行・有効期限(秒) |
| 7 | 86400 | 否定応答(名前が無い)をキャッシュする時間の上限の1つ |
SOA レコード自身の TTL の既定値は900秒です。名前が無いという答え(NXDOMAIN)がキャッシュされる時間は、SOA の最後の値と SOA の TTL の小さいほうで、既定では900秒(15分)です。後の節で、この「無い」という答えが残る様子を実測しています。
パブリックホストゾーンとプライベートホストゾーン
パブリックホストゾーン
インターネットからの問い合わせに答える
Web サイト・メール・API の公開名に使う
NS 4つと SOA が自動でできる。クエリは課金
プライベートホストゾーン
関連付けた VPC の中からの問い合わせだけに答える
db.internal.example.com など社内向けの名前に使う
作成時に VPC を1つ指定する。クエリは無料
moto で VPC を作り、プライベートホストゾーンを作った結果です。
$ VPC=$(aws $E ec2 create-vpc --cidr-block 10.0.0.0/16 --region ap-northeast-1 \
--query Vpc.VpcId --output text)
$ aws $E route53 create-hosted-zone --name internal.example.com --caller-reference priv-1 \
--vpc VPCRegion=ap-northeast-1,VPCId=$VPC --hosted-zone-config PrivateZone=true \
--query '[HostedZone.[Name,Config.PrivateZone],VPC]'
[
["internal.example.com.", true],
{"VPCRegion": "ap-northeast-1", "VPCId": "vpc-cf8796040e37ed2fc"}
]
$ aws $E route53 list-hosted-zones \
--query 'HostedZones[].[Name,Config.PrivateZone,ResourceRecordSetCount]' --output text
example.com. False 21
internal.example.com. True 2
- 公式ドキュメントによると、プライベートホストゾーンには予約済みのネームサーバー(ns-0.awsdns-00.com など4つ)が割り当てられ、インターネットからそのネームサーバーに直接聞いても、プライベートの情報は返りません。
- VPC の外からプライベートホストゾーンの名前を問い合わせると、インターネットで普通に名前解決されます(公式)。同じ名前のパブリックゾーンがあれば、そちらの答えになります。
CallerReferenceは「同じ作成を2回実行しないための一意の文字列」で、毎回違う値を渡します(API リファレンス)。日時を入れるのが簡単です。
レコードの種類とAlias(エイリアス)レコード・CNAMEの違い
この節では、Route 53 で作れるレコードの種類と、Route 53 独自の Alias レコードが CNAME とどう違うのかが、dig の答えの違いで分かります。
Route 53 の公式ドキュメントが挙げるレコードタイプは17種類です。よく使うものを表にしました。
| タイプ | 何を返すか | よくある使い方 |
|---|---|---|
| A / AAAA | IPv4 / IPv6 アドレス | Web サーバー・API の名前 |
| CNAME | 別の名前 | www を別のホスト名へ向ける。頂点には置けない |
| MX | メールサーバーの名前と優先度 | メールの受信先 |
| TXT | 文字列 | SPF・DMARC・ドメインの所有確認 |
| NS / SOA | 担当ネームサーバー / ゾーンの管理情報 | 自動で作られる。サブドメインの委任にも NS を使う |
| CAA | 証明書を発行してよい認証局 | 証明書の発行元を絞る |
| その他 | DS・HTTPS・NAPTR・PTR・SPF・SRV・SSHFP・SVCB・TLSA | SPF タイプは非推奨で、TXT を使う(公式) |
A・CNAME・MX・TXT の役割を dig の出力で比べる内容は、関連記事「DNSレコードの種類一覧|digの実出力で役割と設定ミスを確認」で扱っています。
Alias レコードとは
Alias レコードは、Route 53 が DNS に独自に足した仕組みで、A や AAAA のレコードの値として「AWS のリソース(ALB・CloudFront など)や同じゾーンの別のレコード」を指定できます。公式の比較の要点です。
| 比べる点 | Alias レコード | CNAME レコード |
|---|---|---|
| ドメインの頂点(example.com) | 置ける | 置けない |
| 指せる相手 | 選ばれた AWS リソースと、同じゾーンのレコード | どんな DNS 名でも |
| クエリの料金 | AWS リソース宛ては無料 | 課金。同じゾーンのレコードを指すと2クエリ分 |
| TTL | 設定できない(相手の TTL を使う) | 自分で決める |
| dig での見え方 | A(や AAAA)として見える | CNAME として見え、続けて相手の A が返る |
moto に ALB と CloudFront を指す Alias を作りました。HostedZoneId は自分のゾーンの ID ではなく、指す相手の種類とリージョンで決まる ID です。東京リージョンの ALB は Z14GRHDCWA56QT(AWS General Reference の ELB の表)、CloudFront は常に Z2FDTNDATAQYW2(API リファレンス)です。
{"Changes":[
{"Action":"CREATE","ResourceRecordSet":{"Name":"app.example.com.","Type":"A",
"AliasTarget":{"HostedZoneId":"Z14GRHDCWA56QT",
"DNSName":"my-alb-1234567890.ap-northeast-1.elb.amazonaws.com.","EvaluateTargetHealth":true}}},
{"Action":"CREATE","ResourceRecordSet":{"Name":"cdn.example.com.","Type":"A",
"AliasTarget":{"HostedZoneId":"Z2FDTNDATAQYW2",
"DNSName":"d111111abcdef8.cloudfront.net.","EvaluateTargetHealth":false}}}
]}
このゾーンを dnsmasq に再現して dig で引くと、CNAME の www と Alias 相当の app で、答えの形がはっきり違いました(Alias の先の IP は、ALB が返す値の代わりに文書用のアドレスを入れています)。
$ dig @127.0.0.1 www.example.com A +noall +answer
www.example.com. 300 IN CNAME example.com.
example.com. 300 IN A 192.0.2.10
$ dig @127.0.0.1 app.example.com A +noall +answer
app.example.com. 300 IN A 203.0.113.11
app.example.com. 300 IN A 203.0.113.12
example.com(頂点)を ALB に向けたいとき
CNAME が使えるのは www などのサブドメインだけ
EvaluateTargetHealthを true にすると、Alias は指している ALB などの正常性を引き継ぎます。CloudFront を指す Alias では true にできません(API リファレンス)。- CloudFront を指す Alias は、プライベートホストゾーンには作れません(API リファレンス)。
Route 53のルーティングポリシー8種類と選び方
この節では、Route 53 のルーティングポリシーの種類と、それぞれをどんなときに使うかが分かります。
ルーティングポリシーは、同じ名前への問い合わせに「どの答えを返すか」を決める規則です。以前は7種類と紹介されることが多かったのですが、2026年10月29日時点の公式ドキュメントには IP ベースを含めて8種類が載っています。
| ポリシー | 使う場面 | 設定の要点 |
|---|---|---|
| シンプル | 1つのリソースに向けるだけ | 既定。値を複数書くと全部をまとめて返す |
| 加重(Weighted) | 新しい版に1割だけ流すなど、比率で分ける | Weight は0〜255。全部0なら均等 |
| フェイルオーバー | 正常なら本番、異常なら待機系へ | PRIMARY にヘルスチェックを付ける |
| レイテンシー | 複数リージョンのうち、遅延の小さいほうへ | Region を指定。クエリ単価が上がる |
| 位置情報(Geolocation) | 利用者の国・大陸で答えを変える | どこにも当たらない人向けに既定(*)を作る |
| 地理的近接性 | リソースの位置で分け、バイアスで範囲を動かす | トラフィックフローで作る |
| IP ベース | 送信元の IP アドレスの範囲で答えを変える | CIDR のコレクションを作って使う |
| 複数値回答 | 正常なものだけを複数返す | 正常なレコードを最大8つ返す |
シンプル以外のポリシーでは、同じ名前・同じタイプのレコードを並べ、それぞれに違う SetIdentifier を付けます(API リファレンス)。moto に加重・フェイルオーバー・位置情報・レイテンシー・複数値回答を作り、一覧を取った結果です。
$ aws $E route53 list-resource-record-sets --hosted-zone-id $ZID --query \
'ResourceRecordSets[].[Name,Type,SetIdentifier||`-`,TTL||`-`,join(`,`,ResourceRecords[].Value||[AliasTarget.DNSName])]' \
--output text
example.com. A - 300 192.0.2.10
api.example.com. A primary-tokyo 60 192.0.2.50
api.example.com. A secondary-osaka 60 198.51.100.50
app.example.com. A - - my-alb-1234567890.ap-northeast-1.elb.amazonaws.com.
canary.example.com. A v1 60 192.0.2.71
canary.example.com. A v2 60 192.0.2.72
cdn.example.com. A - - d111111abcdef8.cloudfront.net.
geo.example.com. A jp 60 192.0.2.81
geo.example.com. A default 60 192.0.2.82
lat.example.com. A tokyo 60 192.0.2.91
lat.example.com. A virginia 60 192.0.2.92
mv.example.com. A mv1 60 192.0.2.101
mv.example.com. A mv2 60 192.0.2.102
(ほかの行は省略)
加重の2行は、作るときに次のように書いています。v1 に9割、v2 に1割の答えを返す設定です。
{"Action":"CREATE","ResourceRecordSet":{"Name":"canary.example.com.","Type":"A",
"SetIdentifier":"v1","Weight":90,"TTL":60,"ResourceRecords":[{"Value":"192.0.2.71"}]}},
{"Action":"CREATE","ResourceRecordSet":{"Name":"canary.example.com.","Type":"A",
"SetIdentifier":"v2","Weight":10,"TTL":60,"ResourceRecords":[{"Value":"192.0.2.72"}]}}
- Alias の列が「-」の行は TTL を持ちません。一覧でも TTL が出ないことで Alias と見分けられます。
- 加重の比率は「DNS の答えの比率」です。リゾルバーは答えを TTL の間使い回すため、利用者の数の比率がぴったり9対1になるとは限りません。
- Weight を0にしたレコードは答えに使われません。ただし、同じ名前とタイプの全部を0にすると、すべてに同じ確率で振り分けます(API リファレンス)。
- 位置情報では、どの国にも当たらない問い合わせのために
CountryCodeが*の既定のレコードを作っておきます。無いと、当たらない利用者には答えが返りません。 - 手元の dnsmasq はポリシーを再現できないため、dig の確認では名前ごとに1つ目の値だけを載せました。
ヘルスチェックとDNSフェイルオーバー
この節では、Route 53 のヘルスチェックが何をもって「正常」と判定するのかと、フェイルオーバーのレコードの作り方が分かります。
ヘルスチェックには「エンドポイントを監視する」「他のヘルスチェックの結果をまとめる(算出)」「CloudWatch アラームを監視する」の3種類があります。エンドポイントの判定条件は、公式ドキュメントで次のとおりでした。
| 項目 | 条件(公式) |
|---|---|
| HTTP / HTTPS | TCP 接続を4秒以内に確立し、その後2秒以内に 2xx か 3xx を返す |
| TCP | TCP 接続を10秒以内に確立する |
| 文字列一致 | さらに2秒以内に本文を受け取り、最初の5,120バイトに検索文字列がある |
| 間隔 | 10秒か30秒(RequestInterval) |
| 全体の判定 | 18%を超えるチェッカーが正常と報告すれば正常 |
| 証明書 | HTTPS のチェックは証明書を検証しない(期限切れでも不合格にならない) |
moto でヘルスチェックを作り、フェイルオーバーの PRIMARY に付けました。
$ aws $E route53 create-health-check --caller-reference hc-primary-1 \
--health-check-config '{"Type":"HTTPS","FullyQualifiedDomainName":"primary.example.com",
"Port":443,"ResourcePath":"/health","RequestInterval":30,"FailureThreshold":3}'
{
"HealthCheck": {
"Id": "76f569a8-9539-4d8b-a7cc-add7bf3d86c6",
"CallerReference": "hc-primary-1",
"HealthCheckConfig": {
"Port": 443,
"Type": "HTTPS",
"ResourcePath": "/health",
"FullyQualifiedDomainName": "primary.example.com",
"RequestInterval": 30,
"FailureThreshold": 3,
"MeasureLatency": false,
"Inverted": false,
"Disabled": false,
"EnableSNI": false
},
"HealthCheckVersion": 1
}
}
{"Action":"CREATE","ResourceRecordSet":{"Name":"api.example.com.","Type":"A",
"SetIdentifier":"primary-tokyo","Failover":"PRIMARY","TTL":60,
"HealthCheckId":"76f569a8-9539-4d8b-a7cc-add7bf3d86c6",
"ResourceRecords":[{"Value":"192.0.2.50"}]}},
{"Action":"CREATE","ResourceRecordSet":{"Name":"api.example.com.","Type":"A",
"SetIdentifier":"secondary-osaka","Failover":"SECONDARY","TTL":60,
"ResourceRecords":[{"Value":"198.51.100.50"}]}}
moto の get-health-check-status は、実際にはどこにも通信せず、常に「Success: HTTP Status Code: 200.」を返しました。異常のときに本当に切り替わるかは、モックでは確かめられません。本番で切り替えの訓練をするときは、待機系に向けた TTL の短さと、切り替わるまでの時間(間隔×失敗しきい値+TTL)を見込みます。
- 1ヘルスチェックの URL は「アプリが本当に動いているか」を返すトップページではなく /health のように DB などの依存先も確かめる URL にする
- 2サーバー側でチェッカーの IP を止めていないファイアウォールや WAF で断ると、正常でも異常と判定される
- 3レコードの TTL を短くしているTTL が長いと、切り替えてもキャッシュの間は以前の答えが使われる
- 4証明書の期限は別に監視するHTTPS のヘルスチェックは証明書を検証しない(公式)
AWS CLIでホストゾーンとレコードを作る(motoで実行)
この節では、AWS に接続せずに、AWS CLI で Route 53 のホストゾーンとレコードを作る手順と、その出力が分かります。
moto は AWS の API を手元で真似するライブラリで、サーバーとして起動すると、AWS CLI や SDK の接続先を --endpoint-url で向けられます。認証情報はダミーの値にし、手元の設定ファイルも読ませないようにしました。
python3 -m venv venv && ./venv/bin/pip install 'moto[server]' boto3 awscli
export AWS_ACCESS_KEY_ID=testing AWS_SECRET_ACCESS_KEY=testing AWS_DEFAULT_REGION=us-east-1
export AWS_CONFIG_FILE=$PWD/aws_config AWS_SHARED_CREDENTIALS_FILE=$PWD/aws_creds # 空のファイル
./venv/bin/moto_server -H 127.0.0.1 -p 45841 &
E="--endpoint-url http://127.0.0.1:45841"
レコードは change-resource-record-sets に「変更のまとまり(Change Batch)」の JSON を渡して作ります。A・CNAME・MX・TXT を一度に作りました。
{
"Comment": "first records",
"Changes": [
{"Action": "CREATE", "ResourceRecordSet": {"Name": "example.com.", "Type": "A", "TTL": 300,
"ResourceRecords": [{"Value": "192.0.2.10"}]}},
{"Action": "CREATE", "ResourceRecordSet": {"Name": "www.example.com.", "Type": "CNAME", "TTL": 300,
"ResourceRecords": [{"Value": "example.com"}]}},
{"Action": "CREATE", "ResourceRecordSet": {"Name": "example.com.", "Type": "MX", "TTL": 3600,
"ResourceRecords": [{"Value": "10 mail.example.com"}]}},
{"Action": "CREATE", "ResourceRecordSet": {"Name": "mail.example.com.", "Type": "A", "TTL": 300,
"ResourceRecords": [{"Value": "192.0.2.25"}]}},
{"Action": "CREATE", "ResourceRecordSet": {"Name": "example.com.", "Type": "TXT", "TTL": 300,
"ResourceRecords": [{"Value": "\"v=spf1 ip4:192.0.2.25 -all\""}]}}
]
}
$ aws $E route53 change-resource-record-sets --hosted-zone-id $ZID --change-batch file://batch1.json
{
"ChangeInfo": {
"Id": "/change/C2682N5HXP0BZ4",
"Status": "INSYNC",
"SubmittedAt": "2026-10-29T18:08:09.005367Z"
}
}
$ aws $E route53 list-resource-record-sets --hosted-zone-id $ZID \
--query 'ResourceRecordSets[].[Name,Type,TTL,join(`,`,ResourceRecords[].Value)]' --output text
example.com. A 300 192.0.2.10
example.com. MX 3600 10 mail.example.com
example.com. NS 172800 ns-2048.awsdns-64.com,ns-2049.awsdns-65.net,ns-2050.awsdns-66.org,ns-2051.awsdns-67.co.uk
example.com. TXT 300 "v=spf1 ip4:192.0.2.25 -all"
mail.example.com. A 300 192.0.2.25
www.example.com. CNAME 300 example.com
(SOA の行は省略)
CREATE・UPSERT・DELETE の違い
| Action | 動き(API リファレンス) | 手元の結果 |
|---|---|---|
| CREATE | 新しく作る。すでにあればエラー | 2回目は InvalidChangeBatch |
| UPSERT | 無ければ作り、あれば値を置き換える | 同じ内容を2回送っても成功 |
| DELETE | 作ったときと同じ値をすべて指定して消す | 値が1つでも違うとエラー |
$ aws $E route53 change-resource-record-sets --hosted-zone-id $ZID --change-batch \
'{"Changes":[{"Action":"UPSERT","ResourceRecordSet":{"Name":"mail.example.com.","Type":"A",
"TTL":60,"ResourceRecords":[{"Value":"192.0.2.26"}]}}]}' --query ChangeInfo.Status
"INSYNC"
$ aws $E route53 list-resource-record-sets --hosted-zone-id $ZID \
--start-record-name mail.example.com --start-record-type A --max-items 1
{
"ResourceRecordSets": [
{"Name": "mail.example.com.", "Type": "A", "TTL": 60,
"ResourceRecords": [{"Value": "192.0.2.26"}]}
],
"IsTruncated": true,
"NextRecordName": "www.example.com.",
"NextRecordType": "CNAME",
"MaxItems": "1"
}
1つの Change Batch は「全部成功か、全部取り消し」
API リファレンスは、1つの Change Batch の中の変更は、すべての検証に通ったときだけまとめて適用され、1つでも失敗すると全体が取り消される、としています。新しいレコード1つと、すでにあるレコードの CREATE を同じ JSON に入れて試しました。
$ aws $E route53 change-resource-record-sets --hosted-zone-id $ZID --change-batch file://atomic.json
An error occurred (InvalidChangeBatch) when calling the ChangeResourceRecordSets operation: Tried to create resource record set [name='example.com.', type='A'] but it already exists
$ aws $E route53 list-resource-record-sets --hosted-zone-id $ZID \
--query "ResourceRecordSets[?Name=='new1.example.com.']"
[]
正しいほうの new1.example.com も作られていませんでした。関係のある変更(前の名前の削除と新しい名前の作成など)は1つの Change Batch にまとめると、途中で止まった状態が残りません。
反映を待つ:get-change と wait
本物の Route 53 では、変更の直後は PENDING で、全部のネームサーバーに行き渡ると INSYNC になります。公式は、通常60秒以内に行き渡ると説明しています。スクリプトでは待ってから次へ進みます。
aws route53 get-change --id /change/C2682N5HXP0BZ4 --query ChangeInfo.Status
aws route53 wait resource-record-sets-changed --id /change/C2682N5HXP0BZ4 # INSYNC まで待つ
moto はどちらもすぐに INSYNC を返し、wait も即座に終了コード0で終わりました。ALB を作ってから Alias で向けるまでの一連の CLI 操作は、関連記事「ALBをAWS CLIで作成|ターゲットグループ・リスナー・ルール設定」で、レコード操作のコマンドをさらに細かく並べた内容は、関連記事「Route 53レコードをAWS CLIで作成|A・CNAME・エイリアス例」で扱っています。
boto3とmotoでRoute 53の操作をテストする
この節では、Route 53 を操作する Python のコードを、AWS に接続せずに自動テストする方法が分かります。
moto の mock_aws() の中で作った boto3 のクライアントは、AWS ではなく moto の中の偽の Route 53 に話しかけます。デプロイのスクリプトや、DNS のレコードを書き換えるバッチを、本物のゾーンに触れずに確かめられます。テストしたコードです。
import boto3
def find_zone_id(r53, domain):
"""ドメイン名から公開ホストゾーンの ID を探す"""
name = domain.rstrip(".") + "."
res = r53.list_hosted_zones_by_name(DNSName=name, MaxItems="1")
for z in res["HostedZones"]:
if z["Name"] == name and not z["Config"]["PrivateZone"]:
return z["Id"].split("/")[-1]
raise LookupError(f"hosted zone not found: {name}")
def upsert_a(r53, domain, host, ip, ttl=300):
"""A レコードを作成または更新し、変更 ID を返す"""
zone_id = find_zone_id(r53, domain)
res = r53.change_resource_record_sets(
HostedZoneId=zone_id,
ChangeBatch={"Comment": f"upsert {host}", "Changes": [{
"Action": "UPSERT",
"ResourceRecordSet": {"Name": f"{host}.{domain}.", "Type": "A", "TTL": ttl,
"ResourceRecords": [{"Value": ip}]}}]})
return res["ChangeInfo"]["Id"]
import boto3, pytest
from botocore.exceptions import ClientError
from moto import mock_aws
from dns_ops import find_zone_id, upsert_a
@pytest.fixture
def r53():
with mock_aws(): # AWS には接続しない
c = boto3.client("route53", region_name="us-east-1")
c.create_hosted_zone(Name="example.com", CallerReference="t1")
yield c
def records(c, zid):
return {(r["Name"], r["Type"]): r for r in
c.list_resource_record_sets(HostedZoneId=zid)["ResourceRecordSets"]}
def test_upsert_creates_then_updates(r53):
upsert_a(r53, "example.com", "www", "192.0.2.10")
upsert_a(r53, "example.com", "www", "192.0.2.20", ttl=60)
rr = records(r53, find_zone_id(r53, "example.com"))[("www.example.com.", "A")]
assert rr["ResourceRecords"] == [{"Value": "192.0.2.20"}]
assert rr["TTL"] == 60
def test_zone_has_ns_and_soa(r53):
keys = records(r53, find_zone_id(r53, "example.com")).keys()
assert ("example.com.", "NS") in keys and ("example.com.", "SOA") in keys
def test_unknown_zone(r53):
with pytest.raises(LookupError):
find_zone_id(r53, "example.org")
def test_create_twice_is_error(r53):
zid = find_zone_id(r53, "example.com")
ch = {"Changes": [{"Action": "CREATE", "ResourceRecordSet": {
"Name": "api.example.com.", "Type": "A", "TTL": 300,
"ResourceRecords": [{"Value": "192.0.2.30"}]}}]}
r53.change_resource_record_sets(HostedZoneId=zid, ChangeBatch=ch)
with pytest.raises(ClientError) as e:
r53.change_resource_record_sets(HostedZoneId=zid, ChangeBatch=ch)
assert e.value.response["Error"]["Code"] == "InvalidChangeBatch"
print(e.value.response["Error"]["Message"])
$ python -m pytest -q -s
...Tried to create resource record set [name='api.example.com.', type='A'] but it already exists
.
4 passed in 0.61s
- Route 53 はグローバルなサービスで、boto3 のクライアントは
us-east-1で作ります。Route 53 の ID は/hostedzone/の付いた形で返るため、他の API に渡す前にそろえます(上のsplit("/"))。 - テストでは、ダミーの認証情報を環境変数で与えておきます。
mock_aws()の外で同じクライアントを使うと、本物の AWS へ送られるため、作る場所を fixture の中に閉じ込めています。 - エラーのコードは
e.response["Error"]["Code"]で取ります。
digでRoute 53のレコードを確かめる(dnsmasqでゾーンを再現)
この節では、dig の答えのどこを見れば、Route 53 に置いたレコードが正しく返っているか判断できるのかが分かります。
moto は DNS の問い合わせには答えないため、moto に作ったゾーンの中身を list-resource-record-sets で取り出し、dnsmasq の設定に変換して、自分用のネットワーク空間(ip netns)の中で権威 DNS として動かしました。変換の中心部分です。
for r in json.load(open(sys.argv[1]))["ResourceRecordSets"]:
name, typ = r["Name"].rstrip("."), r["Type"]
vals = [v["Value"] for v in r.get("ResourceRecords", [])]
if "AliasTarget" in r: # Alias は A として答える
vals = ALIAS_IP[r["AliasTarget"]["DNSName"]]
if typ == "A":
for v in vals: out.append(f"host-record={name},{v}")
elif typ == "CNAME":
out.append(f"cname={name},{vals[0].rstrip('.')}")
elif typ == "MX":
pref, host = vals[0].split(); out.append(f"mx-host={name},{host},{pref}")
elif typ == "TXT":
out.append("txt-record=%s,%s" % (name, vals[0]))
$ ip netns add t84dns && ip -n t84dns link set lo up
$ ip netns exec t84dns dnsmasq --conf-file=dnsmasq.conf --listen-address=127.0.0.1 --bind-interfaces ...
$ ip netns exec t84dns dig @127.0.0.1 example.com A +norec
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2079
;; flags: qr aa; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; QUESTION SECTION:
;example.com. IN A
;; ANSWER SECTION:
example.com. 300 IN A 192.0.2.10
;; AUTHORITY SECTION:
example.com. 300 IN NS ns1.example.com.
;; Query time: 4 msec
;; SERVER: 127.0.0.1#53(127.0.0.1) (UDP)
flags の aa(Authoritative Answer)は、ゾーンを持っているサーバー自身の答えという印です。Route 53 のネームサーバーに直接聞いた答えには aa が付き、リゾルバー経由の答えには付きません。本番で確かめるときも、同じ形で dig @ns-xxxx.awsdns-xx.com example.com A のように担当のネームサーバーを指定すると、キャッシュを通らない今の値が分かります。
$ dig @127.0.0.1 example.com MX +noall +answer
example.com. 300 IN MX 10 mail.example.com.
$ dig @127.0.0.1 example.com TXT +noall +answer
example.com. 300 IN TXT "v=spf1 ip4:192.0.2.25 -all"
$ dig @127.0.0.1 nothing.example.com A +norec
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 35030
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; AUTHORITY SECTION:
example.com. 300 IN SOA ns1.example.com. hostmaster.ns1.example.com. 1793297522 1200 180 1209600 300
$ dig @127.0.0.1 example.com AAAA +norec
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62920
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
$ dig @127.0.0.1 www.example.org A +norec
;; ->>HEADER<<- opcode: QUERY, status: REFUSED, id: 44967
| dig の status | 意味 | Route 53 で考えること |
|---|---|---|
| NOERROR(答えあり) | 名前もタイプもある | 値が正しいかを見る |
| NOERROR(ANSWER: 0) | 名前はあるが、そのタイプが無い(NODATA) | A はあるが AAAA が無いなど。タイプを確かめる |
| NXDOMAIN | 名前そのものが無い | 綴り・末尾のドット・別のホストゾーンに作っていないか |
| REFUSED | そのサーバーはこのゾーンを担当していない | 聞いた先のネームサーバーが違う |
| SERVFAIL | 答えを作れなかった | 委任の誤り・DNSSEC の不一致を疑う |
手元の再現では、dnsmasq の権威モードが TTL を auth-ttl の値(ここでは300秒)にそろえるため、Route 53 で60秒にしたレコードも300秒で返りました。TTL の値そのものは Route 53 の list-resource-record-sets で確かめ、dig では答えの形と status を見ます。nslookup でも同じことを確かめられます。nslookup の読み方は関連記事「nslookupの使い方|逆引き・DNS指定・MX・エラーの意味を実例で」で扱っています。
Route 53の変更が反映されない理由(TTLとネガティブキャッシュを実測)
この節では、Route 53 でレコードを変えたのに以前の値が返り続ける理由と、どれだけ待てば変わるのかが、実測で分かります。
Route 53 の側は通常60秒以内に変わりますが、利用者が使うリゾルバーは、前に受け取った答えを TTL が切れるまで使い続けます。同じネットワーク空間の中に、キャッシュをするリゾルバー役の dnsmasq(127.0.0.2)を立て、権威役(127.0.0.1)に問い合わせる形にしました。TTL は30秒です。
値を変えたとき
リゾルバー経由で mail.example.com を一度引いたあと、moto で UPSERT して 192.0.2.25 を 192.0.2.26 に変え、権威役の設定を作り直しました。5秒ごとに両方へ聞いた結果です(左の数字は答えに付いた残りの TTL)。
[03:12:43] UPSERT mail -> 192.0.2.26
INSYNC
[03:12:45] 権威(127.0.0.1): 30 192.0.2.26 | キャッシュ(127.0.0.2): 15 192.0.2.25
[03:12:50] 権威(127.0.0.1): 30 192.0.2.26 | キャッシュ(127.0.0.2): 10 192.0.2.25
[03:12:55] 権威(127.0.0.1): 30 192.0.2.26 | キャッシュ(127.0.0.2): 5 192.0.2.25
[03:13:00] 権威(127.0.0.1): 30 192.0.2.26 | キャッシュ(127.0.0.2): 30 192.0.2.26
[03:13:05] 権威(127.0.0.1): 30 192.0.2.26 | キャッシュ(127.0.0.2): 25 192.0.2.26
まだ無い名前を先に引いてしまったとき
レコードを作る前に shop.example.com を引くと NXDOMAIN(無い)が返り、その「無い」という答えもキャッシュされます。直後にレコードを作っても、リゾルバー経由ではしばらく NXDOMAIN のままでした。
[03:13:34] 作成前に引く status: NXDOMAIN
[03:13:36] 権威: 192.0.2.60 | キャッシュ: status: NXDOMAIN
[03:13:48] 権威: 192.0.2.60 | キャッシュ: status: NXDOMAIN
[03:14:01] 権威: 192.0.2.60 | キャッシュ: status: NXDOMAIN
[03:14:07] 権威: 192.0.2.60 | キャッシュ: status: NOERROR 192.0.2.60
| 状況 | 手元で待った時間 | 本物の Route 53 の既定で見込む時間 |
|---|---|---|
| 値の変更 | 約15秒(残りの TTL) | 変更前のレコードの TTL まで(300秒なら最大5分) |
| 無い名前を先に引いた | 約30秒 | SOA の TTL と最後の値の小さいほう。既定で900秒(15分) |
| ネームサーバー(NS)の変更 | (再現していない) | NS の TTL。Route 53 の既定は172800秒(2日) |
| 権威側への反映 | すぐ(moto は INSYNC) | 通常60秒以内(公式) |
「反映されない」の多くは、Route 53 ではなくキャッシュの問題です。次の順に切り分けます。
- 1変更が INSYNC になったかaws route53 get-change で確かめる
- 2担当のネームサーバーに直接聞くdig @ns-xxx.awsdns-xx.com 名前。ここで新しい値ならゾーンは正しい
- 3ドメインの NS が Route 53 を向いているかdig NS example.com +short が、ホストゾーンの4つと同じか
- 4リゾルバーの答えの TTL を見る残りの秒数が切れるまで以前の値が返る
- 5端末とブラウザのキャッシュを消すOS や ブラウザも DNS の答えを覚えている
移行や切り替えの予定があるときは、前の日までに TTL を60〜300秒に下げておき、以前の TTL が切れるのを待ってから値を変えます。終わったら TTL を元に戻すと、クエリの件数(料金)も戻ります。公式ドキュメントも、TTL を上げるとクエリ料金は減るが、誤って消したときの影響が長引く、と注意しています。
お名前.comなど他社で取ったドメインをRoute 53で使う手順
この節では、お名前.com などのレジストラで登録したドメインの DNS を、Route 53 に切り替える手順が分かります。
ドメインの登録先(レジストラ)はそのままで、DNS だけを Route 53 に任せられます。公式ドキュメントの「使用中のドメインの DNS を Route 53 に移行する」手順を、順番どおりにまとめました。レジストラの管理画面の操作は各社のヘルプで確かめます。
今の DNS の設定を書き出す
今の DNS サービスからゾーンファイルかレコードの一覧を取る。メール(MX・TXT)やドメインの所有確認の TXT を落とさないため。
同じ名前のパブリックホストゾーンを作る
NS(4つ)と SOA が自動でできる。この2つは追加も削除もしない。
レコードを作る
ゾーンファイルの取り込み、コンソール、CLI・SDK のどれかで、今と同じレコードを作る。担当のネームサーバーに dig で聞いて、全部そろったか確かめる。
NS の TTL を下げ、DNSSEC を一時的に外す
今の DNS 側と Route 53 側の NS の TTL を60〜900秒に下げる。DNSSEC を使っているなら、親ゾーン(レジストラ)から DS レコードを外す。
以前の TTL が切れるまで待つ
元の NS の TTL(多くは172800秒=2日)が過ぎるのを待つ。
レジストラのネームサーバーを Route 53 の4つに変える
ホストゾーンの NS レコードにある4つを、すべてレジストラに登録する。今のネームサーバーの名前は、戻すときのために控えておく。
監視して、TTL を戻す
Web・メールなどが届いているか見て、問題が無ければ NS の TTL を172800秒に戻す。DNSSEC を使うなら Route 53 側で署名を有効にし、DS を親ゾーンに登録し直す。
- ドメイン全体ではなく、サブドメイン(aws.example.com など)だけを Route 53 に任せることもできます。aws.example.com のホストゾーンを作り、今の DNS の example.com のゾーンに、aws.example.com の NS レコードとして Route 53 の4つを書きます(公式ドキュメントのサブドメインのルーティングの説明)。
- ACM の証明書を DNS 検証で取るときは、Route 53 に CNAME を作るだけで済みます。手順と「保留中」から進まない原因は、関連記事「ACM証明書のDNS検証|発行手順と保留中から進まない原因」で扱っています。
Route 53のよくあるエラー(InvalidChangeBatchの原文)とモックとの違い
この節では、Route 53 の API で出るエラーの原文と原因、そして moto では通ってしまうが本番では断られる操作が分かります。
レコードの変更で出るエラーの多くは InvalidChangeBatch(HTTP 400)で、メッセージの中に理由が書かれています。手元で出たものと、AWS re:Post のナレッジセンターに載っている原文です。
| エラーの原文(抜粋) | 原因 | 直し方 |
|---|---|---|
Tried to create resource record set [name='example.com.', type='A'] but it already exists(手元) |
同じ名前とタイプがある | 上書きなら UPSERT |
RRSet of type CNAME with DNS name example.com. is not permitted at apex in zone example.com(re:Post) |
頂点に CNAME | Alias にする |
RRSet of type CNAME with DNS name test.example.com. is not permitted as it conflicts with other records with the same DNS name in zone(re:Post) |
CNAME と同じ名前に A・MX・TXT などがある | どちらかを消す・別の名前にする |
Tried to delete resource record set [name='a.domain.com.', type='A'] but the values provided do not match the current values(re:Post) |
DELETE の TTL・値が今の値と違う | 一覧で取った値をそのまま渡す |
Tried to delete resource record set [...] but it was not found(re:Post) |
別のホストゾーン ID を指定 | ゾーン ID を確かめる |
RRSet with DNS name www.example.org is not permitted in zone example.com.(手元) |
ゾーンの外の名前 | 正しいゾーンに作る |
No hosted zone found with ID: Z0000000000NOPE(手元・NoSuchHostedZone) |
ゾーン ID の誤り | list-hosted-zones で確かめる |
The hosted zone contains resource records that are not SOA or NS records.(手元・HostedZoneNotEmpty) |
レコードが残ったままゾーンを消した | NS・SOA 以外を先に消す |
Value 'Delete' is not facet-valid with respect to enumeration(re:Post) |
Action が小文字まじり | CREATE・DELETE・UPSERT と大文字で書く |
API リファレンスには、ほかに PriorRequestNotComplete(前の変更の処理が終わる前に同じゾーンへ次の変更を送った。間隔を広げて再試行)と、スロットリング(Throttling・Rate exceeded。指数バックオフで再試行)が載っています。boto3 の再試行の設定で吸収できます。
moto では通るが本番では断られる操作
moto 5.2.5 で試すと、次の操作はエラーにならずに通りました。モックのテストが通っても、本番の検査はもっと厳しいことがあります。
| 操作 | moto 5.2.5 の結果 | 本番(公式・re:Post) |
|---|---|---|
| example.com(頂点)に CNAME | 作られた | InvalidChangeBatch(at apex) |
| CNAME と同じ名前に TXT | 作られた | InvalidChangeBatch(conflicts) |
| A の値に example.net | 作られた | 値の形式も検査される |
| Alias に TTL を付ける | 作られ、消すときに500エラー | Alias では TTL を省く(API リファレンス) |
| 加重で SetIdentifier なし | 作られた | シンプル以外では SetIdentifier が要る |
| 同じ CallerReference でゾーンを作る | 2つ目ができた | HostedZoneAlreadyExists(409) |
| DELETE で値が違う | InvalidInput(Expected exactly one of …) | InvalidChangeBatch(values provided do not match) |
| 変更の状態・ヘルスチェック | すぐ INSYNC・常に Success | PENDING から INSYNC・実際に判定 |
| TestDNSAnswer・GetHostedZoneLimit | 404 Not Found(未対応) | 使える |
モックは「呼び出し方・処理の流れ・エラーの扱い」を確かめる道具として使い、値の妥当性は、自分のコードの中で頂点の CNAME や Alias の TTL を弾く検査を足しておくと、本番で初めて気づく事態を減らせます。
Route 53を使うかどうかの判断表
この節では、自分の構成で Route 53 を使うべきか、どの機能を選ぶかを判断できます。
| 状況 | 向いている選択 | 理由 |
|---|---|---|
| サイトが ALB・CloudFront・S3 にある | Route 53 のホストゾーン+Alias | 頂点に置け、IP の変化に追従し、クエリが無料 |
| サーバーは AWS の外、レコードも数個 | 今のレジストラの DNS のままでもよい | Route 53 の利点は Alias・ポリシー・API で生きる |
| IaC や CI でレコードを自動で変えたい | Route 53 | API・CLI・CloudFormation・Terraform で扱える |
| 障害時に別の拠点へ自動で切り替えたい | フェイルオーバー+ヘルスチェック | TTL を短くし、切り替えを訓練しておく |
| 新しい版に少しずつ流したい | 加重ルーティング | Weight で比率を変える。比率は DNS の答えの比率 |
| VPC の中だけの名前が欲しい | プライベートホストゾーン | クエリは無料。外からは見えない |
| ドメインの購入も AWS にまとめたい | Route 53 でドメイン登録 | 請求と管理が1か所になる。料金は TLD ごと |
よくある質問
Q. Route 53 とは何ですか? A. AWS の DNS サービスです。ドメインの登録、ホストゾーンに置いたレコードによる DNS ルーティング、ヘルスチェックの3つの機能があり、必要なものだけを使えます。
Q. Route 53 の料金はいくらですか? A. 2026年10月29日時点で、ホストゾーン1つにつき月0.50ドル(26ゾーン目から0.10ドル)、標準のクエリ100万件ごとに0.40ドルです。AWS リソースを指す Alias へのクエリは無料で、ヘルスチェックとドメイン登録は別にかかります。
Q. Route 53 に無料枠はありますか? A. 料金ページに、Route 53 全体の無料利用枠の記載はありません。作成から12時間以内に消したホストゾーン、AWS リソース宛ての Alias のクエリ、条件つきのヘルスチェック50件などが無料と明記されています。
Q. ホストゾーンとドメインは同じものですか? A. 違います。ドメインは登録した名前、ホストゾーンはその名前のレコードを入れる Route 53 の入れ物です。Route 53 でドメインを登録すると、同じ名前のホストゾーンが自動で作られます。
Q. Alias と CNAME はどちらを使えばよいですか? A. 相手が ALB・CloudFront・S3 などの AWS リソースなら Alias です。頂点にも置け、クエリも無料です。AWS の外のホスト名に向けるなら、サブドメインに CNAME を使います。
Q. ネームサーバーを変えたのに切り替わりません。
A. NS の TTL(Route 53 の既定は2日)の間は、リゾルバーが以前のネームサーバーを使うことがあります。dig NS example.com +short の結果が、ホストゾーンの NS の4つと同じかを確かめます。
Q. レコードを変えたのに、以前の IP アドレスが返ります。 A. リゾルバーのキャッシュです。手元の実測では、残りの TTL が切れた瞬間に新しい値に変わりました。担当のネームサーバーに直接 dig して新しい値なら、待てば変わります。
Q. Route 53 のホストゾーンを消すとどうなりますか? A. NS と SOA 以外のレコードが残っていると消せません(HostedZoneNotEmpty)。消したあとも、レジストラがそのネームサーバーを向いたままだと名前が引けなくなるため、先にレジストラの NS を変えます。
Q. AWS に接続せずに Route 53 の操作を試せますか? A. moto を使うと、AWS CLI と boto3 の Route 53 の操作を手元で試せます。DNS の問い合わせには答えないため、dig での確認には dnsmasq などで同じゾーンを再現します。
Q. ルーティングポリシーは何種類ですか? A. 2026年10月29日時点の公式ドキュメントでは、シンプル・フェイルオーバー・位置情報・地理的近接性・レイテンシー・IP ベース・複数値回答・加重の8種類です。
まとめ
- Route 53 は AWS の DNS サービスで、ドメイン登録・DNS ルーティング・ヘルスチェックの3機能。ホストゾーンを作ると NS 4つと SOA が自動でできる。
- 料金はゾーン月0.50ドル+標準クエリ100万件0.40ドルから。AWS リソース宛ての Alias は無料で、頂点(example.com)にも置ける(2026年10月29日時点)。
- ルーティングポリシーは公式で8種類。シンプル以外は SetIdentifier を付け、フェイルオーバーにはヘルスチェックと短い TTL を組み合わせる。
- moto で CLI・boto3 の操作とエラーを確かめられるが、頂点の CNAME や Alias の TTL など、本番で断られる操作も通ってしまう。
- 「反映されない」の多くはキャッシュ。手元の実測では、値の変更は残りの TTL、無い名前を先に引いたときはネガティブキャッシュの時間だけ以前の答えが残った。
次に読むとよい記事です。CLI でのレコード操作は関連記事「Route 53レコードをAWS CLIで作成|A・CNAME・エイリアス例」で、証明書の DNS 検証は関連記事「ACM証明書のDNS検証|発行手順と保留中から進まない原因」で扱っています。
参考・出典
確認日はいずれも 2026年10月29日です。
- AWS Route 53 開発者ガイド(Route 53 の概要):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/Welcome.html
- AWS 料金ページ(Amazon Route 53):https://aws.amazon.com/jp/route53/pricing/
- AWS よくある質問(Amazon Route 53):https://aws.amazon.com/jp/route53/faqs/
- AWS Route 53 開発者ガイド(ルーティングポリシー):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/routing-policy.html
- AWS Route 53 開発者ガイド(エイリアスと非エイリアスの比較):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/resource-record-sets-choosing-alias-non-alias.html
- AWS Route 53 開発者ガイド(DNS レコードタイプ):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/ResourceRecordTypes.html
- AWS Route 53 開発者ガイド(NS レコードと SOA レコード):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/SOA-NSrecords.html
- AWS Route 53 開発者ガイド(プライベートホストゾーン):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/hosted-zones-private.html
- AWS Route 53 開発者ガイド(ヘルスチェックの種類):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/health-checks-types.html
- AWS Route 53 開発者ガイド(エンドポイントの正常性の判定):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/dns-failover-determining-health-of-endpoints.html
- AWS Route 53 開発者ガイド(使用中のドメインの DNS を Route 53 に移行):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/migrate-dns-domain-in-use.html
- AWS Route 53 開発者ガイド(クォータ):https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/DNSLimitations.html
- AWS「ChangeResourceRecordSets」(API リファレンス):https://docs.aws.amazon.com/Route53/latest/APIReference/API_ChangeResourceRecordSets.html
- AWS「CreateHostedZone」(API リファレンス):https://docs.aws.amazon.com/Route53/latest/APIReference/API_CreateHostedZone.html
- AWS「ResourceRecordSet」「AliasTarget」(API リファレンス):https://docs.aws.amazon.com/Route53/latest/APIReference/API_ResourceRecordSet.html
- AWS General Reference「Elastic Load Balancing endpoints and quotas」:https://docs.aws.amazon.com/general/latest/gr/elb.html
- AWS re:Post ナレッジセンター(リソースレコードの作成・変更時のエラー):https://repost.aws/knowledge-center/troubleshoot-route53-resource-record
- AWS re:Post ナレッジセンター(CNAME レコードを作成できない理由):https://repost.aws/knowledge-center/route-53-create-cname-record
- moto ドキュメント:https://docs.getmoto.org/
- dnsmasq の man ページ:https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「Route 53とは|料金・ホストゾーン・Aliasをモックとdigで確認」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。