VPCエンドポイントを使って、脱NATしてみたかった

# はじめに
VPCエンドポイントは、NATゲートウェイなどインターネットGWを経由することなく、
プライベートなサブネットのリソースをVPCの外のサービスにアクセスできるようにしてくれるリソースです。

アーキテクチャの構成次第ですが、このVPCエンドポイントを利用することで、
課金額に大きく跳ねるNATゲートウェイを使わずにすむ可能性があります。

是非使えるようになっておきたいリソースなので、触ってみました！

# VPCエンドポイントとは

![](https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/images/access-with-privatelink.png)

イメージとしては、グローバルなインターネットGWではなく、プライベートな裏口を作る感じです。

上記の図にもある通り、インターネットGWを経由せずに各リージョンリソースにアクセスできます。

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

ほぼすべてのサービスのエンドポイントに対応している「インターフェイスエンドポイント」と、
S3,　DynamoDBにのみ対応している「ゲートウェイエンドポイント」の2種類が存在します。

https://docs.aws.amazon.com/ja_jp/vpc/latest/privatelink/aws-services-privatelink-support.html

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


# やってみた
今回は、NATゲートウェイへのルートを持たない、プライベートサブネットと、EC2を用意しました。
通常のプライベートサブネット上のインスタンスは、NATゲートウェイからインターネットゲートウェイを経由して通信を行いますが、
そもそもプライベートサブネットのルートにNATへのルートがなければ、それもままなりません。

参考イメージ：

![archi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/7a3fa380-ee7d-e0ae-0b81-0bab6ee995f1.png)

このNATゲートウェイへのルートを持たないプライベートサブネット上のEC2から、VPCエンドポイントを利用して、SSM、S3と通信させてみようと思います！

参考イメージ：
![archi2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/fd464adb-6cc0-6092-83f6-bc27400027b0.png)


## ゴールの確認
インターフェイスエンドポイントは、APIエンドポイント先の数だけ配置する必要があります。

ドキュメントによって揺れがあるのですが、今回は下記のドキュメントを参考に、

SSMを実行するためのエンドポイント
- com.amazonaws.ap-northeast-1.ssm
- com.amazonaws.ap-northeast-1.ssmmessages
- com.amazonaws.ap-northeast-1.ec2
- com.amazonaws.ap-northeast-1.ec2messages

S3へのアクセスのためのエンドポイント
- com.amazonaws.ap-northeast-1.s3

これらを作成し、インターネットGWではなく、
プライベートなインターネットを経由してSSM,S3操作を行ってみようと思います！

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-prerequisites.html

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/setup-create-vpc.html

## 事前準備
エンドポイントを作成する前に、
前述したNATへのルートのない孤立したEC2を作成したので、設定の確認を行います。

### VPCの名前解決設定
VPCエンドポイントを使用するためには、
VPC内のリソースが、AWS DNSを利用して、プライベートホストネームを解決できる必要があります。
VPCの「enable_dns_support」「enable_dns_hostnames」がtrueになっていることを確認します。

![cap0.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/d53819b8-78c5-090a-e8de-28cd9ce44bca.png)


https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-dns.html#vpc-dns-support

https://zenn.dev/furururu02/articles/c545f1bb06f6e9

### ルートテーブルのルート設定
VPC内のリソースへのルートが存在し、NATまたはインターネットGWへのルートがないことを確認します

![cap01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/8d438e03-375f-5ddb-74ff-da6e5cd2ae64.png)

### EC2のプライベートDNS割り当て
エンドポイントを利用するインスタンスがプライベートDNS名前解決可能な状態か確認します。

![cap02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/b97b3325-f730-66ca-6f9b-bc9978ebea52.png)

プライベートDNS応答を拒否する設定になっているので、変更します。

![cap17.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/90bb1896-8071-34fc-cf2a-551c837896a3.png)

![cap18.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/d677afd7-befd-0c28-4d80-d3539db2975f.png)

![cap19.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/34acda97-a47b-52c5-cab3-b3e1cd5922fa.png)

### SSM管理できていないことを確認

![cap03.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/d41c56d5-e602-485b-b8d9-eff3dd9a6f34.png)

session managerで接続できないことが確認できればOKです

## VPCインターフェースエンドポイントを作成してSSMしてみる
まずは、インターネットへの通信経路のないEC2にSSMでアクセスできるようにしてみます

SSMを実行するためのエンドポイント
- com.amazonaws.ap-northeast-1.ssm
- com.amazonaws.ap-northeast-1.ssmmessages
- com.amazonaws.ap-northeast-1.ec2
- com.amazonaws.ap-northeast-1.ec2messages

これらを作成していきます！

### エンドポイントにアタッチするセキュリティグループを作成する

VPCインターフェースエンドポイントはプロキシサーバーのようなものです。
443ポートでアクセスできるようセキュリティグループを設定します。

![cap06.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/02de5223-670a-5ca5-32f7-d5214353393a.png)

### エンドポイントを作成する
さっそくインターフェイスエンドポイントを作成していきます。

VPC > エンドポイントと移動します。

![cap05.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/ac53f759-aae1-1d86-f628-428ff7ff41d9.png)

「エンドポイントを作成」をクリックします。

![cap07.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/8ef82ef5-b568-adfa-804d-424b32be66b0.png)

作成画面がでました。
必要な設定を行っていきます。

![cap08.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/ecdc26c9-681c-9a7b-24d7-814606b742fc.png)

エンドポイント名前タグを入力します。
その他の値はデフォルトです。

次に、エンドポイントとするサービスを選択します。

![cap09.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/8deb20e0-6ff5-cf6d-98bf-fa07cbdd2bc1.png)

検索ボックスを利用し、「com.amazonaws.ap-northeast-1.ssm」を指定します。

エンドポイントを作成するVPCを選択します。

![cap10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/c1ef4273-d265-062b-294b-350254307702.png)

用意したVPCを選択します。
その他の値はデフォルトです。DNS有効化が必須な点に注意です。

インターフェイスエンドポイントのみ、AZ, サブネットを選択します。

![cap11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/4f2534cc-9ec5-f87a-acd0-819b882454ce.png)

今回は、EC2の存在するサブネットを指定します。

エンドポイントにアタッチするセキュリティグループを選択します。

![cap12.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/1e1228f3-54fb-ad47-e2f6-5264e446584b.png)

先ほど作成した、VPC内からの443アクセスを許可するセキュリティグループを指定します。

最後に、ポリシーを設定できます。

![cap13.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/e3238c3b-d329-7045-4e78-9bd799642273.png)

今回はフルアクセスを指定します。

![cap14.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/23f36840-baf6-8d6a-8c02-25a9360db5be.png)

タグと、ここまでの設定に問題がなければ、作成をクリックします。

![cap15.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/3b35c80f-b016-1253-c1b9-722ea2b96da6.png)

無事、エンドポイントが作成されました！
サービス名が正しいこと、インターフェイス型なことがコンソールから確認できますね。

### 同じ要領で4つのエンドポイントを作成する
同じ要領で、今回必要となる4つのエンドポイントを用意しました。

![cap16.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/63462626-0f0f-da9f-3d32-74c9ca3a3198.png)

SSMで接続する準備が完了しました！

### SSM経由でアクセスできるか確認
まずはEC2インスタンス接続画面から確認してみます。

![cap21.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/db69c6f7-aea3-5f4c-7149-9faa9bd44c07.png)

「接続」ボタンが活性化され、アラート類が表示されていないですね。

![cap22.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/87c9c265-fef3-b1c7-6deb-0c475ef57af4.png)

無事、session manager経由で接続できました！

### その他のリソースにはアクセスできないことを確認
aws cli でS3にアクセスしてみます。

![cap22_.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/3b7d3d36-eb8b-2693-08d1-3e829e0e9f39.png)

少し待ちましたが、応答が返ってきませんでした・・・・


次はS3へのエンドポイントを作成してみます！

## VPCゲートウェイエンドポイントを作成してS3にアクセスしてみる

それでは、ゲートウェイエンドポイントを作成していきます。
大まかな流れはインターフェイスエンドポイントと同じです！

### エンドポイントを作成する
VPC > エンドポイントから同じく作成していきます。

![cap20.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/c43d7492-a576-573d-582d-83c57d7ed8fb.png)

エンドポイント名とサービスを選択します。

![cap24.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/e8ac90d0-1935-cc3b-1259-ee85e2f8ab05.png)

「com.amazonaws.ap-northeast-1.s3」を選択します。
2つありますが、ゲートウェイタイプを選択します。

ゲートウェイタイプを選択した場合、サブネットやセキュリティグループを選択する必要はありません。
インターネットGWやNATゲートウェイを作成する時と同様、どのルートテーブルのルートに追記するか？を選択します。

![cap25.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/49c1243c-ccc1-96f5-1c08-2694721db0ca.png)

![cap26.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/ce0f4703-ee58-6e28-15fb-de5917021e0c.png)

分かりづらいですが、EC2インスタンスが所属するサブネットに紐づくルートテーブルを指定しています。

![cap27.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/14936890-94c4-7901-5d3f-7d7a0499bebc.png)

設定は以上ですので、作成します！

![cap28.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/de5a18f1-7688-0f8f-fa2c-f100fbc92584.png)

問題なく、ゲートウェイエンドポイントが作成されました。

![cap30.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/2498d20e-d836-fd4a-cd39-e891b83efc7c.png)

作成時に選択したルートテーブルを確認してみると、S3のプレフィックスリストがトラフィックの送信先の場合、vpce（VPCエンドポイント）へターゲットされる設定になっていることが確認できます。

### S3でアクセスできるか確認
session managerから先ほど同様のコマンドを実行してみます。

![cap29.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/b357c9e8-8829-a4c6-b259-df32ac1309d3.png)

パブリックインターネットへのルートがないのにS3にアクセスできました！

# コスト感を比較してみる
動作確認が終わったところで、当初のモチベーションだった、NATの使用を控え、コストを抑えることができるか？に着目してみます。

それぞれ、公式で確認した料金表です。

###### NAT

![cap32.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/6ef011fe-a735-865f-78d1-edc7089254cf.png)


###### VPCエンドポイント

![cap31.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/a2f1e2e9-8c27-6ddc-8f68-b99d7041e25b.png)

表にしてみると以下のようになりますね。

||*1リソースあたり料金*  |*処理データ1GBあたり料金*  |
|---|---|---|
|*NAT*  |0.062USD  |0.062USD  |
|*VPCエンドポイント* |0.014USD  |0.01USD  |

VPCエンドポイントの料金は、処理データ1GBあたりの料金が使用量ごとに減っていきますが、
エンドポイントが増えるたびに、0.014USDがかさんでいきます。

今回の例ですと、5つのエンドポイントを作成するため、0.062 > 0.014 * 5で、
処理データが多い場合でないと、NATを使用したほうが課金額は安く済みそうです。

# おわりに
以外に、VPCエンドポイントを使うだけで簡単にNAT使用量を節約できそうにありませんでした。
NATとVPCエンドポイントの比較には、VPC内でのインターネットトラフィックの量を正しく見積もる必要がありそうでした。

ともあれ、選択肢のひとつにはできる程度には、概要を理解できたと思います！