遙か彼方のVPCエンドポイントを叩く

めちゃくちゃ久しぶりにネットワーク周りを触ったので備忘録。

# やりたいこと
異なるリージョンに作ったVPCエンドポイント（以下VPCe）を、東京リージョンからインターリージョンVPCピアリング越しに叩く。

# 目的
発端はDatadogのエンドポイント（バージニア北部にしかない）をVPCe経由で叩けるかを調べ始めたことだったが（ちなみにこれは[できる](https://docs.datadoghq.com/ja/agent/guide/private-link/?tab=%E3%83%A1%E3%83%88%E3%83%AA%E3%82%AF%E3%82%B9)らしい）、あれこれ触っている内に途中から目的が**リハビリ**に変わった。

# 環境
こんな感じ。
Secure subnetにはNAT Gatewayへのルートが切られておらず、インターネットへの経路がない点がポイント。
![インターリージョンでVPCe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/2e75ce1e-4836-9d45-1234-d2dfe636bbe1.png)

# 準備
まずは、記憶が正しいことを念のため確認。
その昔はインターリージョンVPCピアリング越しにVPCeを叩くことはできなかったが、今はできるようになっているはず。

[AWS PrivateLink が、インターリージョン VPC ピアリングを経由したアクセスをサポート](https://aws.amazon.com/jp/about-aws/whats-new/2018/10/aws-privatelink-now-supports-access-over-inter-region-vpc-peering/)

**2018年の記事**じゃないですか。
既に3年以上前の出来事だったとは。。。ジャネーの法則は正しい気がしてきたぞ。

一応マニュアルにも目を通しておく。

[インターフェイスVPCエンドポイント](https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/vpce-interface.html)
[VPCピア機能とは](https://docs.aws.amazon.com/ja_jp/vpc/latest/peering/what-is-vpc-peering.html)

# ステップバイステップ
今回はアクセス元の東京から見て、遠い側から順に作っていく。
サブネットは既に存在する前提でスタート。

## 1. VPCeを作成
作るものは以下の通り。

- VPCe
    - 公式ドキュメント同様、Kinesis Data Streamsを題材に使う（`com.amazonaws.us-east-1.kinesis-streams`）。
    - サブネットにはアクセス元として使うSecure subnet（`10.100.31.0/24`）を選択する。
    - エンドポイントポリシーは今回の主眼ではないので、デフォルトのままにする。
- セキュリティグループ
    - VPCeに貼るためのセキュリティグループ。
    - 今回はAPIを受け付けるため、Ingressで`443/tcp`を空けておく。
    - 東京リージョンのSecure subnetから接続できればよいので、ソースレンジとして`10.100.31.0/24`を指定する。

こういう感じになる。
![KDS-VPCe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/4622860b-fb9f-af8a-3d88-a9a126f05532.png)
![KDS-VPCe2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/de36ec4d-c21c-ecff-c9dd-285eed6591cc.png)
![KDS-VPCe3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/f9ec4d1a-0c05-6641-3a64-4ab57009d18a.png)
![sg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/6d045528-30fe-8714-faf6-46878259172f.png)

デフォルトでプライベートDNS名が有効になっているが、同僚によるとプライベートDNS名（AWSサービスの[本来のエンドポイント](https://docs.aws.amazon.com/ja_jp/general/latest/gr/ak.html)）をプライベートIPに解決してくれる機能）はリージョン越しでは動かないらしいので、今回はこれはお飾りということになる。

## 2. VPCピアリングを設定
東京リージョンのVPCをリクエスタ、バージニア北部リージョンのVPCをアクセプタとしたインターリージョンVPCピアリングを作成する。
東京側では、以下のような画面から、対象サービス・VPC・サブネット・セキュリティグループを順次設定していく。
![creating-pcx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/dc18fc5f-26e2-8a87-97b2-67c4eee2f599.png)

あとは、バージニア北部側でこのピアリング接続をアクセプトするだけ。それぞれ、識別しやすいようNameタグを付けておく。
作成が完了すると、それぞれ以下のような構成ができる。

【東京側】
![tokyo-pcx1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/7fffb29f-04b0-de09-3c3a-bbc992546ad2.png)

【バージニア北部側】
![virginia-pcx1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/c3aac35a-7d1b-2214-a555-40250de1ff61.png)

なお、[相手VPC内のEC2のDNS名をプライベートIPに解決するためのオプション](https://docs.aws.amazon.com/ja_jp/vpc/latest/peering/modify-peering-connections.html)があるが、今回はEC2の名前解決をするわけではないので、これらはリクエスタ側・アクセプタ側いずれも無効（デフォルト）で構わない。

## 3. ルートテーブルを設定
既にサブネットに貼られているルートテーブルを修正して、VPCピアリングへの経路を掘る。
この時、東京側だけではなくバージニア北部側にもちゃんとルートを設定するのがポイント（うっかり忘れて、しばらく時間を溶かした。。。）。
こんな感じになっているのが正解。

ちなみに今回は関係しないが、東京側にあるpvce-xxxのルートは、S3とDynamoDBのゲートウェイ型VPCeにルーティングするためのもの。昨今はインターフェイス型VPCeが主軸で、ゲートウェイ型はすっかり影が薄くなった感もあるが、これはこれで**利用量が無料**という絶対的な優位性があり、NAT Gatewayの料金抑制手段として意外に出番が多かったりする。

【東京側】
![rt-tokyo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/48a5a207-3d04-cab6-1a11-37f4a9afa940.png)
![tokyo-pcx3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/2cf96c65-44e3-edfa-a126-234aea5952b4.png)

【バージニア北部側】
![rt-virginia.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/2df6cd05-fb0c-982b-ba55-0c32097c0e61.png)
![virginia-pcx3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609876/3d258112-c9dd-2092-f9d1-4a0009821a0d.png)

## 4. Secure subnet上にEC2を作成
インターネットに繋がらないEC2（`ec2-secure`）を作る。
ここも、直接アクセスできるようにVPCeでゴニョゴニョすることも考えたが、話がややこしくなるのでいったん忘れて古のSSHエージェントフォワーディング（`ssh -A`）で進める。
具体的には、`ec2-secure`に貼ったセキュリティグループのIngressに、次の`ec2-public`に貼るセキュリティグループからの`22/tcp`を許可しておけば、エージェントフォワーディングを使って多段ログインができる。
今回の主眼ではないので、EC2の作成ステップも含めて詳細は省略。

## 5. Public subnet上にEC2を作成
インターネットに繋がるEC2（`ec2-public`）を作る。
ここも詳細は省略。

## 6. インターネットに接続できないことを確認
準備ができたので、Secure subnet上のEC2に入り、インターネットへの疎通ができず、AWSコマンドもタイムアウトすることを確認する。
`ec2-public`に手元の端末からエージェントフォワーディングで入り、`ec2-secure`にsshする。

```bash
❯ ssh ./testKeypair.pem -A ec2-user@ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com
Last login: Sat Feb  5 01:01:10 2022 from XXXXXX

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-XXX-XXX-XXX-XXX ~]$ ssh 10.100.31.118
Last login: Sat Feb  5 01:01:16 2022 from ip-XXX-XXX-XXX-XXX.ap-northeast-1.compute.internal

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-10-100-31-118 ~]$ aws ec2 describe-instances --region ap-norhteast-1

Could not connect to the endpoint URL: "https://ec2.ap-norhteast-1.amazonaws.com/"
[ec2-user@ip-10-100-31-118 ~]$ curl -XGET https://www.google.com/
^C
```

## 7. 疎通確認
バージニア北部のVPCe経由でAWS CLIを実行できるか、疎通確認。

```bash
[ec2-user@ip-10-100-31-118 ~]$ aws kinesis list-streams --region us-east-1 --endpoint-url https://vpce-0e9251e82ff15963a-XXXXXXXX.kinesis.us-east-1.vpce.amazonaws.com
{
    "StreamNames": [
        "LabStreamData",
        "taxi-trip-events"
    ]
}
```

**無事疎通**した。
ちなみにプライベートDNS名（本来のエンドポイント名）はグローバルIPに解決されるためこちらは通らない（仕様）。

```bash
[ec2-user@ip-10-100-31-118 ~]$ aws kinesis list-streams --region us-east-1
^C
[ec2-user@ip-10-100-31-118 ~]$ aws kinesis list-streams --region us-east-1 --endpoint-url https://kinesis.us-east-1.amazonaws.com
^C
[ec2-user@ip-10-100-31-118 ~]$ nslookup kinesis.us-east-1.amazonaws.com
Server:		10.100.0.2
Address:	10.100.0.2#53

Non-authoritative answer:
Name:	kinesis.us-east-1.amazonaws.com
Address: 3.91.171.230
```

# まとめ
インターリージョンVPCピアリングを介して、他リージョンのVPCeに通信できることが確認できた。

2022年現在、[リージョン間通信は常にAWSプライベート網を通ることが明記](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/how-it-works.html#what-is-aws-global-network)されていることから、これは自宅の裏庭から東海岸にどこ○もドアで顔を出すような未来感がある。

...と、2018年の機能を今さらながらに試しての感想でした。

---

# おまけ
東京側にVPCeを作った場合の挙動。

```bash
[ec2-user@ip-10-100-31-118 ~]$ aws kinesis list-streams --region ap-northeast-1 --endpoint-url https://vpce-04a505fcafb9fa948-XXXXXXXX.kinesis.ap-northeast-1.vpce.amazonaws.com
{
    "StreamNames": [
        "Foo",
        "Sample000"
    ]
}
```

```bash
[ec2-user@ip-10-100-31-118 ~]$ aws kinesis list-streams --region ap-northeast-1
{
    "StreamNames": [
        "Foo",
        "Sample000"
    ]
}
```

こちらはエンドポイント固有のDNS、プライベートDNS名、いずれも通った。