対象読者: AWSをこれから触る人。 AWS勉強シリーズの13本目で、今回からシリーズ後半の「公開編」です。今回はRoute 53。全体の地図は索引記事にあります。
部品編でEC2を立ててS3に写真を置けるようになった人が、次に必ずつまずく2つから書きます。
- 「IPアドレスでしかアクセスできない。example.com みたいな名前で開きたい」
- 「Aレコード、CNAME、ホストゾーン。DNSの用語が全部初見で分からない」
どちらも「インターネットの電話帳に、自分のページを1冊持つ」の1点で答えが出ます。

Route 53を電話帳に例えた図(筆者作成)。ブラウザは毎回この電話帳で「名前→住所(IP)」を引いてからサーバーに向かいます。
Route 53とは何か
Amazon Route 53は、「名前(ドメイン)をIPアドレスに変換する仕組み」= DNSを提供するサービスです。上の図の電話帳で、あなたが example.com と打つたびに、ブラウザは裏でこの電話帳に問い合わせて、サーバーの住所(IPアドレス)を受け取ってから接続しています。
名前の由来は、DNSが使う53番ポートです。セキュリティグループの許可リストに出てきた「443」「22」と同じ、ポート番号の仲間です。
今シリーズのどこにいるか
ここまでの部品編は「AWSの中」で完結していました。公開編は「外の世界と繋ぐ」話で、その1歩目が「名前を持つ」です。
何に使うか
-
自分のドメインでサイトを開く:
203.0.113.10ではなくexample.comでアクセスさせる - ドメインを買う: Route 53はドメインの購入(登録)の窓口も兼ねる。年間十数USD〜
- サーバーの引っ越しを名前で吸収する: EC2を建て直してIPが変わっても、電話帳の1行を書き換えれば利用者は何も気づかない
- 健康診断つきの案内: サーバーが死んでいたら予備の住所を案内する(ヘルスチェック+フェイルオーバー)。入門の次の段階で使う
今はこれだけ分かればOK
| 必須の3語 | 電話帳で言うと | 中身 |
|---|---|---|
| ホストゾーン | 電話帳の1冊 | 1つのドメイン(example.com)の行をまとめて管理する入れ物 |
| Aレコード | 名前→住所の行 |
www → 203.0.113.10。一番基本の行 |
| CNAME | 名前→別の名前の行 |
blog → www。行き先をもう1回電話帳で引き直す |
TTL(行の暗記時間)、MX(メール)、エイリアスレコードは後回しで大丈夫です。
仕組みの要点。電話帳に書ける行は2種類ある

レコードの図(筆者作成)。入門で書くのはこの2種類だけです。
実測で、電話帳(ホストゾーン)を作った直後の中身を見ると、こうなっています。
初期レコード: [('example.com.', 'NS'), ('example.com.', 'SOA')]
NSとSOAの2行は、作った瞬間から入っています。 NSは「この電話帳の正式な置き場所はここ」という案内、SOAは電話帳自体の管理情報です。この2行は消しませんし、触りません。あなたが書き足すのは、AとCNAMEの行だけです。
このコードを動かす前提
この記事のコードはPython(boto3)です。動かす方法は2通りあります。
A. AWSアカウント無しで試す(おすすめ): motoというAWSのそっくりさんを使うと、課金もサインアップもなしでPCの中だけで動きます。
python3 -m venv venv
./venv/bin/pip install boto3 moto
from moto import mock_aws
@mock_aws # この中のboto3呼び出しは全部ローカルの偽AWSに行く
def main() -> None:
... # 以下の記事のコードをここに入れる
main()
B. 本物のAWSで動かす: 先にIAMユーザーとアクセスキーの設定が要ります。手順はIAM記事の「最初の1回だけやる手順」にあります。なお、本物で最後まで試すにはドメインの購入(有料)が要るので、仕組みの練習はmotoで十分です。
使い方
「電話帳を作る→Aの行を書く→CNAMEの行を書く→行を書き換える」の4手です。
import boto3
r53 = boto3.client("route53", region_name="ap-northeast-1")
# ① 電話帳を1冊作る(ホストゾーン)。CallerReferenceは二重作成防止の合言葉
z = r53.create_hosted_zone(Name="example.com", CallerReference="demo-001")
zid = z["HostedZone"]["Id"]
# ② Aレコード: www.example.com の住所は 203.0.113.10
r53.change_resource_record_sets(HostedZoneId=zid, ChangeBatch={
"Changes": [{"Action": "CREATE", "ResourceRecordSet": {
"Name": "www.example.com", "Type": "A", "TTL": 300,
"ResourceRecords": [{"Value": "203.0.113.10"}]}}]})
# ③ CNAME: blog.example.com は www.example.com と同じ所
r53.change_resource_record_sets(HostedZoneId=zid, ChangeBatch={
"Changes": [{"Action": "CREATE", "ResourceRecordSet": {
"Name": "blog.example.com", "Type": "CNAME", "TTL": 300,
"ResourceRecords": [{"Value": "www.example.com"}]}}]})
# ④ 引っ越し: 住所の書き換えはUPSERT(あれば更新、なければ作成)
r53.change_resource_record_sets(HostedZoneId=zid, ChangeBatch={
"Changes": [{"Action": "UPSERT", "ResourceRecordSet": {
"Name": "www.example.com", "Type": "A", "TTL": 300,
"ResourceRecords": [{"Value": "203.0.113.99"}]}}]})
実測の出力です。
追加後: [('example.com.', 'NS', [...]), ('example.com.', 'SOA', [...]),
('blog.example.com.', 'CNAME', ['www.example.com']),
('www.example.com.', 'A', ['203.0.113.10'])]
UPSERT後のwww: ['203.0.113.99']
④が引っ越しの実体です。IPが変わったらUPSERTで1行書き換えるだけ。実測では、UPSERTの後 blog のCNAMEには何も触っていないのに、blog経由で引き直すと新住所(203.0.113.99)側に付いてきました。
今あなたが作ったもの
- example.comの電話帳が1冊(NS/SOAの2行入り)
- 名前→住所の行(A)と、名前→名前の行(CNAME)が1行ずつ
- 「引っ越してもURLが変わらない」状態。利用者に見せる名前と、実際の住所が分離できた
実際に叩くと止まるところ
間違えたときに何が返るか、実際に叩きました。
| やったこと | 返ってきたもの | 意味 |
|---|---|---|
| 無いゾーンIDにレコード追加 | NoSuchHostedZone |
ゾーンIDのコピペミス。IDは/hostedzone/付きの長い文字列 |
| レコードが残ったままゾーン削除 | HostedZoneNotEmpty: The hosted zone contains resource records that are not SOA... |
NS/SOA以外の行を全部消してからでないと電話帳は捨てられない。VPCのDependencyViolationと同じ思想 |
| 同じレコードを二重CREATE | motoでは通ってしまった |
本物のAWSはInvalidChangeBatch(既に存在する)で弾く。motoの再現漏れ |
| Aレコードの値にドメイン名を書く | motoでは通ってしまった | 本物のAWSはIPアドレス以外を弾く。「名前→名前」を書きたい時はAではなくCNAME。ここもmotoは検証しない |
下2つはmotoの限界です。レコードの中身の検証は本物側でしか効かないので、「AにはIP、CNAMEには名前」を自分のルールとして覚えてください。
似た概念との使い分け
| 迷うところ | 答え |
|---|---|
| AレコードとCNAME、どっち | 行き先がIPならA、別の名前ならCNAME。ドメインの根っこ(example.com自体)にはCNAMEを書けない、という制約が後で出てくるが、入門ではサブドメイン(www等)にだけCNAMEを使えば当たらない |
| ドメインはどこで買う | Route 53でも他社(お名前.com等)でも買える。他社で買ってDNSだけRoute 53、もできる(NSレコードを向ける) |
| VPCのDNSとの違い | VPC内部の名前解決はAWSが自動でやっている。Route 53は「外の世界からの名前」の話 |
| CloudFrontやS3のサイトに繋ぎたい | エイリアスレコードというAWS専用の行を使う(無料で引ける)。次回以降のCloudFront回で扱う |
料金の考え方
課金は3つです。
- ホストゾーン: 1冊あたり月0.50 USD(最初の25冊まで)。作りっぱなしで課金が続くので、練習で作ったら消す
- クエリ(引かれた回数): 100万回あたり0.40 USD。個人サイトなら誤差
- ドメイン登録: 年間十数USD〜(.comで約15 USD)。これはRoute 53と別枠の費用
motoでの練習は全部無料です。本物で練習する時は、ホストゾーンの消し忘れだけ気をつけてください(月0.50 USDの静かな課金が続きます)。
よくある注意点
- レコードの反映には暗記時間(TTL)が効く。 電話帳を引いた側はTTLの秒数だけ結果を暗記する。書き換えた直後に古い住所に繋がるのは異常ではなく、暗記が切れるのを待つ。だから引っ越し予定日の前にTTLを短くしておくのが定石
-
ゾーンを消すには行を先に消す。 実測の通り
HostedZoneNotEmpty。NS/SOA以外を全部消してから -
CallerReferenceは使い回さない。 同じ値で2回作ると
HostedZoneAlreadyExistsで弾かれる(二重作成防止)。日時を入れるのが楽 -
ドメインの根っこにCNAMEは書けない。
example.com自体をCNAMEにしたくなったら、それはエイリアスレコードの出番(CloudFront回で)
まとめ
冒頭の2つに戻ります。
- 「名前で開きたい」→ 電話帳(ホストゾーン)を作って、Aレコードで名前と住所を1行結ぶだけです。ドメインを買えば、その行が世界から引けるようになります
- 「用語が初見」→ 覚えるのは3語(ホストゾーン=電話帳の1冊、A=名前→住所、CNAME=名前→名前)。NS/SOAは最初から入っている触らない行、TTLは暗記時間。これで入門のDNS語彙は足ります
次回はCloudFront(配信)を予定しています。「名前は持てた。次は世界中に速く届ける」の順です。
