AWS ECS Fargate ResourceInitializationError: プライベートレジストリ認証エラーの解決方法
AWS ECS Fargate でプライベートリポジトリを使用する際に、「ResourceInitializationError: unable to pull secrets or registry auth」エラーが発生する問題とその解決方法について解説します。
問題の概要
ECS Fargate platform version 1.4.0 以降で、プライベートコンテナリポジトリの認証やシークレットの取得に失敗し、以下のエラーが発生します:
ResourceInitializationError: unable to pull secrets or registry auth: execution resource retrieval failed: unable to get registry auth from asm: service call has been retried 1 time(s): asm fetching secret from the service for <secretname>: RequestError: ...
このエラーは、ECSタスクがAWS Secrets ManagerやECRへのアクセスに必要なネットワーク接続を確立できない場合に発生します。
根本原因
AWS従業員の回答によると、この問題はFargate platform version 1.3.0から1.4.0への変更に起因しています:
- バージョン1.3.0以前: Fargateタスクは2つのネットワークインターフェースを使用
- 1つはアプリケーション通信、ログ、コンテナイメージ取得用
- もう1つはECR認証情報とシークレット取得用のプラットフォーム専用
- バージョン1.4.0以降: 単一のネットワークインターフェースに統合
- すべてのトラフィックが顧客VPC内を通るよう変更
- VPCフローログで監視可能、ネットワークレベルの制御が可能に
この変更により、ネットワーク制御の柔軟性は向上しましたが、ユーザーはVPC内でECRやSecrets Managerへのネットワークパスを適切に設定する責任を負うことになりました。
解決方法
以下のいずれかの方法で問題を解決できます。
方法1: パブリックサブネットでの実行
パブリックサブネットでタスクを実行し、パブリックIPアドレスを割り当てます:
WARNING
セキュリティ上の理由から、本番環境では慎重に検討してください。
- ECSサービス設定で「Auto-assign public IP」を「ENABLED」に設定
- インターネットゲートウェイ経由でECRおよびSecrets Managerにアクセス
方法2: NATゲートウェイの使用
プライベートサブネットでタスクを実行し、NATゲートウェイを経由して外部接続を許可します:
// プライベートサブネットのルートテーブル
Destination: 0.0.0.0/0
Target: nat-{NATゲートウェイID}
// アウトバウンドルール
Type: All traffic
Protocol: All
Port: All
Destination: 0.0.0.0/0
方法3: VPCエンドポイントの設定(推奨)
プライベートサブネットでタスクを実行し、VPCエンドポイントを使用してAWSサービスにアクセスします。これが最も安全で推奨される方法です。
必要なVPCエンドポイント
サービス | エンドポイント名 |
---|---|
ECR API | com.amazonaws.<region>.ecr.api |
ECR DKR | com.amazonaws.<region>.ecr.dkr |
S3 | com.amazonaws.<region>.s3 (ゲートウェイエンドポイント) |
CloudWatch Logs | com.amazonaws.<region>.logs |
Secrets Manager | com.amazonaws.<region>.secretsmanager |
KMS | com.amazonaws.<region>.kms |
セキュリティグループ設定
VPCエンドポイント用のセキュリティグループを作成し、インバウンドルールを設定します:
Type: HTTPS
Protocol: TCP
Port: 443
Source: <ECSサービスにアタッチされたセキュリティグループ>
resource "aws_security_group" "vpc_endpoint_sg" {
name = "vpc-endpoint-sg"
description = "Security group for VPC endpoints"
vpc_id = aws_vpc.main.id
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
security_groups = [aws_security_group.ecs_service.id]
}
}
IAM権限の確認
ECSタスク実行ロールに以下の権限が付与されていることを確認してください:
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchGetImage",
"ecr:GetDownloadUrlForLayer",
"logs:CreateLogStream",
"logs:PutLogEvents",
"secretsmanager:GetSecretValue"
],
"Resource": "*"
}
{
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
シークレットARNの形式確認
Secrets Managerを使用する場合、シークレットARNの形式を確認してください:
{
"containerDefinitions": [{
"secrets": [{
"name": "MY_SECRET",
"valueFrom": "arn:aws:secretsmanager:<region>:<account>:secret:<secret_name>:MY_SECRET"
}]
}]
}
{
"containerDefinitions": [{
"secrets": [{
"name": "MY_SECRET",
"valueFrom": "arn:aws:secretsmanager:<region>:<account>:secret:<secret_name>:MY_SECRET::"
}]
}]
}
トラブルシューティングツール
AWS Systems Managerの自動化実行機能を使用して問題を診断できます:
- AWS Systems Managerコンソールにアクセス
- Automation → Execute automationを選択
- 実行ドキュメント名で
AWSSupport-TroubleshootECSTaskFailedToStart
を検索 - 必要なパラメータを入力して実行
このツールは、以下の問題を自動的に診断します:
- 欠落しているVPCエンドポイント
- セキュリティグループの設定ミス
- IAM権限の問題
- イメージプールの失敗
Terraform設定例
以下は、適切に設定されたVPCとエンドポイントのTerraform設定例です:
Terraform設定例
variable "name" {
description = "プロジェクト名"
type = string
}
variable "environment" {
description = "環境名"
type = string
}
variable "aws_region" {
description = "AWSリージョン"
type = string
}
data "aws_availability_zones" "available" {}
locals {
num_availability_zones = 3
availability_zones = slice(data.aws_availability_zones.available.names, 0, local.num_availability_zones)
public_cidrs = [for n in range(1, local.num_availability_zones + 1): "10.0.${n}.0/24"]
private_cidrs = [for n in range(local.num_availability_zones + 1, local.num_availability_zones * 2 + 1): "10.0.${n}.0/24"]
}
resource "aws_vpc" "this" {
cidr_block = "10.0.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
tags = {
Name = "${var.name}-${var.environment}"
}
}
resource "aws_subnet" "private" {
count = local.num_availability_zones
availability_zone = element(local.availability_zones, count.index)
cidr_block = element(local.private_cidrs, count.index)
vpc_id = aws_vpc.this.id
tags = {
Name = "${var.name}-${var.environment}-private-${count.index + 1}"
}
}
resource "aws_vpc_endpoint" "ecr_dkr" {
private_dns_enabled = true
service_name = "com.amazonaws.${var.aws_region}.ecr.dkr"
vpc_endpoint_type = "Interface"
vpc_id = aws_vpc.this.id
security_group_ids = [aws_security_group.this.id]
subnet_ids = aws_subnet.private[*].id
tags = {
Name = "${var.name}-${var.environment}-privatelink-ecr-dkr"
}
}
resource "aws_vpc_endpoint" "ecr_api" {
private_dns_enabled = true
service_name = "com.amazonaws.${var.aws_region}.ecr.api"
vpc_endpoint_type = "Interface"
vpc_id = aws_vpc.this.id
security_group_ids = [aws_security_group.this.id]
subnet_ids = aws_subnet.private[*].id
tags = {
Name = "${var.name}-${var.environment}-privatelink-ecr-api"
}
}
resource "aws_vpc_endpoint" "cloudwatch" {
private_dns_enabled = true
service_name = "com.amazonaws.${var.aws_region}.logs"
vpc_endpoint_type = "Interface"
vpc_id = aws_vpc.this.id
security_group_ids = [aws_security_group.this.id]
subnet_ids = aws_subnet.private[*].id
tags = {
Name = "${var.name}-${var.environment}-privatelink-cloudwatch"
}
}
resource "aws_vpc_endpoint" "s3_gateway" {
service_name = "com.amazonaws.${var.aws_region}.s3"
vpc_endpoint_type = "Gateway"
vpc_id = aws_vpc.this.id
route_table_ids = [aws_default_route_table.this.id]
tags = {
Name = "${var.name}-${var.environment}-privatelink-s3-gateway"
}
}
まとめ
ECS Fargate platform version 1.4.0以降では、ネットワークアーキテクチャの変更により、プライベートサブネットでタスクを実行する場合は適切なVPCエンドポイントの設定が必須です。最も安全で推奨される解決方法は、VPCエンドポイントを使用してAWSサービスにアクセスする方法です。
問題が発生した場合は、以下の順序で確認することをおすすめします:
- VPCエンドポイントの設定とセキュリティグループ
- IAM実行ロールの権限
- シークレットARNの形式
- サブネットのルートテーブル設定
- AWSのトラブルシューティングツールの実行
これらの設定を適切に行うことで、ResourceInitializationError
を解決し、安定したECS Fargate環境を構築できます。