Update a resource in an Azure Resource Manager template

There can be times when you need to update a resource during a deployment, such as when you can't specify all the properties for a resource until other, dependent resources are created. For example, if you create a backend pool for a load balancer, you might update the network interfaces (NICs) on your virtual machines (VMs) to include them in the backend pool. Resource Manager does support updating of resources during deployment, but you must design your template correctly to avoid errors and to ensure that the deployment is handled as an update.

When you create a resource and update it later, you reference it twice. You reference it first in the template that creates it. Later, when you update the resource, you reference it by the same name. However, if two resources have the same name in a template, Resource Manager throws an exception. To avoid this error, specify the updated resource in a second template that's either linked or included as a subtemplate that uses the Microsoft.Resources/deployments resource type.

In the second template, you must either specify the name of the property to change or a new name for a property to add. You must also specify the names and original values of the properties that don't change. If you fail to specify one or more of the original properties, Resource Manager assumes that you want to create a new resource and deletes the original one.

Example template

Let's look at an example template that demonstrates the technique. The template deploys a virtual network named firstVNet that has one subnet named firstSubnet. It then deploys a virtual network interface (NIC) named nic1 and associates the NIC with the subnet. A deployment resource named updateVNet includes a nested template that updates firstVNet by adding a second subnet named secondSubnet.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {},
    "resources": [
        {
            "apiVersion": "2020-05-01",
            "name": "firstVNet",
            "location": "[resourceGroup().location]",
            "type": "Microsoft.Network/virtualNetworks",
            "properties": {
                "addressSpace": {
                    "addressPrefixes": [
                        "10.0.0.0/22"
                    ]
                },
                "subnets": [
                    {
                        "name": "firstSubnet",
                        "properties": {
                            "addressPrefix": "10.0.0.0/24"
                        }
                    }
                ]
            }
        },
        {
            "apiVersion": "2020-05-01",
            "type": "Microsoft.Network/networkInterfaces",
            "name": "nic1",
            "location": "[resourceGroup().location]",
            "dependsOn": [
                "firstVNet"
            ],
            "properties": {
                "ipConfigurations": [
                    {
                        "name": "ipconfig1",
                        "properties": {
                            "privateIPAllocationMethod": "Dynamic",
                            "subnet": {
                                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'firstVNet', 'firstSubnet')]"
                            }
                        }
                    }
                ]
            }
        },
        {
            "apiVersion": "2020-06-01",
            "type": "Microsoft.Resources/deployments",
            "name": "updateVNet",
            "dependsOn": [
                "nic1"
            ],
            "properties": {
                "mode": "Incremental",
                "parameters": {},
                "template": {
                    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.1",
                    "parameters": {},
                    "variables": {},
                    "resources": [
                        {
                            "apiVersion": "2020-05-01",
                            "name": "firstVNet",
                            "location": "[resourceGroup().location]",
                            "type": "Microsoft.Network/virtualNetworks",
                            "properties": {
                                "addressSpace": "[reference('firstVNet').addressSpace]",
                                "subnets": [
                                    {
                                        "name": "[reference('firstVNet').subnets[0].name]",
                                        "properties": {
                                            "addressPrefix": "[reference('firstVNet').subnets[0].properties.addressPrefix]"
                                        }
                                    },
                                    {
                                        "name": "secondSubnet",
                                        "properties": {
                                            "addressPrefix": "10.0.1.0/24"
                                        }
                                    }
                                ]
                            }
                        }
                    ],
                    "outputs": {}
                }
            }
        }
    ],
    "outputs": {}
}

Consider the resource object for our firstVNet resource. Notice that we specify again the settings for our firstVNet in a nested template—this is because Resource Manager doesn't allow the same deployment name in the same template, and nested templates are considered to be a different template. By again specifying our values for our firstSubnet resource, we tell Resource Manager to update the existing resource instead of deleting it and redeploying it. Finally, our new settings for secondSubnet are picked up during this update.

Try the template

An example template is available on GitHub. To deploy the template, run the following Azure CLI commands:

az group create --location <location> --name <resource-group-name>
az deployment group create -g <resource-group-name> \
    --template-uri https://raw.githubusercontent.com/mspnp/template-examples/master/example1-update/deploy.json

After deployment finishes, open the resource group that you specified in the portal. You see a virtual network named firstVNet and a NIC named nic1. Click firstVNet, then click subnets. You see the firstSubnet that was originally created, and you see the secondSubnet that was added in the updateVNet resource.

Original subnet and updated subnet

Then, go back to the resource group and click nic1, and then click IP configurations. In the IP configurations section, the subnet is set to firstSubnet (10.0.0.0/24).

nic1 IP configurations settings

The original firstVNet was updated instead of re-created. If firstVNet had been re-created, nic1 wouldn't be associated with firstVNet.

Next steps