状況
ECRイメージを指す新しいECSタスク定義をデプロイしました。タスクは初期化中に即座に失敗し、コンテナすら起動しませんでした。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
コンテナログはなし。CloudWatchにも何もなし。タスクは終了コード None で STOPPED 状態を繰り返していました。
原因は2つ考えられます:タスク実行ロールのIAM権限が不足しているか、ECSエージェントがECRに到達できないネットワーク問題です。どちらも同じエラーメッセージが出るため、デバッグが厄介です。
デバッグ手順
ステップ1:タスク実行ロールを確認する
タスク実行ロールはタスクロールとは別物です。ECSエージェントがイメージをプルしたりシークレットを取得するために使用するロールであり、アプリケーションコードが実行時に使用するロールではありません。
タスク定義でタスク実行ロールを見つけて確認します:
aws iam list-attached-role-policies --role-name ecsTaskExecutionRole
出力に AmazonECSTaskExecutionRolePolicy が含まれている必要があります。見当たらない場合、それが問題です。このマネージドポリシーは最低限必要なもの(ECRのプルとCloudWatch Logsへの書き込み)をカバーしています。
次に、信頼関係がECSにこのロールの引き受けを実際に許可しているか確認します:
aws iam get-role --role-name ecsTaskExecutionRole --query 'Role.AssumeRolePolicyDocument'
期待される出力:
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
信頼ポリシーが誤っているか存在しない場合、ECSはロールをまったく引き受けられず、初期化を通過できません。
ステップ2:ネットワークアクセスを確認する(プライベートサブネット内のFargate)
これが落とし穴です。実行ロールに問題がない場合、原因はほぼ確実にネットワーク接続です。プライベートサブネット内のFargateタスクは、起動するだけでいくつかのAWSエンドポイントに到達する必要があります:
ecr.dkr.ecr.<region>.amazonaws.com— イメージレイヤーecr.api.ecr.<region>.amazonaws.com— 認証トークンs3.<region>.amazonaws.com— ECRはイメージレイヤーをS3に保存logs.<region>.amazonaws.com— CloudWatch Logsssm.<region>.amazonaws.com— Secrets ManagerまたはSSMパラメータストアを使用する場合
NATゲートウェイもVPCエンドポイントもないプライベートサブネットでは、これらのいずれにもルーティングできません。ECSエージェントは静かにタイムアウトし、まさにこのエラーが発生します。
既存のVPCエンドポイントを確認します:
aws ec2 describe-vpc-endpoints \
--filters "Name=vpc-id,Values=vpc-xxxxxxxx" \
--query 'VpcEndpoints[*].{Service:ServiceName,State:State}'
ステップ3:ECRイメージURIを確認する
あまり一般的ではありませんが、素早く確認する価値はあります。URIのアカウントIDやリージョンが誤っている場合も認証失敗につながります。これは、タスク定義をリージョン間でコピーする際(例:us-east-1 から ap-northeast-1)にURIの更新を忘れると発生しがちです。
aws ecs describe-task-definition --task-definition my-task \
--query 'taskDefinition.containerDefinitions[*].image'
正しい形式:123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-repo:tag
修正方法
修正1:実行ロールに正しいマネージドポリシーをアタッチする
aws iam attach-role-policy \
--role-name ecsTaskExecutionRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
Secrets ManagerやSSMを使って環境変数を注入している場合、実行ロールには以下の追加権限が必要です:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"ssm:GetParameters",
"kms:Decrypt"
],
"Resource": "*"
}
]
}
修正2:プライベートサブネット用のVPCエンドポイントを追加する(NATゲートウェイなし)
ECR用のインターフェースエンドポイントとS3用のゲートウェイエンドポイントを作成します:
# ECR APIエンドポイント
aws ec2 create-vpc-endpoint \
--vpc-id vpc-xxxxxxxx \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.ap-northeast-1.ecr.api \
--subnet-ids subnet-xxxxxxxx \
--security-group-ids sg-xxxxxxxx \
--private-dns-enabled
# ECR DKRエンドポイント(イメージレイヤー)
aws ec2 create-vpc-endpoint \
--vpc-id vpc-xxxxxxxx \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.ap-northeast-1.ecr.dkr \
--subnet-ids subnet-xxxxxxxx \
--security-group-ids sg-xxxxxxxx \
--private-dns-enabled
# S3ゲートウェイエンドポイント(ECRはレイヤーをここに保存)
aws ec2 create-vpc-endpoint \
--vpc-id vpc-xxxxxxxx \
--vpc-endpoint-type Gateway \
--service-name com.amazonaws.ap-northeast-1.s3 \
--route-table-ids rtb-xxxxxxxx
# CloudWatch Logsエンドポイント
aws ec2 create-vpc-endpoint \
--vpc-id vpc-xxxxxxxx \
--vpc-endpoint-type Interface \
--service-name com.amazonaws.ap-northeast-1.logs \
--subnet-ids subnet-xxxxxxxx \
--security-group-ids sg-xxxxxxxx \
--private-dns-enabled
各VPCエンドポイントのセキュリティグループは、タスクサブネットからのインバウンドHTTPS(ポート443)を許可する必要があります。これがないと、エンドポイントは存在していてもトラフィックが通過できません。
修正3:代替案 — パブリックIPを割り当てる(簡易テストのみ)
エンドポイントをセットアップする前に、問題がネットワーク関連かどうかを切り分けたいですか?ワンオフのテスト実行でパブリックIPの自動割り当てを有効にします:
aws ecs run-task \
--cluster my-cluster \
--task-definition my-task \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[subnet-xxxxxxxx],securityGroups=[sg-xxxxxxxx],assignPublicIp=ENABLED}"
パブリックIPありで起動し、なしで失敗する場合はネットワークが原因と確定です。VPCエンドポイントをセットアップしましょう。この設定を本番環境にデプロイしてはいけません。
確認
修正が完了したら、タスクを再実行してイベントを監視します:
aws ecs describe-tasks \
--cluster my-cluster \
--tasks <task-arn> \
--query 'tasks[0].{Status:lastStatus,StoppedReason:stoppedReason,Containers:containers[*].{Name:name,Reason:reason}}'
正常にプルされると、タスクは PENDING → ACTIVATING → RUNNING と遷移します。まだ失敗する場合は stoppedReason を確認してください。ECSコンソールに表示される情報より詳細な内容が含まれていることが多いです。
起動したらログをリアルタイムで確認します:
aws logs tail /ecs/my-task --follow
教訓
- ECSタスク実行ロールは必ず
AmazonECSTaskExecutionRolePolicyをベースにしてください。ポリシーをゼロから書くと必ず何かが抜けます。 - 新しいVPCにECSをセットアップする際は、タスクをデプロイする前にECR/S3/LogsのVPCエンドポイントを用意しておきましょう。デプロイが壊れた状態で後から追加するのは辛いです。
- エラーには「3回リトライ」と書かれています。これはネットワークタイムアウトであり、IAMによる認証拒否ではありません。本当の403はIAMから返されると見た目が異なります。
ResourceInitializationErrorのラッパーが両方のケースを隠してしまうため、常にIAMとネットワークの両方を確認してください。 - タスク実行ロールとタスクロールは異なる目的を持っています。開発者は片方を設定してもう片方の存在を忘れがちです。
- タスク定義内のSecrets Manager参照には、実行ロールに
secretsmanager:GetSecretValueが必要です。プライベートサブネットで実行している場合は、Secrets Manager用のVPCエンドポイントも別途必要になります。ECRとは別のエンドポイントです。

