AWS Transit Gatewayを使用してEC2同士のクロスアカウント通信を行う

はじめに
こんにちは、yuuchanです。
前回執筆時とは違う新しいPJに参画し、AWSを用いて複数のアカウントが絡んだりオンプレ環境との接続も絡んだりするような、比較的複雑なネットワークを構築するタスクを担当しています。
比較的規模の大きいネットワークの設計は考慮しなければいけない観点が多くあり大変ですが、あまり普段触らないサービスにもチャレンジできスキルアップにもつながっていると感じています。
さて今回は、AWS Transit Gatewayというサービスを使用し、自AWSアカウントにあるEC2と他AWSアカウントにあるEC2との間で通信ができるようなネットワークを作成していきたいと思います。
今回作成するネットワークの構成

今回AWS Transit Gateway(以下、TGW)を用いてクロスアカウントでの通信を検証するにあたり、上図のような構成でネットワークの構築を行います。
最終的に、それぞれのアカウントにあるEC2インスタンス間でpingを使用し疎通をとることを目標とします。
VPC、サブネット、EC2インスタンスの作成
まず、それぞれのアカウントにVPCやサブネット、EC2インスタンスといった、基本的なリソースを作成します。
こちらの詳細な作成手順については省略いたします。
それぞれのアカウントに以下のようなリソースを作成しました。
Account 1
・VPC

・サブネット

・ルートテーブル

・EC2

Account 2
・VPC

・サブネット

・ルートテーブル

・EC2

Transit Gatewayの作成
前節でVPC等の基本的なリソースの作成ができました。
いよいよ主役となるTGWを作成していきます。
TGWはVPCの一機能になりますので、管理コンソールのVCPダッシュボードから作成できます。
以下のようなパラメータを入力しTGWを作成しました。
※Account 1側で作成します。

作成したTGWの状態が「Pending」->「Available」になったら利用可能になります。
Transit Gateway Attachmentの作成、接続
TGWを介して通信を行うために、各アカウントのVPCをTGWに接続していきます。
接続するためにはTransit Gateway Attachment(以下、TGWアタッチメント)というリソースを作成し、各VPCに紐つける必要があります。
Account 1
TGWと同様にVPCダッシュボードから、以下のようなパラメータで作成しました。

作成したTGWアタッチメントの状態が「Pending」->「Available」になったら利用可能になります。
TGWを作成したアカウント側でのTGWアタッチメントの作成およびVPCへの紐付けは、この作業のみで完了です。
Account 2
TGWを作成していない方のアカウントでのTGWアタッチメントの作成およびVPCへの紐付けは、少し追加の作業が必要になります。
リソース共有の作成 (Account 1側での操作)
まずAccount 1側で作成したTGWの画面に移動し「リソースの共有」を選択します。

Resource Access Managerの画面に遷移するので、以下画像とおりにリソース共有を作成し前節で作成したTGWを追加します。


プリンシパルタイプとしてAWSアカウントを選択し、共有したい相手(Account 2)のAWSアカウントIDを入力し追加します。

入力した内容を確認し、リソース共有の作成を完了させます。
以上でAccount 1側でリソース共有を作成しAccount 2側へ共有リクエストを送ることができました。
リソース共有の承認 (Account 2側での操作)
Account 1からのリソース共有リクエストを承認していきます。
Resource Access Managerを開き、「自分と共有」->「リソースの共有」の画面を開きます。

一覧にAccount 1からのリソース共有が表示されるので、選択し「リソース共有を承諾」します。


ステータスが「アクティブ」になればリソース共有完了です。

TGWアタッチメントの作成 (Account 2側での操作)
引き続きAccount 2側でのTGWアタッチメントを作成していきます。
リソース共有が完了すると、TGWアタッチメントの作成画面において以下のようにAccount 1側で作成したTGWが参照できるようになります。
作成手順はAccount 1側でTGWアタッチメントを作成した際と同様です。

作成したTGWアタッチメントの状態が「Pending」->「Available」になったら利用可能になります。
TGWアタッチメントの承諾 (Account 1側での操作)
Account 1側で、「Transit Gateway アタッチメントを承諾」すればAccount 2側のTGWアタッチメント作成は完了です。


ルートテーブル、セキュリティグループの編集
最後に、各VPCのルートテーブルにTGW(TGWアタッチメント)をターゲットとするルートを登録します。
また、各EC2に適用されているセキュリティグループにも、他アカウントからのインバウンド通信を許可する設定を追加します。今回はpingによる疎通確認を行う想定ですので、ICMPのインバウンド通信を許可しておきます。
Account 1
・ルートテーブル

・セキュリティグループ

Account 2
・ルートテーブル

・セキュリティグループ

クロスアカウント通信の確認
ここまでの手順で、TGWを介して別アカウントに存在するEC2同士が通信を行う準備ができました。
早速、期待通りに通信ができるか確認していきます。
Account 1 -> Account 2の通信

Account 2 -> Account 1の通信

それぞれのアカウントのEC2から他方のEC2に対してpingが通るか試行してみたところ、無事パケットが到達していることが確認できました。
おわりに
今回は、TGWを使用して他アカウントに存在するEC2リソースとの通信を行う手順と、その確認結果を紹介いたしました。
TGWはVPC以外にもDirect ConnectやVPNなどとの接続にも対応しており、オンプレ環境が絡むようなより複雑なネットワークを構築する際にとても有用です。
今後も、AWSにおけるネットワークまわりのノウハウを共有していけたらと思います。