When using an ARM template to deploy resources in Azure, there are two options for choosing a deployment mode: incremental and complete. This blog post will cover the difference between the two using an ARM template to deploy a virtual network using the Azure PowerShell module.

Azure Resource Manager (ARM) templates can be used to target resource deployments to subscriptions or resource groups. Using JSON formatted files, you can deploy networks, virtual machines, storage accounts, really just about any resource. However, you can use ARM templates as a way to validate a deployment after its initial use. The ARM template can be used as sort of a gold standard for how the environment should be configured. If a resource is accidentally deleted, you can use the same ARM template to deploy the resource again.

Here’s our ARM template to deploy our virtual network vnetA:

{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "resources": [ { "name": "vnetA", "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2019-09-01", "location": "centralus", "properties": { "addressSpace": { "addressPrefixes": [ "192.168.1.0/24" ] } } } ] }

I can then use the New-AzResourceGroupDeployment and specify the JSON file hosting the ARM template code and deploy to the armdemo resource group:

New-AzResourceGroupDeployment -ResourceGroupName armdemo -TemplateFile .\deploy-vnet.json

And this will successfully deploy the virtual network:

Virtual network deployed using ARM template

If I change the “name” property in the ARM template to “vnetB” as well as the “addressPrefixes” to “192.168.2.0/24” and re-run my PowerShell deployment command, it will perform an incremental deployment. This means it will go ahead and deploy any resources to the resource group that don’t exist but leave any existing ones alone. The resource group ends up with both a vnetA and a vnetB:

Additional virtual network deployed using incremental mode

To summarize, incremental mode will deploy any resources defined in the ARM template that don’t already exist but leave any resources not defined in the ARM template alone. To explicitly use incremental, use -Mode Incremental with the previous command:

New-AzResourceGroupDeployment -ResourceGroupName armdemo -TemplateFile .\deploy-vnet.json -Mode Incremental

If I switch the value from Incremental to Complete, I end up with different behavior. Complete deployment mode will delete any resources that are not defined in the ARM template. If I deploy this template with just vnetB defined using complete mode:

{ "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "resources": [ { "name": "vnetB", "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2019-09-01", "location": "centralus", "properties": { "addressSpace": { "addressPrefixes": [ "192.168.2.0/24" ] } } } ] }

New-AzResourceGroupDeployment -ResourceGroupName armdemo -TemplateFile .\deploy-vnet.json -Mode Complete

This will verify that vnetB is deployed but then remove vnetA since it is not defined in template. In fact, you will get a prompt saying that resources not defined will be deleted:

Complete deployment mode warning

Going back to the virtual networks in the portal, only vnetB remains as vnetA was not defined in the ARM template, therefore it was deleted:

Remaining virtual network after complete mode deployment

So incremental mode can be used to make changes to existing resources by specifying the changes in the ARM template but not delete other resources. However, Microsoft’s document recommends always specifying other values for the resource, not just the ones being modified by the template as Resource Manager could end up overwriting those values as well.

Another important point for complete mode is it does not do a complete re-deployment of all the resources; it will just verify the resources defined in the template are already created and remove any resources that are not defined. Another important note is the version of REST API being used. If using a version earlier than 2019-05-10, the resources are not deleted. The complete delete actions are only applied if using a REST API later than 2019-05-10.

Questions or comments? If so, drop me a note below or find me on Twitter or LinkedIn to discuss further.

Reference:

Microsoft Docs: Azure Resource Manager deployment modes

https://docs.microsoft.com/azure/azure-resource-manager/deployment-modes