色々なネットワーク間接続を試しつつTransit Gatewayを理解する。（その１：VPC Peering）

# はじめに
AWSには各ネットワークを繋ぐためのサービスが色々とあります。

必要に応じて毎回調べながら導入するようなことをよくやっていますが、改めてきちんと整理してAWSのネットワーク間接続をまとめてみようと思い、今回から何回かに分けてAWSのネットワーク間接続を色々と試しつつ学んでいこうと思います。

また、仕事で`Transit Gateway`を使うことも増えたことと、資格勉強も兼ねて特に`Transit Gateway`に関しては深く調べてみたいと思います。

- 【次】[色々なネットワーク間接続を試しつつTransit Gatewayを理解する。（その２：Site-to-Site VPN）](https://qiita.com/sakai00kou/items/2259980f282af5eca259)

# AWSのネットワーク間接続について
TCP/IPの世界において、端末間で通信を行うためには同一ネットワークである必要があり、同一ネットワーク以外の端末などと通信を行うためにはルータなどのゲートウェイ機器が必要となります。

AWSでは`VPC`内通信であれば、デフォルトで作られるルートテーブルに従って双方向に通信できますが、`VPC`を超えた通信については、色々なゲートウェイサービスを利用する必要があります。

|サービス|説明|備考|
|:--|:--|:--|
|Internet Gateway|インターネットと双方向通信するために必要|外→内、内→外の通信|
|NAT Gateway|インターネットと片方向通信するために必要|内→外の通信のみ|
|VPC Peering接続|VPC間を接続するために必要|VPC間の接続なので相手VPCもAWSである必要がある|
|VPN接続|離れたネットワークと接続するために必要|AWS以外のネットワークとも接続できる|
|Direct Connect|離れたネットワークと接続するために必要|オンプレのネットワークと接続するために使用|
|Transit Gateway|VPC間を接続したりVPNなどと連携したりするために必要|大規模のネットワークを構築するのに適している|

`Direct Connect`も勉強として試してみたいところですが、データセンターに機器を設置したりしないといけないことから、さすがに個人で試すことは厳しいので除外します。

また、今回は`VPC`間や他の内部ネットワークとの接続を試すことを目的としているため、`Internet Gateway`と`NAT Gateway`の説明も除外します。

# VPC Peeringとは
`VPC Peering`とは`VPC`間を直接接続するのに使うサービスとなります。

`Transit Gateway`でも同じように接続することはできますが、自分も相手もAWS環境であれば一番手軽に接続できるサービスです。

費用も他のサービスと比べて安く、相手が別AWSアカウントのVPCとの接続だとしても、同一のアベイラビリティゾーン（`AZ`）への通信であれば費用はかからず、別`AZ`の場合は1GBあたり$0.01となります。

そのため、AWS同士のネットワークを接続する場合には、まず最初に検討すべき接続方法となります。

|AZ通信|費用|
|:--|:--|
|同一AZ内|無料|
|別AZ|$0.01/GB|

ちなみに`ap-northeast-1a`などのアベイラビリティゾーンの名前ですが、この名前はAWSアカウントごとに紐づいているゾーンは変わるそうなので、別のAWSアカウントの`VPC`と接続する場合は以下のように「**アベイラビリティゾーンID**」で判断するようにしてください。

![Monosnap_20231210_171518.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/3e2e6ce4-a1e3-bc99-c56f-2fbc8bbfd1db.png)

- [AWS リソースのアベイラビリティーゾーン ID](https://docs.aws.amazon.com/ja_jp/ram/latest/userguide/working-with-az-ids.html)

## VPC Peeringの制限
通常のIPネットワークの場合、以下のように複数ネットワークを経由したネットワークであっても、適切にルーティングを設定すれば双方向に通信できますが、`VPC Peering`では`VPC Peering`で繋いだ`VPC`としか通信できないようになっているので、`VPC Peering`を経由して更に他のネットワークへ行くことはできません。

![vpc_peering.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/bc1aff6b-55db-ddcb-e1aa-b8d09478f152.png)

そのため、A、B、Cそれぞれ双方向で通信を行うようにするためにはA、B、Cそれぞれフルメッシュで`VPC Peering`を行う必要があります。

また、`VPC Peering`は`VPC`あたり最大でも125接続しか作成できないため、拠点数が多い場合は利用できません。

- [VPC ピアリング接続のクォータ](https://docs.aws.amazon.com/ja_jp/vpc/latest/peering/vpc-peering-connection-quotas.html)

全拠点双方向で通信するためには、拠点が増えるごとに毎回ピアリングの設定を行う必要があることから設定の抜け漏れも起こる可能性が高くなるので、そのような場合は`Transit Gateway`の使用を検討しましょう。

# 同一AWSアカウント内のVPC Peering
実際に`VPC Peering`を試して見るため、AWSアカウントで適当な`VPC`、サブネット、EC2を作成して疎通確認を試してみます。

![vpc_peering_internal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/c53cb696-74b5-4e1d-b89b-d8c9ecea09f2.png)

## VPC Peering確認用VPCの作成
`VPC`の作成は「**VPCダッシュボード**」→「**お使いのVPC**」の「**VPCを作成**」から以下のような設定で行いました。

|項目|VPC-A設定|VPC-B設定|備考|
|:--|:--|:--|:--|
|作成するリソース|VPCなど|VPCなど|まとめてサブネットなど作成|
|名前タグの自動生成|自動生成|自動生成|
|名前|VPC-A|VPC-B|
|IPv4 CIDRブロック|10.20.0.0/16|10.30.0.0/16|任意のブロックを指定|
|IPv6 CIDRブロック|IPv6 CIDRブロックなし|IPv6 CIDRブロックなし|今回はIPv6は作成しない|
|テナンシー|デフォルト|デフォルト||
|アベイラビリティゾーン(AZ)の数|1|1|テストなので今回は1つだけ作成|
|パブリックサブネットの数|1|1||
|プライベートサブネットの数|0|0|今回はプライベートサブネットは作成しない|
|NATゲートウェイ|なし|なし||
|VPCエンドポイント|なし|なし|目的とは異なるので今回は作成しない|
|DNSホスト名を有効化|有効化|有効化|デフォルトのまま|
|DNS解決を有効化|有効化|有効化|デフォルトのまま|

リソースマップ的にはこんな感じ。

- VPC-A
![Monosnap_20231210_181957.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/afc32ba6-0b20-a3c6-65c4-85c0078dafdd.png)

- VPC-B
![Monosnap_20231210_182132.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/8abe0936-7d22-4c52-9b6f-2108dfbd2c63.png)

## 疎通確認用EC2の作成
疎通確認用の`EC2`もそれぞれの`VPC`に作成しておきます。

基本的にはデフォルト設定ですが、疎通確認するために`EC2`にログインするため、セッションマネージャ接続用のロールを新規作成＆アタッチします。

`EC2`作成時の「**高度な詳細**」から「**新しいIAMプロファイルの作成**」でロールを作成できます。

![Monosnap_20231210_224742.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/4c871543-3e3e-9f2c-100d-f83b9141a053.png)

|項目|設定|備考|
|:--|:--|:--|
|信頼されたエンティティタイプ|AWSのサービス||
|サービスまたはユースケース|EC2||
|ユースケース|EC2 Role for AWS Systems Manager|セッションマネージャ接続のため選択|
|ロール名|SessionManager-Role|任意の名前を指定|

その他`EC2`の設定は以下で設定しました。

|項目|VPC-A用EC2設定|VPC-B用EC2設定|備考|
|:--|:--|:--|:--|
|名前|VPC-A-EC2|VPC-B-EC2|任意の名前を指定|
|AMI|Amazon Linux 2023 AMI|Amazon Linux 2023 AMI||
|アーキテクチャ|64ビット(x86)|64ビット(x86)||
|インスタンスタイプ|t2.micro|t2.micro|||
|キーペア名|キーペアなしで続行|キーペアなしで続行|セッションマネージャで繋ぐため無しで作成|
|VPC|VPC-A-vpc|VPC-B-vpc|先程作成したVPCを指定|
|サブネット|VPC-A-subnet-public1-ap-northeast-1a|VPC-B-subnet-public1-ap-northeast-1a|先程作成したサブネットを指定|
|パブリックIPの自動割り当て|有効化|有効化|セッションマネージャを使用するため有効化|
|セキュリティグループ名|VPC-A-sg|VPC-B-sg|任意の名前を指定|
|説明|デフォルトのまま|デフォルトのまま||
|タイプ|すべてのICMP - IPv4|すべてのICMP - IPv4|Ping疎通確認用|
|プロトコル|ICMP|ICMP||
|ポート範囲|すべて|すべて||
|ソースタイプ|任意の場所|任意の場所||
|ソース|0.0.0.0/0|0.0.0.0/0||
|説明|空欄|空欄||
|IAMインスタンスプロフィール|SessionManager-Role|SessionManager-Role|先程作成したロールを指定|

なお、「**高度な詳細**」の設定は「**IAMインスタンスプロフィール**」設定のみ行い、他の設定は全てデフォルトの値とします。

## VPC Peeringの作成
準備ができたので、`VPC Peering`で`VPC`同士を接続します。

`VPC Peering`は「**VPCダッシュボード**」の「**仮想プライベートクラウド**」→「**ピアリング接続**」から「**ピアリング接続を作成**」より作成します。

今回は同じアカウント内での接続となるため、以下のように設定します。

![Monosnap_20231210_231728.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/9427b3b2-da20-4eb3-65d0-193324fae6b8.png)

ピアリングを行う場合、接続のリクエストを行う側（リクエスタ）から接続のリクエストを受け付ける側（アクセプタ）に接続のリクエストを行い、相手側から承認されれば`VPC Peering`で繋がるようになります。

アクセプタ側で1週間承認されないとリクエスト自体がキャンセルされるため、注意してください。

今回はリクエスタ、アクセプタ共に自分のアカウントなので「**アクション**」→「**リクエストを承認**」を行うと承認できます。

![Monosnap_20231210_232202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/4287ae4d-307e-6d71-e6eb-2f3c939156a7.png)

![Monosnap_20231210_233033.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/384a9d20-3010-26e4-3024-bfcaff5ae21a.png)

承認後、以下のようなインフォメッセージが表示されるため、「**ルートテーブルを今すぐ変更**」を選択してルートテーブルの追加を行います。

![Monosnap_20231210_233129.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/7b986339-28a3-e5a4-d086-fbd4749f4c98.png)

## ルートテーブルの追加
先程の設定で`VPC Peering`で`VPC-A`と`VPC-B`が繋がったので、それぞれのサブネットに付与されているルートテーブルに相手側`VPC`へ行くためのルーティングを設定します。

「**VPCダッシュボード**」の「**仮想プライベートクラウド**」→「**ルートテーブル**」から`VPC-A`、`VPC-C`のルートテーブルを選択して「**ルート**」タブ→「**ルートを編集**」でルーティングを追加します。

送信先を相手先ネットワーク、ターゲットで「**ピアリング接続**」を選び、先程作成したピアリングIDを指定すればOKです。

今回はそれぞれ以下のように設定しました。

- VPC-A用ルートテーブル設定

![Monosnap_20231211_092446.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/f4ad7501-cd29-75a0-83d9-811953e2613d.png)

- VPC-B用ルートテーブル設定

![Monosnap_20231211_092633.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/084f9c7f-881b-ea0e-2e2a-c7f946478069.png)

今回は相手先`VPC`のアドレスレンジ全てを対象とするため、「**10.xx.0.0/16**」と指定していますが、特定のセグメント宛の通信のみ`VPC Peering`で転送したい場合はセグメントに合わせて指定してください。

## 疎通確認
ネットワークの準備ができたので、先程作成した`EC2`インスタンスを使い、`VPC Peering`経由で疎通できるか確認してみます。

`EC2`インスタンスにはセッションマネージャー経由で接続できるように設定しているので、「**EC2ダッシュボード**」から「**インスタンス**」で先程作成したEC2インスタンスを選択→「**接続**」から「**セッションマネージャー**」タブの「**接続**」で作成したインスタンスに接続します。

![Monosnap_20231213_222644.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/b3377915-89dc-bddc-b776-30e1b52a322d.png)

今回は`VPC-A`側の`EC2`インスタンスは「**10.20.0.207**」、`VPC-B`側の`EC2`インスタンスは「**10.30.4.69**」のアドレスが振られたため、`VPC-A`側の`EC2`インスタンスから`VPC-B`側の`EC2`インスタンスに`ping`を実行した結果、以下のように疎通できました。

![Monosnap_20231213_223119.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/e00efb45-11e7-55e9-e9e4-74a53cd0e4f5.png)

# 別AWSアカウントとのVPC Peering
次は、別のAWSアカウントに存在する`VPC`と`VPC Peering`を行い、アカウント跨ぎの`VPC`とも接続できるかを確認してみようと思います。

![vpc_peering_external.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/37e2d596-64f7-23da-c198-121965192504.png)

## 別AWSアカウント側VPC Peering確認用VPCの作成
別のAWSアカウントと接続確認を行うため、別のAWSアカウントで以下`VPC`の作成を行いました。

|項目|VPC-C設定|備考|
|:--|:--|:--|
|作成するリソース|VPCなど|まとめてサブネットなど作成|
|名前タグの自動生成|自動生成|
|名前|VPC-C|
|IPv4 CIDRブロック|10.120.0.0/16|任意のブロックを指定|
|IPv6 CIDRブロック|IPv6 CIDRブロックなし|今回はIPv6は作成しない|
|テナンシー|デフォルト||
|アベイラビリティゾーン(AZ)の数|1|テストなので今回は1つだけ作成|
|パブリックサブネットの数|1||
|プライベートサブネットの数|0|今回はプライベートサブネットは作成しない|
|NATゲートウェイ|なし||
|VPCエンドポイント|なし|目的とは異なるので今回は作成しない|
|DNSホスト名を有効化|有効化|デフォルトのまま|
|DNS解決を有効化|有効化|デフォルトのまま|

同様に疎通確認用の`EC2`インスタンスも作成しておきます。

合わせてセッションマネージャ接続用IAMロールは先程と同様作成しておいてください。

|項目|VPC-C用EC2設定|備考|
|:--|:--|:--|
|名前|VPC-C-EC2|任意の名前を指定|
|AMI|Amazon Linux 2023 AMI||
|アーキテクチャ|64ビット(x86)||
|インスタンスタイプ|t2.micro|||
|キーペア名|キーペアなしで続行|セッションマネージャで繋ぐため無しで作成|
|VPC|VPC-C-vpc|先程作成したVPCを指定|
|サブネット|VPC-C-subnet-public1-ap-northeast-1a|先程作成したサブネットを指定|
|パブリックIPの自動割り当て|有効化|セッションマネージャを使用するため有効化|
|セキュリティグループ名|VPC-C-sg|任意の名前を指定|
|説明|デフォルトのまま||
|タイプ|すべてのICMP - IPv4|Ping疎通確認用|
|プロトコル|ICMP||
|ポート範囲|すべて||
|ソースタイプ|任意の場所||
|ソース|0.0.0.0/0||
|説明|空欄||
|IAMインスタンスプロフィール|SessionManager-Role|先程作成したロールを指定|

## AWSアカウントID、VPC IDの確認
別AWSアカウントの`VPC`と`VPC Peering`を行うためにはAWSアカウントIDと接続する`VPC`の`VPC ID`が必要となります。

今回は最初に操作したAWSアカウントで作成した`VPC-A`と別アカウントで作成した`VPC-C`を`VPC Peering`で接続しようと思うので、`VPC-C`側のAWSアカウントIDと`VPC-C`の`VPC ID`を確認します。

「**VPCダッシュボード**」より該当の`VPC`の詳細から`VPC ID`とAWSアカウント（所有者ID）を確認できるのでこちらを確認しておきます。

![Monosnap_20231215_155155.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/327e1cf7-b34c-319a-8c82-6990963145ab.png)

## 別AWSアカウントとのVPC Peeringの設定
同AWSアカウントで設定する場合と同様、`VPC Peering`の設定を行います。

今回は`VPC-A`と、別AWSアカウント上の`VPC`となる`VPC-C`を`VPC Peering`で接続しようと思います。

`VPC Peering`の作成はどちらのアカウントで作成しても良いですが、今回は`VPC-A`側のアカウントで以下のように設定します。

アカウントIDと`VPC ID`は先程確認したアカウントIDと`VPC ID`を入力します。

![Monosnap_20231215_155922.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/5993d672-1a70-ec4d-0d94-26a73bebbe72.png)

`VPC-A`側アカウントでピアリングを行うと、`VPC-C`側アカウントに以下のようなリクエストが届くため、`VPC-C`側アカウントで「**リクエストを承諾**」を行います。

![Monosnap_20231215_164521.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/b9f73c18-74c1-6bf7-7996-f7842f0252fe.png)

## ルートテーブルの追加
`VPC Peering`で`VPC-A`と`VPC-C`を接続したので、ルートテーブルを追加していきます。

- VPC-A用ルートテーブル設定

![Monosnap_20231215_165438.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/0b96e514-512a-deea-4fa1-a58052624906.png)

- VPC-C用ルートテーブル設定

![Monosnap_20231215_165611.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/bf756ef6-6e13-76ae-5362-66d5930bb857.png)

## 疎通確認
一通り設定できたので同一アカウント内の`VPC Peering`を行ったときと同様、セッションマネージャで`EC2`に接続して`ping`で確認を行います。

今回も`VPC-A`側の`EC2`インスタンスから`VPC-C`側`EC2`インスタンスに`ping`を行ったところ、以下のように無事疎通できました。

![Monosnap_20231215_170041.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/c7f87ca8-b46f-a729-f287-66d869f82578.png)

# 本当にVPC Peeringを経由した通信はできないのか？
`VPC Peering`を経由した通信はできないと書きましたが、本当にできないのか確認してみたいと思います。

先程までの手順で`VPC-A`から`VPC-B`、`VPC-C`ともに`VPC Peering`で接続できています。

そのため、ネットワーク的にはルーティングさえ行ってしまえば`VPC-B`から`VPC-C`に通信ができそうなので、`VPC-B`には`VPC-C`向けルートテーブル、`VPC-C`には`VPC-B`向けルートテーブルをそれぞれ設定します。

- VPC-B用ルートテーブル設定

![Monosnap_20231215_171419.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/716d68d8-5be8-4c02-605d-85ed4458941a.png)

- VPC-C用ルートテーブル設定

![Monosnap_20231215_171256.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/b664e7b9-e76c-4fce-d45b-6e72bd398c4e.png)

ルーティング的には`VPC-B`、`VPC-C`間で`ping`が届きそうですが、結果はドキュメントの通り、通信できませんでした。

![Monosnap_20231215_171818.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569912/a88062e6-8ebb-8fe3-23ea-da5fb391a8a5.png)

# おわりに
今回は色々あるAWSのネットワーク間通信サービスのうち、`VPC Peering`の設定を行ってみました。

同一アカウント内であっても別アカウントであっても簡単な手順で`VPC`同士を接続できるのでお手軽に接続できますが、同一AZ同士でなければ費用がかかってしまうため、その点は注意して設定する必要があると感じました。

次回は`Site to Site VPN`についてまとめてみたいと思います。