基本上,我需要使用ECS容器的Bitbucket源代码配置CI / CD。我想使用CodePipline将新的ECR映像部署到ECS。
当前,AWS CodePipline中没有选项将bitbucket指定为源。但是,我设法通过Webhooks配置CodeBuild,因此它会构建docker文件,并在每次发布发布分支时将其推送到ECR。
我想将ECR配置为CodePipline中的“源”阶段,并将其部署到现有的ECS集群/服务中,因此部署将实现自动化。
不幸的是,如果在部署步骤中出现以下错误,则会得到基本配置和工件链接:
Invalid action configuration
The image definition file imageDetail.json contains invalid JSON format
尽管“ Amazon ECR”阶段将imageDetail.json作为输出工件提供,但“ Amazon ECS”部署提供程序似乎并不期望这样做。有什么合理的方法解决这个问题吗?
我知道,可以使用bitbucket + API网关/ Lambda + CodePipeline配置CI / CD,我也考虑使用CodeCommit代替bitbucket作为源存储库-仍然,希望有一种可能的优雅解决方案直接将Bitbucket与CodePipeline结合使用。
UPD: 我最终获得了不错的配置,如this博客中所述:总体思路是允许CodeBuild将源代码从bitbucket上传到S3,然后将CodePipeline与S3一起用作将新docker映像部署到ECR的源并在ECS集群中发布新的任务定义修订。 S3仍在开销中,我正在为该任务寻找更优雅的解决方案。
答案 0 :(得分:5)
我有一个类似的用例,遇到了同样的问题。解决我的用例的解决方案有点长答案...
根据此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 Standard Deploy aka 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"
]
}
我用来解决此问题的方法是:
在Source阶段:除了ECR源,我还从s3中添加了一个源,该源在zip中包含imagedefinitions.json。
在ECS Deploy阶段操作中,我指的是s3源中的Output工件,其中包含imagedefinitions.json,其格式为ECS Standard Deploy可以理解。
注意:imagedefinitions.json在s3存储桶中是静态的,并且始终引用所述图像上的最新标记。因此,在“质量检查图像定义”存储区中,我将获得一个图像定义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"
}
答案 1 :(得分:1)
最近,我不得不解决一个类似的问题,我想使用ECR作为管道的源并将其部署到ECS。我发现的解决方案是创建3个阶段:
这是我正在用作构建阶段的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 Deploy阶段格式化的json文件,这是没有自定义的标准阶段。