Skip to content

Instantly share code, notes, and snippets.

@losvedir
Last active May 25, 2022 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save losvedir/db18a73bb8811863d805a79053345d5a to your computer and use it in GitHub Desktop.
Save losvedir/db18a73bb8811863d805a79053345d5a to your computer and use it in GitHub Desktop.
Clean up old ECR images

Cleaning up old ECR images

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, the jq 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.

Process

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment