A process to delete old ECR images using the aws
CLI tool and jq
.
The general idea is to use aws ecr describe-images
to enumerate the images, and aws ecr batch-delete-image
to delete them. The latter command can take a --cli-input-json
argument specifying a JSON file which lists the images to delete. jq
is used to filter describe-images
to only the old ones, and munge it into the format that batch-delete-image
expects. Unfortunately, batch-delete-image
supports a maximum of 100 images at a time, so the process may need to be repeated several times.
Limitations:
- I can't find a way to do this as a neat command line pipeline.
--cli-input-json
seems to require that the input comes from a file, rather than STDIN. (AWS CLI tracking issue: aws/aws-cli#3209) - Since
batch-delete-image
can only handle 100 images at a time, thejq
command slices to[0:100]
after filtering to just the old images. This means the process may have to be repeated. - This just goes by the date the image was pushed. It's possible that an old image is still in use! Make sure you choose a filter date that works for you.
Query ECR for images, use jq
to filter and format, and save to a file:
> aws ecr describe-images --repository-name myapp --output json | jq '{imageIds: [.imageDetails | .[] | select(.imagePushedAt < "2022") | {imageDigest}][0:100]}' > myapp.json
The select(.imagePushedAt < "2022-")
filters to only images pushed prior to 2022. It can be updated as necessary to filter more or less stringently. imagePushedAt
is an ISO-formatted string, and jq
sorts strings alphabetically, so this basically works how we need. You could, for example, do < "2022-04"
which would be any image from an earlier year, or an earlier month of 2022.
This, as written here, will query for all the ECR images, and then filter down to just old ones, and then take just 100 of them. This can be slow and a lot of extra requests if the repository has a ton of images, and so you can pass, e.g., --max-items 150
to retrieve fewer items initially. However, if you do this, watch out: since the images returned are unordered, if you have lots of newer items, you may fill up your 150 spots with newer items, and then end up deleting far fewer than 100 images after filtering them out.
Next, you use that file to delete images:
> aws ecr batch-delete-image --repository-name myapp --cli-input-json file://myapp.json
That will delete up to 100 images (the max supported by batch-delete-image
).
If necessary, repeat.