DirectConnectに直結していないVPCからオンプレサーバへアクセスする

# 1. はじめに

- 業務上でDirect Connect(DX)を含むネットワーク設計をしていて、少しクセのある要件に悩んだため、備忘のため検討結果をまとめておく。

:::note 
- 検討した構成は全て実機検証しているが、今回の記事は考え方をまとめるもので、具体的な手順のキャプチャなどは記載しない。
- もしかしたらよりよい接続方法などあるかもしれない。。
:::

# 2. 今回のネットワーク要件

- VPC-Aに接続されているVGWがDXGWに接続されている。
- VPC-Bに存在するサーバ(Origin)から、DXの先にあるオンプレサーバ(Target)にhttpアクセスしたい。(DXGWと直結しているVPC-AはCIDRが小さく、そこにはサーバを立てられない、という制約あり)
- VPC-BのCIDRをDX網側に広報できない。(VPC-Bと重複するCIDRがDX網に接続されている別拠点に既に存在する、という制約あり)
- DXはホスト型であるため、TransitVifなどは使用できない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/1d0970d7-225a-5bfd-dbea-6a6c72df55fd.png)

:::note 
2024/4/18 追記
- 通信方向が逆向きの要件の構成に関する別記事も作成しました。「[DirectConnectに直結していないVPCへ、オンプレサーバからアクセスする](https://qiita.com/mksamba/items/33c7b8b03c59b6db4543)」
:::


# 3. 構成検討

## 3.1 構成案
- 試行錯誤した結果、以下の案1,2,3の場合、要件を満たすことができた。
- なるべく構成がシンプルにできること、また今回はオンプレのターゲットサーバの数が少なく、NLBのターゲットグループへの登録の手間はかからないことから案1or2を採用することとした。

|案  |方式  |実現性  | 設定内容 | 注意点(デメリット) |
|---|---|---|---|---|
|1 |Peering + NLB  |○  |VPC-AとVPC-Bをpeering<br>VPC-AにNLBを設置|オンプレサーバを個別にNLBのターゲットに設定する必要がある
|2 |Privatelink + NLB  |○|VPC-AにNLBを設置、EndpointService作成<br>VPC-BにEndpoint作成|オンプレサーバを個別にNLBのターゲットに設定する必要がある
|3 |Transit Gateway + NAT gateway|○|VPC-AとVPC-BをTGWで接続<br>VPC-AにNATGW設置|TGW Attachment用Subnetが必要
|4 |Peering + NAT gateway|×|VPC-AとVPC-Bをpeering<br>VPC-BからNATGWを利用|この構成では接続不可だった

## 3.2 案1: Peering + NLB

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/f6346da9-c384-1216-cb14-366f6c1c7872.png)

### 設定内容
- VPC-AとVPC-BのPeeringを作成。
- VPC-A内にInternal NLBを作成。
    - 足だしは10.10.0.0/28へ。NLBのIPは10.10.0.7。
    - TARGET(10.0.0.6)のみを含むTargetGroupを作成しNLBに設定。
- RouteTableを更新。
    - VPC-A/Subnet(10.10.0.0/28)のRoutetable
        - dst: 10.0.0.0/24 target: VGW
        - dst: 10.20.0.0/16 target: peering
    - VPC-B/Subnet(10.20.0.0/24)のRoutetable
        - dst: 10.0.0.0/24 target: peering
        - dst: 10.10.0.0/24 target: peering

### 確認内容
- Originのインスタンスから「curl 10.10.0.7」で、NLBを経由して、Target(10.0.0.6)のnginxにhttpアクセスできることを確認。
- Targetのnginxのaccesslogで、アクセス元IPがNLBのIP(10.10.0.7)になっていることを確認。

## 3.3 案2: Privatelink + NLB

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/fb8dc707-b0a2-b9a4-fa20-3c5f89bfb445.png)

### 設定内容
- PrivateLinkを作成。
    - VPC-AにInternal NLBに紐づくEndpoint Serviceを作成。
    - VPC-Bに上記のEndpoint Serviceと接続するEndpointを作成。EndpointのIPは10.20.0.22。
- VPC-A内にInternal NLBを作成(案1と同じ)。
    - 足だしは10.10.0.0/28のみ。NLBのIPは10.10.0.7。
    - TARGET(10.0.0.6)のみを含むTargetGroupを作成しNLBに設定。

### 確認内容
- Originのインスタンスから「curl 10.20.0.22」で、PrivateLink及びNLBを経由して、Target(10.0.0.6)のnginxにhttpアクセスできることを確認。
- Targetのnginxのaccesslogで、アクセス元IPがNLBのIP(10.10.0.7)になっていることを確認。

## 3.4 案3: Transit Gateway + NAT Gateway

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/1b10dabe-3954-bf5e-e99e-43fe428309e8.png)


### 設定内容
- Transit Gatewayを作成。
- Transit Gateway Attachementを2つ作成。
    - VPC-AのSubnet 10.10.0.16/28に接続するAttachment
    - VPC-BのSubnet 10.20.0.0/24に接続するAttachment
- VPC-A/Subnet(10.10.0.0/28)にInternal NAT Gatewayを作成。
- RouteTableを更新。
    - TGWのRoutetable
        - dst: 10.0.0.0/24 target: VPC-A側のAttachment
    - VPC-A/Subnet(10.10.0.0/28)のRoutetable
        - dst: 10.0.0.0/24 target: VGW
        - dst: 10.20.0.0/16 target: TGW
    - VPC-A/Subnet(10.10.0.16/28)のRoutetable
        - dst: 10.0.0.0/24 target: NATGW
        - dst: 10.20.0.0/16 target: TGW
    - VPC-B/Subnet(10.20.0.0/24)のRoutetable
        - dst: 10.0.0.0/24 target: TGW
        - dst: 10.10.0.0/24 target: TGW

### 確認内容
- Originのインスタンスから「curl 10.0.0.6」で、TGW及びNATGWを経由して、Target(10.0.0.6)のnginxにhttpアクセスできることを確認。
- Targetのnginxのaccesslogで、アクセス元IPがNATGWのIP(10.10.0.10)になっていることを確認。

:::note 
- DST: 10.0.0.0/24へのルートがVGWではなくNATGWになっているSubnet(10.10.0.16/28)のほうにAttachmentを作ることにより、Originインスタンスからの通信がNATGWを経由するようにする。
- 今回の構成では3つのSubnetはすべて同一AZ。(TGW使用時に複数AZある場合、もう少し考慮要)
:::


## 3.5 案4: Peering + NAT Gateway

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/d93fced3-a1fd-a230-4890-b659bc784d08.png)


### 設定内容
- VPC-A/Subnet(10.10.0.0/28)にInternal NAT Gatewayを作成。（案3と同じ）
- VPC-AとVPC-BのPeeringを作成。（案1と同じ)
- RouteTableを更新
    - VPC-A/Subnet(10.10.0.0/28)のRoutetable
        - dst: 10.0.0.0/24 target: VGW
        - dst: 10.20.0.0/16 target: peering
    - VPC-A/Subnet(10.10.0.16/28)のRoutetable
        - dst: 10.0.0.0/24 target: NATGW
        - dst: 10.20.0.0/16 target: peering
    - VPC-B/Subnet(10.20.0.0/24)のRoutetable
        - dst: 10.0.0.0/24 target: peering
        - dst: 10.10.0.0/24 target: peering
        
### 確認内容
- 通常、NATGW経由の通信を行いたい場合、RoutetableでtargetにNATGWを指定する。今回、VPC-Bにおいて、10.0.0.0/24宛の通信をVPC-AのNATGW経由としたいところだが、peering相手のVPC-A内のNATGWをRoutetableのTargetとして指定することはできなかった。（↓ここの設定箇所にpeering相手のVPCのNATGWが出てくればよいのだが、残念ながら出てこない）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/a11f639f-419e-c971-05fe-71f95bc7f8bc.png)

- 代わりにVPC-Bにおいて、10.0.0.0/24宛の通信のTargetをVPC-Aへのpeeringとしたが、それだとNATGWを経由した通信を実現させることはできなかった。


# 4. 所感
- なんだかいろいろ検討して勉強になった。他にも個別にProxyサーバを立てたり、VPC Latticeを使ったりなどいろいろやりようはありそう。