允许在 AWS ECS 容器上执行命令的 IAM 角色

IAM role to allow command execution on AWS ECS containers

我对 Terraform 和 AWS 都不熟悉。我正在尝试在现有的 Fargate 服务上设置 enable_execute_command=true,角色和 cluster/service/task 定义如下:

data "aws_iam_policy_document" "ecs_task_execution_role_base" {
  version = "2012-10-17"
  statement {
    sid = ""
    effect = "Allow"
    actions = ["sts:AssumeRole"]
 
    principals {
      type        = "Service"
      identifiers = ["ecs-tasks.amazonaws.com"]
    }
  }
}
 
resource "aws_iam_policy" "ecs_exec_policy" {
  name = "ecs_exec_policy"
 
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action   = ["ssmmessages:CreateControlChannel",
                    "ssmmessages:CreateDataChannel",
                    "ssmmessages:OpenControlChannel",
                    "ssmmessages:OpenDataChannel"
                    ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}
 
resource "aws_iam_role" "ecs_task_execution_role" {
  name               = var.ecs_task_execution_role_name
 
  assume_role_policy  = data.aws_iam_policy_document.ecs_task_execution_role_base.json
  managed_policy_arns = ["arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole", aws_iam_policy.ecs_exec_policy.arn]
 
resource "aws_ecs_cluster" "main" {
  name = "backendcluster"
}
 
data "template_file" "backendapp" {
  template = file("./templates/ecs/backend_app.json.tpl")
 
  vars = {
    server_image      = var.server_image
    celery_image      = var.celery_image
    app_port       = var.app_port
    fargate_cpu    = var.fargate_cpu
    fargate_memory = var.fargate_memory
    aws_region     = var.aws_region
    database_host = aws_db_instance.default.address
    database_port = aws_db_instance.default.port
    redis_host = aws_elasticache_cluster.default.cache_nodes.0.address
    redis_port = aws_elasticache_cluster.default.cache_nodes.0.port
  }
}
 
resource "aws_ecs_task_definition" "app" {
  family                   = "backend-app-task"
  execution_role_arn       = aws_iam_role.ecs_task_execution_role.arn
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = var.fargate_cpu
  memory                   = var.fargate_memory
  container_definitions    = data.template_file.backendapp.rendered
}
 
resource "aws_ecs_service" "main" {
  name            = "backendservice"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.app.arn
  desired_count   = var.app_count
  launch_type     = "FARGATE"
  enable_execute_command = true
 
  network_configuration {
    security_groups  = [aws_security_group.ecs_tasks.id]
    subnets          = aws_subnet.private.*.id
    assign_public_ip = true
  }
 
  load_balancer {
    target_group_arn = aws_alb_target_group.app.id
    container_name   = "server"
    container_port   = var.app_port
  }
 
  depends_on = [aws_alb_listener.backend]
}

运行 terraform apply 给出:

Error: error updating ECS Service (arn:aws:ecs:eu-west-2:00000000:service/backendcluster/backendservice): InvalidParameterException: The service couldn't be updated because a valid taskRoleArn is not being used. Specify a valid task role in your task definition and try again.

在您的 resource "aws_ecs_task_definition" "app" 中您指定了一个 execution_role_arn,但您没有指定一个 task_role_arn。这就是错误的意思,您需要提供任务角色 ARN。

执行角色授予 ECS 服务执行诸如从 ECR 存储库中读取图像以及在 SecretsManager 中查找需要注入到其创建的容器中的秘密等操作的权限。

任务角色赋予ECStask/container内部的软件运行访问AWS资源的权限。命令执行权限需要分配给任务角色,而不是执行角色。

您至少可以尝试添加:

task_role_arn = aws_iam_role.ecs_task_execution_role.arn

但遵循 principal of least privilege 会要求您将这些角色分成具有不同权限的独立 IAM 角色。