Back to list
    Rejecting an AI-Proposed Plan to Rethink ECR Authentication for Jenkins
    Dev Labo
    PRThis article contains advertisements

    Rejecting an AI-Proposed Plan to Rethink ECR Authentication for Jenkins

    15 min read

    I wanted to use an ECR prebuilt image as a Jenkins pipeline agent. The motivation was simple — stop running docker build every time and just pull a pre-built image to speed up the pipeline.

    So I had Claude Code draft a plan, and the proposal that came back was more complex than I expected.

    I rejected it.

    The Initial Proposal

    The current Jenkinsfile has this structure:

    pipeline {
        agent {
            dockerfile {
                label 'ec2-fleet-small'
                dir '.'
                filename 'Dockerfile'
                args "-v \${WORKSPACE}:/workspace -w /workspace"
            }
        }
        stages { ... }
        post { /* archiveArtifacts, cleanWs, webhook */ }
    }

    To switch this to an ECR image, the AI proposed the following structure:

    pipeline {
        agent { label 'ec2-fleet-small' }  // bare host first
        stages {
            stage('ECR Login') { ... }     // authenticate here
            stage('Run in Docker') {
                agent { docker { image ECR_IMAGE, reuseNode true } }
                stages { all existing stages }
                post { archiveArtifacts, cleanup }
            }
        }
        post { cleanWs, webhook }
    }

    The reasoning made sense. Run the ECR Login on the bare host, then use those credentials to launch the Docker agent. With reuseNode true, the same node is reused, so the authenticated state carries over.

    The split post blocks were logical too. Steps that need access to files in the Docker container's /tmp/ must run in the Docker stage's post before the container dies. cleanWs and the webhook stay in the pipeline-level post.

    But it required restructuring the entire pipeline — nested stages, split post blocks, script-scoped variable management...

    The amount of change felt disproportionate to what I was trying to achieve.

    "Isn't There an Easier Way?"

    I rejected the plan and asked.

    Two alternatives came up:

    Option 1: amazon-ecr-credential-helper (EC2 OS level)

    Option 2: Jenkins Amazon ECR Plugin (Jenkins side)

    Comparing the Two Approaches

    Both aim to let Docker automatically pull images from ECR. The difference is in the mechanism and where it's configured.

    credential-helperJenkins ECR Plugin
    Where it livesEC2 instance (OS level)Jenkins (plugin)
    Auth methodIAM instance profileJenkins Credentials
    Jenkinsfile changesagent block onlyregistryUrl + credentialsId
    ScopeAll Docker on instanceTarget job only
    Scaling to other jobsNo Jenkinsfile changesMust add to each file
    EC2 changes neededAMI/user data updateNone

    In terms of Jenkinsfile changes, credential-helper wins by a wide margin.

    // Using the ECR Plugin
    agent {
        docker {
            image '<ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/your-image:latest'
            registryUrl 'https://<ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/'
            registryCredentialsId 'ecr:ap-northeast-1:<Jenkins Credential ID>'
            label 'ec2-fleet-small'
        }
    }
    
    // Using credential-helper
    agent {
        docker {
            image '<ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com/your-image:latest'
            label 'ec2-fleet-small'
            alwaysPull true
        }
    }

    With credential-helper installed, the Jenkinsfile needs zero authentication configuration. Docker handles ECR auth automatically using the EC2's IAM instance profile.

    Why I Chose credential-helper

    I went with credential-helper for two main reasons.

    I don't want authentication config scattered across Jenkinsfiles.

    This isn't just about one job. Other pipelines will be switching to ECR images too. With the ECR plugin, every Jenkinsfile would need registryUrl and registryCredentialsId added. With credential-helper, none of them need anything.

    No impact on other registries like Docker Hub.

    I checked this first. credential-helper uses a credHelpers mechanism that works on a per-domain basis:

    {
      "credHelpers": {
        "<ACCOUNT_ID>.dkr.ecr.ap-northeast-1.amazonaws.com": "ecr-login"
      }
    }

    It doesn't touch any registry not listed here. Docker Hub pulls continue to work as before.

    The trade-off is that the EC2 AMI or user data needs to be updated. It's an infrastructure-layer change, so the blast radius is wider than a Jenkinsfile change. But given that it's a one-time setup that benefits all jobs, I judged it an acceptable cost.

    So, Infrastructure First

    This is where I realized the sequencing matters.

    If credential-helper isn't installed on the EC2 instances, switching the Jenkinsfile to an ECR image simply won't work. The prerequisite isn't met.

    What's needed:

    1. Install amazon-ecr-credential-helper on EC2 fleet instances
    2. Configure credHelpers in ~/.docker/config.json for the Docker user
    3. Verify the EC2 IAM role has the required ECR permissions (ecr:GetAuthorizationToken, ecr:BatchGetImage, ecr:GetDownloadUrlForLayer)

    This is an infrastructure code change, not a Jenkinsfile change.

    So rather than touching the Jenkinsfile first, I filed an IaC issue to update the infrastructure. Once that's done, the Jenkinsfile change is just a few lines in the agent block.

    Current Status

    The Jenkinsfile hasn't been changed yet.

    I created the infrastructure issue and prioritized that work first. Once it's done, I'll submit the Jenkinsfile PR.

    Documenting the decision process here while it's still fresh.

    The following books are helpful for understanding Jenkins pipeline design and AWS infrastructure operations.

    Was this article helpful?

    Coffee cup

    If this article helped you organize your thoughts

    a coffee-sized support would be much appreciated.

    ※ This is separate from tipping, but—

    If you'd like to organize similar themes in your own context, I also offer dialogue sessions as a form of thought organization.

    About Dialogue Sessions