How to Push to Account Using ASSUME_ROLE in AWS ECR

Viewed 393

What am I missing? Regardless of what syntax I try, pushing to AWS ECR always lands in the main / management AWS account. In the AWS console I can switch into that account with the appropriate role. Using Terraform I can set the assume_role.role_arn property to create resources in the correct account. However, no config or syntax for Docker and the AWS CLI seems to work. I'm clearly missing a step, property, or global option.

If I go the Terraform route, I can do anything I need. So, I know it should work ...

provider "aws" {
  region = "us-gov-west-1"
  shared_credentials_file = "~/.aws/credentials"
  profile = "govcloud"

  assume_role {
    role_arn = "arn:aws-us-gov:iam::123456789012:role/Build_Administrator"
  }
}

However, I would rather NOT use Terraform for such a simple task as pushing to ECR.

I've tried using the role_arn property in the ~/.aws/config and that doesn't work...

[govcloud]
region = us-gov-west-1
output = json

[govcloud-assume]
region = us-gov-west-1
output = json
role_arn=arn:aws-us-gov:iam::123456789012:role/Build_Administrator

In any other scenario, calling get-login-password / create-repository will leverage the current configured keys and will manipulate the configured account...

aws ecr get-login-password | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-gov-west-1.amazonaws.com
aws ecr create-repository --repository-name "complexapi" --image-tag-mutability MUTABLE 

It feels as if there should be some type of global option to set the target account or role_arn, however no combination works...

aws ecr get-login-password --profile govcloud-assume --region us-gov-west-1 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-gov-west-1.amazonaws.com
aws ecr create-repository --profile govcloud-assume --region us-gov-west-1 --repository-name "complexapi" --image-tag-mutability MUTABLE 

Update 1:
Feels like I'm getting closer. After setting the access key I can successfully call aws sts assume-role and return a Credentials object. Just don't know what to do with it yet.

Update 2:
STS was a waste of time and sent me down the wrong path. Don't go there. It's not needed and will pollute your local auth environment for the AWS CLI.

1 Answers

To assume a role using the AWS CLI with ECR, you must use the --profile property within your scripts and structure the ~/.aws/config with two properties together: role_arn and source_profile

The ~/.aws/config requires both the main account and the sub-account you wish to work with. This sub-account contains the role you wish to assume with the ARN is maintained in its role_arn property. The profile of the sub-account is what you will reference in your scripts however the config must also point back to the source_profile which will maintain the actual credentials:

[default]
region = us-gov-west-1
output = json

[profile gov-mgmt]
region = us-west-1
output = json

[profile gov-staging]
role_arn = arn:aws-us-gov:iam::123456789123:role/BuildBoxRole
source_profile = gov-mgmt
region = us-gov-west-1

Your ~/.aws/credentials file then contains the keys for the main account:

[gov-mgmt]
aws_access_key_id = ABCDEFGHIJKLMNOPQRST
aws_secret_access_key = abcdefghijklmnopqrstuvwxyz1234567890ab12

Once in place, your commands will reference the profile containing the role you wish to assume (the target account) and, where needed, you use that account ID. In the example of the get-login-password command, the AWC CLI is passed the --profile property using the name of the sub-account. Docker will receive the resulting password from the AWS CLI and directly reference the sub-account by number.

For example, here are the commands to create the AWS ECR repository in the sub-account (note both the sub-account ID is used as well as the name of that account's profile):

aws ecr get-login-password --profile gov-staging | docker login \
  --username AWS \
  --password-stdin 123456789123.dkr.ecr.us-gov-west-1.amazonaws.com

aws ecr create-repository \
  --profile gov-staging \
  --repository-name "complexapi" \
  --image-tag-mutability MUTABLE 

... and the commands needed to push an image into the sub-account's registry with both the latest tag and a proper version number:

docker tag fredlackey/complexapi:0.0.0 \
  123456789012.dkr.ecr.us-gov-west-1.amazonaws.com/complexapi:0.0.0

docker tag fredlackey/complexapi:0.0.0 \
  123456789012.dkr.ecr.us-gov-west-1.amazonaws.com/complexapi:latest

aws ecr get-login-password \
  --profile gov-staging | docker login \
  --username AWS \
  --password-stdin 123456789012.dkr.ecr.us-gov-west-1.amazonaws.com

docker push 123456789012.dkr.ecr.us-gov-west-1.amazonaws.com/complexapi:0.0.0

docker push 123456789012.dkr.ecr.us-gov-west-1.amazonaws.com/complexapi:latest
Related