Azure DevOps: Cleanup Docker images for your Pull Requests
If you automatically creates docker images for Pull Requests, it is quite important that you automate cleanup of these images to avoid filling your docker registry with unused images.
This article is a prosecution of the previous one on creating Docker Images for your Pull Requests and deals with cleanup of your Docker Registry.
Authentication to Azure
In Azure DevOps you can use connected services to connect to Azure Accounts or external services, but since I’m using mainly PowerShell scripts inside my repository, I often prefer using a Service Principal. This is a good practice because you can limit the access of the service principal to only the resources it needs to access, and you can revoke the access at any time.
To create a service principal you can simply create an App Registration in your Azure Entra administration portal. Then you only need to create a secret for the application that will constitute the password of the service principal.
Figure 1: Create an Entra application
I like service principals because they starts having no permission and then you can go to various resources and start adding Roles to the principal based on the resource you want it to access. In this example I’ve created a single service principal that I’m using for all my Azure DevOps basic pipeline, but you can create how many you want.
Using a service principal gives me two advantage, granularity of access and being able to manage everything from Azure Portal.
The script
The script to cleanup resources is really simple, it starts authenticating to Azure with Service Principal and then get a reference for all images inside that container registry.
|
|
As you can see I need to pass ApplicationId and TenantId of the Service Principal (the entra application) I’ve created and then converting the secret to a secure string to create a credential object. Then I simply connect to Azure with the service principal. If everything is ok you will seee a message and then the call to Get-AzContainerRegistryRepository succeeds.
Now it is time to list all the tag, for all tag that have the form PRxxxx extract pull request number and then check the status of the pull request on Azure DevOps. If the pull request is not active, I can safely delete the image.
First of all I define a function to get the status of a pull request
|
|
This function is declared inside the main script, it works with a Personal Access Token contained in $pat variable and also it uses the organizationUrl and project variables. This function simply calls the Azure DevOps REST API to get the status of a pull request.
Given this function the script can enumerate all the tags and delete those one that are not bound to an Active Pull Request.
Thanks to a simple RegEx we can identify all Docker Images bound to a Pull Request, and delete them if the correspoinding Pull Requests are not active.
|
|
This allows me to print a nice output like this one.
|
|
Now you can schedule this script to run every night with a simple Azure DevOps pipeline.
Once you have a PowerShell script that performs some maintenance, the easiest way to schedule it is to create a pipeline that runs the script at a specific time.
|
|
This pipeline runs on a special repository called SetupScript where we stored all setup and build script related to release. As you can see we can simply use the $(System.AccessToken) to access the Azure DevOps REST API with standard pipeline permission. The secret for the Service Principal is stored in a variable called appsecret.
This allows us to create how many images we need for our Pull Requests without the risk of filling the Docker Registry with unused images.
Gian Maria.