AWS Privatelink (NLB不要版) を使ってみる

# 1. はじめに
- CIDRが重複するVPC間を接続するのにPrivatelinkをよく使っている。（従来のPrivatelinkの構成については過去記事「[【初心者】AWS PrivateLink を使ってみる](https://qiita.com/mksamba/items/20903940b8b256ef2487)」を参照）
- これまでは接続される側のVPCにNLBなどを用意する必要があったが、2024/12にNLBなしでの構成ができるというアップデートがあったため、設定手順を確認する。

# 2. やったこと
- VPC1にnginx(接続される用)を作成
- VPC1にResource Gateway/Resource Configuration(VPC外からの接続を受けるための設定)を作成
- VPC2にクライアント(curl打つ用)を作成
- VPC2にResource Endpoint(VPC1のResource Configurationと繋ぐためのEndpoint)を作成
- VPC2のクライアントから上記の経路を使用してVPC1のnginxへ接続

# 3. 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/6ad29dae-ccc6-67fb-6408-b6a4d0dc0b7e.png)


- 2024/12時点で、Resource Gateway/Configurationのアイコンがない！

# 4. AWS Privatelink （NLB不要版） の概念（自分の理解）
- 接続される側のVPCで「Resource Gateway」を作り、VPC外からの接続を受ける口を作る。
- 「Resource Configuration」を「Resource Gateway」の中に作り、VPC外から接続させたいリソース(EC2インスタンスやRDSインスタンスなど)を設定する。
- 接続する側のVPCで「Resource Endpoint」を作り、接続したい「Resource Configuration」との道を作る。
- 「Resource Gateway」「Resource Configuration」「Resource Endpoint」の3点セットで新しいPrivatelink、というイメージ。

# 5. 手順
## 5.1 VPCなどの準備
- VPC1/VPC2を構成図のCIDRで作成
- VPC1にnginx(接続される用)インスタンスを作成
- VPC2にcurl用のインスタンスを作成

## 5.2 Resource Gatewayの作成
- VPC1にResource Gatewayを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/1d75deb0-9f0e-7e30-8dde-790d65b5ef62.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/de53f2d2-fecf-71cc-9c89-73cf57032e04.png)

- 足だしするAZ/subnetを指定すると、指定したsubnetにENIが作られる。

## 5.3 Resource Configurationの作成
- Resource Gatewayの中に Resource Configurationを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/863b5a3c-a05d-388a-7baa-207bb81b55e8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/5cc28a34-7f84-5bcd-4709-801009c51d61.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/9b8d9418-9957-73cc-453e-587fbb240691.png)

- VPC外から接続させたいインスタンスのホスト名とポート番号を指定する。
- 今回は後で通信ログを見れるように、CloudWatch Logsへの出力を有効化する。（デフォルトはログなし）

## 5.4 Resource Endpointの作成
- VPC2に、Resource Configurationへ繋げるための Resource Endpointを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/6edbed7f-5f59-4003-c2a3-e99d0d4a52bf.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/0bc0d664-e057-0374-4cf3-9c59f308518f.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/90a322d9-fa91-8665-67da-df49753a6089.png)

- Endpointのタイプとして Resourceを選択する。
- 接続させたい先として、前の手順で作成したResource Configuration (=nginxへつなぐConfiguration)を選択する。
- Endpointの作成場所として、VPC2内のAZ/subnetを選択する。そのsubnetにEndpointのENIが作られる。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/c07c5386-8fda-be83-f631-6c0a77fc3835.png)

- Endpointの作成に成功すると、指定したsubnetにENIが作成され、IPアドレスが割り当てられる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189302/2fa09dc4-8943-aabe-dc5f-4d39f1fd7054.png)


- 「エンドポイントの関連付け」のところから、このEndpointのDNS名も確認できる。

## 5.5 接続確認

### 名前解決
- VPC2では、Resource EndpointのDNS名の名前解決が可能。
```
[ec2-user@ip-10-0-0-121 ~]$ dig vpce-xxxxxxxxxxxxxxxx.rcfg-xxxxxxxxxxxxxxxx.xxxxxxx.vpc-lattice-rsc.ap-northeast-3.on.aws
～中略～
;; ANSWER SECTION:
vpce-xxxxxxxxxxxxxxxx.rcfg-xxxxxxxxxxxxxxxx.xxxxxxx.vpc-lattice-rsc.ap-northeast-3.on.aws. 60 IN A 10.0.2.243
```

### AZ-3a経由のアクセス
- AZ-3a側のResource Endpoint(10.0.2.243)経由でアクセスする。

```
[ec2-user@ip-10-0-0-121 ~]$ curl 10.0.2.243
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
～以後略～
```

- Resource Configurationに関するCloudWatch Logsは以下のように保存される。

```
{
"eventTimestamp": "2024-12-26T09:10:43.578Z",
"vpcEndpointId": "vpce-xxxxxxxxxxxxxxxx",
"sourceVpcArn": "arn:aws:ec2:ap-northeast-3:xxxxxxxxxxxx:vpc/vpc-xxxxxxxxxxxxxxxx",
"resourceConfigurationArn": "arn:aws:vpc-lattice:ap-northeast-3:xxxxxxxxxxxx:resourceconfiguration/rcfg-xxxxxxxxxxxxxxxx",
"protocol": "tcp",
"sourceIpPort": "10.0.0.121:33818",
"destinationIpPort": "10.0.2.243:80",
"gatewayIpPort": "10.0.0.179:43971",
"resourceIpPort": "10.0.2.185:80"
}
```

- nginxのアクセスログは以下。アクセス元のSRCIPは、Resource GatewayのENIが「プレフィクス委任」として、10.0.0.176/28を持っており、そこのIPになる様子。

```
[root@ip-10-0-2-185 nginx]# tail /var/log/nginx/access.log
10.0.0.179 - - [26/Dec/2024:09:10:43 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.5.0" "-"
```

### AZ-3b経由のアクセス
- AZ-3b側のResource Endpoint(10.0.3.123)経由でアクセスする。
```
[ec2-user@ip-10-0-0-121 ~]$ curl 10.0.3.123
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
～以後略～
```

- Resource Configurationに関するCloudWatch Logsは以下のように保存される。

```
{
"eventTimestamp": "2024-12-26T09:23:47.177Z",
"vpcEndpointId": "vpce-xxxxxxxxxxxxxxxx",
"sourceVpcArn": "arn:aws:ec2:ap-northeast-3:xxxxxxxxxxxx:vpc/vpc-xxxxxxxxxxxxxxxx",
"resourceConfigurationArn": "arn:aws:vpc-lattice:ap-northeast-3:xxxxxxxxxxxx:resourceconfiguration/rcfg-xxxxxxxxxxxxxxxx",
"protocol": "tcp",
"sourceIpPort": "10.0.0.121:59610",
"destinationIpPort": "10.0.3.123:80",
"gatewayIpPort": "10.0.1.35:58673",
"resourceIpPort": "10.0.2.185:80"
}
```

- nginxのアクセスログは以下。アクセス元のSRCIPは、Resource GatewayのENIが「プレフィクス委任」として、10.0.1.32/28を持っており、そこのIPになる様子。

```
[root@ip-10-0-2-185 nginx]# tail /var/log/nginx/access.log
10.0.1.35 - - [26/Dec/2024:09:23:47 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/8.5.0" "-"
```

# 6. 参考URL

https://dev.classmethod.jp/articles/privatelink-vpc-endpoint-direct-access-update/

https://blog.serverworks.co.jp/access-vpc-resources-aws-privatelink

https://dev.classmethod.jp/articles/aws-privatelink-vpc-lattice-relation/

# 7. 所感

- 概念は分かったつもりになったので、使い分けなどを整理していきたい。また次は、EC2インスタンスではなくRDSインスタンスへの接続について検証したい。