Automating Azure Container Image Cleanup

Managing container images in Azure Container Registry (ACR) can become cumbersome over time, especially when old images accumulate. To maintain a clean and efficient registry, it’s essential to periodically remove outdated images. In this post, we’ll walk through writing a script to automatically delete container images older than 7 days.

This also helps Microsoft Cloud Defender to keep maintaining a vulnerability check on container images that actually matter, reducing noise and effort.

Prerequisites

Before we begin, ensure you have the following:

  • Azure CLI installed and configured.
  • Access to your Azure Container Registry.
  • Basic knowledge of shell scripting.

Step-by-Step Guide

Step 1: List Images in ACR

First, we need to list all the images in our Azure Container Registry. We can use the Azure CLI for this purpose.

az acr repository list --name <your-acr-name> --output table

Step 2: Filter Images Older Than 7 Days

Next, we’ll filter out the images that are older than 7 days. We’ll use a combination of Azure CLI and shell scripting to achieve this.

Option 1

#!/bin/bash

ACR_NAME=<your-acr-name>
REPOSITORIES=$(az acr repository list --name $ACR_NAME --output tsv)

for REPO in $REPOSITORIES; do
  TAGS=$(az acr repository show-tags --name $ACR_NAME --repository $REPO --output tsv --orderby time_desc)
  for TAG in $TAGS; do
    CREATED_TIME=$(az acr repository show-manifests --name $ACR_NAME --repository $REPO --query "[?tags[0]=='$TAG'].timestamp" --output tsv)
    CREATED_DATE=$(date -d $CREATED_TIME +%s)
    CURRENT_DATE=$(date +%s)
    AGE=$(( (CURRENT_DATE - CREATED_DATE) / 86400 ))
    if [ $AGE -gt 7 ]; then
      echo "Deleting $REPO:$TAG (Age: $AGE days)"
      az acr repository delete --name $ACR_NAME --repository $REPO --tag $TAG --yes
    fi
  done
done

Option 2

  • If you would like to target a particular repository and also leave the last image behind during a clean up , run the following script.
#!/bin/bash

# Set the ACR name and login server
ACR_NAME=ACR_NAME # Replace with your ACR name
LOGIN_SERVER=${ACR_NAME}.azurecr.io

# Set the repository name
REPOSITORY_NAME=REPO_NAME # Replace with your repository name

# Set the retention period (7 days)
RETENTION_PERIOD=7

# Get the current date and time
CURRENT_DATE=$(date +"%Y-%m-%dT%H:%M:%SZ")

# Calculate the date 7 days ago
RETENTION_DATE=$(date -d "-$RETENTION_PERIOD days" +"%Y-%m-%dT%H:%M:%SZ")

# Get the list of images older than the retention period
images=$(az acr manifest list-metadata --name $REPOSITORY_NAME --registry $ACR_NAME --orderby time_asc -o tsv --query "[?lastUpdateTime < '$RETENTION_DATE'].[digest, lastUpdateTime]")

# Delete the old images, except the last one
count=0
while IFS=$'\t' read -r digest lastUpdateTime; do
  ((count++))
  if [ $count -eq $(echo "$images" | wc -l) ]; then
    echo "Skipping deletion of last image: $REPOSITORY_NAME@$digest"
  else
    tags=$(az acr repository show-tags -n $ACR_NAME --repository $REPOSITORY_NAME --filter $digest --query "[].name")
    if [ -n "$tags" ]; then
      echo "Deleting image: $REPOSITORY_NAME@$digest with tags: $tags"
    else
      echo "Deleting image: $REPOSITORY_NAME@$digest (no tags)"
    fi
    az acr repository delete -n $ACR_NAME --image $REPOSITORY_NAME@$digest --yes
  fi
done <<< "$images"

Github Link

Step 3: Automate the Script To ensure this script runs periodically, we can set up a cron job (on Linux) or a scheduled task (on Windows).

Automation On Linux:

Open the crontab editor:

crontab -e

Add the following line to run the script daily at midnight:

0 0 * * * /path/to/your/script.sh

Automation On Windows:

Open Task Scheduler. Create a new task and set the trigger to daily. Set the action to run your script.

Conclusion

By following these steps, you can automate the cleanup of old container images in your Azure Container Registry, ensuring your registry remains clean and efficient. Happy automating!