1
votes

I'm using ARM template file to deploy two resources:

  1. An Azure Cloud Service (with 4 roles)
  2. Autoscale settings (that include rules for all 4 roles)

If the Cloud Service exists, and the roles are running, then I have no issue in deploying both in parallel, it works successfully with the following template.

The issue occurs when the cloud service is being deployed for the first time. This is reasonable as the autoscale settings need a targetResourceUri to apply the rules, if that resource does not exist - it is good thing to fail the deployment.

For that, they've invented the dependsOn property, but for some reason I cannot get it to work, the autoscale rules fail to be deployed due the targetResourceUri not exists (the scale rules are being deployed too quickly, before the roles are deployed).

Here's the template:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "serviceName": {
      "type": "string"
    },
    "PackageLink": {
      "type": "string"
    },
    "serviceConfigurationLink": {
      "type": "string"
    },
    "deploymentLabel": {
      "type": "string"
    },
    "autoscaled_resource_name": {
      "defaultValue": "autoscale-rules-default",
      "type": "string"
    },
    "metricResourceUri_cpu": {
      "type": "string"
    },
    "autoscale_resourceUri": {
      "type": "string"
    },
    "autoscale_rules_enabled": {
      "defaultValue": true,
      "type": "bool"
    },
    "min_instance_count": {
      "type": "string"
    },
    "max_instance_count": {
      "type": "string"
    },
    "default_instance_count_when_metric_unavailable": {
      "type": "string"
    }
  },
  "variables": {
    "resourceLocation": "[resourcegroup().location]"
  },
  "resources": [
    {
      "apiVersion": "2016-04-01",
      "type": "Microsoft.ClassicCompute/domainNames",
      "name": "[parameters('serviceName')]",
      "location": "[variables('resourceLocation')]",
      "resources": [
        {
          "apiVersion": "2016-04-01",
          "name": "production",
          "type": "deploymentSlots",
          "dependsOn": [
            "[resourceId('Microsoft.ClassicCompute/domainNames', parameters('serviceName'))]"
          ],
          "properties": {
            "packageLink": {
              "uri": "[parameters('PackageLink')]"
            },
            "deploymentLabel": "[parameters('deploymentLabel')]",
            "ConfigurationLink": {
              "uri": "[parameters('serviceConfigurationLink')]"
            },
            "deploymentOptions": "StartDeployment"
          }
        }
      ]
    },
    {
      "type": "microsoft.insights/autoscalesettings",
      "name": "[parameters('autoscaled_resource_name')]",
      "apiVersion": "2014-04-01",
      "location": "eastus",
      "dependsOn": [
        "[parameters('serviceName')]"
      ],
      "properties": {
        "profiles": [
          {
            "name": "[parameters('autoscaled_resource_name')]",
            "capacity": {
              "minimum": "[parameters('min_instance_count')]",
              "maximum": "[parameters('max_instance_count')]",
              "default": "[parameters('default_instance_count_when_metric_unavailable')]"
            },
            "rules": [
              {
                "metricTrigger": {
                  "metricName": "Percentage CPU",
                  "metricNamespace": "",
                  "metricResourceUri": "[parameters('metricResourceUri_cpu')]",
                  "timeGrain": "PT5M",
                  "statistic": "Average",
                  "timeWindow": "PT5M",
                  "timeAggregation": "Average",
                  "operator": "GreaterThan",
                  "threshold": 85
                },
                "scaleAction": {
                  "direction": "Increase",
                  "type": "PercentChangeCount",
                  "value": "45",
                  "cooldown": "PT10M"
                }
              }
            ]
          }
        ],
        "enabled": "[parameters('autoscale_rules_enabled')]",
        "name": "[parameters('autoscaled_resource_name')]",
        "targetResourceUri": "[parameters('autoscale_resourceUri')]",
        "notifications": [
          {
            "operation": "Scale",
            "email": {
              "sendToSubscriptionAdministrator": true,
              "sendToSubscriptionCoAdministrators": true,
              "customEmails": []
            }
          }
        ]
      }
    }
  ]
}

Here's the powershell log:

VERBOSE: Performing the operation "Creating Deployment" on target "************".
WARNING: The DeploymentDebug setting has been enabled. This can potentially log secrets like passwords used in resource
 property or listKeys operations when you retrieve the deployment operations through
Get-AzureRmResourceGroupDeploymentOperation
VERBOSE: 1:00:25 AM - Template is valid.
VERBOSE: 1:00:28 AM - Create template deployment 'azuredeploy-0615-2200'
VERBOSE: 1:00:28 AM - Checking deployment status in 5 seconds
VERBOSE: 1:00:34 AM - Checking deployment status in 10 seconds
VERBOSE: 1:00:44 AM - Resource Microsoft.ClassicCompute/domainNames/deploymentSlots '************/production'
provisioning status is running
New-AzureRmResourceGroupDeployment : 1:00:44 AM - Resource microsoft.insights/autoscalesettings
'autoscale-rules-default' failed with message '{
  "code": "TargetResourceNotFound",
  "message": "The target resource id '/subscriptions/************/resourceGroups/"************/providers/Microsoft.ClassicCompute/domainNames/"************/slots/Production/roles/WorkerRole' was not found."
}'
At C:\Users\************\Deploy-AzureResourceGroup.ps1:98 char:1
+ New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $TemplateFil ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [New-AzureRmResourceGroupDeployment], Exception
    + FullyQualifiedErrorId : Microsoft.Azure.Commands.ResourceManager.Cmdlets.Implementation.NewAzureResourceGroupDep
   loymentCmdlet

VERBOSE: 1:00:44 AM - Resource Microsoft.ClassicCompute/domainNames '************' provisioning status is succeeded
VERBOSE: 1:00:45 AM - Checking deployment status in 15 seconds
VERBOSE: 1:01:00 AM - Checking deployment status in 20 seconds
VERBOSE: 1:01:21 AM - Checking deployment status in 25 seconds
VERBOSE: 1:01:47 AM - Checking deployment status in 30 seconds

It looks like the autoscale rules are being deployed even before there's a confirmation on the successful creation of the cloud service.

Do I have a mistake in my configuration?

1
so the template thinks that the cloudservice is deployed before it is actually deployed right? in that case there is nothing you can do. well divide template in 2 parts and create some logic in powershell\whatever to monitor when cloud service is ready and start the second part4c74356b41
x20...Use the Powershell, young one!Hackerman
@Hackerman - I'm using powershell of course.johni
@4c74356b41 - are you certain there's nothing we can do?johni
well, you could check the time it takes for the cloud service to be actually up and running and force template to do something during that time, but nothing you can do to make this reliable, unless you do it outside of the template4c74356b41

1 Answers

1
votes

The depended resources, in my case autoscalesettings should be depended on the deployment of the cloud service, which is either production or staging - both of them of type: Microsoft.ClassicCompute/domainNames/deploymentSlots.

The important part is this:

  "dependsOn": [
    "[resourceId('Microsoft.ClassicCompute/domainNames/deploymentSlots', parameters('serviceName'), 'production')]"
  ]

Here's how I've done:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "deploymentLabel": {
      "type": "string"
    },
    "serviceName": {
      "type": "string"
    },
    "PackageLink": {
      "type": "securestring"
    },
    "serviceConfigurationLink": {
      "type": "securestring"
    },
    "autoscaled_resource_name": {
      "type": "string"
    },
    "metricResourceUri": {
      "type": "string"
    },
    "autoscale_resourceUri": {
      "type": "string"
    }
  },
  "variables": {
    "resourceLocation": "[resourcegroup().location]"
  },
  "resources": [
    {
      "apiVersion": "2016-04-01",
      "type": "Microsoft.ClassicCompute/domainNames",
      "name": "[parameters('serviceName')]",
      "location": "[variables('resourceLocation')]",
      "resources": [
        {
          "apiVersion": "2016-04-01",
          "name": "production",
          "type": "deploymentSlots",
          "dependsOn": [
            "[resourceId('Microsoft.ClassicCompute/domainNames', parameters('serviceName'))]"
          ],
          "properties": {
            "packageLink": {
              "uri": "[parameters('PackageLink')]"
            },
            "deploymentLabel": "[parameters('deploymentLabel')]",
            "ConfigurationLink": {
              "uri": "[parameters('serviceConfigurationLink')]"
            },
            "deploymentOptions": "StartDeployment"
          }
        }
      ]
    },
    {
      "type": "microsoft.insights/autoscalesettings",
      "name": "[parameters('autoscaled_resource_name')]",
      "apiVersion": "2014-04-01",
      "location": "eastus",
      "dependsOn": [
        "[resourceId('Microsoft.ClassicCompute/domainNames/deploymentSlots', parameters('serviceName'), 'production')]"
      ], 
      "properties": {
        "profiles": [],
        "enabled": true,
        "name": "[parameters('autoscaled_resource_name')]",
        "targetResourceUri": "[parameters('autoscale_resourceUri')]"
      }
    }
  ]
}