Push to ECR present in different AWS account from Jenkins CI/CD

902 Views Asked by At

I have Jenkins Slave node as EC2 instance where i am running my CI/CD and pushing image to AWS ECR.

 stage('Push Image to ECR'){
        steps{
              withAWS(region: 'us-east-1', roleAccount: shared_services_account, role: 
                             'Role-Name') {

             sh 'eval \$(aws ecr get-login --no-include-email --region us-east-1)'
             sh 'docker tag test-image 5722XXXXXX.dkr.ecr.us-east- 
                 1.amazonaws.com/Dev/DC/DCservice:latest'
             sh 'sudo docker push 572205XXXX.dkr.ecr.us-east- 
                  1.amazonaws.com/Dev/DC/DCservice:latest'
           }

Now here my EC2 Jenkins slave node and ECR are in same account.

But for production if want to use same Jenkins EC2 slave node and push it to ECR of production AWS account.

I believe the code below will not work as it will push to ECR of same AWS account ?

   sh 'eval \$(aws ecr get-login --no-include-email --region us-east-1'

Please suggest how can i push to ECR of prod AWS account using the same EC2 slave node.

1

There are 1 best solutions below

1
On

To answer your immediate question, you need to specify the registry_id in the get-login command (relevant docs)

sh 'eval \$(aws ecr get-login --registry-ids 012345678910 --no-include-email --region us-east-1'

However, there are a few other things it's worth checking.

Under the assumption that you're OK pushing to your ECR over the internet, you need the following:

An IAM Instance Profile attached to your Jenkins EC2 instance with a role policy that allows you to push the the ECR in the 'other' account, see this for examples of the policy structures

Your Jenkins EC2 instance needs a security group rule that allows HTTPS outbound access to the internet

Your ECR policy in the 'other' account needs to allow writes from the Jenkins Instance Profile, see this for an example of ECR policies

(something like this should work)

{
  "Version": "2008-10-17",
  "Statement": [
    {
      "Sid": "AllowPushPull",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::123456789012:instance-profile/jenkins_ec2"
        ]
      },
      "Action": [
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage",
        "ecr:BatchCheckLayerAvailability",
        "ecr:PutImage",
        "ecr:InitiateLayerUpload",
        "ecr:UploadLayerPart",
        "ecr:CompleteLayerUpload"
      ]
    }
  ]
}

If you don't want to push via the internet, you can use the recently released ECR endpoints, see this for more info