3

I want to disable "Windows Updates" for ARM template-based VM deployments. I found a relevant setting enableAutomaticUpdates in a recent Microsoft.Compute provider schema. But I did not find any ARM template using this setting. I searched a couple of Azure Quickstart templates related to Windows VM deployments - but none of them intends to control the behaviour of Windows Update service at provisioning time. I am aware of options available with CLASSIC deployment model, but I am explicitly looking for a solution using Azure Resource Manager Deployment model.

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",

...

{
  "apiVersion": "2015-06-15",
  "type": "Microsoft.Compute/virtualMachines",
  "name": "[parameters('vmName')]",
  "location": "[parameters('vmLocation')]",
  "tags": {
    "displayName": "VirtualMachine"
  },
  "dependsOn": [
    "[concat('Microsoft.Storage/storageAccounts/', parameters('vmStorageAccountName'))]",
    "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
  ],
  "properties": {
    "hardwareProfile": {
      "vmSize": "[parameters('vmSize')]"
    },
    "osProfile": {
      "computerName": "[parameters('vmName')]",
      "adminUsername": "[parameters('adminUsername')]",
      "adminPassword": "[parameters('adminPassword')]"
    },
    "windowsConfiguration": {
      "enableAutomaticUpdates": false        
    },
    ...

My attempt to use the property windowsConfiguration in my existing ARM template leads to a failed deployment and this error message (shown in Azure Portal).

Could not find member 'windowsConfiguration' on object of type 'Properties'. Path 'properties.windowsConfiguration', line 1, position 259. (Code: BadRequest)

When I upgrade Microsoft.Compute to version 2015-08-01, trying to refer the schema containing configuration property enableAutomaticUpdates, the VM deployment fails with this error message. Obviously I am doing something wrong.

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",

...

{
  "apiVersion": "2015-08-01",
  "type": "Microsoft.Compute/virtualMachines",
  "name": "[parameters('vmName')]",
  "location": "[parameters('vmLocation')]",
  "tags": {
    "displayName": "VirtualMachine"
  },
  "dependsOn": [
    "[concat('Microsoft.Storage/storageAccounts/', parameters('vmStorageAccountName'))]",
    "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
  ],
  "properties": {
    "hardwareProfile": {
      "vmSize": "[parameters('vmSize')]"
    },
    "osProfile": {
      "computerName": "[parameters('vmName')]",
      "adminUsername": "[parameters('adminUsername')]",
      "adminPassword": "[parameters('adminPassword')]"
    },
    "windowsConfiguration": {
      "enableAutomaticUpdates": false        
    },
    ...

No registered resource provider found for location 'West Europe' and API version '2015-08-01' for type 'virtualMachines'. The supported api-versions are '2015-05-01-preview, 2015-06-15, 2016-03-30'. The supported locations are 'eastus, eastus2, westus, centralus, northcentralus, southcentralus, northeurope, westeurope, eastasia, southeastasia, japaneast, japanwest, australiaeast, australiasoutheast, brazilsouth'. (Code: NoRegisteredProviderFound)

I am asking for some guidance how to write ARM templates that use Azure Compute Provider schema version 2015-08-01 to disable Windows Updates at provisioning time. My .NET solution uses Azure SDK 2.7.1.

Sascha Gottfried
  • 3,303
  • 20
  • 30

2 Answers2

4

I was pretty close to the solution. I just misunderstood the schema. According to this part of the schema windowsConfiguration is part of osProfile. If the ARM template is written like this Azure Resource Manager is understanding what I want and disables AutomaticUpdates at provisioning time.

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",

...

{
  "apiVersion": "2015-06-15",
  "type": "Microsoft.Compute/virtualMachines",
  "name": "[parameters('vmName')]",
  "location": "[resourceGroup().location]",
  "tags": {
    "displayName": "VirtualMachine"
  },
  "dependsOn": [
    "[concat('Microsoft.Storage/storageAccounts/', parameters('vmStorageAccountName'))]",
    "[concat('Microsoft.Network/networkInterfaces/', variables('nicName'))]"
  ],
  "properties": {
    "hardwareProfile": {
      "vmSize": "[parameters('vmSize')]"
    },
    "osProfile": {
      "computerName": "[parameters('vmName')]",
      "adminUsername": "[parameters('adminUsername')]",
      "adminPassword": "[parameters('adminPassword')]",
      "windowsConfiguration": {
        "enableAutomaticUpdates": false        
      }
    },
    ...

The incredible tool Resource Explorer in Azure Portal shows the current configuration for the given resource. As you can see EnableAutomaticUpdates is set to false.

{
    "properties": {
        "vmId": "10400cdd-26be-4be4-99d8-2d5c22d96911",
        "hardwareProfile": {
            "vmSize": "Standard_D2"
        },
        "storageProfile": {
            "imageReference": {
                "publisher": "MicrosoftWindowsServer",
                "offer": "WindowsServer",
                "sku": "2012-R2-Datacenter",
                "version": "latest"
            },
            "osDisk": {
                "osType": "Windows",
                "name": "osdisk",
                "createOption": "FromImage",
                "vhd": {
                    "uri": "this_is_not_for_public_use"
                },
                "caching": "ReadWrite"
            },
            "dataDisks": []
        },
        "osProfile": {
            "computerName": "this_is_not_for_public_use",
            "adminUsername": "this_is_not_for_public_use",
            "windowsConfiguration": {
                "provisionVMAgent": true,
                "enableAutomaticUpdates": false
            },
            "secrets": []
        },
        "networkProfile": {
            "networkInterfaces": [
                {
                    "id": "this_is_not_for_public_use/providers/Microsoft.Network/networkInterfaces/ComputeNode15-Nic"
                }
            ]
        },
        "provisioningState": "Creating"
    },
    "id": "this_is_not_for_public_use/providers/Microsoft.Compute/virtualMachines/this_is_not_for_public_use",
    "name": "this_is_not_for_public_use",
    "type": "Microsoft.Compute/virtualMachines",
    "location": "westeurope",
    "tags": {
        "displayName": "VirtualMachine"
    }
}

And I changed the template to use the location of the resource group - a useful option in most case. Thanks to Martyn C for providing this hint and for valuable feedback pushing me into the right direction.

Sascha Gottfried
  • 3,303
  • 20
  • 30
1

Looking at the above error message, you are passing the location as "West Europe" when it should be "westeurope". Region names should be passed all lower case.

You can just use the location of the resource group using the following line in your JSON template, "location": "[resourceGroup().location]" which would be the better practice.

Martyn C
  • 1,109
  • 9
  • 18
  • Using "West Europe" as a location string is valid according to https://github.com/Azure/azure-resource-manager-schemas/blob/master/schemas/2015-01-01/deploymentTemplate.json#L307 – Sascha Gottfried Apr 11 '16 at 15:50
  • Not for the `location` property. My templates which I have just exported out of the portal, all say `northeurope` or `westeurope`. Your link references a different parameter. – Martyn C Apr 11 '16 at 15:55
  • These deployments run since months. But may be your template is refering another schema. Please pay attention to the first line refering https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json. Are there any differences in your ARM templates? – Sascha Gottfried Apr 11 '16 at 16:04
  • Are you passing them as a deployment template parameter? I'm using the latest schema (in fact it's a preview schema that's not public yet). Can you just try what I've suggested to see if it works? Also check the supported versions which the error message does actually list... **The supported api-versions are '2015-05-01-preview, 2015-06-15, 2016-03-30'.** – Martyn C Apr 11 '16 at 16:06
  • I now changed the template that it always uses "location": "[resourceGroup().location]" to reduce the number of required parameters. – Sascha Gottfried Apr 11 '16 at 16:11
  • Please provide more information on the preview schema you mentioned – Sascha Gottfried Apr 11 '16 at 16:11
  • Cool, now when you deploy to a resource group it will just use the location the resource group sits in. I can't regarding the preview schema, it's on the TAP program so is NDA. – Martyn C Apr 11 '16 at 16:12
  • I think this is the way to go. https://github.com/Azure/azure-resource-manager-schemas/blob/master/schemas/2015-08-01/Microsoft.Compute.json#L642 Means windowsConfiguration is part of osProfile – Sascha Gottfried Apr 11 '16 at 16:15
  • Yes that is the schema for the compute provider. – Martyn C Apr 11 '16 at 16:16
  • Thank you. I upvoted your answer since it provided valueable feedback. – Sascha Gottfried Apr 11 '16 at 17:47