You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS ECS Fargate任务被EventBridge触发时退出码2故障排查求助

ECS Fargate任务退出码2排查求助
  • 用Terraform配置了ECS任务和EventBridge调度规则,EventBridge显示调用失败,但ECS中能看到任务被创建,随即停止,退出码为2,仅提示Docker容器退出,无额外错误信息
  • 已配置ECS任务日志权限,但未生成任何日志
  • 任务配置在可访问互联网的私有子网中,通过ECS控制台使用完全相同的私有子网和安全组手动运行任务可成功

Terraform EventBridge配置

resource "aws_cloudwatch_log_group" "ecs_log_group" {
    name = "/aws/ecs/dbt"
}

# EventBridge Rule
resource "aws_cloudwatch_event_rule" "ecs_schedule" {
    name                = "ecs-dbt-schedule"
    schedule_expression = "cron(0 6-17 ? * MON-FRI *)"
}

# EventBridge Target to trigger ECS task
resource "aws_cloudwatch_event_target" "ecs_task_target" {
    rule = aws_cloudwatch_event_rule.ecs_schedule.name
    arn = aws_ecs_cluster.fargate.arn
    role_arn = aws_iam_role.ecs_events_role.arn

    ecs_target {
        task_count          = 1
        task_definition_arn = aws_ecs_task_definition.dbt.arn
        launch_type         = "FARGATE"
        network_configuration {
            subnets = var.subnets
            security_groups = var.security_group_ids
            assign_public_ip = false
        }
    }
}

Terraform ECS配置

# ECS Cluster
resource "aws_ecs_cluster" "fargate" {
    name = "${var.environment}-dbt-cluster"
}

# ECS Task Definition
resource "aws_ecs_task_definition" "dbt" {
    family                   = "dbt"
    network_mode             = "awsvpc"
    requires_compatibilities = ["FARGATE"]

    cpu    = "256"
    memory = "512"

    execution_role_arn = data.aws_iam_role.ecs_task_execution_role.arn

    container_definitions = jsonencode([
        {
            name  = "dbt_container"
            image = var.dbt_image_uri

            command = [
                "bash",
                "-c",
                <<-EOF
                    "Bash code to run on the ECS instance is added here"
                EOF
            ]

            cpu       = 256
            memory    = 512
            essential = true
            logConfiguration = {
                logDriver = "awslogs"
                options = {
                    "awslogs-group"         = aws_cloudwatch_log_group.ecs_log_group.name
                    "awslogs-region"        = var.region
                    "awslogs-stream-prefix" = "ecs"
                }
            }
        }
    ])
}

Terraform ECS IAM配置

# IAM Role
data "aws_iam_role" "ecs_task_execution_role" {
    name = "ecsTaskExecutionRole"
}

# IAM Policy
resource "aws_iam_policy" "ecs_task_execution_policy" {
    name        = "ecsTaskExecutionPolicy"
    description = "Policy for ECS task execution role"

    policy = jsonencode({
        Version = "2012-10-17",
        Statement = [
            {
                Action   = [
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents",
                    "secretsmanager:GetSecretValue",
                    "ecr:GetAuthorizationToken",
                    "ecr:BatchCheckLayerAvailability",
                    "ecr:GetDownloadUrlForLayer",
                    "ecr:BatchGetImage",
                ],
                Effect   = "Allow",
                Resource = "*",
            },
        ],
    })
}

# IAM Role Policy Attachment
resource "aws_iam_role_policy_attachment" "ecs_task_execution_attachment" {
    policy_arn = aws_iam_policy.ecs_task_execution_policy.arn
    role       = data.aws_iam_role.ecs_task_execution_role.name
}

Terraform EventBridge IAM配置

data "aws_iam_policy_document" "assume_role" {
    statement {
        effect = "Allow"

        principals {
            type        = "Service"
            identifiers = ["events.amazonaws.com"]
        }

        actions = ["sts:AssumeRole"]
    }
}

resource "aws_iam_role" "ecs_events_role" {
    name               = "ecs_event_role"
    assume_role_policy = data.aws_iam_policy_document.assume_role.json
}

data "aws_iam_policy_document" "ecs_events_run_task_with_any_role" {
    statement {
        effect    = "Allow"
        actions   = ["iam:PassRole"]
        resources = ["*"]
    }

    statement {
        effect    = "Allow"
        actions   = ["ecs:RunTask"]
        resources = [replace(aws_ecs_task_definition.dbt.arn, "/:\\d+$/", ":*")]
    }

}

resource "aws_iam_policy" "events_run_ecs_tasks_policy" {
    name        = "events-run-ecs-tasks-policy"
    description = "Policy for allowing ECS to assume role"
    policy      = data.aws_iam_policy_document.ecs_events_run_task_with_any_role.json
}

# IAM Role Policy Attachment
resource "aws_iam_policy_attachment" "ecs_events_run_ecs_tasks_attachment" {
    policy_arn = aws_iam_policy.events_run_ecs_tasks_policy.arn
    role       = data.aws_iam_role.ecs_task_execution_role.name
}

潜在问题排查点

  1. EventBridge IAM权限绑定错误:在aws_iam_policy_attachment.ecs_events_run_ecs_tasks_attachment中,将events-run-ecs-tasks-policy绑定到了ecs_task_execution_role,但该权限应该绑定到aws_iam_role.ecs_events_role,否则EventBridge角色没有足够权限执行RunTask操作。
  2. Task Definition中Command格式错误:command里的EOF内容被额外加了双引号,会导致bash执行时把整个字符串当作命令,可能触发语法错误,应去掉EOF内的双引号:
    command = [
        "bash",
        "-c",
        <<-EOF
            Bash code to run on the ECS instance is added here
        EOF
    ]
    
  3. 日志未生成的可能原因:如果任务在启动前就退出(比如命令解析错误),日志驱动可能还没初始化,导致没有日志输出。先修复命令格式和IAM绑定问题后再验证日志。

内容的提问来源于stack exchange,提问作者MattSt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 07:03:11