Azure Container Instance: Purge images from network-restricted registry

Posted by  Bin Du on Saturday, December 27, 2025

Registry with no public internet access

After disabling public internet access on Azure Container Registry (ACR), any service or client that needs to access the registry must do so through the private endpoint or trusted Azure service. Previously, I discussed several solutions to allow Azure Container Registry Tasks to access network-restricted registry. Azure Container Instance (ACI) is another popular service to run containerized workloads in Azure and it can run inside a virtual network to access the private endpoint of the registry. In this blog, I will discuss a solution to run acr purge command using ACI to purge images from a network-restricted ACR.

Prerequisites

Run ACI in virtual network

To allow ACI to access the network-restricted ACR, we need to create the ACI instance inside a dedicated subnet which has access to the private endpoint of the registry. The subnet must be delegated to Microsoft.ContainerInstance/containerGroups service.

Assign ACI managed identity with AcrPush role

Managed identity is the recommended way to authenticate ACI to access ACR. We need to prepare a user-assigned managed identity and assign it with AcrPush role on the target ACR.

Run acr purge command using ACI

In the following example, we will using mcr.microsoft.com/acr/acr-cli image to create an ACI instance inside a virtual network and assign it with a user-assigned managed identity. The ACI instance will execute run-acr-with-mi.sh hosted in github repo. The script will use the managed identity to login the ACR and run acr purge command.

# Prerequisite
# 1) Install azure-cli

acr_name="the-name-of-the-acr"
aci_name="the-name-of-the-aci"
resource_group="the-name-of-the-resource-group-containing-aci"
subnet_id="the-resource-id-of-the-subnet-for-aci" # e.g. /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.Network/virtualNetworks/{vnet-name}/subnets/{subnet-name}
user_assigned_identity_id="the-resource-id-of-the-user-assigned-identity" # e.g. /subscriptions/{subscription-id}/resourceGroups/{resource-group-name}/providers/Microsoft.ManagedIdentity/userAssignedIdentities/{identity-name}

location=$(az network vnet show --ids $subnet_id --query location -o tsv)
registry=$(az acr show --name $acr_name --query loginServer -o tsv)
tenant_id=$(az identity show --ids $user_assigned_identity_id --query tenantId -o tsv)
principal_id=$(az identity show --ids $user_assigned_identity_id --query principalId -o tsv)
registry_resource_id=$(az acr show -n $registry_name --query "id" -o tsv)

# Assign AcrPush role to the User Assigned Managed Identity
# az role assignment create \
#   --role AcrPush \
#   --assignee-object-id $principal_id \
#   --assignee-principal-type ServicePrincipal \
#   --scope $registry_resource_id

# Assign AcrPush role to the User Assigned Managed Identity
# az network vnet subnet update \
#   --ids $subnet_id \
#   --delegations Microsoft.ContainerInstance/containerGroups

az container create \
  --resource-group $resource_group \
  --name $aci_name \
  --location $location \
  --subnet $subnet_id \
  --os-type Linux \
  --cpu 1 \
  --memory 1 \
  --image mcr.microsoft.com/acr/acr-cli:0.17 \
  --assign-identity $user_assigned_identity_id \
  --restart-policy Never \
  --gitrepo-url https://github.com/northtyphoon/acr-samples \
  --gitrepo-mount-path /mnt/gitrepo \
  --command-line "/mnt/gitrepo/acr-purge-in-aci/run-acr-with-mi.sh purge --registry $registry --filter 'hello-world:.*' --ago 7d --untagged --dry-run" \
  --environment-variables Registry=$registry Tenant=$tenant_id