VPCエンドポイント勉強

## 〇自戒のための自己への宣誓
1. お前に足りないのはインプットだ！！！インプットしろ！！！インプットの奴隷になれ！！！
2. 記事の書き方とか今はどうでもいいから書け！！！インプットをアウトプットしろ！！！やる前からこだわりとか持つな！！！
3. 見られることとか評価されることとか気にするな！！！MECEとか構造化されてるかどうかとか気にするな！！！構造化はアウトプットの整地であって、インプットが足りないお前が手を出す領域ではない！！！ていうかお前頭良いんだからインプットに注力しろ！！歴史を刻め！！！歴史をまとめようとするな！！！未来を描け！！過去を清算するな若者め！！！！
4. 疑問を持つことを恥じるな！！！お前は頭はいいがインプットが足りない未熟者だ！！！インプットの奴隷になれ（再掲）！！！

## 〇学んだこと
まず一般的に、EC2などのインスタンスがS3やLambda、KMSなどのサービスを利用する際は、インターネットゲートウェイから出て、各サービスのエンドポイント（サービスのシステムへの接続ポイント）に接続する。このとき、「インターネットゲートウェイ」を通ってはいるけど、AWSネットワーク（という閉塞網）から出るわけじゃない。
ただし、VPCにインターネットゲートウェイを追加する必要があるため、トラフィックがAWSネットワークから出すことが設定上可能になる。つまり可否ではなく選択の自由になる。この設定がネットワークセキュリティ要件から外れてしまう場合、IGWを使わずにAWSサービスを利用できるようになる「AWS PrivateLink」が選択肢に上がってくる。

AWS PrivateLinkっていうのが大きな括りで、その中にVPCエンドポイントっていう実現手段（技術要素？）があるらしい。AWS PrivateLinkっていうのはサービス名であり実現したいことで、VPCエンドポイントはその一つの実現手段みたいな感じ？

AWS PrivateLinkを介して各サービスのエンドポイントに通信するには、まずインターフェース型のVPCエンドポイントを作成する必要がある。
VPCエンドポイントを作成する＝AWSサービス宛てのトラフィックを、各AWSサービスのエンドポイントのプライベートIPアドレスに名前解決する（加えて、AWSサービスはVPCエンドポイント経由のトラフィックは動的に受け入れるようになる）システムを作成(追加)する
という感じっぽい。
VPCエンドポイントにはサブネット単位でのENIが必要で、すなわちIPアドレスが１つ必要になる。1つのVPCで２つのサブネットにVPCエンドポイントを設定する場合、ENIが各サブネットで１つずつ、合計２つ必要になる。
各IPアドレス=各AWSサービスのエンドポイント
という感じ。


### AWSサービスのFQDNフォーマット
```
protocol://service_code.region_code.amazonaws.com
```
### リージョン間通信のエンドポイントのFQDNフォーマット
```
endpoint_id.service_id.region.vpce.amazonaws.com
```
### AZ間通信のエンドポイントのFQDNフォーマット
```
endpoint_id-az_name.service_id.region.vpce.amazonaws.com
```

VPCのリソースは`protocol://service_code.region_code.amazonaws.com`でDNSリクエストを出して、Route 53 ResolverがVPCエンドポイントのプライベートIPアドレスをレスポンスで返して、VPCのリソースはそのIPアドレスで（デフォルトゲートウェイに？）通信を送る。

## 「VPCエンドポイントを作成する」は具体的には？
「VPCエンドポイントを作成する」とは以下を表す。
1. IPアドレス割り当て：各サブネット内の各ENI１つずつに、AWS閉塞網でアクセス可能なAWSサービスのエンドポイントアクセス用プライベートIPアドレスが割り当てられる。
2. リージョン/AZレベルのDNS名と名前解決設定追加：VPCエンドポイント用のDNS名（パブリックに公開されたDNSレコード）が作成され、それらのDNS名前解決設定が追加される（※）。リージョンレベルのものとAZレベルのものがそれぞれ作成される。
3. (DNS名を有効化した場合)DNS解決設定追加：リージョンレベルのパブリックエンドポイント(public Regional endpoints)から、VPCエンドポイントとして設定したENIのプライベートIPアドレスを返すDNS解決の設定が追加される。

※作成されるVPCエンドポイントのFQDNはパブリックDNS解決できるが、DNSレスポンスで返ってくるIPアドレスはプライベートIPアドレスなので、DNSリクエストを送ったリソースがVPCへ接続されていない/できない限りは、実質的にVPCエンドポイントへのDNS解決は機能しない。また、VPCで`DNS hostnames`と`DNS resolution`を有効化した状態で、インターフェース型VPCエンドポイントのプライベートDNSを有効化すれば、AWS閉塞網内にAWSマネージドのプライベートホストゾーンを作成してくれるらしい。この「AWSマネージドのプライベートホストゾーン」では、AWSサービスへの既存のDNS解決をプライベートIPアドレスに自動的に更新してくれるらしい。なので、途中でVPCエンドポイントを作成した場合でも新しく作成する場合と変わらず利用できる（追加の設定が必要ない）。
これらのDNS解決はRoute53リゾルバが行う。もしオンプレからVPCエンドポイントに接続し（て閉塞網にトラフィックを収め）たい場合は、Route53リゾルバエンドポイントとリゾルバルールを利用する必要がある。

また、VPCを跨ぐ場合は、Transit GatewayやVPC Peering、VPC Sharing、そしてNACLの設定を鑑みて、通信可能か否かを判断すればよい。

ユーザー側で考えるべきことを単純化すると、
①リソースと対象のENIとの通信：VPCエンドポイントのSecurity Group, NACL, VPC間の接続
②オンプレからVPCエンドポイントを利用したい（AWS閉塞網でトラフィックを完結させたい）場合：Route 53 Resolver, Route 53 Resolver Endpoint, Resolverルール

## 〇AWSおすすめ！本番環境のVPCエンドポイント構成
- 1つのVPCエンドポイントにつき2つ以上のAZで設定し、デプロイするリソースもそれらのAZにあるサービスに接続できるようにする→耐AZ障害性向上
- VPCエンドポイント用のプライベートDNS解決設定をする（設定しない場合、DNSリクエストはインターネットゲートウェイを通ってパブリックDNSサーバーとDNS解決をすることになり、つまりAWSサービスAPIへのパブリックIPアドレスが返される。）
- リージョン間DNSネームを使ってAWSサービスにアクセスする（VPCエンドポイントFQDNを使うと複雑性が増したり、Route53を利用する場合と比べると可用性や耐障害性が下がるらしい。）

## 〇AWS PrivateLink対応サービス
下記AWS公式ドキュメント参照。
https://docs.aws.amazon.com/vpc/latest/privatelink/aws-services-privatelink-support.html
一つのサービスに複数のエンドポイントがある。目的/できること毎にAPIがあるっぽい。詳しくは各サービスのエンドポイントの説明ドキュメントを参照。