デフォルトのAmazonProvidedDNSは
ip-10-0-1-5.ap-northeast-1.compute.internal のような機械的な名前しか解決できません。本番環境では db.internal.example.com や api.prod.example.com のような人間が読めるプライベートドメインを使いたいはずです。この記事では、Route 53プライベートホストゾーンを使ってVPC専用のDNSレコードを設定する方法を解説します。動作確認済みの実行環境はAWS CLI v2 + Amazon Linux 2023です。
・ホストゾーンの作成とVPCへの関連付け手順
・マルチVPC・クロスアカウント対応の設計パターン
・Resolver Endpointを使ったオンプレミス連携(ハイブリッドDNS)まで
この記事のポイント
・VPC内でカスタムドメインを使うにはプライベートホストゾーンが必要
・enableDnsSupportとenableDnsHostnamesを両方ONにしないと解決されない
・マルチVPCや別アカウントのVPCにも追加の関連付けで対応できる
・オンプレミスとの双方向DNS解決はResolver Endpointで実現する
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
Route 53プライベートホストゾーンとVPC内DNSの仕組み
AWSのVPCには、デフォルトでDNSサーバー(AmazonProvidedDNS)が組み込まれています。VPCのCIDRブロックのIPアドレス+2番(例: 10.0.0.0/16なら10.0.0.2)がDNSサーバーのアドレスです。このDNSが解決できるのは、Amazonのパブリックドメイン(.amazonaws.com)と、EC2インスタンスに自動付与される内部ドメイン(.ec2.internal、.ap-northeast-1.compute.internal)だけです。プライベートホストゾーンは、このAmazonProvidedDNSに「専用のDNSゾーン」を追加する仕組みです。
example.internal のようなドメインを作成してVPCに関連付けると、そのVPC内のEC2インスタンスから db.example.internal を名前解決できるようになります。インターネットには公開されません。パブリックホストゾーンとの違いをまとめると次のとおりです。
| 項目 | パブリックホストゾーン | プライベートホストゾーン |
|---|---|---|
| 解決できる範囲 | インターネット全体 | 関連付けたVPC内のみ |
| ドメイン例 | example.com | example.internal |
| 使用DNSサーバー | Route 53のパブリックNS | AmazonProvidedDNS(VPC+2) |
| VPCとの関連付け | 不要 | 必須(1つ以上のVPCを指定) |
プライベートホストゾーンの基本設定|作成からVPC関連付け・動作確認まで
まずVPC側の前提条件を確認します。Route 53プライベートホストゾーンを機能させるには、対象VPCで2つのDNS設定を有効にする必要があります。# VPCのDNS設定を確認する $ aws ec2 describe-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --attribute enableDnsSupport { "VpcId": "vpc-0a1b2c3d4e5f67890", "EnableDnsSupport": { "Value": true } } $ aws ec2 describe-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --attribute enableDnsHostnames { "VpcId": "vpc-0a1b2c3d4e5f67890", "EnableDnsHostnames": { "Value": true } }
true であることが必須条件です。false になっている場合は以下で有効化してください。# enableDnsSupportを有効にする $ aws ec2 modify-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --enable-dns-support "{\"Value\":true}" # enableDnsHostnamesを有効にする $ aws ec2 modify-vpc-attribute --vpc-id vpc-0a1b2c3d4e5f67890 --enable-dns-hostnames "{\"Value\":true}"
1. ホストゾーンを作成する
プライベートホストゾーンを作成します。ここではapp.internal というドメインを作成し、東京リージョン(ap-northeast-1)の特定VPCに関連付けます。$ aws route53 create-hosted-zone \ --name "app.internal" \ --caller-reference "$(date +%s)" \ --hosted-zone-config "Comment=Production private zone,PrivateZone=true" \ --vpc "VPCRegion=ap-northeast-1,VPCId=vpc-0a1b2c3d4e5f67890" { "Location": "https://route53.amazonaws.com/2013-04-01/hostedzone/Z1234ABCD5EFGH", "HostedZone": { "Id": "/hostedzone/Z1234ABCD5EFGH", "Name": "app.internal.", "Config": { "Comment": "Production private zone", "PrivateZone": true }, "ResourceRecordSetCount": 2 }, "VPC": { "VPCRegion": "ap-northeast-1", "VPCId": "vpc-0a1b2c3d4e5f67890" } }
SOA レコードと NS レコードだけが存在する状態です(ResourceRecordSetCount: 2)。なお --caller-reference には重複リクエストを防ぐ一意な文字列が必要で、date +%s(Unixタイムスタンプ)がよく使われます。2. Aレコードを登録して動作確認する
データベースサーバー(db.app.internal → 10.0.1.50)を登録して動作確認します。# レコード登録用のJSONを作成 $ cat > /tmp/change-batch.json << 'EOF' { "Changes": [ { "Action": "CREATE", "ResourceRecordSet": { "Name": "db.app.internal", "Type": "A", "TTL": 300, "ResourceRecords": [ { "Value": "10.0.1.50" } ] } } ] } EOF # レコードを登録する $ aws route53 change-resource-record-sets \ --hosted-zone-id Z1234ABCD5EFGH \ --change-batch file:///tmp/change-batch.json { "ChangeInfo": { "Id": "/change/C2ABCDEF3GHIJK", "Status": "PENDING", "SubmittedAt": "2026-08-24T03:15:42.123Z" } }
Status: PENDING はRoute 53のDNSサーバーへの反映中を意味します。通常60秒以内に INSYNC に変わります。VPC内のEC2インスタンスからdigで確認します。# VPC内のEC2からdigで名前解決を確認 [ec2-user@ip-10-0-1-100 ~]$ dig db.app.internal +short 10.0.1.50
3. Route 53の自動ドメイン(ec2.internal)との使い分け
EC2インスタンスには作成時に自動的に内部DNS名(例:ip-10-0-1-100.ap-northeast-1.compute.internal)が付与されます。これはIPアドレスが変わると変わるため、Auto ScalingやBlue/Greenデプロイとは相性が悪いです。プライベートホストゾーンでは「db.app.internal → 現在の正しいインスタンスのIP」という形でレコードを管理し、IPが変わってもアプリ側はホスト名を使い続けられるように設計します。VPCとプライベートホストゾーンを組み合わせた設計フローについては、Linux DNS設定の基本(resolv.conf・nmcliでの設定手順)も参考になります。
マルチVPC設計|複数VPCへの関連付けとクロスアカウント対応
本番VPC・ステージングVPC・監視VPCなど、複数のVPCで同じプライベートホストゾーンを参照したいケースは少なくありません。Route 53プライベートホストゾーンは複数のVPCを関連付けることができます。1. 同一アカウント内の複数VPCに関連付ける
# ステージングVPCを追加で関連付ける $ aws route53 associate-vpc-with-hosted-zone \ --hosted-zone-id Z1234ABCD5EFGH \ --vpc "VPCRegion=ap-northeast-1,VPCId=vpc-0b9c8d7e6f5a43210" { "ChangeInfo": { "Id": "/change/C3LMNOP4QRSTUV", "Status": "PENDING", "SubmittedAt": "2026-08-24T03:22:11.456Z" } } # 関連付け済みVPCを確認する $ aws route53 get-hosted-zone --id Z1234ABCD5EFGH | jq '.VPCs' [ { "VPCRegion": "ap-northeast-1", "VPCId": "vpc-0a1b2c3d4e5f67890" }, { "VPCRegion": "ap-northeast-1", "VPCId": "vpc-0b9c8d7e6f5a43210" } ]
db.app.internal を解決できるようになります。このとき両VPC間にVPCピアリングやTransit Gatewayは不要です。DNS解決のレイヤーだけで完結します。2. 別アカウントのVPCと共有する(CLIのみ対応)
マルチアカウント構成では、ホストゾーンのオーナーアカウントとVPCを所有する別アカウントとで2ステップの操作が必要です。マネジメントコンソールからはできないため、CLIで作業します。# ── ステップ1: ホストゾーン所有アカウント(Account A)で認証リクエストを作成 ── $ aws route53 create-vpc-association-authorization \ --hosted-zone-id Z1234ABCD5EFGH \ --vpc "VPCRegion=ap-northeast-1,VPCId=vpc-0c1d2e3f4a5b67890" { "HostedZoneId": "Z1234ABCD5EFGH", "VPC": { "VPCRegion": "ap-northeast-1", "VPCId": "vpc-0c1d2e3f4a5b67890" } } # ── ステップ2: VPC所有アカウント(Account B)で関連付けを実行 ── $ aws route53 associate-vpc-with-hosted-zone \ --hosted-zone-id Z1234ABCD5EFGH \ --vpc "VPCRegion=ap-northeast-1,VPCId=vpc-0c1d2e3f4a5b67890" { "ChangeInfo": { "Status": "INSYNC" } }
delete-vpc-association-authorization で削除してください。マルチVPC・マルチアカウント設計の全体像を体系的に学びたい方は、AWSマスターセミナー上級編も合わせてご確認ください。現役エンジニアが設計判断の根拠も含めてハンズオンで解説しています。
オンプレミスとのハイブリッドDNS設計
Direct ConnectやSite-to-Site VPNでAWS VPCとオンプレミスデータセンターを接続している場合、DNS解決もその接続を通して行う設計が求められます。Route 53 Resolver Endpointがその仕組みを担います。エンドポイントには2種類あります。
・Inbound Resolver Endpoint:オンプレミス → VPC方向。オンプレのDNSサーバーがAWSのResolver Endpointにクエリを転送することで、VPC内のプライベートホストゾーンを解決できます。
・Outbound Resolver Endpoint:VPC → オンプレミス方向。VPC内のEC2がオンプレミスのDNSドメインを解決したい時に使います。Resolver Rulesと組み合わせて動作します。
1. Inbound Resolver Endpoint(オンプレミスからVPC方向)
Inbound Endpointは最低2つの異なるAZのサブネットにENIを持たせてマルチAZ冗長化します。# Inbound Resolver Endpointを作成する $ aws route53resolver create-resolver-endpoint \ --creator-request-id "inbound-ep-$(date +%s)" \ --direction INBOUND \ --security-group-ids sg-0a1b2c3d4e5f67890 \ --ip-addresses SubnetId=subnet-0aaa111b2cc333d,Ip=10.0.1.10 \ SubnetId=subnet-0bbb222c3dd444e,Ip=10.0.2.10 \ --name "prod-inbound-resolver" { "ResolverEndpoint": { "Id": "rslvr-in-0a1b2c3d4e5f67890", "Name": "prod-inbound-resolver", "Direction": "INBOUND", "Status": "CREATING", "IpAddressCount": 2 } } # 作成完了を確認(StatusがOPERATIONALになるまで待つ) $ aws route53resolver get-resolver-endpoint \ --resolver-endpoint-id rslvr-in-0a1b2c3d4e5f67890 \ --query 'ResolverEndpoint.Status' "OPERATIONAL"
sg-0a1b2c3d4e5f67890)にはオンプレミスのDNSサーバーからのポート53(UDP・TCP)を許可するインバウンドルールが必要です。エンドポイント作成後、割り当てられたIP(10.0.1.10 / 10.0.2.10)をオンプレミスのDNSサーバーに「app.internal のクエリはこのIPへ転送する」という条件付き転送(Conditional Forwarder)として登録します。2. Outbound Resolver EndpointとResolver Rules(VPCからオンプレミス方向)
# Outbound Resolver Endpointを作成する $ aws route53resolver create-resolver-endpoint \ --creator-request-id "outbound-ep-$(date +%s)" \ --direction OUTBOUND \ --security-group-ids sg-0a1b2c3d4e5f67890 \ --ip-addresses SubnetId=subnet-0aaa111b2cc333d \ SubnetId=subnet-0bbb222c3dd444e \ --name "prod-outbound-resolver" { "ResolverEndpoint": { "Id": "rslvr-out-0b9c8d7e6f5a43210", "Name": "prod-outbound-resolver", "Direction": "OUTBOUND", "Status": "CREATING", "IpAddressCount": 2 } }
# Resolver Rule(条件付き転送ルール)を作成する # オンプレミスのドメイン corp.example.com をDNS 192.168.1.53 へ転送 $ aws route53resolver create-resolver-rule \ --creator-request-id "rule-corp-$(date +%s)" \ --domain-name "corp.example.com" \ --rule-type FORWARD \ --resolver-endpoint-id rslvr-out-0b9c8d7e6f5a43210 \ --target-ips Ip=192.168.1.53,Port=53 \ --name "forward-to-onprem-corp" { "ResolverRule": { "Id": "rslvr-rr-0c7d6e5f4a3b21098", "Name": "forward-to-onprem-corp", "DomainName": "corp.example.com.", "RuleType": "FORWARD", "TargetIps": [ { "Ip": "192.168.1.53", "Port": 53 } ] } } # ルールをVPCに関連付ける(必須・忘れると機能しない) $ aws route53resolver associate-resolver-rule \ --resolver-rule-id rslvr-rr-0c7d6e5f4a3b21098 \ --vpc-id vpc-0a1b2c3d4e5f67890 { "ResolverRuleAssociation": { "Id": "rslvr-rrassoc-0d3c2b1a0e9f87654", "ResolverRuleId": "rslvr-rr-0c7d6e5f4a3b21098", "VPCId": "vpc-0a1b2c3d4e5f67890", "Status": "COMPLETE" } }
Status: COMPLETE になれば、VPC内のEC2から nslookup fileserver01.corp.example.com がオンプレミスのIPを返すようになります。ルールのVPC関連付けを忘れるミスが多いため、作成直後に必ず確認してください。トラブルシュート|名前解決できない時の3点切り分け
プライベートホストゾーンで名前解決できない場合、以下の3点を順番に確認します。① VPCのDNS設定を確認する
enableDnsSupportまたはenableDnsHostnamesが無効だと、プライベートホストゾーンのレコードが一切解決されません。前述のdescribe-vpc-attribute手順でtrueになっているか確認してください。
② ホストゾーンのVPC関連付けを確認する
# ホストゾーンに関連付けられたVPCを確認する $ aws route53 get-hosted-zone --id Z1234ABCD5EFGH \ --query 'VPCs' [ { "VPCRegion": "ap-northeast-1", "VPCId": "vpc-0a1b2c3d4e5f67890" } ]
associate-vpc-with-hosted-zone で追加してください。③ AmazonProvidedDNSに直接クエリを投げる
EC2内で次のコマンドを実行し、VPCのDNSサーバー(VPC CIDRのベースIP+2)に直接クエリを投げます。
# VPCのCIDRが10.0.0.0/16であればDNSは10.0.0.2 [ec2-user@ip-10-0-1-100 ~]$ dig @10.0.0.2 db.app.internal +short 10.0.1.50
/etc/resolv.conf かネットワーク設定の問題です。解決できないならホストゾーンの設定(VPC関連付け・レコード登録)を見直してください。本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| プライベートホストゾーンを作成してVPCに関連付ける | aws route53 create-hosted-zone --name ドメイン名 --hosted-zone-config PrivateZone=true --vpc VPCRegion=リージョン,VPCId=VPC_ID |
| 別のVPCを追加で関連付ける | aws route53 associate-vpc-with-hosted-zone --hosted-zone-id ゾーンID --vpc VPCRegion=リージョン,VPCId=VPC_ID |
| Aレコードを登録する | aws route53 change-resource-record-sets --hosted-zone-id ゾーンID --change-batch file://change.json |
| Inbound Resolver Endpointを作成する | aws route53resolver create-resolver-endpoint --direction INBOUND --security-group-ids SG_ID --ip-addresses SubnetId=...,Ip=... |
| Resolver Ruleを作成してVPCに関連付ける | aws route53resolver create-resolver-rule --domain-name ドメイン --rule-type FORWARD --resolver-endpoint-id EP_ID --target-ips Ip=DNS_IP,Port=53 |
db.app.internal というホスト名を使い続けられます。マルチVPC設計ではVPCピアリングなしにDNS共有ができ、オンプレミスとのハイブリッド構成ではResolver Endpointが双方向の名前解決を実現します。設計の肝は「enableDnsSupport・enableDnsHostnamesの有効化」と「Resolver RuleのVPC関連付け忘れ防止」の2点です。AWSのより深い実践については、以下の記事も参考にしてください。
・Linux DNS設定の基本(resolv.conf・nmcliでの設定手順)
Linuxの実践力を体系的に身につけたい方は、以下のセミナーLP・AWSコース紹介ページもご覧ください。
>> AWSの設計・構築を体系的に学ぶ(上級LPはこちら)
>> AWSをはじめて学ぶ方はこちら(入門LP)
AWSのDNS設計を「実機で動かして理解する」習慣は、Linuxサーバー構築の「型」から生まれます
Route 53やResolver EndpointはAWSコンソールで設定できても、「なぜこの設計にするか」を説明できるかどうかで現場での信頼が変わります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:aws apigatewayv2コマンドでHTTP APIを設計する方法|Lambda統合・Cognitoオーソライザー・スロットリングの実践構成
- この記事の属するカテゴリ:AWS(Amazon Linux)へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます