AWSのクロスアカウント構成におけるRoute 53での名前解決方式紹介

はじめに
こんにちは、yuuchanです。
最近、久しぶりにコーヒー豆の自家焙煎をしてみました。
特別な機器などは持っていないので、焙煎用の手網とカセットコンロを使用して2, 30分ひたすらシャカシャカシャカシャカ焙煎していきます。
お店で購入するコーヒー豆も勿論良いですが、やはり拙いながらも自分で焙煎した豆で淹れるコーヒーはそれはそれは格別な味がする・・・気がします。
さて今回は、PJでAWS上にネットワーク構築を行った際の経験を踏まえ、AWSのクロスアカウント構成における名前解決方式を2パターンほど紹介しようと思います。
紹介する方式の概要
クロスアカウントでの名前解決を行うにあたり、今回は2パターンの構成を紹介いたします。
どちらの方式も、アカウントBにプライベートホストゾーンを作成してあり、アカウントAから名前解決を行いたいシチュエーションを想定しています。
尚、下図に登場するVPCやEC2等のリソースの作成手順やパラメータに関する説明は、必要な場合を除き本記事では省略します。
パターン1
「アカウントBのホストゾーンにアカウントAのVPCを関連付ける」

パターン2
「Resolver Endpointを使用しアカウントBに名前解決リクエストを転送する」

※Transit Gatewayを使用してVPC同士を接続する方法については、以下記事を参照ください。

プライベートホストゾーンの作成
それぞれの方式の説明を行う前に、プライベートホストゾーンを作成していきます。
ホストゾーンの作成

上記のように、
ドメイン名(例): nr-practice.private
タイプ: プライベートホストゾーン
ホストゾーンに関連付けるVPC: DstVPCのID
を設定しホストゾーンを作成します。
※本記事で紹介する例ではDstVPCから名前解決をリクエストは行いませんが、ホストゾーン作成時に少なくとも1つのVPCを関連付ける必要があるため、DstVPCを関連付けてあります。
レコードの作成
今回は、dstec2.nr-practice.private
という名前をDstVPCにあるEC2のIPアドレスに解決するようなレコードを作成します。

上記のように、
レコード名: dstec2
レコードタイプ: A
値: 10.2.10.70 (DstVPCにあるEC2のプライベートIPアドレス)
を設定しレコードを作成します。
パターン1
「アカウントBのホストゾーンにアカウントAのVPCを関連付ける」
最初に紹介するのは、名前解決のリクエスト元であるアカウントAのVPCを、アカウントBのホストゾーンに関連付ける方式です。
ホストゾーンには、ホストゾーンを作成したアカウントにあるVPCだけではなく、他アカウントにあるVPCも関連付けることができます。
ホストゾーンを作成したアカウントにあるVPCを関連付ける際は、AWS管理コンソール(GUI)からVPCを選択するだけですが、他アカウントにあるVPCを関連付ける際はAWS CLIで操作を行う必要があります。
アカウントB側での操作
以下コマンドを実行し、VPC とプライベートホストゾーンの関連付けを承認します。
ホストゾーンのIDには前節で作成したホストゾーンのIDを設定し、関連付けるVPCのリージョンやIDにはSrcVPCの情報を設定します。
aws route53 create-vpc-association-authorization --hosted-zone-id <ホストゾーンのID> --vpc VPCRegion=<関連付けるVPCのリージョン>,VPCId=<関連付けるVPCのID>
アカウントA側での操作
アカウントB側での操作後、以下コマンドを実行しVPCをホストゾーンに関連付けます。
こちらも同様に、ホストゾーンのIDには前節で作成したホストゾーンのIDを設定し、関連付けるVPCのリージョンやIDにはSrcVPCの情報を設定します。
aws route53 associate-vpc-with-hosted-zone --hosted-zone-id <ホストゾーンのID> --vpc VPCRegion=<関連付けるVPCのリージョン>,VPCId=<関連付けるVPCのID>
関連付けの確認
アカウントA側での操作後、SrcVPCがプライベートホストゾーンに関連付いたことを確認します。
AWS管理コンソールから、「ホストゾーンの詳細」の「関連付けられたVPC」にSrcVPCのIDが表示されていれば無事関連付けができています。

名前解決および疎通確認
では実際に、SrcVPCにあるEC2からDstVPCにあるEC2に対してpingを送ってみます。
[ec2-user@ip-10-1-10-77 ~]$ ping -c 4 dstec2.nr-practice.private
PING dstec2.nr-practice.private (10.2.10.70) 56(84) bytes of data.
64 bytes from ip-10-2-10-70.ap-northeast-1.compute.internal (10.2.10.70): icmp_seq=1 ttl=126 time=1.79 ms
64 bytes from ip-10-2-10-70.ap-northeast-1.compute.internal (10.2.10.70): icmp_seq=2 ttl=126 time=1.05 ms
64 bytes from ip-10-2-10-70.ap-northeast-1.compute.internal (10.2.10.70): icmp_seq=3 ttl=126 time=1.40 ms
64 bytes from ip-10-2-10-70.ap-northeast-1.compute.internal (10.2.10.70): icmp_seq=4 ttl=126 time=1.56 ms
--- dstec2.nr-practice.private ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 1.051/1.449/1.789/0.268 ms
上記のように、dstec2.nr-practice.private
に対してpingを送ると、無事DstEC2に到達できることが確認できました。
パターン2
「Resolver Endpointを使用しアカウントBに名前解決リクエストを転送する」
次に紹介するのは、Resolver Endpointを使用してアカウントAからアカウントBに名前解決リクエストを転送する方式です。
※パターン2を進める前に、パターン1で実施したSrcVPCのホストゾーンへの関連付けは削除しておきます。関連付けの削除はAWS管理コンソールからでも実施可能です。
アカウントAにアウトバウンドエンドポイントを作成する
まず、アカウントAのSrcVPCにアウトバウンドエンドポイントを作成します。


上記のように各設定値を入力しアウトバウンドエンドポイントを作成します。
エンドポイントに適用するセキュリティグループは、AWSの公式ドキュメントに則って設定します。
また今回はマルチAZ構成をとっていないため、IPアドレス#1と#2はともに同じサブネットに作成してあります。
アカウントBにインバウンドエンドポイントを作成する
続いて、アカウントBのDstVPCにインバウンドエンドポイントを作成します。


上記のように各設定値を入力しインバウンドエンドポイントを作成します。
セキュリティグループやIPアドレスについては、アウトバウンドエンドポイントを作成した際と同様です。
アカウントA側でリゾルバールールを作成しアウトバウンドエンドポインに紐づける
次に、アカウントA側でリゾルバールールを作成します。

上記のように各設定値を入力し、dstec2.nr-practice.private
の名前解決リクエストをアカウントBのインバウンドエンドポイントに転送するようなルールを作成します。
アウトバウンドエンドポイントには前の手順で作成したアウトバウンドエンドポイントを指定し、ターゲットIPアドレスには前手順で作成したインバウンドエンドポイントのIPアドレスを設定します。
名前解決および疎通確認
それではパターン1と同様に、SrcVPCのEC2からDstVPCのEC2に向かってpingを送ってみます。
[ec2-user@ip-10-1-10-77 ~]$ ping -c 4 dstec2.nr-practice.private
PING dstec2.nr-practice.private (10.2.10.70) 56(84) bytes of data.
64 bytes from ip-10-2-10-70.ap-northeast-1.compute.internal (10.2.10.70): icmp_seq=1 ttl=126 time=1.36 ms
64 bytes from ip-10-2-10-70.ap-northeast-1.compute.internal (10.2.10.70): icmp_seq=2 ttl=126 time=0.985 ms
64 bytes from ip-10-2-10-70.ap-northeast-1.compute.internal (10.2.10.70): icmp_seq=3 ttl=126 time=1.33 ms
64 bytes from ip-10-2-10-70.ap-northeast-1.compute.internal (10.2.10.70): icmp_seq=4 ttl=126 time=2.16 ms
--- dstec2.nr-practice.private ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 0.985/1.459/2.157/0.429 ms
パターン2でも、dstec2.nr-practice.private
に対してpingを送ると、無事DstEC2に到達できることが確認できました。
おわりに
いかがでしたでしょうか。
今回は、他アカウントのホストゾーンがドメインの情報を持っている場合に自アカウント内のリソースから名前解決を行う方式を2パターン紹介しました。
実際のPJでは可用性や信頼性を考慮して構築する必要がありますが、どちらのパターンでもそこまで手間をかけずに他アカウントのホストゾーンにアクセスすることができました。
今後もPJでのネットワーク構築等の経験を踏まえ、様々なノウハウを共有できればと思います。