fargateアプリケーションをprivate subnetに配置する場合の注意点

たびたびこのパターンで構築するたびに、ハマるので細かめにパッとチェックポイントわかるようにメモ。
仕様が細かすぎるAWS。

# Fargateがインタネットへ経路を持たない場合に、必要なネットワーク経路について

ECRのVPCエンドポイントがサポートされるまでは、NATゲートウェイを利用する必要がありました。
様々な記事に書かれている通り、ECRのpullのたびにネットワーク量が大きいため、費用がかさみますのでおすすめできない。

その変わり、VPCエンドポイントを色々作成するのだが、これも正直めんどい。がやるしかない。

[Fargate1.4の細かい話の公式ブログ](https://aws.amazon.com/jp/blogs/containers/aws-fargate-launches-platform-version-1-4/)

引用元。
https://docs.aws.amazon.com/AmazonECS/latest/developerguide/vpc-endpoints.html

## 利用AWSサービス別のメモ

これまで自身がはまったサービスのみです。
網羅はしていないです。

### ECR

fargate自体が利用するため、必ずVPCエンドポイントが必要。
また、Fargateプラットフォームバージョンに従って、種類が増える。

https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/vpc-endpoints.html

>Fargate 起動タイプおよびプラットフォームバージョン 1.3.0 以前を使用する Amazon ECS タスクでは、この機能を活用するために必要なのは com.amazonaws.region.ecr.dkr Amazon ECR VPC エンドポイントおよび Amazon S3 ゲートウェイエンドポイントのみです。

> Fargate 起動タイプとプラットフォームバージョン 1.4.0 以降を使用する Amazon ECS タスクでこの機能を使用するには、com.amazonaws.region.ecr.dkr と com.amazonaws.region.ecr.api Amazon ECR VPC エンドポイントの両方、および Amazon S3 ゲートウェイエンドポイントが必要です。

### s3

上段の通り、
fargate自体が利用するため、必ずVPCエンドポイントが必要。

セキュリティに厳しくしたい場合、権限を絞れる
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/userguide/vpc-endpoints.html#ecr-setting-up-s3-gateway

### Secret Manager

VPCエンドポイントが必要。

>To allow your tasks to pull sensitive data from Secrets Manager, you must create the interface VPC endpoints for Secrets Manager. For more information, see Using Secrets Manager with VPC Endpoints in the AWS Secrets Manager User Guide. 

https://docs.aws.amazon.com/AmazonECS/latest/developerguide/vpc-endpoints.html#ecs-setting-up-secrets

>If you are referencing either Secrets Manager secrets or Systems Manager Parameter Store parameters in your task definitions to inject sensitive data into your containers, you need to create the interface VPC endpoints for Secrets Manager or Systems Manager so those tasks can reach those services. You only need to create the endpoints from the specific service your sensitive data is hosted in.

### cloudwatch log

多くのECSでは、awslogsログライバーを利用してると思いますが
この場合も、VPCエンドポイントが必要。

>f your VPC doesn't have an internet gateway and your tasks use the awslogs log driver to send log information to CloudWatch Logs, you must create an interface VPC endpoint for CloudWatch Logs. For more information, see Using CloudWatch Logs with Interface VPC Endpoints in the Amazon CloudWatch Logs User Guide. 

### API Gateway

必要。

## 可能性のあるエラーメッセージ

追記2024/7/12
もうこちらをみたほうがよいです
https://aws.amazon.com/jp/about-aws/whats-new/2024/07/amazon-ecs-stopped-task-error-messages-troubleshooting/



https://docs.aws.amazon.com/AmazonECS/latest/developerguide/vpc-endpoints.html#ecs-setting-up-secrets
ドキュメントにあるトラブルシュート。

1:  Connection timed out

```
CannotPullContainerError: API error (500): Get https://111122223333.dkr.ecr.us-east-1.amazonaws.com/v2/: net/http: request canceled while waiting for connection"
```

2: Context canceled

3: Image not found

```
CannotPullContainerError: API error (404): repository 111122223333.dkr.ecr.us-east-1.amazonaws.com/<repo>/<image> not found
```

以下はこれまでハマった上記ドキュメントにないメッセージ。これもきっとネットワーク経路問題ですが、推測で書いてます

1: private subnetがインターネットを通して、ECRからpullしようとしている場合に起きる

```
CannotPullContainerError: Error response from daemon: Get https://111122223333.dkr.ecr.ap-northeast-1.amazonaws.com/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
```

2: AWS CodeDeployを通してfargateをdeployする場合に、タスク定義にある`image`の`ECRのarn..:lastest`的な記載がある場合に、恐らく`lastest`を解決できないと言っているのではないかと。。。`InternalError`なんて書かれると仕様バグか？と思ってしまうが、たぶんきっとこれもネットワークの問題。

```
 InternalError: failed to normalize image reference "arn:aws:ecr:region:111122223333:repository/xxxxx:latest"
```

## ちなみにEC2タイプの場合

地味にまた制限あり。はまりそう。

### container agentのバージョン

>Tasks using the EC2 launch type require that the container instances that they're launched on to run version 1.25.1 or later of the Amazon ECS container agent. For more information, see Amazon ECS Container Agent Versions.  

### 既存にEC2タイプを動かしている中で、新規にVPCエンドポイントを作る場合

1. 以下のエンドポイントを順番に作らないといけない。（きっとネットワーク経路の問題）

>If you have existing container instances within your VPC, you should create the endpoints in the order that they're listed. If you plan on creating your container instances after your VPC endpoint is created, the order doesn't matter

com.amazonaws.${region}.ecs-agent
com.amazonaws.${region}.ecs-telemetry
com.amazonaws.${region}.ecs

2. ECSコンテナの再起動が必要。

>If you have existing tasks that are using the EC2 launch type, after you have created the VPC endpoints, each container instance needs to pick up the new configuration. For this to happen, you must either reboot each container instance or restart the Amazon ECS container agent on each container instance. To restart the container agent, do the following. 

# VPC endpointの設定について

https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#create-interface-endpoint.html
Interface VPC endpoints (AWS PrivateLink)

VPCエンドポイントの一覧 (ここにあるサービスをFargateが利用しているなら要注意する)
https://docs.aws.amazon.com/vpc/latest/userguide/integrated-services-vpce-list.html

VPCエンドポイントの仕様もまぁまぁ細かい気が。

## 基本

- 仕組みとしては、サブネット内にエンドポイントネットワークインターフェースを作成され、「エンドポイントネットワークインターフェース」がサブネットレンジのIPからプライベートIPアドレスを保持する。（そのため、一応IPアドレスが枯渇しないようにする必要あり)
- エンドポイント固有のDNSホスト名が作成され、VPC内のエンドポイントネットワークインターフェースのプライベートIPアドレスに解決される。

（この図がこれ）
![スクリーンショット 2020-12-05 19.44.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77622/74eeae1d-f495-f34d-9940-23ed7c50d9ab.png)

## 耐障害性

- 耐障害性を考慮する場合に、ネットワーク経路を意識してVPCエンドポイントは作成する必要があります。
  - (疑問)プライベートサブネット1つの場合は、SPOFになるよって言ってる？
    - >Choose a subnet in your VPC to use the interface endpoint. We create an endpoint network interface in the subnet. An endpoint network interface is assigned a private IP address from the IP address range of your subnet, and keeps this IP address until the interface endpoint is deleted. You can specify more than one subnet in different Availability Zones (as supported by the service) to help ensure that your interface endpoint is resilient to Availability Zone failures. In that case, we create an endpoint network interface in each subnet that you specify. 
   - インターフェースエンドポイントの場合は、他アカウントと独立したAZに作成されるらしい。[参照](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#vpce-interface-availability-zones)
   - ["Creating and managing a notification for an interface endpoint"](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#create-notification-interface-endpoint)
    - 特定のイベントのアラートを受信するための通知を受け取れるようになっている。これは、サードパーティから提供されている場合のものを意識してるっぽい？

## ネットワーク性能

- デフォルトのネットワーク処理量: 10 Gbps per AZ.  bursts of up to 40Gbps. (これ以上の用途になるならサポートに連絡して許可してもらえるようにするらしい)

## お値段

- VPCエンドポイントは1サブネットに紐づく。（数によっては、VPCエンドポイントはランニングコストが発生するので、サブネット数が多いとか用途に応じては作成しなきゃいけないVPCエンドポイントが多いと、意外と高くつくのかも・・・）
    - >AWS PrivateLink エンドポイントを作成して、AWS または AWS のお客様やパートナーによって所有されるサービスへのプライベート接続を確立できます。各アベイラビリティーゾーンに VPC エンドポイントがプロビジョニングされている間、サービスとの関連性のステータスにかかわらず、時間単位の料金が発生します 
    - https://aws.amazon.com/jp/privatelink/pricing/

## セキュリティグループ設定

- ゲートウェイタイプを除き、VPCエンドポイントは、中身ネットワークインターフェースなので、セキュリティグループの設定が必要。ここ漏れやすい、重要ポイント。
    - ネットワーク経路からINにHTTPS443を許可する必要がある。
    - OUTが必要なのかは書いている箇所をが見つからず、いらないっぽい。（変にハマるの嫌だし、何かセキュリティホールになるのか？と思い、開けてしまったものもある）
        - よって、セキュリティグループは配置されるサブネットレンジからの443許可がいいのだと思う。
        - > If the network ACL for your subnet restricts traffic, you might not be able to send traffic through the endpoint network interface. Ensure that you add appropriate rules that allow traffic to and from the CIDR block of the subnet.
        - >Ensure that the security group that's associated with the endpoint network interface allows communication between the endpoint network interface and the resources in your VPC that communicate with the service. To ensure that AWS command line tools such as the AWS CLI can make requests over HTTPS from resources in the VPC to an AWS service, the security group must allow inbound HTTPS (port 443) traffic .

## VPCエンドポイントポリシー

以下の機能はECSだと使えない。

https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-endpoints-access.html

>Controlling access to Amazon ECS by attaching an endpoint policy to the VPC endpoint isn't currently supported. By default, full access to the service will be allowed through the endpoint. For more information, see Controlling Access to Services with VPC Endpoints in the Amazon VPC User Guide. 

## デバッグ方法

- 構築したはずがネットワーク経路っぽいエラーが解決しない場合の疎通テスト方法。
    - [ここを見る](https://docs.aws.amazon.com/vpc/latest/userguide/vpce-interface.html#access-service-though-endpoint)

# VPC設定

` [プライベート DNS 名を有効にする]`必要がある場合がある。

- com.amazonaws.${region}.ecr.dkr 
- com.amazonaws.${region}.ecr.api