Updates to Azure Resource Manager capabilities make leveraging ARM templates less painful.
In September 2017 Microsoft released some updates to the Azure Resource Manager capabilities that allow authors of ARM templates to leverage an expanded set of capabilities including conditionals and logical functions when creating new resource manager templates.
These capabilities have allowed authors to simplify how they write templates, as well as reduced the need to use nested templates for simple scenarios.
There is an excellent write up here which contains a number of samples and does a really great job of explaining the functionality. I wanted to share some of the work I have done recently to illustrate some of the capabilities and how I have leveraged them in ARM.
Multiple Extensions on a single VM
One of the more likely scenarios you may run into is the need to deploy multiple VM extensions on a VM as part of your deployment process. For example, perhaps you are deploying a new Windows 2016 VM with SQL 2016 SP1. As part of the deployment process you need to ensure the SQL Server Automatic Patching extension is deployed. In addition, you need to deploy and configure and IIS based web application on the server. Lastly the server might need to be joined to a domain, so the domain extension needs to be included in the ARM template.
In order to accomplish the above we will need 3 VM extensions total. The SQL Auto Patching Extension, the Custom Script extension and the Domain Join extension.
The key to getting this to work properly is to set the dependencies correctly for each of the extensions included in the template by leveraging the ‘DependsOn’ property. Below is an example of setting the dependencies for each extension.
{
"condition": "[equals(parameters('server_sku'), 'AllInOne')]",
"name": "ApplicationDeployment",
"type": "extensions",
"location": "[resourceGroup().location]",
"apiVersion": "2016-03-30",
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines', concat('winvm', copyIndex(1)))]",
"[concat('Microsoft.Compute/virtualMachines/', concat('winvm', copyIndex(1)),'/extensions/SqlIaasExtension')]"
],
"tags": {
"displayName": "ApplicationDeployment"
},
"properties": {
"publisher": "Microsoft.Compute",
"type": "CustomScriptExtension",
"typeHandlerVersion": "1.8",
"autoUpgradeMinorVersion": true,
"settings": {
"fileUris": [
"[parameters('appscripturi')]"
]
},
"protectedSettings": {
"commandToExecute": "[parameters('appscriptcmd')]",
"storageAccountName": "[parameters('appscriptstorageAccount')]",
"storageAccountKey": "[parameters('appscriptstorageKey')]"
}
}
},
{
"condition": "[equals(parameters('domjoin'), 'yes')]",
"comments": "Join domain - JsonADDomainExtension",
"apiVersion": "2015-06-15",
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines', concat('winvm', copyIndex(1)))]",
"[concat('Microsoft.Compute/virtualMachines/', concat('winvm', copyIndex(1)),'/extensions/SqlIaasExtension')]",
"[concat('Microsoft.Compute/virtualMachines/', concat('winvm', copyIndex(1)),'/extensions/ApplicationDeployment')]"
],
"type": "extensions",
"name": "joindomain",
"location": "[resourceGroup().location]",
"properties": {
"publisher": "Microsoft.Compute",
"type": "JsonADDomainExtension",
"typeHandlerVersion": "1.3",
"autoUpgradeMinorVersion": true,
"settings": {
"Name": "[parameters('domainFQDN')]",
"User": "[parameters('domainJoinUserName')]",
"Restart": "true",
"Options": "[variables('domainJoinOptions')]",
"OUPath": "[parameters('ouPath')]"
},
"protectedSettings": {
"Password": "[parameters('domainJoinUserPassword')]"
}
}
},
{
"comments": "SQL Autopatch",
"apiVersion": "2015-06-15",
"dependsOn": [
"[resourceId('Microsoft.Compute/virtualMachines', concat('winvm', copyIndex(1)))]"
],
"type": "extensions",
"name": "SqlIaasExtension",
"location": "[resourceGroup().location]",
"properties": {
"type": "SqlIaaSAgent",
"publisher": "Microsoft.SqlServer.Management",
"typeHandlerVersion": "1.2",
"autoUpgradeMinorVersion": "true",
"settings": {
"AutoPatchingSettings": {
"PatchCategory": "WindowsMandatoryUpdates",
"Enable": true,
"DayOfWeek": "Sunday",
"MaintenanceWindowStartingHour": "18",
"MaintenanceWindowDuration": "60"
}
}
}
}
As can be seen in the above example by setting the DependsOn property we can control how the extensions are installed and the order they are installed in. If the DependsOn property is not leveraged to specify dependencies all extensions included in the ARM template will be installed in Parallel and will likely fail during deployment.
Principal Engineer at Microsoft
6 年extensions dependsOn.. much needed!!