跨账户 ECR 登录和推送构建的 Docker 映像的 CodePipeline 错误

Posted

技术标签:

【中文标题】跨账户 ECR 登录和推送构建的 Docker 映像的 CodePipeline 错误【英文标题】:CodePipeline with CodeBuild error for cross-account ECR login & push for built Docker image 【发布时间】:2020-01-01 12:18:43 【问题描述】:

嘿云大师 :) 我需要你的帮助!

我很长一段时间以来一直在尝试设置从源到的 AWS CodePipeline 为管道位于另一个容器中的 Docker 容器构建到 ECR 到 ECS 部署它的帐户。实际上,我有多个部署 帐户:Dev、Test 和 Prod,但是,现在我的目标只是将其部署到 开发。

(另外,在我的设置中,我在所有三个部署帐户中都有 ECR 存储库 - 与可能的一个 ECR 回购相比,这是推荐的方法吗? 与管道相同的帐户?)

所有人都在使用 CloudFormation 模板,包括 AWS 基础设施和管道。

问题

我目前遇到了 CodeBuild 推送到 ECR 存储库的权限问题 在另一个帐户中作为 CodeBuild 及其服务角色。

概述

Pipeline 帐户有一个包含两个阶段的流水线:源和构建 来自 CodeCommit 和 CodeBuild 的代码来构建容器。第一阶段 有效,但不是第二次buildspec.yml 无法登录 ECR 我喜欢的回购:

pre_build:
  commands:
    - $(aws ecr get-login --no-include-email --region eu-west-1 --registry-ids DEV_ACCOUNT_ID)

这会失败并出现明显的预期错误:

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken
operation: User: arn:aws:sts::PIPELINE_ACCOUNT_ID:assumed-role/delivery-pipeline-foundation-BuildProjectRole-AAGTGRD1TAPI/AWSCodeBuild-25244ee4-e337-4617-b203-d1687a6a116e
is not authorized to perform: ecr:GetAuthorizationToken on resource: * 

CodeBuild 项目服务角色没有跨账户权限 访问 ECR。我知道,但还不知道如何解决它。

AFAIK,CodePipeline 需要同一帐户中的服务角色。构建项目 服务角色也必须在同一个帐户中并提供权限 例如CodeBuild、工件存储和 KMS。

我尝试在 Dev 帐户中为 CodeBuild 项目分配一个角色,但出现错误:

Failed to call UpdateProject, reason: Invalid service role: Service role account
ID does not match caller's account (Service: AWSCodeBuild; Status Code: 400;
Error Code: InvalidInputException; Request ID: 123458e0-f5d4-4ac9-1060-067e70123249)

总而言之,管道需要管道帐户中的角色,对于 代码构建项目。这一切都是有道理的,因为那些在那里运行并且还需要访问 工件 S3 存储桶和相关 KMS。

那么,如何以及在何处提供登录 ECR 的角色/权限以及稍后 推入特定的仓库,以便 docker 命令可以在 buildspec.yml 文件?

我计划在构建阶段工作后使用 CodeDeploy ECS 进行部署。

是否推荐用于跨账户部署的整体方法和/或 您还使用其他方法吗?

网上大部分例子都很多simpler with a single account 与this related issue 或者只是general cross-account without ECR(我正在工作)。

在此先感谢您对此的帮助!

【问题讨论】:

我以两种方式“解决”了它: 1. 使用aws sts assume-role 在代码构建 cli(构建脚本)中假设跨账户角色。 2.我使用了CloudFormationCreateUpdateStackAction,它允许你做第二个场景。这意味着将跨账户角色传递给资源,并在构建规范中从具有部署 cloudformation 所需权限的跨账户传递角色。但是第二种方法不适用于代码构建。我的想法是,codebuild 实际上在跨帐户上部署了 codebuild 资源,但 cloudformation 仅在部署时以承担角色调用它。你解决了吗? 【参考方案1】:

您可以在另一个持有 ECR 存储库的帐户中创建一个用户,并将其访问密钥和秘密密钥作为环境变量提供给您的 CodeBuild 项目。

【讨论】:

【参考方案2】:

将 AmazonEC2ContainerRegistryPowerUser 添加到您的构建角色。 如果您为构建角色设置了权限边界(Codestar 默认创建权限边界),您还必须对其进行更新。在权限边界内容的末尾添加此内容。 "Sid": "7", "Effect": "Allow", "Action": [ "ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability", "ecr:GetDownloadUrlForLayer", "ecr:GetRepositoryPolicy", "ecr:DescribeRepositories", "ecr:ListImages", "ecr:DescribeImages", "ecr:BatchGetImage", "ecr:GetLifecyclePolicy", "ecr:GetLifecyclePolicyPreview", "ecr:ListTagsForResource", "ecr:DescribeImageScanFindings", "ecr:InitiateLayerUpload", "ecr:UploadLayerPart", "ecr:CompleteLayerUpload", "ecr:PutImage" ], "Resource": [ "*" ]

【讨论】:

以上是关于跨账户 ECR 登录和推送构建的 Docker 映像的 CodePipeline 错误的主要内容,如果未能解决你的问题,请参考以下文章

Docker 推送到 AWS ECR 问题

使用 AWS ECR 登录 Docker 的问题

在 EKS 中使用其他账户的 ECR 图像

sh docker登录到aws ecr

将 docker 映像从一个 AWS ECR 存储库复制到另一个

Gitlab CI - Docker 推送到 AWS ECR