Edit

Failed to delete a virtual network or subnet used by Azure Container Instances

Summary

This article discusses errors that occur when you delete a virtual network (VNet) or subnet used by Azure Container Instances (ACI) and provides workarounds.

Note

This article uses the following terms to distinguish the ACI networking models:

  • Modern ACI networking: The container group references the delegated subnet directly. The subnet's ipConfigurationProfiles property is empty or absent. This model is used by ACI API version 2021-07-01 and later.
  • Legacy ACI networking: The subnet's ipConfigurationProfiles property references a Microsoft.Network/networkProfiles resource. Network profiles are retired starting with ACI API version 2021-07-01, but existing legacy profiles can still block subnet deletion.

Use the subnet's ipConfigurationProfiles property to distinguish the models. A current az container show response might display subnetIds for a container group that you originally deployed by using a legacy network profile.

Symptoms

  • When you delete a subnet used by ACI, you receive errors that resemble the following ones:

    (SubnetInUse) The subnet '<subnet-resource-id>' is still in use.
    Please delete all container groups in the subnet and try again.
    One sample container group in use is '<container-group-resource-id>'.
    
    Failed to delete subnet '<subnet-name>'.
    Error: 'Subnet /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Network/virtualNetworks/<vnet-name>/subnets/<subnet-name> requires any of the following delegations
    [Microsoft.ContainerInstance/containerGroups] to reference service association link /
    subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Network/virtualNetworks/<vnet-name>/subnets/<subnet-name>/serviceAssociationLinks/acisal.'
    
    Subnet <subnet-name> is in use by /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Network/networkProfiles/aci-network-profile-<network-profile-name>/containerNetworkInterfaceConfigurations/eth0/ipConfigurations/ipconfigprofile and cannot be deleted. 
    In order to delete the subnet, delete all the resources within the subnet. See aka.ms/deletesubnet.
    
    Failed to delete subnet '<subnet-name>'. 
    Error: Subnet <subnet-name> is in use by /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Network/networkProfiles/aci-network-profile-<network-profile-name>/containerNetworkInterfaceConfigurations/eth0/ipConfigurations/ipconfigprofile/aci-network-profile-<network-profile-name>/eth0/ipconfigprofile and cannot be deleted. 
    In order to delete the subnet, delete all the resources within the subnet. See aka.ms/deletesubnet.
    
  • When you delete a VNet used by ACI, you receive the following error:

    Failed to delete virtual network '<vnet-name>'. 
    Error: 'Subnet /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Network/virtualNetworks/<vnet-name>/subnets/<subnet-name> requires any of the following delegations [Microsoft.ContainerInstance/containerGroups] to reference service association link 
    /subscriptions/<subscription-id>/resourceGroups/<resource-group-name>/providers/Microsoft.Network/virtualNetworks/<vnet-name>/subnets/<subnet-name>/serviceAssociationLinks/acisal.'
    

ACI creates a service association link (SAL) named acisal on the delegated subnet. The SAL prevents the ACI delegation from being removed while a container group still uses the subnet. In some cases, the SAL can remain after all container groups are deleted and block deletion of the subnet or VNet.

Note

Don't remove the ACI subnet delegation while the SAL exists. First delete all container groups that reference the subnet and allow the platform to clean up the SAL. After the SAL is removed, you can remove the delegation or delete the subnet.

  1. Attempt to explicitly delete the subnet first to discard cascading delete operation errors.

  2. Check the subnet dependencies:

    az network vnet subnet show \
      --resource-group <vnet-resource-group> \
      --vnet-name <vnet-name> \
      --name <subnet-name> \
      --query "{
        serviceAssociationLinks:serviceAssociationLinks[].{
          name:name,
          linkedResourceType:linkedResourceType
        },
        ipConfigurationProfiles:ipConfigurationProfiles[].id,
        ipConfigurations:ipConfigurations[].id,
        privateEndpoints:privateEndpoints[].id
      }" \
      --output json
    
  3. Delete every container group that references the subnet. A container group doesn't have to be in the Running state to retain the subnet dependency.

    az container list \
      --subscription <subscription-id> \
      --query "[].{
        name:name,
        resourceGroup:resourceGroup,
        provisioningState:provisioningState,
        subnetIds:subnetIds[].id
      }" \
      --output json
    

    Delete each matching container group:

    az container delete \
      --resource-group <container-group-resource-group> \
      --name <container-group-name> \
      --yes
    
  4. Retry the subnet deletion. If the ACI SAL still blocks the operation, wait 10-15 minutes for platform cleanup and retry.

  5. If no container group or legacy network profile references the subnet and the SAL continues to block deletion, remove the SAL by using one of the following methods.

    Az PowerShell:

    Remove-AzContainerInstanceSubnetServiceAssociationLink `
      -ResourceGroupName <vnet-resource-group> `
      -VirtualNetworkName <vnet-name> `
      -SubnetName <subnet-name>
    

    Azure CLI:

    SUBNET_ID=$(az network vnet subnet show \
      --resource-group <vnet-resource-group> \
      --vnet-name <vnet-name> \
      --name <subnet-name> \
      --query id \
      --output tsv)
    
    az resource delete --ids /subscriptions/<subscription-id>/resourceGroups/<resourcegroup-name>/providers/Microsoft.Network/virtualNetworks/<vnet-name>/subnets/<subnet-name>/providers/Microsoft.ContainerInstance/serviceAssociationLinks/default --api-version 2018-10-01
    

    The subnet displays the Network resource provider SAL as serviceAssociationLinks/acisal. The delete operation uses the ACI extension resource path providers/Microsoft.ContainerInstance/serviceAssociationLinks/default.

    Note

    A read request such as az resource show can return DisallowedResourceOperation for this extension resource even when the delete operation is supported. Check the subnet's serviceAssociationLinks property to determine whether the SAL exists.

  6. Query the subnet again and verify that serviceAssociationLinks no longer contains acisal. Then retry the intended subnet or VNet deletion.

Cause 2: Network profiles block the deletion of the VNet or subnet

When you remove a container group that uses legacy ACI networking, its network profile might not be deleted correctly. The profile's IP configuration continues to reference the subnet and blocks deletion of the subnet or VNet.

Note

Network profiles are retired starting with ACI API version 2021-07-01. This cause applies only when the target subnet's ipConfigurationProfiles property contains one or more Microsoft.Network/networkProfiles resource IDs. Use API version 2021-07-01 or later for new deployments.

Workaround 1: Delete the network profile of the container group from the Azure portal

After deleting all ACI container groups, follow these steps:

  1. Query the target subnet and identify the exact network profile resource ID in ipConfigurationProfiles.

    az network vnet subnet show \
      --resource-group <vnet-resource-group> \
      --vnet-name <vnet-name> \
      --name <subnet-name> \
      --query "ipConfigurationProfiles[].id" \
      --output tsv
    
  2. Go to the resource group shown in the network profile resource ID.

  3. Select Show hidden types. By default, network profiles are hidden in the Azure portal.

  4. Select the network profile related to the container group.

  5. Select Delete.

  6. Retry the intended operation:

    • To delete only the subnet, delete the subnet.
    • To delete the entire VNet, first verify that no other resources use any subnet in the VNet, and then delete the VNet.

Workaround 2: Delete the network profile of the container group via Azure CLI

After deleting all ACI container groups, follow these steps:

  1. Get the network profile IDs from the target subnet:

    NETWORK_PROFILE=$(az network vnet subnet show \
      --resource-group <vnet-resource-group> \
      --vnet-name <vnet-name> \
      --name <subnet-name> \
      --query "ipConfigurationProfiles[].id" \
      --output tsv)
    
  2. Delete the network profile, Azure CLI accepts these child resource IDs and resolves the corresponding parent profiles:

    az network profile delete --ids $NetworkProfile --yes
    
  3. Retry the intended operation.

    To delete only the subnet:

    az network vnet subnet delete \
      --resource-group <vnet-resource-group> \
      --vnet-name <vnet-name> \
      --name <subnet-name>
    

    To delete the entire VNet:

    az network vnet delete \
      --resource-group <vnet-resource-group> \
      --name <vnet-name>
    

    Important

    Delete the subnet or the VNet according to your intended scope. Don't run both commands as consecutive cleanup steps. The VNet delete command must use the VNet name, not the subnet name.

  4. Verify that the intended resource was deleted. Don't rely only on the delete command's exit code.

Workaround 3: Update the containerNetworkInterfaceConfigurations property via Azure CLI

If deleting the network profile through the Azure portal and Azure CLI fails with NetworkProfileAlreadyInUseWithContainerNics, update the network profile property containerNetworkInterfaceConfigurations to an empty list.

  1. Get the exact network profile ID from the target subnet.

    NETWORK_PROFILE_ID=$(az network vnet subnet show \
      --resource-group <vnet-resource-group> \
      --vnet-name <vnet-name> \
      --name <subnet-name> \
      --query "ipConfigurationProfiles[0].id" \
      --output tsv)
    
  2. Convert the returned child resource ID to the parent network profile ID, and review it:

    NETWORK_PROFILE_ID=${NETWORK_PROFILE_ID%%/containerNetworkInterfaceConfigurations/*}
    echo "$NETWORK_PROFILE_ID"
    

    Here, ipConfigurationProfiles[0].id selects a profile reference from the target subnet. It isn't the same as az network profile list --query "[0].id", which selects the first profile returned for an entire resource group. If the subnet returns more than one profile reference, repeat these steps for each returned ID.

  3. Clear containerNetworkInterfaceConfigurations.

    az resource update \
      --ids $NETWORK_PROFILE_ID \
      --set properties.containerNetworkInterfaceConfigurations=[]
    
  4. Delete the network profile. ```azurecli az network profile delete --ids "$NETWORK_PROFILE_ID" --yes

    
    
  5. Query the subnet again and verify that ipConfigurationProfiles is empty.

  6. Delete either the subnet or the VNet by using the appropriate command from Workaround 2.