3
votes

Hey cloud gurus :) I need your help!

I'm trying since quite a while to set up an AWS CodePipeline from source to build to ECR to ECS for a Docker container where the pipeline is in another account from where it is deployed. Actually, I have multiple deployment accounts: Dev, Test and Prod, however, now I just aim to get it deployed into Dev.

(Also, in my setup I also have ECR repos in all three deployment accounts - is this the recommended approach compared to maybe one ECR repo in probably the same account as the pipeline?)

All is using CloudFormation templates, both the AWS infra as well as the pipeline.

Problem

I'm currently stuck with a permission issue for CodeBuild pushing to an ECR repo in another account as CodeBuild and its service role.

Overview

The Pipeline account has a pipeline with two stages: source and build taking the code from CodeCommit and then CodeBuild to build the container. The first stage works but not the second where the buildspec.yml fails logging into the ECR repo that I have like so:

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

This fails with the clear and expected error:

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: * 

The CodeBuild project service role does not have permissions to cross-account access ECR. I know that but not yet how to approach solving it.

AFAIK, CodePipeline requires a service role in the same account. The build project service role must also be in the same account and provides permissions to e.g. CodeBuild, artifacts store and KMS.

I tried to give the CodeBuild project a role in the Dev account but got an error:

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)

In summary, the pipeline needs the role in the pipeline account, same for the CodeBuild project. That all makes sense as those run there and also need access to artifacts S3 bucket and related KMS.

So, how and where to provide the role/permissions to log in to ECR as well as later to push into a specific repo so that the docker commands can be in the buildspec.yml file?

I'm planning to use CodeDeploy ECS to deploy once I have the build stage working.

Is the overall approach recommended for cross-account deployments and/or are there other approaches you use?

Most examples online are much simpler with a single account with this related issue or just general cross-account without ECR (which I have working).

Thanks in advance for your help on this one!

2

2 Answers

0
votes

You can create a user in the other account which holds ECR repo and give its Access Key and Secret Key as Environment Variables to your CodeBuild Project.

0
votes

Add AmazonEC2ContainerRegistryPowerUser to your build role. If you have permission boundary set to your build role( Codestar by-default creates the permission boundary), you have to update that also.Added this at the end of permission boundary content. { "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": [ "*" ] }