Overcoming the maximum limit for deployments per Resource Group [2020 Updated]

Overcoming the maximum limit for deployments per Resource Group [2020 Updated]

You may have reached a certain point where you cannot make a new deployment against a particular resource group. The error goes like this:
Creating the deployment 'Your-Deployment-Name-Goes-Here' would exceed the quota of '800'. The current deployment count is '800', please delete some deployments before creating a new one. Please see https://aka.ms/arm-deploy for usage details. because you have reached the limit of the maximum number of deployments allower per resource group.
Did you know that all your deployments were being persisted as a history of your resource group? That's handy for auditing when you want to track which deployment changed your resources in a particular way. Having reached the resource group limit of 800 deployments is a milestone itself. Congrats, that's probably a good indicator that your cycle time is short and you release more frequently!

Automatic deletions from deployment history

July 2020 update: A new feature for automatic deletion of deployments has been announced. At the time of writing it is not yet rolled out. More info: https://docs.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-history-deletions?tabs=azure-powershell

However, you may still want to delete old deployments using some of the snippets below.

How to clean up old deployments manually?

There is no way to select all your deployments and simply delete them from the Azure Portal. Deleting them one by one manually is a painful process.
So to make that a repeatable process you can use either PowerShell or Bash to accomplish this goal. Note that cleaning 800 deployments takes some time.

Here are the scripts which will delete all but the 100 latest deployments(Note that the actual resources won't be affected. You are deleting the "deployment logs"). I implemented this both in Azure Powershell and Azure CLI:

Azure Powershell version

$resourceGroup = 'your-resource-group'
Get-AzureRmResourceGroupDeployment -ResourceGroupName $resourceGroup `
| Select-Object -Skip 100 `
| Remove-AzureRmResourceGroupDeployment

Azure CLI + Bash

resourceGroup='your-resource-group'; \
az group deployment list --resource-group $resourceGroup --query "[*].name | [100:] | join(' ', @)" \
| sed 's|[",]||g' \
| xargs -n 1 -r \
	az group deployment delete --resource-group $resourceGroup --name

Who is responsible to do the cleaning?

You will be tempted to automate this by invoking it from some kind of a scheduled process. But let's take a step back.
Since you have hit the limitation of having 800 deployments, your are most likely using the Infrastructure as Code(IaC) principle. It means that some part of your delivery process is creating the deployments. So why not to consider including a clean-up script right into the release definition to maintain a healthy state of your deployment history? Ideally, it would delete 1 deployment at a time, just make sure you leave enough deployments to serve as a buffer for an audit trail.