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

如何使用Terraform在CodePipeline中运行一次性ECS任务?

解决CodePipeline中执行Django数据库迁移一次性任务的问题

问题分析

你尝试用CodeBuild、CodePipeline和Terraform部署Django应用,但在流水线中启动数据库迁移的一次性任务时遇到问题——当前CodePipeline的ECS阶段配置里,TaskDefinition不是有效参数。这是因为你使用的ECS provider的Deploy类型动作,是用来更新ECS服务的,而非触发一次性任务执行。

解决方案

有两种常用方式实现流水线中的数据库迁移任务:

方案一:用CodeBuild直接执行迁移

无需依赖ECS任务,直接在CodeBuild阶段运行迁移命令。需要确保CodeBuild环境能访问数据库,且已安装Django项目依赖。

修改Terraform配置,添加CodeBuild阶段:

stage {
  name = "RunMigrations"

  action {
    name            = "RunMigrationsAction"
    category        = "Build"
    owner           = "AWS"
    provider        = "CodeBuild"
    version         = "1"
    input_artifacts = ["BuildOutput"]
    configuration = {
      ProjectName = aws_codebuild_project.django_migration.name
    }
  }
}

resource "aws_codebuild_project" "django_migration" {
  name          = "django-migration-build"
  description   = "执行Django数据库迁移"
  build_timeout = "5"

  source {
    type            = "CODEPIPELINE"
    buildspec       = <<EOF
version: 0.2
phases:
  install:
    runtime-versions:
      python: 3.11
    commands:
      - pip install -r requirements.txt
  build:
    commands:
      - export DJANGO_SETTINGS_MODULE=你的项目名.settings.production
      - python manage.py migrate --noinput
EOF
  }

  environment {
    compute_type                = "BUILD_GENERAL1_SMALL"
    image                       = "aws/codebuild/amazonlinux2-x86_64-standard:4.0"
    type                        = "LINUX_CONTAINER"
    environment_variable {
      name  = "DATABASE_URL"
      value = var.database_url
    }
    # 添加其他必要环境变量,比如SECRET_KEY等
  }

  service_role = aws_iam_role.codebuild-service-role.arn
}

# 配置CodeBuild角色权限
resource "aws_iam_role" "codebuild-service-role" {
  name = "codebuild-django-migration-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "codebuild.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy_attachment" "codebuild-policy" {
  role       = aws_iam_role.codebuild-service-role.name
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
  # 按需添加数据库访问权限,比如RDS相关权限
}

方案二:通过CodeBuild调用ECS Run Task执行迁移

如果必须用ECS任务执行迁移,可在CodeBuild中通过AWS CLI调用ecs run-task命令触发任务。

stage {
  name = "RunMigrations"

  action {
    name            = "RunMigrationsAction"
    category        = "Build"
    owner           = "AWS"
    provider        = "CodeBuild"
    version         = "1"
    input_artifacts = ["BuildOutput"]
    configuration = {
      ProjectName = aws_codebuild_project.django_migration_ecs.name
    }
  }
}

resource "aws_codebuild_project" "django_migration_ecs" {
  name          = "django-migration-ecs-build"
  description   = "触发ECS迁移任务"
  build_timeout = "5"

  source {
    type            = "CODEPIPELINE"
    buildspec       = <<EOF
version: 0.2
phases:
  build:
    commands:
      - aws ecs run-task --cluster ${var.ecs_cluster_name} --task-definition ${aws_ecs_task_definition.django_migration.family}:${aws_ecs_task_definition.django_migration.revision} --launch-type FARGATE --network-configuration "awsvpcConfiguration={subnets=[${join(",", var.private_subnets)}],securityGroups=[${var.security_group_id}],assignPublicIp=DISABLED}"
EOF
  }

  environment {
    compute_type                = "BUILD_GENERAL1_SMALL"
    image                       = "aws/codebuild/amazonlinux2-x86_64-standard:4.0"
    type                        = "LINUX_CONTAINER"
  }

  service_role = aws_iam_role.codebuild-ecs-role.arn
}

# 配置CodeBuild角色的ECS权限
resource "aws_iam_role" "codebuild-ecs-role" {
  name = "codebuild-django-migration-ecs-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "codebuild.amazonaws.com"
        }
      }
    ]
  })
}

resource "aws_iam_role_policy" "ecs-run-task-policy" {
  name   = "ecs-run-task-policy"
  role   = aws_iam_role.codebuild-ecs-role.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "ecs:RunTask",
          "iam:PassRole"
        ]
        Effect   = "Allow"
        Resource = [
          aws_ecs_task_definition.django_migration.arn,
          aws_iam_role.ecs-task-execution-role.arn
        ]
      }
    ]
  })
}

优化ECS任务定义建议

保留你原有的ECS任务定义,但可做以下调整:

  • 删除portMappings配置:迁移任务无需对外暴露端口
  • 确保任务执行角色拥有数据库访问权限

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 07:44:56