Understanding dependsOn

There are often multiple resources in an ARM template, and, by default, they are all provisioned in parallel. However, this default behavior can be modified using the dependsOn element. dependsOn helps to define dependencies between resources within an ARM template. If there are resources that are dependent on another resource availability, the resources should be provisioned only after those independent resources have been provisioned. dependsOn does not create a parent-child relationship between resources, however; it just mandates the deployment sequence of resources. Each resource can declare multiple resources within its dependsOn section, but they will only be provisioned after all declared resources are provisioned. It is important to note that there can be multiple levels of dependencies between Azure resources.

The dependsOn element accepts a JSON array as its input, as shown in the following example:

      "dependsOn": [
"[parameters('storageAccountName')]"
]

In this example, there is just one resource identifier supplied to dependsOn: the storage account name. This means that the current resource will be provisioned only after the storage account is provisioned. Let's see a complete example of dependsOn.

In the following example, two resources are provisioned, serverfarm and sites. These are also known as hosting plan and web app in Azure. Every web app needs a hosting plan a.k.a serverfarm. It is important that serverfarm resource is created before the web app resource. Although these are the two resources in the template and they can be provisioned in parallel, it is quite possible that sites resource tries to get provisioned before the serverfarm resource. This can lead to errors and unexpected results. In short, executing a template containing inter-dependent resources without defining the dependencies might lead to unpredictable results.

TheMicrosoft.Web/serverfarms resource does not have any dependsOn element. However, the Microsoft.Web/sites resource does have dependsOn element and it refers to the Microsoft.Web/serverfarms resource by its name. Defining theMicrosoft.Web/serverfarms resource name as a variable is useful as it can be repeatedly used at multiple locations. When this template is deployed, first Microsoft.Web/serverfarms resource is provisioned followed by theMicrosoft.Web/sites resource.

The following template is available in the file chapter-3 - listing3.txt with the accompanying chapter code.

The ARM template accepts a couple of parameters related to the App Service Plan and Web App resource as shown next:

 "parameters": {
"skuName": {
"type": "string",
"defaultValue": "F1"
},
"skuCapacity": {
"type": "int",
"defaultValue": 1,
"minValue": 1
}
}

In the next code snippet, there are a couple of variables declared in the variables section. They relate to the names of  App Service Plan and Web App resource:

 "variables": {
"hostingPlanName": "[concat('hostingplan', uniqueString(resourceGroup().id))]",
"webSiteName": "[concat('webSite', uniqueString(resourceGroup().id))]"
}

The resources section contains two top-level resources of type  Microsoft.Web/serverfarms and Microsoft.Web/sites. The code relating to Microsoft.Web/serverfarms is shown next:

 {
"apiVersion": "2016-03-01",
"name": "[variables('hostingPlanName')]",
"type": "Microsoft.Web/serverfarms",
"location": "[parameters('location')]",
"tags": {
"displayName": "HostingPlan"
},
"sku": {
"name": "[parameters('skuName')]",
"capacity": "[parameters('skuCapacity')]"
},
"properties": {
"name": "[variables('hostingPlanName')]"
}
}

The code related to Microsoft.Web/sites is shown in the following snippet. Notice how this resource declares its dependency on the previous resource, Microsoft.Web/serverfarms. Remember, this resource will only be provisioned after its parent resource has been:

{
"apiVersion": "2016-03-01",
"name": "[variables('webSiteName')]",
"type": "Microsoft.Web/sites",
"location": "[resourceGroup().location]",
"dependsOn": [
"[variables('hostingPlanName')]"
],
"properties": {
"name": "[variables('webSiteName')]",
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('hostingPlanName'))]"
}
}

The last segment of this template contains an outputs element that returns back data as shown in the following snippet:

"outputs": {
"siteUri": {
"type": "string",
"value": "[reference(concat('Microsoft.Web/sites/', variables('webSiteName'))).hostnames[0]]"
}
}

By using dependsOn, it is possible to create a complete graph of resources based on their dependencies.