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