Untagging images from AWS ECR (without deleting be like
I had to go full Rube Goldberg to clean up old image tags from closed PRs, while still leaving deletion of untagged image to the ECR repo’s own lifecycle policy. Never go full Rube Goldberg:
<span style="color:#63a35c;">name</span><span style="color:#323232;">: </span><span style="color:#183691;">ECR Retention Policy
</span><span style="color:#323232;">
</span><span style="color:#0086b3;">on</span><span style="color:#323232;">:
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">pull_request</span><span style="color:#323232;">:
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">types</span><span style="color:#323232;">:
</span><span style="color:#323232;"> - </span><span style="color:#183691;">closed
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">workflow_call</span><span style="color:#323232;">:
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">workflow_dispatch</span><span style="color:#323232;">:
</span><span style="color:#323232;">
</span><span style="color:#63a35c;">jobs</span><span style="color:#323232;">:
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">clean-unused-ecr</span><span style="color:#323232;">:
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">name</span><span style="color:#323232;">: </span><span style="color:#183691;">Delete unused container images
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">runs-on</span><span style="color:#323232;">: </span><span style="color:#183691;">runs-on,runner=2cpu-linux-x64,run-id=${{ github.run_id }},image=ecr_login_image
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">steps</span><span style="color:#323232;">:
</span><span style="color:#323232;"> - </span><span style="color:#63a35c;">name</span><span style="color:#323232;">: </span><span style="color:#183691;">Configure AWS credentials
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">uses</span><span style="color:#323232;">: </span><span style="color:#183691;">aws-actions/configure-aws-credentials@v4
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">with</span><span style="color:#323232;">:
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">aws-region</span><span style="color:#323232;">: </span><span style="color:#183691;">${{ env.RUNS_ON_AWS_REGION }}
</span><span style="color:#323232;"> - </span><span style="color:#63a35c;">name</span><span style="color:#323232;">: </span><span style="color:#183691;">AWS ECR Login
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">id</span><span style="color:#323232;">: </span><span style="color:#183691;">login-ecr
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">uses</span><span style="color:#323232;">: </span><span style="color:#183691;">aws-actions/amazon-ecr-login@v2
</span><span style="color:#323232;"> - </span><span style="color:#63a35c;">name</span><span style="color:#323232;">: </span><span style="color:#183691;">AWS ECR Info
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">shell</span><span style="color:#323232;">: </span><span style="color:#183691;">bash
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">run</span><span style="color:#323232;">: </span><span style="font-weight:bold;color:#a71d5d;">|
</span><span style="color:#183691;"> echo "ECR_REGISTRY=${{ steps.login-ecr.outputs.registry }}" >> $GITHUB_ENV
</span><span style="color:#183691;"> echo "ECR_REPO=$(basename ${{ github.repository }})" >> $GITHUB_ENV
</span><span style="color:#323232;"> - </span><span style="color:#63a35c;">name</span><span style="color:#323232;">: </span><span style="color:#183691;">Docker meta
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">id</span><span style="color:#323232;">: </span><span style="color:#183691;">docker_meta
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">uses</span><span style="color:#323232;">: </span><span style="color:#183691;">docker/metadata-action@v5
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">with</span><span style="color:#323232;">:
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">images</span><span style="color:#323232;">: </span><span style="color:#183691;">${{ env.ECR_REGISTRY }}/${{ env.ECR_REPO }}
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">flavor</span><span style="color:#323232;">: </span><span style="color:#183691;">suffix=-
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">tags</span><span style="color:#323232;">: </span><span style="color:#183691;">type=raw,value=${{ github.head_ref || github.ref_name }}
</span><span style="color:#323232;"> </span><span style="font-style:italic;color:#969896;"># NOTE: This is convoluted because AWS ECR has no simple way to untag image without deletion
</span><span style="color:#323232;"> </span><span style="font-style:italic;color:#969896;"># given we want to leave deletion of untagged image to the ECR repo's own lifecycle policy
</span><span style="color:#323232;"> </span><span style="font-style:italic;color:#969896;"># https://stackoverflow.com/questions/70065254/remove-ecr-image-tag-despite-imagereferencedbymanifestlist-error
</span><span style="color:#323232;"> </span><span style="font-style:italic;color:#969896;"># https://github.com/aws/containers-roadmap/issues/1567
</span><span style="color:#323232;"> - </span><span style="color:#63a35c;">name</span><span style="color:#323232;">: </span><span style="color:#183691;">AWS ECR Cleanup
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">shell</span><span style="color:#323232;">: </span><span style="color:#183691;">bash
</span><span style="color:#323232;"> </span><span style="color:#63a35c;">run</span><span style="color:#323232;">: </span><span style="font-weight:bold;color:#a71d5d;">|
</span><span style="color:#183691;"> REPO_EXISTS=$(aws ecr describe-repositories --repository-names $ECR_REPO 2>&1 || true)
</span><span style="color:#183691;"> if echo "${REPO_EXISTS}" | grep -q 'RepositoryNotFoundException'; then
</span><span style="color:#183691;"> echo "Repository not found, skipping cleanup."
</span><span style="color:#183691;"> exit 0
</span><span style="color:#183691;"> fi
</span><span style="color:#183691;"> IMAGE_TAGS=$(aws ecr list-images --repository-name $ECR_REPO --query 'imageIds[*].imageTag' --output text)
</span><span style="color:#183691;">
</span><span style="color:#183691;"> docker pull busybox
</span><span style="color:#183691;"> docker tag busybox $ECR_REGISTRY/$ECR_REPO:_
</span><span style="color:#183691;"> docker push $ECR_REGISTRY/$ECR_REPO:_
</span><span style="color:#183691;">
</span><span style="color:#183691;"> TEMP_IMAGE=$(
</span><span style="color:#183691;"> aws ecr batch-get-image
</span><span style="color:#183691;"> --repository-name $ECR_REPO
</span><span style="color:#183691;"> --image-ids imageTag=_ )
</span><span style="color:#183691;"> TEMP_MANIFEST=$(echo $TEMP_IMAGE | jq -r '.images[].imageManifest')
</span><span style="color:#183691;"> TEMP_DIGEST=$(echo $TEMP_IMAGE | jq -r '.images[].imageId.imageDigest')
</span><span style="color:#183691;">
</span><span style="color:#183691;"> TAG_PREFIX=$(echo ${{ fromJSON(steps.docker_meta.outputs.json).tags[0] }} | cut -d: -f2)
</span><span style="color:#183691;"> for TAG in $IMAGE_TAGS
</span><span style="color:#183691;"> do
</span><span style="color:#183691;"> if [[ $TAG == $TAG_PREFIX* ]]; then
</span><span style="color:#183691;"> docker tag busybox $ECR_REGISTRY/$ECR_REPO:$TAG
</span><span style="color:#183691;"> docker push $ECR_REGISTRY/$ECR_REPO:$TAG
</span><span style="color:#183691;"> echo "Untaged image $TAG"
</span><span style="color:#183691;"> fi
</span><span style="color:#183691;"> done
</span><span style="color:#183691;">
</span><span style="color:#183691;"> # Delete the temporary image by digest
</span><span style="color:#183691;"> aws ecr batch-delete-image
</span><span style="color:#183691;"> --repository-name $ECR_REPO
</span><span style="color:#183691;"> --image-ids imageDigest=$TEMP_DIGEST
</span>
Add comment