ECSに必要なVPCエンドポイントまとめ(2022年版)

ECSで必要なVPCエンドポイントをまとめました。NATを使わず、VPCエンドポイントのみで構成する場合は参考にしてください。
2022.10.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、八木です。

プライベートサブネットからAWSのサービスエンドポイントに接続するには、NAT Gatewayを使ってインターネット経由でアクセスするか、VPCエンドポイントを使用する必要があります。
この際、セキュリティ要件などからインターネットを経由したくない場合があります。また、料金の面からNAT GatewayではなくVPCエンドポイントを使いたいといったケースもあるでしょう。

今回の記事では、ECSを利用する際に必要なVPCエンドポイントをまとめてみました。
NATとVPCエンドポイントどちらを使うか悩んでいる方、VPCエンドポイントのみで構成したい方の参考になれば幸いです。

以前の記事で似たものがありますが、本記事執筆時点ではサービスアップデートによる変更があります。
具体的には、Fargateのプラットフォームタイプ、バージョンによって必要なエンドポイントが変わりました。

また、今回の記事では必須のエンドポイントだけでなく、構成によって必要になるエンドポイントもあわせてご紹介します。

先に結論

ECSのエンドポイント

エンドポイント EC2 Fargate
com.amazonaws.region.ecs-agent 必要 不要
com.amazonaws.region.ecs-telemetry 必要 不要
com.amazonaws.region.ecs 必要 不要

ECRのエンドポイント

エンドポイント EC2 Fargate Linux 1.4.0 Fargate Linux 1.3.0以前 Fargate Windows 1.0.0
com.amazonaws.region.ecr.dkr 必要 必要 必要 必要
com.amazonaws.region.ecr.api 必要 必要 不要 必要
com.amazonaws.region.s3(ゲートウェイ型) 必要 必要 必要 必要

その他エンドポイント

以下のエンドポイントは構成によって必要になります。

  • CloudWatch Logs エンドポイント(com.amazonaws.region.logs
  • Secrets Manager エンドポイント(com.amazonaws.region.secretsmanager
  • Systems Manager エンドポイント(com.amazonaws.region.ssm, com.amazonaws.region.ssmmessages

ECSのエンドポイント解説

表に記載した通りです。EC2の場合はVPCエンドポイントが必要な一方、Fargateでは必要ありません。
EC2ではコンテナエージェントがECSサービスと通信する必要があるため、VPCエンドポイントが必要になっています。

ECRのエンドポイント解説

コンテナイメージをECRに保存している場合はECRへのエンドポイントが必要です。
必要なエンドポイントはキャパシティプロバイダーごとに決まっており、EC2の場合はcom.amazonaws.region.ecr.dkr, com.amazonaws.region.ecr.api, com.amazonaws.region.s3(ゲートウェイ型)の3つ全てが必要です。
Fargateは以前はcom.amazonaws.region.ecr.apiが必要なかったのですが、Linux 1.4.0およびWindows 1.0.0から必要になりました。

その他エンドポイントの解説

以降のエンドポイントは、構成によって必要なものです。それぞれ解説していきます。

CloudWatch Logs エンドポイント

com.amazonaws.region.logs

ログをCloudWatch Logsに送信するのに必要なエンドポイントです。SaaSや独自でログを取得するシステムを構築していない限り、サービス運用上ほぼ必須と言って良いでしょう。
awslogsログドライバーを使用する場合、必ず必要になります。

Secrets Manager エンドポイント

com.amazonaws.region.secretsmanager

タスク定義でSecrets Managerの値を環境変数として渡すように指定していた場合、必要になります。
DBへの接続情報などをSecrets Managerに保存している場合は利用することになるでしょう。

Systems Manager エンドポイント

com.amazonaws.region.ssm,com.amazonaws.region.ssmmessages

Systems Managerのエンドポイントは、パラメータストアとECS Execを使用する際に必要です。

Secrets Managerと同様、ECSではコンテナに環境変数としてSSMパラメータストアの値を渡すことができます。
SSMパラメータストアを利用するには、com.amazonaws.region.ssmのVPCエンドポイントが必要です。

ECS Execは稼働中のコンテナにログインできる機能です。この機能はSSM Session Managerを利用しており、com.amazonaws.region.ssmmessagesのVPCエンドポイントが必要になります。

やってみた

今回の記事で取り上げたVPCエンドポイントを使う構成を作ってみます。
VPCエンドポイントが1つもない状態から構築し、タスク起動時のエラー内容を確認しながらVPCエンドポイントを追加していきます。

構成は以下です。

キャパシティプロバイダー:Fargate
コンテナイメージリポジトリ:ECR
ログ:CloudWatch Logs
パラメータストア:Systems Manager Parameter Store, Secrets Manager

事前準備

ECR, ECS, KMS, SSM Parameter Store, Secrets Managerを作成します。

なお、今回の検証ではVPCエンドポイント起因のエラーに着目するため、ECSのタスク実行ロールおよびタスクロールにAdministrator権限を使用しています。本番運用では必要最小限のアクセス許可を指定してください。

まずECRリポジトリを作成します。

aws ecr create-repository --repository-name ecs-test

作成したECRリポジトリにログインし、

aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com

適当なDockerイメージをDocker Hubからpullして、

docker pull --platform linux/amd64 httpd:2.4

ECRリポジトリにpushします。

docker tag httpd:2.4 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-test:latest
docker push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-test:latest

次にSSMパラメータストアの暗号化に使用するKMSキーを作成します。

aws kms create-key

SSMパラメータストアに、作成したKMSを使って暗号化した値を保存します。
(暗号化してもしなくても、必要なVPCエンドポイントは変わりません。KMSのVPCエンドポイントが必要ないことを確認するためにKMS暗号化をしています。)

aws ssm put-parameter --name ecs-test --value "secret-value-in-parameter-store" --type SecureString --key-id xxxx-xxxxxxx-xxxxxxx-xxxxxxx

Secrets Managerのシークレットを作成します。

aws secretsmanager create-secret --name ecs-test --secret-string '{"key1":"secret-value-1"}'

次にECSクラスター、タスク定義を作成します。
タスク定義では、Secrets ManagerおよびSSMパラメータストアの値をコンテナの環境変数で利用するように設定します。

aws ecs create-cluster --cluster-name ecs-test --capacity-providers FARGATE
aws ecs register-task-definition \
--family ecs-test \
--task-role-arn arn:aws:iam::123456789012:role/ECSExecTaskRole \
--execution-role-arn arn:aws:iam::123456789012:role/ecsTaskExecutionRole \
--network-mode awsvpc --cpu 256 --memory 512 \
--container-definitions '[{"name":"web","image":"123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/ecs-test","portMappings":[{"containerPort":80}],"essential":true,"secrets":[{"name":"SECRETS_MANAGER_VALUE","valueFrom":"arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:ecs-test-0x0KIE:key1::"},{"name":"SSM_PARAMETER_VALUE","valueFrom":"arn:aws:ssm:ap-northeast-1:123456789012:parameter/ecs-test"}],"logConfiguration":{"logDriver":"awslogs","options":{"awslogs-region":"ap-northeast-1","awslogs-group":"/ecs/ecs-test","awslogs-stream-prefix": "ecs"}}}]' \
--runtime-platform '{"cpuArchitecture":"X86_64","operatingSystemFamily":"LINUX"}' \
--requires-compatibilities "FARGATE"

以上でECSの実行環境が整いました。

エラーを確認しつつ、VPCエンドポイントを追加してみる

ではタスクを実行し、エラーを確認しつつエンドポイントを追加していきます。

まず、VPCエンドポイントがない状態でECSタスクを実行してみます。

aws ecs run-task \
--task-definition ecs-test \
--cluster ecs-test \
--count 1 \
--enable-execute-command \
--launch-type FARGATE \
--network-configuration '{"awsvpcConfiguration":{"subnets":["subnet-xxxxxxxxxxxxxx"],"securityGroups":["sg-xxxxxxxxxxxxxxxxxxx"]}}'

AWSコンソールからタスクを確認してみると、ステータスが「停止済み」になっていました。

停止理由に ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve secret from asm: service call has been retried 5 time(s): failed to fetch secret arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:ecs-test-0x0KIE from secrets manager: RequestCanceled: request context canceled caused by: context deadline exceededとあります。
環境変数に指定しているSecrets Managerの値を取得できないことが原因のようです。

Secrets ManagerへのVPCポイント(com.amazonaws.region.secretsmanager)を追加してみます。

再度ECSタスクを実行してみると、停止理由が変わりました。

ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve secrets from ssm: service call has been retried 5 time(s): RequestCanceled: request context canceled caused by: context deadline exceeded
Secrets Managerのエラーは解消しましたが、次はSSMパラメータストアからの値が取れていないようです。

SSMパラメータストアに必要なVPCポイント(com.amazonaws.region.ssm)を追加してみます。

再びECSタスクを立ち上げると停止理由が以下になりました。


ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to retrieve ecr registry auth: service call has been retried 3 time(s): RequestError: send request failed caused by: Post "https://api.ecr.ap-northeast-1.amazonaws.com/": dial tcp xxx.xxx.xxx.xxx:443: i/o timeout
ECRレジストリの認証エラーです。

今回はFargate Linux 1.4.0を利用しているため、ECRからイメージのプルに必要な以下のVPCエンドポイントを追加します。

  • com.amazonaws.region.ecr.dkr
  • com.amazonaws.region.ecr.api
  • com.amazonaws.region.s3(ゲートウェイ型)

再びECSタスクを立ち上げると停止理由が変わりました。


ResourceInitializationError: failed to validate logger args: : signal: killed
エラー内容からは原因を特定しにくいですが、CloudWatch Logsへ通信できないことが原因です。
awslogsログドライバーが無効の場合はこちらのエラーは発生しません。

では、CloudWatchLogsのエンドポイントを追加します。


タスクはまた停止しましたが、別の停止理由になりました。


ResourceInitializationError: failed to validate logger args: create stream has been retried 1 times: failed to create Cloudwatch log stream: ResourceNotFoundException: The specified log group does not exist. : exit status 1
今度は通信エラーではなく、Cloud Watch Logsのロググループが存在しないことが原因でした。

CLIからロググループを作成し、再度起動します。

aws logs create-log-group --log-group-name /ecs/ecs-test

ついにタスクが停止することなく、動作しました。

以上でECSタスクの実行に必要なVPCエンドポイントは揃いました。

最後はECS Execの確認です。
CLIからECS Execを実行してみます。

aws ecs execute-command --cluster ecs-test --task d3d8b8e2a39c46b6a9d69b057eb7302d --container web --interactive --command "/bin/bash"

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


An error occurred (TargetNotConnectedException) when calling the ExecuteCommand operation: The execute command failed due to an internal error. Try again later.

エラー終了してしまいました。
ECS Execに必要なVPCエンドポイントはcom.amazonaws.region.ssmmessagesです。

ただしログをCloud Watch LogsやS3に保存する場合や、クライアントとECSタスク間の通信の暗号化に独自のKMSキーを利用する場合は、別途VPCエンドポイントが必要です。

com.amazonaws.region.ssmmessagesを追加します。

既存のタスクに再度接続しようとしましたが、同じエラーが発生してしまいました。

新しくタスクを起動してログインしてみると問題なく接続できました。

aws ecs execute-command --cluster ecs-test --task b89090a220ba42b7a215b0d28203efa1 --container web --interactive --command "/bin/bash"

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


Starting session with SessionId: ecs-execute-command-09f3ef4c8736bf1fa
root@ip-10-0-3-225:/usr/local/apache2#

Secrets ManagerおよびSSMパラメータストアから正常に環境変数に設定されていることも確認できました。

root@ip-10-0-3-225:/usr/local/apache2# echo $SECRETS_MANAGER_VALUE
secret-value-1
root@ip-10-0-3-225:/usr/local/apache2# echo $SSM_PARAMETER_VALUE
secret-value-in-parameter-store

さいごに

今回の記事ではECSに必要なVPCエンドポイントをまとめました。
コンプライアンスやコストの面から、NAT Gatewayではなく、VPCエンドポイントを利用するという選択肢を取ることもあるかと思います。
アーキテクチャによって、必要なVPCエンドポイントを整理し、追加していきましょう。

以上、八木でした!

参考リンク

Linux プラットフォームのバージョン - Amazon Elastic Container Service
Amazon ECR インターフェイス VPC エンドポイント (AWS PrivateLink) - Amazon ECR
ステップ 6: VPC エンドポイントの作成 - AWS Systems Manager
Amazon ECS とインターフェイス VPC エンドポイント (AWS PrivateLink) - Amazon Elastic Container Service
デバッグ用にAmazon ECS Exec を使用 - Amazon ECS
コンテナへの機密データの受け渡し - Amazon ECS
リファレンス: ec2messages、ssmmessages およびその他の API オペレーション - AWS Systems Manager