CodePipeline:ECR源+ECS部署配置
CodePipeline: ECR source + ECS deploy configuration
基本上,我需要使用 bitbucket 源代码配置 CI/CD 到 ECS 容器。我想使用 CodePipline 将新的 ECR 镜像部署到 ECS。
目前,AWS CodePipline 中没有指定 bitbucket 作为源的选项。但是,我已经设法使用 webhooks 配置 CodeBuild,因此它构建 docker 文件并在每次推送到发布分支时将其推送到 ECR。
我想将 ECR 配置为 CodePipline 中的 "source" 阶段,并将其部署到现有 ECS cluster/service,以便自动部署。
- 我将 "Amazon ECR" 指定为动作提供者,在源阶段使用 "image_details" 输出工件。
- 我指定 "Amazon ECS"(不是 "Amazon ECS (Blue/Green)")作为部署阶段的操作提供者,"image_details" 作为输入工件
不幸的是,如果在部署步骤中出现以下错误,将导致基本配置和工件链接:
Invalid action configuration
The image definition file imageDetail.json contains invalid JSON format
虽然 "Amazon ECR" 阶段提供 imageDetail.json 作为输出工件,但似乎并不期望 "Amazon ECS" 部署提供程序。有什么合理的方法可以解决这个问题吗?
我知道,可以使用 bitbucket + API Gateway/Lambda + CodePipeline 配置 CI/CD,我还考虑使用 CodeCommit 而不是 bitbucket 作为源代码库 -尽管如此,还是希望有一个可能的优雅解决方案,可以直接将 bitbucket 与 CodePipeline 一起使用。
更新:
我最终得到了相当不错的配置,如 this 博文所述:总体思路是允许 CodeBuild 将源代码从 bitbucket 上传到 S3,然后使用以 S3 为源的 CodePipeline 来部署新的 docker 图像到 ECR 并在 ECS 集群中发布新的任务定义修订。
S3 仍在开销中,我正在为该任务寻找更优雅的解决方案。
我最近不得不解决一个类似的问题,我想使用 ECR 作为我的管道源并将图像部署到 ECS。我找到的解决方案是创建 3 个阶段:
- 来源:ECR
- 构建:将 ECR 工件转换为部署阶段可以理解的工件的自定义代码
- 部署:到ECS
这是我用作构建阶段的 buildspec.yml 文件:
version: 0.2
phases:
install:
runtime-versions:
python: 3.7
build:
commands:
- PHP_REPOSITORY_URI=$(cat imageDetail.json | python -c "import sys, json; print(json.load(sys.stdin)['ImageURI'].split('@')[0])")
- IMAGE_TAG=$(cat imageDetail.json | python -c "import sys, json; print(json.load(sys.stdin)['ImageTags'][0])")
- echo $PHP_REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Writing image definitions file...
- printf '[{"name":"container","imageUri":"%s"}]' $PHP_REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
基本上,它所做的是读取 imageDetail.json 文件并提取 ECR 存储库 URL 和 TAG,并输出为 ECS 部署阶段格式化的 json 文件,这只是一个没有定制的标准舞台。
我有一个类似的用例并遇到了同样的问题。解决我的用例的解决方案的答案有点长...
- 用例: 工具帐户具有执行 CodeBuild 的 CodePipeline 和 docker 推送到 QA 帐户 ECR。该图像将有 2 个标签 - "commit hash" 和 "latest"。 QA 帐户有一个管道,该管道在新图像可用时执行,并且该管道将新图像部署到 QA 帐户中的 Fargate 集群中。
- 部署平台: Amazon ECS 标准部署操作。
- 来源: ECR.
- 问题的原因: ECR 源的输出工件 正确地 仅包含有关的信息图像,不包括 ECS 标准部署所需的容器名称。
- 对 AWS 的建议: 鉴于使用 ECR 作为 ECS 源的流行场景,我们可以提出具有在输出工件中添加容器名称的能力(可选)的论点- 这将允许生成可接受作为 ECS 标准部署输入的输出工件。
根据此 official doco from AWS ECS 标准部署需要 - imagedefinitions.json 文件,其中提供容器名称和图像 URI。 它应该如下所示:
[
{
"name": "sample-app",
"imageUri": "11111EXAMPLE.dkr.ecr.us-west-2.amazonaws.com/ecs-repo:latest"
}
]
但 ECR 源会生成一个名为 imageDetail.json 的输出工件,示例如下。这与 ECS 标准部署又名 imagedefinitions.json 的预期输入格式不匹配 - 其中包括容器名称(名称)并且部署失败并显示类似 Deploy Failure:
的消息
{
"ImageSizeInBytes": "44728918",
"ImageDigest": "sha256:EXAMPLE11223344556677889900bfea42ea2d3b8a1ee8329ba7e68694950afd3",
"Version": "1.0",
"ImagePushedAt": "Mon Jan 21 20:04:00 UTC 2019",
"RegistryId": "EXAMPLE12233",
"RepositoryName": "dk-image-repo",
"ImageURI": "ACCOUNTID.dkr.ecr.us-west-2.amazonaws.com/dk-image-repo@sha256:example3",
"ImageTags": [
"latest"
]
}
我解决这个问题的方法是:
在源代码阶段:除了 ECR 源代码之外,我还添加了一个来自 s3 的源代码,其中包含 imagedefinitions.json 压缩文件。
在 ECS 部署阶段操作中,我引用了 s3 源中的输出工件,其中包含 imagedefinitions.json,采用 ECS 标准部署可以理解的格式。
注意: imagedefinitions.json 在 s3 存储桶中是静态的,始终引用所述图像上的最新标签。因此,在 QA 图像定义桶中,我最终会得到一个图像定义 zip,即每个 Fargate 服务实例一个。
我在这里导出了我的管道以供一般参考:
{
"pipeline": {
"roleArn": "arn:aws:iam::ACCOUNTID:role/service-role/AWSCodePipelineServiceRole-REGION-PIPELINENAME",
"stages": [
{
"name": "Source",
"actions": [
{
"inputArtifacts": [],
"name": "Source",
"region": "REGION",
"actionTypeId": {
"category": "Source",
"owner": "AWS",
"version": "1",
"provider": "ECR"
},
"outputArtifacts": [
{
"name": "SourceArtifact"
}
],
"configuration": {
"ImageTag": "latest",
"RepositoryName": "PIPELINENAME"
},
"runOrder": 1
},
{
"inputArtifacts": [],
"name": "sourceimagedeffile",
"region": "REGION",
"actionTypeId": {
"category": "Source",
"owner": "AWS",
"version": "1",
"provider": "S3"
},
"outputArtifacts": [
{
"name": "PIPELINENAME-imagedefjson"
}
],
"configuration": {
"S3Bucket": "BUCKETNAME",
"PollForSourceChanges": "true",
"S3ObjectKey": "PIPELINENAME.zip"
},
"runOrder": 1
}
]
},
{
"name": "Deploy",
"actions": [
{
"inputArtifacts": [
{
"name": "PIPELINENAME-imagedefjson"
}
],
"name": "Deploy",
"region": "REGION",
"actionTypeId": {
"category": "Deploy",
"owner": "AWS",
"version": "1",
"provider": "ECS"
},
"outputArtifacts": [],
"configuration": {
"ClusterName": "FARGATECLUSTERNAME",
"ServiceName": "PIPELINENAME",
"FileName": "imageDetail.json"
},
"runOrder": 1
}
]
}
],
"artifactStore": {
"type": "S3",
"location": "codepipeline-REGION-555869339681"
},
"name": "PIPELINENAME"
}
基本上,我需要使用 bitbucket 源代码配置 CI/CD 到 ECS 容器。我想使用 CodePipline 将新的 ECR 镜像部署到 ECS。
目前,AWS CodePipline 中没有指定 bitbucket 作为源的选项。但是,我已经设法使用 webhooks 配置 CodeBuild,因此它构建 docker 文件并在每次推送到发布分支时将其推送到 ECR。
我想将 ECR 配置为 CodePipline 中的 "source" 阶段,并将其部署到现有 ECS cluster/service,以便自动部署。
- 我将 "Amazon ECR" 指定为动作提供者,在源阶段使用 "image_details" 输出工件。
- 我指定 "Amazon ECS"(不是 "Amazon ECS (Blue/Green)")作为部署阶段的操作提供者,"image_details" 作为输入工件
不幸的是,如果在部署步骤中出现以下错误,将导致基本配置和工件链接:
Invalid action configuration
The image definition file imageDetail.json contains invalid JSON format
虽然 "Amazon ECR" 阶段提供 imageDetail.json 作为输出工件,但似乎并不期望 "Amazon ECS" 部署提供程序。有什么合理的方法可以解决这个问题吗?
我知道,可以使用 bitbucket + API Gateway/Lambda + CodePipeline 配置 CI/CD,我还考虑使用 CodeCommit 而不是 bitbucket 作为源代码库 -尽管如此,还是希望有一个可能的优雅解决方案,可以直接将 bitbucket 与 CodePipeline 一起使用。
更新: 我最终得到了相当不错的配置,如 this 博文所述:总体思路是允许 CodeBuild 将源代码从 bitbucket 上传到 S3,然后使用以 S3 为源的 CodePipeline 来部署新的 docker 图像到 ECR 并在 ECS 集群中发布新的任务定义修订。 S3 仍在开销中,我正在为该任务寻找更优雅的解决方案。
我最近不得不解决一个类似的问题,我想使用 ECR 作为我的管道源并将图像部署到 ECS。我找到的解决方案是创建 3 个阶段:
- 来源:ECR
- 构建:将 ECR 工件转换为部署阶段可以理解的工件的自定义代码
- 部署:到ECS
这是我用作构建阶段的 buildspec.yml 文件:
version: 0.2
phases:
install:
runtime-versions:
python: 3.7
build:
commands:
- PHP_REPOSITORY_URI=$(cat imageDetail.json | python -c "import sys, json; print(json.load(sys.stdin)['ImageURI'].split('@')[0])")
- IMAGE_TAG=$(cat imageDetail.json | python -c "import sys, json; print(json.load(sys.stdin)['ImageTags'][0])")
- echo $PHP_REPOSITORY_URI:$IMAGE_TAG
post_build:
commands:
- echo Writing image definitions file...
- printf '[{"name":"container","imageUri":"%s"}]' $PHP_REPOSITORY_URI:$IMAGE_TAG > imagedefinitions.json
artifacts:
files: imagedefinitions.json
基本上,它所做的是读取 imageDetail.json 文件并提取 ECR 存储库 URL 和 TAG,并输出为 ECS 部署阶段格式化的 json 文件,这只是一个没有定制的标准舞台。
我有一个类似的用例并遇到了同样的问题。解决我的用例的解决方案的答案有点长...
- 用例: 工具帐户具有执行 CodeBuild 的 CodePipeline 和 docker 推送到 QA 帐户 ECR。该图像将有 2 个标签 - "commit hash" 和 "latest"。 QA 帐户有一个管道,该管道在新图像可用时执行,并且该管道将新图像部署到 QA 帐户中的 Fargate 集群中。
- 部署平台: Amazon ECS 标准部署操作。
- 来源: ECR.
- 问题的原因: ECR 源的输出工件 正确地 仅包含有关的信息图像,不包括 ECS 标准部署所需的容器名称。
- 对 AWS 的建议: 鉴于使用 ECR 作为 ECS 源的流行场景,我们可以提出具有在输出工件中添加容器名称的能力(可选)的论点- 这将允许生成可接受作为 ECS 标准部署输入的输出工件。
根据此 official doco from AWS ECS 标准部署需要 - imagedefinitions.json 文件,其中提供容器名称和图像 URI。 它应该如下所示:
[
{
"name": "sample-app",
"imageUri": "11111EXAMPLE.dkr.ecr.us-west-2.amazonaws.com/ecs-repo:latest"
}
]
但 ECR 源会生成一个名为 imageDetail.json 的输出工件,示例如下。这与 ECS 标准部署又名 imagedefinitions.json 的预期输入格式不匹配 - 其中包括容器名称(名称)并且部署失败并显示类似 Deploy Failure:
的消息{
"ImageSizeInBytes": "44728918",
"ImageDigest": "sha256:EXAMPLE11223344556677889900bfea42ea2d3b8a1ee8329ba7e68694950afd3",
"Version": "1.0",
"ImagePushedAt": "Mon Jan 21 20:04:00 UTC 2019",
"RegistryId": "EXAMPLE12233",
"RepositoryName": "dk-image-repo",
"ImageURI": "ACCOUNTID.dkr.ecr.us-west-2.amazonaws.com/dk-image-repo@sha256:example3",
"ImageTags": [
"latest"
]
}
我解决这个问题的方法是:
在源代码阶段:除了 ECR 源代码之外,我还添加了一个来自 s3 的源代码,其中包含 imagedefinitions.json 压缩文件。
在 ECS 部署阶段操作中,我引用了 s3 源中的输出工件,其中包含 imagedefinitions.json,采用 ECS 标准部署可以理解的格式。
注意: imagedefinitions.json 在 s3 存储桶中是静态的,始终引用所述图像上的最新标签。因此,在 QA 图像定义桶中,我最终会得到一个图像定义 zip,即每个 Fargate 服务实例一个。
我在这里导出了我的管道以供一般参考:
{
"pipeline": {
"roleArn": "arn:aws:iam::ACCOUNTID:role/service-role/AWSCodePipelineServiceRole-REGION-PIPELINENAME",
"stages": [
{
"name": "Source",
"actions": [
{
"inputArtifacts": [],
"name": "Source",
"region": "REGION",
"actionTypeId": {
"category": "Source",
"owner": "AWS",
"version": "1",
"provider": "ECR"
},
"outputArtifacts": [
{
"name": "SourceArtifact"
}
],
"configuration": {
"ImageTag": "latest",
"RepositoryName": "PIPELINENAME"
},
"runOrder": 1
},
{
"inputArtifacts": [],
"name": "sourceimagedeffile",
"region": "REGION",
"actionTypeId": {
"category": "Source",
"owner": "AWS",
"version": "1",
"provider": "S3"
},
"outputArtifacts": [
{
"name": "PIPELINENAME-imagedefjson"
}
],
"configuration": {
"S3Bucket": "BUCKETNAME",
"PollForSourceChanges": "true",
"S3ObjectKey": "PIPELINENAME.zip"
},
"runOrder": 1
}
]
},
{
"name": "Deploy",
"actions": [
{
"inputArtifacts": [
{
"name": "PIPELINENAME-imagedefjson"
}
],
"name": "Deploy",
"region": "REGION",
"actionTypeId": {
"category": "Deploy",
"owner": "AWS",
"version": "1",
"provider": "ECS"
},
"outputArtifacts": [],
"configuration": {
"ClusterName": "FARGATECLUSTERNAME",
"ServiceName": "PIPELINENAME",
"FileName": "imageDetail.json"
},
"runOrder": 1
}
]
}
],
"artifactStore": {
"type": "S3",
"location": "codepipeline-REGION-555869339681"
},
"name": "PIPELINENAME"
}