0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ECS の execution role と task role の違いを理解する:Secrets Manager 権限でハマらないために

0
Posted at

IAM の構成を理解する

IAM まわりのリソースは、大きく分けると次の 3 つです。

概念 役割
Role AWS サービスが利用する身分
Policy 許可する権限
Attachment Role に Policy を紐づけるもの

つまり、基本的な流れはいつも次のようになります。

Role を作成
→ Policy を作成
→ Policy を Role に Attach

ECS で Role が 2 つ必要になる理由

ECS では、一般的に Role が 2 種類必要になります。

Role 用途
execution role ECS 自体がタスクを起動・実行するため
task role コンテナ内のアプリケーションコードが使うため

この違いを理解することが一番重要です。

execution role

execution role は、ECS が task を起動するときに使用する Role です。

たとえば、次のような処理で使われます。

  • ECR からイメージを pull する
  • CloudWatch Logs にログを送信する
  • Secrets Manager から secret を取得する

つまり、Secrets Manager から環境変数を読み込むための権限は、この execution role に付与する必要があります。

task role

task role は、コンテナ内部で動いているアプリケーションが使用する Role です。

たとえば、アプリケーションコードから次のような AWS サービスへアクセスする場合に使います。

  • S3 へのアクセス
  • DynamoDB へのアクセス
  • SES によるメール送信

つまり、アプリケーションコード内で S3 SDK を使う場合は、task role に S3 の権限を付与します。


1. ECS Execution Role を作成する

resource "aws_iam_role" "ecs_task_execution" {
  name = "${var.project}-ecs-task-execution-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"

    Statement = [
      {
        Effect = "Allow"

        Principal = {
          Service = "ecs-tasks.amazonaws.com"
        }

        Action = "sts:AssumeRole"
      }
    ]
  })
}

ここでは、ecs-tasks.amazonaws.com がこの Role を引き受けられるようにしています。


2. ECS Execution 用の基本 Policy を紐づける

ECS の実行に必要な AWS 管理ポリシーを attach します。

resource "aws_iam_role_policy_attachment" "ecs_task_execution" {
  role       = aws_iam_role.ecs_task_execution.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy"
}

この Policy には、主に次のような権限が含まれています。

  • ECR からの image pull
  • CloudWatch Logs へのログ送信

ただし、重要なのは次の点です。

Secrets Manager へのアクセス権限は含まれていない

ということです。


3. Secrets Manager にアクセスするための Policy を作成する

Secrets Manager から値を読み取るための権限を、別途作成します。

resource "aws_iam_policy" "ecs_secrets" {
  name = "${var.project}-ecs-secrets-policy"

  policy = jsonencode({
    Version = "2012-10-17"

    Statement = [
      {
        Effect = "Allow"

        Action = [
          "secretsmanager:GetSecretValue"
        ]

        Resource = [
          "arn:aws:secretsmanager:ap-northeast-2:yourIAMnumber:secret:yourapp"
        ]
      }
    ]
  })
}

4. Secrets 用 Policy を Execution Role に紐づける

ここはよく間違えやすいポイントです。

Secrets Manager の権限は、必ず次の Role に付与します。

execution role
resource "aws_iam_role_policy_attachment" "ecs_secrets_attach" {
  role       = aws_iam_role.ecs_task_execution.name
  policy_arn = aws_iam_policy.ecs_secrets.arn
}

もしこの権限を task role に付与してしまうと、次のようなエラーが発生します。

AccessDeniedException:
is not authorized to perform:
secretsmanager:GetSecretValue

なぜなら、ECS が secret を読み込むときに使用する主体は task role ではなく、execution role だからです。


5. Task Role を作成する

次に、アプリケーションコード用の Role を作成します。

resource "aws_iam_role" "ecs_task" {
  name = "${var.project}-ecs-task-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"

    Statement = [
      {
        Effect = "Allow"

        Principal = {
          Service = "ecs-tasks.amazonaws.com"
        }

        Action = "sts:AssumeRole"
      }
    ]
  })
}

6. アプリケーション用の権限を紐づける

たとえば、アプリケーションコードから S3 にアクセスする必要がある場合は、次のような Policy を作成します。

resource "aws_iam_policy" "ecs_s3_access" {
  name = "${var.project}-ecs-s3-access"

  policy = jsonencode({
    Version = "2012-10-17"

    Statement = [
      {
        Effect = "Allow"

        Action = [
          "s3:ListBucket"
        ]

        Resource = data.aws_s3_bucket.app.arn
      },

      {
        Effect = "Allow"

        Action = [
          "s3:GetObject",
          "s3:PutObject",
          "s3:DeleteObject"
        ]

        Resource = "${data.aws_s3_bucket.app.arn}/*"
      }
    ]
  })
}

そして、この Policy を task role に attach します。

resource "aws_iam_role_policy_attachment" "ecs_s3_access" {
  role       = aws_iam_role.ecs_task.name
  policy_arn = aws_iam_policy.ecs_s3_access.arn
}

7. ECS Task Definition に Role を設定する

ECS の task definition には、それぞれの Role を設定します。

resource "aws_ecs_task_definition" "app" {
  execution_role_arn = aws_iam_role.ecs_task_execution.arn
  task_role_arn      = aws_iam_role.ecs_task.arn
}

それぞれの意味は次のとおりです。

フィールド 役割
execution_role_arn ECS が task を実行するための Role
task_role_arn アプリケーションコードが使用する Role

8. Secrets Manager の値を環境変数として設定する

Secrets Manager の値を ECS の環境変数として注入します。

locals {
  secret_keys = [
    "DATABASE_URL",
    "AUTH_SECRET",
    "AUTH_GOOGLE_ID"
  ]
}
secrets = [
  for key in local.secret_keys : {
    name      = key
    valueFrom = "${var.secrets_arn}:${key}::"
  }
]

Secrets Manager 側の値は、JSON 形式になっている必要があります。

{
  "DATABASE_URL": "...",
  "AUTH_SECRET": "...",
  "AUTH_GOOGLE_ID": "..."
}

最終的な構成

最終的な構成は、次のようになります。

ECS Task
 ├─ execution role
 │    ├─ AmazonECSTaskExecutionRolePolicy
 │    └─ SecretsManager access
 │
 └─ task role
      └─ S3 access

重要なのは、次の切り分けです。

Secrets Manager の権限は execution role
アプリケーションの業務ロジックで使う権限は task role
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?