NSXとAWSをTerraformを使ってIPsecで接続する

この記事は [vExperts Advent Calendar 2024](https://adventar.org/calendars/10310) の12月9日分の投稿記事です。

https://adventar.org/calendars/10310

## はじめに

オンプレ環境とAWSをちょっと繋いで検証したいけど、設定が多くてIPsecの接続するのが面倒だったり、接続を維持すると料金がかかってしまうのはもったいないというモチベーションで、NSXとAWS環境をIPsecで繋いだり削除したりできるTerraformを書きました。

https://github.com/masanara/terraform-ipsec-nsx2aws/

## 接続のイメージ

### 接続前

AWS側にはリソースが存在しない状態です。NSX側はT0GWを作成し、BGPに関する設定がされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27668/9cf281ab-577f-3ff8-8a4b-aee258e63398.png)

### 接続後

AWS側にネットワークに必要なリソースを作成し、T0GWからIPsecを構成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27668/1ba09b5d-a360-c234-4d5e-22f8ba48960c.png)

## 使い方

### 前提条件

- NSX側にはあらかじめT0GWが作成されていて、インターネット通信が可能であること
- BGPが有効になっていること
- BGP経由のルート再配布の設定が有効になっていること

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27668/bb12329b-ff50-7074-7b3b-124891faa198.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27668/7ea046c5-549f-3271-ec7d-9cafb555ee7d.png)

### terraform.tfvars

構成に必要なパラメータは`terraform.tfvars`として以下のように用意します。

```hcl
vpc_cidr           = "10.0.0.0/16"                          # VPCのCIDR
region             = "ap-northeast-1"                       # VPCを作成するリージョン
availability_zones = ["ap-northeast-1a", "ap-northeast-1c"] # サブネットを作成するAZ

local_asn = "65413"                    # オンプレミス側のT0GWのAS番号 (要事前設定)
cloud_asn = "65412"                    # 作成するVPN GatewayのAS番号

local_ep      = "203.0.113.100"        # ローカルエンドポイントのIPアドレス
local_address = "198.51.100.10"        # ローカルエンドポイントのローカルID
nsx_host      = "192.0.2.20"           # NSX ManagerのIPアドレス
nsx_username  = "admin"                # NSX Managerのログインユーザー名
nsx_password  = "NsxAdminP@ssword"     # NSX Managerのログインパスワード
nsx_t0gw      = "t0gw"                 # 既存のT0 Gatewayの名称
```

## 実行して作成されるもの

`terraform apply`を実行するとAWS・NSXで以下のリソースが作成・構成されます。

### AWS

- VPC
- インターネットゲートウェイ
- Privateサブネットx 2
- Publicサブネット x 2
- Privateルートテーブル (ルート伝播有効)
- Publicルートテーブル (ルート伝播有効)
- カスタマーゲートウェイ
- 仮想プライベートゲートウェイ
- Site-to-Site VPN接続
- クライアント VPN エンドポイント

正常に実行できると、マネジメントコンソールでは、IPsecトンネルが「アップ」になります。

![image-20241207075534350.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27668/8533f73b-3c90-b7fa-ff79-fe1feb80ae35.png)

ルートテーブルを確認すると、オンプレミスで再配布された経路が伝播されて、ターゲットとして仮想プライベートゲートウェイ(VGW)になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27668/50ac9969-8581-7935-a730-53dae0ad577d.png)

### NSX

- VPNサービス
- IPsecセッション
- ローカルエンドポイント
- BGPネイバー設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27668/38a960de-9230-5d22-2e14-71ea21862d70.png)

T0GWのSRを確認すると、BGP経由でVPCのCIDRを学習して経路として利用されています。

```
edge01(tier0_sr[3])> get bgp
BGP IPv4  table version is 6, BGP IPv6  table version is 0
Local router ID is 10.44.58.34
Status flags: > - best, I - internal
Origin flags: i - IGP, e - EGP, ? - incomplete

EVPN type-2 prefix: [2]:[EthTag]:[MAClen]:[MAC]:[IPlen]:[IP]
EVPN type-3 prefix: [3]:[EthTag]:[IPlen]:[OrigIP]
EVPN type-4 prefix: [4]:[ESI]:[IPlen]:[OrigIP]
EVPN type-5 prefix: [5]:[EthTag]:[IPlen]:[IP]

   Network                             Next Hop                            Metric       LocPrf  Weight   Path            RD
 > 10.0.0.0/16                         169.254.121.157                     100          100     0        65412 i
 > 10.44.58.32/32                      0.0.0.0                             0            100     32768    ?
 > 192.168.100.0/24                    100.64.0.1                          0            100     32768    ?
 > 192.168.200.0/24                    100.64.0.1                          0            100     32768    ?
 > 192.168.210.0/24                    100.64.0.1                          0            100     32768    ?
Fri Dec 06 2024 UTC 22:57:54.722
```

## まとめ

NSXとAWSという異なる環境を双方の状態を認識して設定できるのはTerraformの良いところです。
必要なときに、気軽にIPsec構成して不要になったらすぐ削除できますが、削除忘れると想定外の請求になるので注意しましょう。