複数 VPC を Transit Gateway で集約接続し VPC 間のルーティングを制御する
AWS Transit Gateway(TGW)は、複数の VPC やオンプレミスネットワークを 1 つのハブに集約して相互接続するマネージドサービスです。VPC ピアリングでは接続が増えるほどフルメッシュ構成が複雑化しますが、TGW を使えば各 VPC を「ハブ」に 1 本ずつ繋ぐだけで相互通信を実現できます。このハンズオンでは 3 つの VPC を作成し、TGW でルーティングを集約・制御する一連の流れを体験します。
| 項目 | 内容 |
|---|---|
| 対象サービス | Transit Gateway、VPC、EC2、ルートテーブル、Session Manager |
| 主な学習内容 | TGW 作成・VPC アタッチメント・ルート伝播・TGW ルートテーブルによる通信制御 |
| 所要時間 | 75〜90 分 |
| 難易度 | ★★★☆☆(中級者向け) |
| 前提知識 | VPC・サブネット・ルートテーブル・セキュリティグループの基礎知識 |
| 費用目安 | 約 1〜3 USD(TGW アタッチメント時間課金 + EC2。数時間で完了しクリーンアップ前提) |
| 観点 | VPC ピアリング | Transit Gateway |
|---|---|---|
| 接続形態 | 1 対 1(フルメッシュ) | ハブ & スポーク |
| 接続数(N VPC) | N×(N-1)/2 本 | N 本 |
| 推移的ルーティング | 不可 | 可能 |
| ルート制御 | 各 VPC ルートテーブル | TGW ルートテーブルで集中管理 |
| 課金 | データ転送のみ | アタッチメント時間 + データ処理 |
このハンズオンで構築する構成です。3 つの VPC を Transit Gateway に接続し、VPC-A と VPC-B は相互通信可能、VPC-C は最終ステップで分離制御を試します。
10.0.0.0/1610.1.0.0/1610.2.0.0/16TGW で接続する VPC は CIDR が重複してはいけません。重複するとルーティングが成立しません。
| VPC 名 | VPC CIDR | サブネット CIDR | EC2 |
|---|---|---|---|
| VPC-A | 10.0.0.0/16 | 10.0.1.0/24 | EC2-A(10.0.1.x) |
| VPC-B | 10.1.0.0/16 | 10.1.1.0/24 | EC2-B(10.1.1.x) |
| VPC-C | 10.2.0.0/16 | 10.2.1.0/24 | EC2-C(10.2.1.x) |
TGW のルーティングには「アソシエーション」と「プロパゲーション(伝播)」の 2 概念があります。
デフォルト TGW ルートテーブルでは全アタッチメントが自動アソシエート・自動プロパゲートされ、全 VPC が相互通信できます。Step5 ではこれを手動制御して VPC を分離します。
AmazonSSMManagedInstanceCore)を用意できることすべてのリソースを同一リージョンに作成します。このハンズオンでは ap-northeast-1(東京) を使用します。コンソール右上のリージョンを固定してください。
各 EC2 はプライベートサブネットに配置し、SSH キーやパブリック IP を使わずに Session Manager で接続します。これにより踏み台不要で安全に検証できます。Session Manager を使うには EC2 に SSM 用 IAM ロールをアタッチし、SSM エンドポイントへの到達性(NAT または VPC エンドポイント)が必要です。本ハンズオンでは簡易化のため各 VPC に NAT ゲートウェイ、もしくはパブリックサブネット + パブリック IP の EC2 を使う構成でも代替可能です。
CIDR の重ならない 3 つの VPC を作成し、各 VPC に EC2 を 1 台ずつ起動します。ここでは VPC-A・VPC-B を中心に進め、VPC-C は Step5 用に用意します。
VPC コンソール → 「VPC を作成」 →「VPC など」を選択すると、サブネット・ルートテーブルまで一括作成できます。VPC-A を以下で作成します。
同様に tgw-vpc-b(10.1.0.0/16)、tgw-vpc-c(10.2.0.0/16)を作成します。
EC2 に Session Manager で接続するため、AmazonSSMManagedInstanceCore ポリシーをアタッチした EC2 用ロール(インスタンスプロファイル)を用意します。IAM → ロール → 「ロールを作成」→ 信頼されたエンティティ「EC2」→ AmazonSSMManagedInstanceCore を選択 → ロール名 ec2-ssm-role で作成します。
EC2 コンソール →「インスタンスを起動」で 3 台起動します。各台の設定例(EC2-A):
EC2-B(tgw-vpc-b)、EC2-C(tgw-vpc-c)も同様に起動します。
VPC 間で ping 疎通を確認するため、各 EC2 のセキュリティグループのインバウンドに以下を追加します。
| タイプ | プロトコル | ソース |
|---|---|---|
| すべての ICMP - IPv4 | ICMP | 10.0.0.0/8(検証用に広めに許可) |
本番環境では必要な CIDR・ポートのみに絞ってください。ここでは 10.0.0.0/8 で 3 VPC をまとめて許可しています。
3 つの VPC とそれぞれに 1 台ずつ EC2(計 3 台)が「実行中」になり、Session Manager の「接続」ボタンが有効(緑)になっていれば準備完了です。各 EC2 のプライベート IP をメモしておきます。
ハブとなる Transit Gateway を作成し、VPC-A と VPC-B をアタッチします。
VPC コンソール左メニュー → 「Transit Gateway」→「Transit Gateway を作成」 をクリックします。
| 設定項目 | 設定値 |
|---|---|
| 名前タグ | handson-tgw |
| 説明 | Hands-on Transit Gateway |
| Amazon 側 ASN | デフォルト(64512)のまま |
| デフォルトルートテーブルの関連付け | 有効(チェック) |
| デフォルトルートテーブルの伝播 | 有効(チェック) |
| DNS サポート | 有効 |
「Transit Gateway を作成」をクリックします。状態が available になるまで数分待ちます。
両方を有効にすると、後でアタッチする VPC が自動的にデフォルト TGW ルートテーブルに関連付けられ、CIDR が伝播されます。つまり アタッチするだけで全 VPC が相互通信できる状態になります。Step5 ではこの自動動作を理解した上で手動制御を行います。
「Transit Gateway アタッチメント」→「Transit Gateway アタッチメントを作成」 をクリックします。
| 設定項目 | 設定値 |
|---|---|
| 名前タグ | attach-vpc-a |
| Transit Gateway ID | handson-tgw |
| アタッチメントタイプ | VPC |
| VPC ID | tgw-vpc-a |
| サブネット | tgw-vpc-a のサブネット(AZ ごとに 1 つ選択) |
「Transit Gateway アタッチメントを作成」をクリックします。
同じ手順で VPC-B をアタッチします。名前タグ attach-vpc-b、VPC ID tgw-vpc-b を指定します。
VPC-C は Step5 のルート制御の検証で使用するため、この時点ではアタッチしないでおきます。
アタッチメント一覧で attach-vpc-a と attach-vpc-b の状態が available になれば成功です(数分かかります)。
TGW にアタッチしただけでは VPC 内のサブネットは相手 VPC への経路を知りません。各 VPC のサブネットルートテーブルに「相手の CIDR → TGW」のルートを追加する必要があります。
VPC コンソール → 「ルートテーブル」→ VPC-A の EC2-A が属するサブネットに関連付いたルートテーブルを選択 → 「ルート」タブ →「ルートを編集」 をクリックします。以下を追加します。
| 送信先(Destination) | ターゲット(Target) |
|---|---|
| 10.1.0.0/16(VPC-B の CIDR) | Transit Gateway → handson-tgw |
「変更を保存」をクリックします。
同様に VPC-B のサブネットルートテーブルに、VPC-A への戻りルートを追加します。
| 送信先(Destination) | ターゲット(Target) |
|---|---|
| 10.0.0.0/16(VPC-A の CIDR) | Transit Gateway → handson-tgw |
ping は「行き」と「帰り」の両方の経路が必要です。VPC-A 側だけにルートを追加しても、VPC-B から VPC-A への戻り経路がないと疎通しません。必ず両 VPC にルートを追加してください。
VPC-A と VPC-B のルートテーブルに、それぞれ相手の CIDR 宛て TGW ルートが「アクティブ」状態で表示されていれば成功です。
EC2-A から EC2-B へ ping を打ち、TGW 経由で VPC をまたいだ通信が成立することを確認します。
EC2 コンソール → tgw-ec2-a を選択 → 「接続」→「セッションマネージャー」タブ →「接続」をクリックします。ブラウザ上でターミナルが開きます。
EC2-B のプライベート IP(例:10.1.1.x)に対して ping を実行します。
応答が返れば TGW 経由で VPC-A → VPC-B の通信が成立しています。
64 bytes from 10.1.1.100: icmp_seq=1 ttl=126 time=1.20 ms 64 bytes from 10.1.1.100: icmp_seq=2 ttl=126 time=0.98 ms --- 10.1.1.100 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss
EC2-B のセッションを開き、EC2-A(10.0.1.x)へ ping して双方向の疎通を確認します。
available かEC2-A ⇔ EC2-B 間で ping 応答が返れば、Transit Gateway によるハブ & スポーク接続が成功です 🎉
応用として VPC-C をアタッチし、TGW ルートテーブルの「関連付け」と「伝播」を手動制御することで、VPC-C を VPC-A とは通信させ、VPC-B とは遮断するといったセグメント分離を実現します。
Step2 と同じ手順で VPC-C をアタッチします(名前タグ attach-vpc-c、VPC tgw-vpc-c)。デフォルト伝播が有効なため、この時点では VPC-C も全 VPC と通信可能な状態です。
「Transit Gateway ルートテーブル」→「Transit Gateway ルートテーブルを作成」 で 2 つ作成します。
| 名前タグ | 用途 |
|---|---|
| rt-prod | VPC-A・VPC-B 用(相互通信グループ) |
| rt-isolated | VPC-C 用(VPC-A とのみ通信、VPC-B とは遮断) |
各ルートテーブルの「関連付け」タブ →「関連付けを作成」で、アタッチメントを割り当てます。
| TGW ルートテーブル | 関連付けるアタッチメント |
|---|---|
| rt-prod | attach-vpc-a, attach-vpc-b |
| rt-isolated | attach-vpc-c |
アタッチメントから「入ってくる」パケットが、どの TGW ルートテーブルを見て転送先を決めるかの設定です。VPC-C から出たパケットは rt-isolated を参照します。
各 TGW ルートテーブルの「伝播」タブ →「伝播を作成」で、どのアタッチメントの CIDR をそのルートテーブルに登録するかを決めます。
| TGW ルートテーブル | 伝播させるアタッチメント | 結果(このRTが知る経路) |
|---|---|---|
| rt-prod | attach-vpc-a, attach-vpc-b, attach-vpc-c | VPC-A・B・C すべてへ到達可 |
| rt-isolated | attach-vpc-a のみ | VPC-A へのみ到達可(VPC-B は知らない) |
rt-isolated に VPC-A の経路があるので通信可能rt-isolated に VPC-B の経路がないので遮断rt-prod に VPC-C の経路があるので通信可能これにより「VPC-A は共有サービス VPC、VPC-B と VPC-C は互いに分離されたテナント」のような設計が表現できます。
VPC-C のサブネットルートテーブルに、VPC-A 宛てのルートを追加します(Step3 と同じ要領)。
| 送信先 | ターゲット |
|---|---|
| 10.0.0.0/16(VPC-A) | Transit Gateway → handson-tgw |
VPC-A のルートテーブルにも VPC-C 宛て(10.2.0.0/16)の TGW ルートを追加します。
EC2-C に Session Manager で接続し、ping を実行して期待通りの分離になっているか確認します。
# EC2-C のセッションで実行 ping -c 3 10.0.1.100 # VPC-A 宛て → 成功するはず ping -c 3 10.1.1.100 # VPC-B 宛て → タイムアウトするはず(遮断)VPC-C → VPC-A は ping 成功、VPC-C → VPC-B はタイムアウトすれば、TGW ルートテーブルによるセグメント分離が成功しています。TGW のルートテーブルを使えば VPC ごとに「誰と通信できるか」を中央集権的に制御できることが体験できました。
Transit Gateway はアタッチメントごとに時間課金が発生します(1 アタッチメントあたり約 $0.07/時 + データ処理)。EC2・NAT ゲートウェイ(作成した場合)も課金対象です。
tgw-ec2-a / tgw-ec2-b / tgw-ec2-c を選択 →「インスタンスを終了」
attach-vpc-a / -b / -c を選択 →「削除」。状態が deleted になるまで待つ
rt-prod / rt-isolated を削除
handson-tgw を選択 →「削除」(アタッチメントがすべて消えてから実行可能)
tgw-vpc-a / -b / -c を削除(NAT ゲートウェイを作った場合は先に削除)
ec2-ssm-role を削除
| 習得したスキル | 実践内容 |
|---|---|
| Transit Gateway の作成 | ハブとなる TGW を作成し VPC をアタッチ |
| VPC アタッチメント | 複数 VPC を 1 つのハブに集約接続 |
| ルーティング設計 | VPC サブネットルートと TGW ルートの 2 階層を理解 |
| VPC 間疎通確認 | Session Manager + ping で TGW 経由通信を検証 |
| セグメント分離制御 | TGW ルートテーブルのアソシエーション/プロパゲーションで通信を制御 |