SJ blog
backend
A

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

ECSタスクロール vs 実行ロール — 2種類のIAMロールの役割と設計

ECSのタスク実行ロール(ECSエージェントが使うロール)とタスクロール(コンテナアプリが使うロール)の違い、ECRからのイメージ取得、Secrets Manager統合、コンテナレベルの最小権限設計を解説。

一言結論

タスク実行ロールはECSエージェントがコンテナ起動に使う権限でタスクロールはアプリが業務ロジックで使う権限であり、混同すると過大な権限付与や動作不良につながるため「誰が使うか」を起点に明確に分けて設計することが最小権限の原則の第一歩だ。

2種類のIAMロールの役割

ECSには紛らわしい2種類のIAMロールが存在する。混同しないことが重要だ。

ロール誰が使うか主な用途
タスク実行ロール(Task Execution Role)ECSエージェント(AWS側)ECRからイメージをプル、Secrets Manager/SSMから環境変数を取得、CloudWatchにログを送信
タスクロール(Task Role)コンテナ内のアプリケーションS3へのアクセス、DynamoDBへの読み書き等、アプリの業務ロジックに必要な権限
起動フロー:
  ECSサービス(エージェント)
    ↓ タスク実行ロールを使って:
    ↓ ECRからDockerイメージをプル
    ↓ Secrets ManagerからDBパスワードを取得
    ↓ タスクを起動

  コンテナ内のアプリケーション
    ↓ タスクロールを使って:
    ↓ S3にファイルをアップロード
    ↓ DynamoDBに書き込み

タスク実行ロール

// タスク実行ロールに必要な最小権限(AWSマネージドポリシーを使う場合)
// arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy が基本

// カスタムで追加する権限(Secrets Manager/SSMを使う場合)
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken",
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetSecretValue",
        "kms:Decrypt"
      ],
      "Resource": [
        "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/db-password*",
        "arn:aws:kms:ap-northeast-1:123456789012:key/xxx"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "ssm:GetParameters",
      "Resource": "arn:aws:ssm:ap-northeast-1:123456789012:parameter/myapp/prod/*"
    }
  ]
}

タスクロール

// タスクロール(アプリが使う権限)
{
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:PutObject"],
      "Resource": "arn:aws:s3:::app-data-bucket/*"
    },
    {
      "Effect": "Allow",
      "Action": ["dynamodb:PutItem", "dynamodb:GetItem"],
      "Resource": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/Orders"
    }
  ]
}

タスク定義での設定

{
  "family": "my-app",
  "executionRoleArn": "arn:aws:iam::123456789012:role/ECSTaskExecutionRole",
  "taskRoleArn": "arn:aws:iam::123456789012:role/ECSTaskRole",
  "containerDefinitions": [
    {
      "name": "app",
      "image": "123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/my-app:latest",
      "secrets": [
        {
          "name": "DB_PASSWORD",
          "valueFrom": "arn:aws:secretsmanager:ap-northeast-1:123456789012:secret:prod/db-password"
        }
      ],
      "environment": [
        {
          "name": "APP_ENV",
          "value": "production"
        }
      ],
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/my-app",
          "awslogs-region": "ap-northeast-1",
          "awslogs-stream-prefix": "ecs"
        }
      }
    }
  ]
}

コンテナ内でのクレデンシャル取得

ECS Fargateでは、タスクメタデータエンドポイント経由でタスクロールのクレデンシャルを取得する。EC2インスタンスメタデータとは異なるエンドポイントだ。

# アプリケーションはSDKを使うだけで自動的にタスクロールのクレデンシャルを使う
import boto3

# これだけでタスクロールのクレデンシャルが自動的に使われる
s3 = boto3.client('s3')
s3.put_object(Bucket='app-data-bucket', Key='data.json', Body='...')
# タスクメタデータエンドポイント(コンテナ内から確認)
curl $AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
# → 一時クレデンシャルが返る(IMDSv2と同様の形式)

マイクロサービスごとの最小権限

各サービスに専用のタスクロールを作成し、最小権限を付与する。

OrderService のタスクロール:
  → DynamoDB Orders テーブルのみ

PaymentService のタスクロール:
  → Secrets Manager の決済APIキーのみ

NotificationService のタスクロール:
  → SES(メール送信)のみ
  → SNS(SMS送信)のみ

試験頻出ポイント

シナリオ回答
ECRからイメージをプルする権限タスク実行ロール
コンテナがS3にアクセスする権限タスクロール
Secrets Managerから環境変数を注入タスク実行ロール(secretsフィールド)
CloudWatchにログを送信タスク実行ロール
アプリがDynamoDBに書き込むタスクロール

まとめ

タスク実行ロールは「ECSがコンテナを起動する際に必要な権限」、タスクロールは「起動後のアプリケーションが必要な権限」として明確に分けて設計する。特に本番環境ではコンテナごとに専用タスクロールを作成し、最小権限の原則を徹底することが重要だ。