リソースゲートウェイを使ってNLB無しでPrivateLinkを構築する

## はじめに

AWS PrivateLink(以下PrivateLink)はVPCエンドポイントからAWSのサービス・他のVPC内のアプリケーションに、パブリックインターネットを経由せずアクセスさえるネットワーキングサービスです。

PrivateLinkで接続される側(=サービスプロバイダー)のVPCでは、リクエスト元(=サービスコンシューマー)からのトラフィックをルーティングするため、NLBまたはGWLBをデプロイする必要がありました。
(サービスプロバイダーVPCの入口となるエンドポイントサービスに、NLBまたはGWLBを関連付ける)

re:Invent2024のアップデートでリソースエンドポイント & リソースゲートウェイが登場し、NLB/GWLB無しでPrivateLinkを張れるようになりました。
リソースゲートウェイ経由のアクセスをどうやって制限するのか気になったので、本記事では実際にリソースエンドポイントとリソースゲートウェイを構築して調べてみたいと思います。


リソースエンドポイントのドキュメント(英語版)

https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-access-resources.html

リソースゲートウェイのドキュメント(英語版)

https://docs.aws.amazon.com/vpc/latest/privatelink/resource-gateway.html


## リソースエンドポイントを使ったPrivateLinkの構成

今回はService Provider VPCにEC2を立て、Resource Gateway経由で通信させます。
Service Provider EC2のResource ConfigurationをResource EndpointとResource Gatewayに関連付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/5c39b6e1-edbb-2622-f5d8-f166b4e36a55.png)


## リソースゲートウェイ経由のPrivateLinkの構築

### リソースゲートウェイの作成
サービスプロバイダ側のVPCで作成します。設定項目はシンプルです。
![ResourceGateway1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/68d90c1f-008b-82f4-a60d-6d2180f587ef.png)

![ResourceGateway2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/af34cc90-4b7e-d03f-0945-9896781930de.png)


### Resource Configurationの作成
サービスプロバイダ側のアカウントで設定します。

ターゲット(DNS,IPなど)を1つ設定する場合はConfiguration Typeを`Resource`に指定します。Resource Groupに入れるリソースを作成する場合も`Resource`を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/1963423c-68e5-511c-c837-a7eeaac07159.png)


### リソース共有の作成(サービスコンシューマがサービスプロバイダと別アカウントの場合)
Resource Access Managerからリソース共有を作成し、Resource Configurationと関連付けます。

VPC Lattice Resource Configurationsを選択していますが、
表記はVPC Lattice Resource Configurationとなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/97a87a90-a669-dc36-6b37-b458b4ae500d.png)

RAMで共有リソースをResource Configurationに、共有プリンシパルに共有先のアカウントIDを入力します。(検証に使える別アカウントが無く、無理やり共有元と同じアカウントIDを入れているためエラーになっています、ステータスが失敗になってるの見た目がイマイチすぎますね、すみません…)
![20241214_RAM8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/21a36f3c-b1f4-9a94-c8a1-85b539470e39.png)

キャプチャだと自アカウントとは共有できないよ！って怒られてますが、こんな感じでResource Configurationを別アカウントに共有できそうです。
![20241214_RAM9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/80b0bd5a-ebd3-502c-1b84-72ec223a0eda.png)


### リソースエンドポイントの作成
リソースエンドポイントは他のインターフェイスVPCエンドポイントと同じように作成します。セキュリティグループも設定できます。
![ResourceEndpoint1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/badae4a8-3e64-88f6-d99f-4b9fa821f4e0.png)


### 疎通確認
自アカウントのVPC同士ですが、サービスコンシューマVPC内のEC2からリソースゲートウェイ経由でサービスプロバイダVPC内のEC2にリクエストを投げてみました。

リソースエンドポイントのDNS名を確認します。
![ResourceEndpoint2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/962755b0-c371-be83-f0c1-a7e61236fb91.png)

ターゲットのEC2には8080宛のリクエストにHello Worldを返す簡単なシェルスクリプトを仕込んでいます。
```bash
#!/bin/bash
PORT=8080
while true; do
  {
    echo -ne "HTTP/1.1 200 OK\nContent-Type: text/plain\n\nHello, World!\n";
  } | nc -l -p $PORT
done
```
リソースエンドポイント宛にcurlを投げたらちゃんと返ってきました。
![疎通確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/1f381e5b-ecca-8b99-a8f4-104a57499214.png)

こちらはリクエストを受けた側のEC2の出力です。塗りつぶしちゃってますが、
Host:リソースエンドポイントのDNS名 となっています。
![疎通確認2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3458266/cc61e326-42cd-eda1-37d8-55d9a661af71.png)


## おわりに
NLB使わなくてもPrivateLink張れる、これは嬉しいアプデだ！と思いつつ
PrivateLinkで接続してくるアカウントを限定したり、リソースエンドポイントとの接続時に承認を必須にできるのかな？と思ったりもしました。

サービスプロバイダのリソースゲートウェイに紐づけたResource Configurationの共有設定でアクセスを許可するアカウントを指定できそうです。

リソースエンドポイントにエンドポイントポリシーは設定できなさそうなので、
あとはリソースエンドポイントへのアクセスをセキュリティグループで制御することでアクセス絞ることになりそうです。

リソースエンドポイントの作成時にResource Configurationを指定しますが、サービスコンシューマとサービスプロバイダが同じアカウントの場合はリソースエンドポイント作成後の承認は必要ありませんでした。(承認の画面は探した限り無い)

クロスアカウントの場合を確かめられていませんが、リソース設定が共有されている=接続を承認されている、という扱いになりそうです。

NLBを使ったサービスエンドポイントのようにVPCエンドポイントとサービスエンドポイントの接続時にサービスプロバイダ側での承認をする、といった考え方ではなく、Resource Configurationでリソースエンドポイント - リソースゲートウェイ - リソースを紐づけるというイメージかなと構築しながら思いました。


Resource ConfigurationはVPC Latticeの仕組みをかなり利用しているようなので、
より理解を深めるためにVPC Latticeをお勉強したほうがよさそうです。