Deployment quota behavior when child resource is locked

Eric Hodges 20 Reputation points
2024-12-13T19:07:12.0233333+00:00

I have a Resource Group with many resources; one of which is a storage resource. I have a Delete lock on the Storage resource. Recently I tried to perform a deployment on the Resource Group and it failed, sighting the 800 deployment count.

I am familiar with the article https://learn.microsoft.com/en-us/azure/azure-resource-manager/troubleshooting/deployment-quota-exceeded?tabs=azure-cli, however it is ambiguous. It seems to imply this problem occurs when the Resource Group itself has a Delete lock. But that is not the case - only the Storage account has the delete lock.

My questions are:

  • If this the expected behavior, that Resource Group deployments >700 will not be removed if a child resource has a delete lock?
  • If so, how can I still protect my storage resource (since there is no soft delete for an entire Storage resource) while not being blocked on deployments unexpectedly?
Azure Storage Accounts
Azure Storage Accounts
Globally unique resources that provide access to data management services and serve as the parent namespace for the services.
3,292 questions
{count} votes

Accepted answer
  1. Marcin Policht 29,885 Reputation points MVP
    2024-12-13T19:28:19.9633333+00:00

    AFAIK, this is expected behavior under certain conditions. The deployment history cleanup process for a resource group depends on its ability to safely delete older deployments. When a resource group or any of its child resources has a delete lock, Azure Resource Manager cannot delete those deployment records. This leads to accumulation beyond the quota (800 deployments), eventually blocking new deployments.

    The issue occurs because ARM treats deployment cleanup as a form of delete operation, and delete locks prevent that operation—even if the lock is on a child resource like a storage account and not the resource group itself.

    To address this, you might consider any of the following:

    Option 1: Use Read-Only Lock Instead of Delete Lock - assuming of course that you don't intend to modify the storage account (control plane)

    Option 2: Remove the Lock Temporarily During Deployments

    • Script your deployment process to temporarily remove the delete lock before deployment and reapply it afterward.
    • This ensures that the lock does not interfere with deployment cleanup, while still protecting the resource when the deployment is not in progress.
       az lock delete --name "DeleteLock" --resource-group <RG_NAME> --resource <STORAGE_NAME> --resource-type "Microsoft.Storage/storageAccounts"
    
       # Run deployment commands here
    
       az lock create --name "DeleteLock" --resource-group <RG_NAME> --resource <STORAGE_NAME> --lock-type CanNotDelete --resource-type "Microsoft.Storage/storageAccounts"
    

    Option 3: Monitor Deployment History and Clean Up Regularly

    Option 4: Split Resources into Multiple Resource Groups

    • If your resource group contains many resources and frequent deployments, consider dividing resources into multiple groups.
    • This might help reduce the deployment count in each group and isolates the impact of locks.

    You might also want to consider using deployment stacks and replace the resource lock with explicit deny...


    If the above response helps answer your question, remember to "Accept Answer" so that others in the community facing similar issues can easily find the solution. Your contribution is highly appreciated.

    hth

    Marcin

    0 comments No comments

2 additional answers

Sort by: Most helpful
  1. Keshavulu Dasari 2,420 Reputation points Microsoft Vendor
    2024-12-16T03:35:37.9566667+00:00

    Hi Eric Hodges,
    Greetings! Welcome to Microsoft Q&A Forum. Thanks for posting you query here!
    To the deployment history limit of 800 deployments per resource group, the article you mentioned indicates that if a resource group has a delete lock, deployments cannot be automatically deleted from the history, which can cause deployment failures, it doesn't explicitly state that a delete lock on a child resource (like your storage account) would prevent deployment history deletions. Based on your experience, it seems that the delete lock on the storage account might be indirectly affecting the deployment history cleanup process.

    1. Protecting Your Storage Resource While Avoiding Deployment Blocks: To protect your storage resource without being blocked by the deployment history limit, you can consider the following approaches:
    2. Manually Delete Old Deployments: Regularly clean up old deployments from the deployment history using the Azure CLI or PowerShell. This can help you stay below the 800-deployment limit. For example, you can use the following Azure CLI command to delete deployments older than five days, to delete all deploy
    startdate=$(date +%F -d "-5days")
    deployments=$(az deployment group list --resource-group exampleGroup --query "[?properties.timestamp<'$startdate'].name" --output tsv)
    for deployment in $deployments
    do
      az deployment group delete --resource-group exampleGroup --name $deployment
    done
    

    You can get the current count in the deployment history with the following command. This example requires a Bash environment.User's image Use Resource Locks Strategically: Instead of a delete lock, consider using a read-only lock on your storage account. This will prevent modifications but still allow deletions if necessary. be cautious as this might impact other operations on the storage account.

    Monitor Deployment History: Keep an eye on the number of deployments in your resource group. You can use the Azure CLI to get the current count:
    For more information:
    https://learn.microsoft.com/en-us/azure/azure-resource-manager/troubleshooting/deployment-quota-exceeded?tabs=azure-cli
    Please let us know if you have any further queries. I’m happy to assist you further.  


      Please do not forget to "Accept the answer” and “up-vote” wherever the information provided helps you, this can be beneficial to other community members.


  2. Sumarigo-MSFT 47,366 Reputation points Microsoft Employee
    2024-12-17T05:43:27.36+00:00

    @Eric Hodges Welcome to Microsoft Q&A Forum, Thank you for posting your query here!

    Adding more information to the above response!

    There are a lot of these considerations before applying Resource locks. These are documented in the Azure Resource Locks docs. Here are a few excerpts:

    • A cannot-delete lock on a resource group prevents Azure Resource Manager from automatically deleting deployments in the history. If you reach 800 deployments in the history, your deployments will fail.

    This blog provides detailed information on your requirements : https://techcommunity.microsoft.com/blog/coreinfrastructureandsecurityblog/using-resource-locks-to-prevent-accidental-changes-in-azure/3842402

    Note:

    • Deployment limit per resource group: Each Azure resource group has a limit of 800 deployments in its history. 
    • Lock impact: If a child resource within a resource group is locked (like a storage account), any deployment attempting to modify that resource group will fail due to the lock. 
    • Lock types: Depending on the lock type ("ReadOnly" or "CanNotDelete"), you may be able to view the locked resource, but not modify or delete it

    Expected Behavior with Delete Lock on Child Resource: The issue you're experiencing is related to the deployment history limit of 800 deployments in a Resource Group. According to the information, a CanNotDelete lock on a Resource Group prevents Azure Resource Manager from automatically deleting deployments in the history. However, if the lock is only on a child resource (like your storage account), it should not directly affect the deployment history of the entire Resource Group. The deployment history is managed at the Resource Group level, and locks on individual resources should not interfere with this process.

    Protecting Storage Resource Without Blocking Deployments: To protect your storage resource while avoiding deployment issues, you can consider the following approaches:

    • Manual Deletion of Deployment History: Regularly delete old deployments from the deployment history to stay below the 800 deployment limit. You can use the Azure CLI or PowerShell commands to delete deployments older than a certain number of days.
    • Use Resource Locks Strategically: Apply the CanNotDelete lock only when necessary and remove it temporarily during deployments if needed. This way, you can ensure that the deployment history is managed without interruptions.
    • Automate Deployment History Management: Set up automation scripts to periodically clean up the deployment history, ensuring that you do not hit the 800 deployment limit.

    For detailed information on Limits, please refer to this article
    User's image

    1. To protect your Azure Storage resource without a full storage account-level soft delete, you can use Azure Resource Locks to prevent accidental deletion, while still allowing deployments by applying a "ReadOnly" lock instead of a "Delete" lock; this will prevent deletion of the storage account while still enabling modifications within it (Protects the storage account against deletion or configuration changes. Doesn't protect containers or blobs in the account from being deleted or overwritten.)

    Apply an Azure Resource Manager lock to a storage account

    Additional information : Recommendations for basic data protection
    If you're looking for basic data protection coverage for your storage account and the data that it contains, then Microsoft recommends taking the following steps to begin with:

    Overview of data protection options

    • Configure an Azure Resource Manager lock on the storage account to protect the account from deletion or configuration changes. Learn more...
    • Enable container soft delete for the storage account to recover a deleted container and its contents. Learn more...
    • Save the state of a blob at regular intervals:
      • For Blob Storage workloads, enable blob versioning to automatically save the state of your data each time a blob is overwritten. Learn more...
        • For Azure Data Lake Storage workloads, take manual snapshots to save the state of your data at a particular point in time. Learn more...

    These options, as well as other data protection options for other scenarios, are described in more detail in the following section.

    For an overview of the costs involved with these features, see Summary of cost considerations.

    Please let us know if you have any further queries. I’m happy to assist you further.  


      Please do not forget to "Accept the answer” and “up-vote” wherever the information provided helps you, this can be beneficial to other community members.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.