Skip to content

Instantly share code, notes, and snippets.

@tillig
Created November 5, 2020 16:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tillig/51139dadc905231629555cae0ce92e52 to your computer and use it in GitHub Desktop.
Save tillig/51139dadc905231629555cae0ce92e52 to your computer and use it in GitHub Desktop.
Prunes the set of images in an Azure Container Registry.
<#
.SYNOPSIS
Trims down the set of images in an Azure Container Registry.
.DESCRIPTION
There isn't really a retention policy setting on ACR such that the last X
tags will be retained for a given repository. This script helps bridge that gap by
going through all the repositories in an ACR, selecting the latest X tags to ignore,
then removing tags that were created after that time.
.PARAMETER Registry
The name of the container registry with the images to prune.
.PARAMETER TagsToKeep
The number of recent tags to keep.
.PARAMETER RepositoryMatch
An optional filter regex that allows you to only prune repositories that match the expression.
.EXAMPLE
./Delete-AzureContainerImages.ps1 `
-Registry "sourceacr" `
-TagsToKeep 5
This will prune every repository in the `sourceacr` registry. Each repository will
only keep the most recent five tags.
.EXAMPLE
./Delete-AzureContainerImages.ps1 `
-Registry "sourceacr" `
-TagsToKeep 5 `
-RepositoryMatch 'services/accounts/.+'
This will prune every repository in the `sourceacr` registry that has a name
matching the regular expression 'services/accounts/.+' - so `services/accounts/test`
and `services/accounts/spec` will be pruned, but `services/balances/test` will not.
Only the most recent five tags will be kept.
#>
[CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'High')]
Param(
[Parameter(Mandatory = $True)]
[ValidateNotNullOrEmpty()]
[ValidateLength(5, 50)]
[ValidatePattern('[a-z0-9]+')]
[string]
$Registry,
[Parameter(Mandatory = $True)]
[ValidateRange(1, [System.Int32]::MaxValue)]
[int]
$TagsToKeep,
[Parameter(Mandatory = $False)]
[string]
$RepositoryMatch
)
Begin {
Write-Verbose "Checking for az CLI."
If ($null -eq (Get-Command "az")) {
Throw "The az CLI was not found. Install here: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"
Exit 1
}
}
Process {
Write-Progress -Activity "Pruning Azure Container Registry Images" -Status "Getting images from $Registry" -CurrentOperation "Retrieving repository list" -PercentComplete 1
$RepoListJson = az acr repository list -n $Registry
If ($LASTEXITCODE -ne 0) {
Throw "Unable to read repository list from $Registry."
Exit 1
}
$RepoList = $RepoListJson | ConvertFrom-Json -NoEnumerate
Write-Verbose "Found $($SourceRepoList.Length) repositories in $Registry."
$ImagesToPrune = @()
for ($i = 1; $i -le $RepoList.Length; $i++) {
$RepositoryName = $RepoList[$i - 1]
$PercentComplete = 25 * ($i / $RepoList.Length)
Write-Progress -Activity "Pruning Azure Container Registry Images" -Status "Getting image tags from $Registry" -CurrentOperation "Retrieving tags for $RepositoryName" -PercentComplete $PercentComplete
If ((-not [System.String]::IsNullOrWhiteSpace($RepositoryMatch)) -and (-not ($RepositoryName -match $RepositoryMatch))) {
Write-Verbose "$RepositoryName does not match against $RepositoryMatch; skipping."
Continue
}
$TagListJson = az acr repository show-tags -n $Registry --repository $RepositoryName --orderby time_desc
If ($LASTEXITCODE -ne 0) {
Throw "Unable to read repository tags for $RepositoryName from $Registry."
Exit 1
}
$TagList = $TagListJson | ConvertFrom-Json -NoEnumerate
Write-Verbose "Found $($TagList.Length) tags for $RepositoryName."
for ($j = 0; $j -lt $TagList.Length; $j++) {
If ($j -lt $TagsToKeep) {
Continue
}
$Tag = $TagList[$j]
$ImagesToPrune += "$RepositoryName`:$Tag"
}
}
for ($i = 1; $i -le $ImagesToPrune.Length; $i++) {
$ImageName = $ImagesToPrune[$i - 1]
$PercentComplete = 25 + 75 * ($i / $ImagesToPrune.Length)
Write-Progress -Activity "Pruning Azure Container Registry Images" -Status "Pruning images" -CurrentOperation "Removing $ImageName" -PercentComplete $PercentComplete
If ($PSCmdlet.ShouldProcess($ImageName, "Prune image")) {
az acr repository delete -n $Registry --image $ImageName --only-show-errors -y | Out-Null
If ($LASTEXITCODE -ne 0) {
Throw "Failed to prune $ImageName."
Exit 1
}
}
}
Write-Progress -Activity "Copying Azure Container Registry Images" -Completed
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment