2

我想创建一个 CodePipeline,它从 CodeCommit 源构建容器映像,然后以蓝/绿方式将新映像部署到我的 ECS 服务(EC2 启动类型)。

  • 源阶段是 CodeCommit,它已经包含 appspec.json
    以及 taskdef.json
  • 构建阶段正在构建新容器并成功将其推送到 ECR,文件 imagedefinition.json 是此步骤创建的 BuildArtifact,包含容器和最近创建的镜像,其标签对应于 CodeCommit 提交 ID。
  • 部署阶段由动作“Amazon ECS (Blue/Green)”组成,使用 SourceArtifact 和 BuildArtifact 作为 InputArtifacts,从 SourceArtifact 中获取 appspec 和 taskdef 以及从 BuildArtifact 中获取图像描述,最终在 Blue/ 中部署新容器绿色方式。

问题在于 BuildArtifact 中的图像定义。管道在部署阶段失败并出现错误:

"" Invalid action configuration 尝试从工件读取图像工件文件时出现异常:BuildArtifact。“”

如何正确配置“Amazon ECS(蓝/绿)”部署阶段,以便它可以使用最近创建的映像并部署它....通过替换 taskdef.json 中的占位符 IMAGE_NAME ?

任何提示高度赞赏:D

4

4 回答 4

5

在这里回答我自己的问题,希望它可以帮助面临同样情况的其他人。

  1. 文件 imagedefinitions.json 不适合部署操作“Amazon ECS Blue/Green”。为此,您必须在构建步骤中创建文件imageDetail.json并将其作为工件提供给部署步骤。如何 ?这是我的 buildspec.yaml 底部的样子:
      - printf '{"ImageURI":"%s"}' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
artifacts:
  files: 
    - 'image*.json'
    - 'appspec.yaml'
    - 'taskdef.json'
  secondary-artifacts:
    DefinitionArtifact:
      files:
        - appspec.yaml
        - taskdef.json
    ImageArtifact:
      files:
        - imageDetail.json
  1. 在 CodePipeline 的 Deploy 阶段,使用 DefinitionArtifact 和 ImageArtifact 作为 Input Artifact,并在相应的“ Amazon ECS 任务定义”和“ AWS CodeDeploy AppSpec 文件”部分进行配置。

确保您的 appspec.yaml 包含任务定义的占位符。这是我的 appspec.yaml:

version: 0.0

Resources:
  - TargetService:
      Type: AWS::ECS::Service
      Properties:
        TaskDefinition: <TASK_DEFINITION>
        LoadBalancerInfo:
          ContainerName: "my-test-container"
          ContainerPort: 8000

还要确保您的 taskdef.json 包含最终图像的占位符,例如

...
"image": <IMAGE1_NAME>,
...
  1. 通过将输入工件选择为“ImageArtifact”和占位符,在“动态更新任务定义图像 - 可选”部分的蓝/绿部署阶段的代码管道配置中使用该占位符<IMAGE1_NAME>
于 2020-05-27T07:46:20.160 回答
2

Amazon ECS 蓝/绿(或 CodeDeployToECS)CodePipeline 操作需要 TaskDefinitionTemplateArtifact 参数(请参阅 [1])。

除了上述文件注意之外,ECS 蓝/绿部署还需要 imageDetail.json(不是“imagedefinition.json”)。文件结构和详细信息可在此处获得 [2]。将此文件添加到部署工件/版本控制的根目录。如果您不想手动添加此文件,您可以使用 ECR 源操作到 CodePipeline 并使用您在 ECS 服务/taskdef.json 中使用的图像进行配置。为了清楚起见,所有这些都在 [2] 中进行了讨论。

要了解这一切是如何组合在一起的,您还可以按照此处 [3] 的 ECS 蓝/绿部署的分步说明进行操作。

参考:

[1] https://docs.aws.amazon.com/codepipeline/latest/userguide/reference-pipeline-structure.html#action-requirements:CodePipeline管道结构参考 - CodePipeline 中的操作结构要求 [2] https:// docs.aws.amazon.com/codepipeline/latest/userguide/file-reference.html#file-reference-ecs-bluegreen:图像定义文件参考 - Amazon ECS 蓝/绿部署操作的 imageDetail.json 文件 [3] https: //docs.aws.amazon.com/codepipeline/latest/userguide/tutorials-ecs-ecr-codedeploy.html:教程:使用 Amazon ECR 源和 ECS-to-CodeDeploy 部署创建管道

于 2020-05-27T01:17:45.590 回答
1

我遇到了同样的问题。

tl:博士

我没有将带有 imageDetail.json 的正确输入工件传递给管道 CodeDeployToECS 操作。

概括:

我没有使用“<IMAGE1_NAME>”占位符签入任务定义的版本,而是在管道内动态生成任务定义输入到 CodeDeploy。

项目早期的任务定义非常不稳定,新变量等被传递给容器。它在管道 (Cloudformation) 中生成并注册,然后通过 Codebuild 项目读出,用“<IMAGE1_NAME>”替换图像占位符,并通过管道工件传递到管道的下一个阶段。

修复它:

  1. 我在生成 imageDetail.json 的管道中有一个 CodeBuild 项目:
   {"ImageURI":"########.dkr.ecr.eu-west-1.amazonaws.com/##/#####:2739511dd87d4e4e1f65ed69c9e779b63fb72e36-master-fbe73fdc-6213-4bd6-a784-dcc3d2ae7845"}

它的管道输出名为“BuildDockerOutput”

  1. 我有另一个 Codebuild 项目,它产生:

任务定义.json

{
  "containerDefinitions": [
    {
      "name": "ronantest1",
      "image": "<IMAGE1_NAME>",
                       ]
}

appspec.json

{
  "version": 0.0,
  "Resources": [
    {
      "TargetService": {
        "Type": "AWS::ECS::Service",
        "Properties": {
          "TaskDefinition": "<TASK_DEFINITION>",
          "LoadBalancerInfo": {
            "ContainerName": "ronantest1",
            "ContainerPort": "8080"
          }
        }
      }
    }
  ],
  "Hooks": [
      {
      "AfterAllowTestTraffic": "arn:aws:lambda:eu-west-1:######:function:code-deploy-after-allow-test-traffic"
      }

    ]
  }

它的管道输出名为“PrepareCodeDeployOutputTesting”

我的最终 CodeDeploy 操作如下所示:

            - Name: BlueGreenDeploy
              InputArtifacts:
              - Name: BuildDockerOutput
              - Name: PrepareCodeDeployOutputTesting
              Region: !Ref DeployRegion1
              ActionTypeId:
                Category: Deploy
                Owner: AWS
                Version: '1'
                Provider: CodeDeployToECS
              RoleArn: !Sub arn:aws:iam::${TestingAccountId}:role/######/CrossAccountsDeploymentRole
              Configuration:

                AppSpecTemplateArtifact: PrepareCodeDeployOutputTesting
                AppSpecTemplatePath: appspec.json

                ApplicationName: !Ref ApplicationName
                DeploymentGroupName: !Ref ApplicationName
                
                TaskDefinitionTemplateArtifact: PrepareCodeDeployOutputTesting
                TaskDefinitionTemplatePath: taskdef.json

                Image1ArtifactName: BuildDockerOutput
                Image1ContainerName: "IMAGE1_NAME"
              RunOrder: 4

请注意 CodeDeployToECS 的不同方面需要来自不同 InputArtifacts 的人工制品,特别是“Image1ArtifactName”

于 2021-03-18T20:13:26.930 回答
0

谢谢大家,这让我对解决这个问题有了一些了解。

我想补充一点,当您使用aws cli,cloudformationTerraformconfigurecodepipeline时,某些参数和选项在控制台中不可用,并且在这些工具中设置一些变量(例如空字符串“”)会导致异常错误。

使用这些工具进行部署时,请始终检查codepipeline控制台中的设置。

所以当您定义图像工件但未定义占位符时会发生错误

imageDetail.jsoncodedeploy可以使用以下方法传入:

  • git 源(codecommit 或 github)存在于您的应用程序代码库中的文件
  • ECR 源 - 文件将由 ECR 自动生成,但将使用 SHA256 而不是图像标签
  • CodeBuildsource - 您使用codebuildbuildspec.yml 更新文件并将其传递到codedeploy阶段。
于 2021-01-23T13:13:08.293 回答