amazon-ecr-login icon indicating copy to clipboard operation
amazon-ecr-login copied to clipboard

Log into registry in another account in different region under a self-hosted environment

Open keithalpichi opened this issue 4 years ago • 6 comments

I'm in a situation where I need to authenticate to an ECR registry in a different account and region than where the self-hosted runner is running in. This is part of an internal project of migrating AWS accounts but still needing to access resources within the account we're moving away from.

A self-hosted runner in Account A (in region us-west-2) contains a IAM instance profile that allows it to assume a role in Account B to push images to the ECR registry (in region us-east-1), amongst many other things.

I can successfully assume the role in Account B using aws-actions/configure-aws-credentials@v1, but since the region input is for the initial client, aws-actions/amazon-ecr-login implicitly inherits it when it authenticates to ECR. I need it to use a different region.

At first I thought I could modify the region in it's own step:

# there is a step prior that assumes the role
# ....
- name: Set AWS region to us-east-1
  run: aws configure set default.region us-east-1
- name: Login to Amazon ECR
  id: login-ecr
  uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Account B AWS ECR
  run: |
    docker build -t $ACCT_B_ECR_REGISTRY/$ECR_REPOSITORY:$VERSION .
    docker push $ACCT_B_ECR_REGISTRY/$ECR_REPOSITORY:$VERSION

But it didn't work. This Github Action still authenticated to the ECR registry in the us-west-2 region.

Then I thought to run AWS ECR commands directly to specify the region:

# there is a step prior that assumes the role
# ....
- name: Login to Account B ECR
  run: |
    aws ecr get-login-password --region $ACCT_B_REGION | \
    docker login --username AWS --password-stdin $ACCT_B_ECR_REGISTRY
- name: Build, tag, and push image to Account B AWS ECR
  run: |
    docker build -t $ACCT_B_ECR_REGISTRY/$ECR_REPOSITORY:$VERSION .
    docker push $ACCT_B_ECR_REGISTRY/$ECR_REPOSITORY:$VERSION

This works but it replaces this convenient Github Action. It would be nice, despite it being very uncommon, if I could just provide this Github Action the region I need to authenticate into. This approach also stores the credentials unencrypted- WARNING! Your password will be stored unencrypted in /root/.docker/config.json.

Another approach I took is using aws-actions/configure-aws-credentials@v1 again to use the temporary assumed-role credentials (set to environment variables in a previous step) to set the region for subsequent steps.

# there is a step prior that assumes the role
# ....
- name: Configure temp AWS credentials for ECR login
  uses: aws-actions/configure-aws-credentials@v1
  with:
    aws-access-key-id: ${{ env.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ env.AWS_SECRET_ACCESS_KEY }}
    aws-session-token: ${{ env.AWS_SESSION_TOKEN }}
    aws-region: us-east-1
- name: Login to Amazon ECR
  id: login-ecr
  uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Account B AWS ECR
  env:
    ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
   run: |
     docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$VERSION .
     docker push $ECR_REGISTRY/$ECR_REPOSITORY:$VERSION

This worked but adds another step to the job.

So, is there a simpler way to do this than what I've done above? Is there a simpler way to modify the region before running this Github Action? If not, could we add a region input to this Github Action. I can work on this if this is something desired.

keithalpichi avatar Jun 01 '21 23:06 keithalpichi

I have a similar issue where I need to pull images from two different regions in the same account

usjpaq avatar Jun 04 '21 17:06 usjpaq

Having same issue with login to the ecr repo from another account, but on the same region.

kirillbilchenko avatar Jun 17 '21 14:06 kirillbilchenko

running into the same issue, had to resort to writing the following script:

registries=()

for region in $REGIONS; do
  registry="${ACCOUNT_ID}.dkr.ecr.${region}.amazonaws.com"
  aws ecr get-login-password --region "$region"  | docker login --username AWS --password-stdin "$registry"
  registries+=("$registry")
done

echo ::set-output name=registries::"${registries[@]}"

dudicoco avatar Aug 09 '21 09:08 dudicoco

the same for push image to different account ECR

jeff51419 avatar Aug 30 '21 06:08 jeff51419

+1

sbkg0002 avatar Sep 17 '21 13:09 sbkg0002

At first I thought I could modify the region in it's own step:

# there is a step prior that assumes the role
# ....
- name: Set AWS region to us-east-1
  run: aws configure set default.region us-east-1
- name: Login to Amazon ECR
  id: login-ecr
  uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to Account B AWS ECR
  run: |
    docker build -t $ACCT_B_ECR_REGISTRY/$ECR_REPOSITORY:$VERSION .
    docker push $ACCT_B_ECR_REGISTRY/$ECR_REPOSITORY:$VERSION

But it didn't work. This Github Action still authenticated to the ECR registry in the us-west-2 region.

If your prior steps involve using the aws-actions/configure-aws-credentials action, then part of the problem you're having is probably the fact that that action doesn't merely configure the default AWS profile, it also exports a bunch of environment variables into the job environment for all future steps, including AWS_REGION; so even if you edit the default profile's configured region to be us-east-1, that won't actually matter to the subsequent amazon-ecr-login action, because the default region of the active profile is being ignored in favor of the region specified by the AWS_REGION environment variable (which is still set to us-west-2) anyway.

If you're not using aws-actions/configure-aws-credentials, then you can ignore this comment.

philomory avatar Jan 27 '22 22:01 philomory

You can use the following way:

      - name: Assume aws role
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ vars.AWS_ROLE_ARN }}
          aws-region: ${{ vars.AWS_REGION_RUNNER }}
          role-skip-session-tagging: true
          role-duration-seconds: 2400

      - name: Login to AWS Registry
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2
        with:
          mask-password: 'true'
        env:
          AWS_DEFAULT_REGION: ${{ vars.AWS_REGION }}
          AWS_REGION: ${{ vars.AWS_REGION }}

where AWS_REGION_RUNNER is us-east-1 and AWS_REGION is us-east-2 for example.

stefam avatar May 15 '24 17:05 stefam

@stefam You mean us-east-2 for AWS_REGION_RUNNER and us-east-1 for AWS_REGION, right? This works for me. Thanks!!

IjjS avatar May 21 '24 09:05 IjjS