Tuesday, July 4, 2017

Adding Azure VM auto shutdown via ARM template

This post is intended to show how can we use a simple Azure feature via ARM template. The feature is 'scheduled shutdown of virtual machines'. It is useful when we play with machines. Seriously, never shutdown production machines unless there is a real business scenario such as your business is strictly running during a particular time and you don't want to keep the system open for hackers to play with. eg: day trading.

Before we go ahead, this article doesn't promote the use of virtual machines. Virtual machines which is in cloud terms 'Infrastructure as a Service' is the last to consider when we design for cloud. One, it is costly. It is not truly pay as use mode. Virtual machines have to run regardless there is workload or not. We have to pay for all these idle times. Also virtual machines take more time to scale out as the boot time is more. By the time, the spike in requests/workload might be over. But there would be scenarios where we have to use VMs. When we deal with older systems without enough budget to rewrite, we have to go for VMs. Also when our corporate IT is not believing in PaaS because of security, VM is the option.

Now coming to the point. Auto shutdown can easily be done from portal as shown in the announcement. There are some sites out there which explains how to setup auto shut down via ARM. This is my experience with the same.

The schema of ARM template can be found in the below link. It is the starting point.

Sample ARM template to shutdown

Below goes JSON to set auto shutdown to a VM
      "apiVersion": "2017-04-26-preview",
      "type": "Microsoft.DevTestLab/schedules",
      "name": "shutdown-computevm-nanotest",
      "location": "[resourceGroup().location]",
      "properties": {
        "status": "Disabled",
        "timeZoneId": "Pacific Standard Time",
        "taskType": "ComputeVmShutdownTask",
        "notificationSettings": {
          "status": "Disabled",
          "timeInMinutes": 15,
          "webhookUrl": "http://joymononline.in"
        "targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', parameters('nanoName'))]",
        "dailyRecurrence": {
          "time": "1600"
        //"hourlyRecurrence": {
        //  "minute": "1"
We can see webHookUrl is given to a dummy url and hourlyRecurrence is commented. Lets see the details.

Where to add this JSON fragment in ARM template

This is not a sub resource of VM mode. Rather this needs to be directly added into top level resources node in ARM template.

Can we shutdown VM hourly

If we are using an Azure subscription which credits 50$ per month, it is not good to set auto shutdown daily one. As soon as we are done with the VM, it should be shutdown. Even if we forget, it has to shutdown. But currently the feature doesn't support hourly recurrence though the schema supports. That is why it is commented.

Can we omit daily recurrence value?

Below is the error which will pop when we don't give value for daily recurrence. Notice that this error won't be displayed during validation. But throws when we execute ARM template with ARM manager in Azure.

17:48:25 - [ERROR] Microsoft.DevTestLab/schedules 'autoShutDownPolicy' failed with message '{
17:48:25 - [ERROR]   "error": {
17:48:25 - [ERROR]     "code": "MissingRequiredProperty",
17:48:25 - [ERROR]     "message": "Missing required property DailyRecurrence."
17:48:25 - [ERROR]   }
17:48:25 - [ERROR] }'

What is big deal with the name

Below is the error receive when a pet name given to schedule. Again notice that validation don't show but execution throws. In other words its runtime error.

17:55:49 - [ERROR] New-AzureRmResourceGroupDeployment : 5:55:49 PM - Resource
17:55:49 - [ERROR] Microsoft.DevTestLab/schedules 'autoShutDownPolicy' failed with message '{
17:55:49 - [ERROR]   "error": {
17:55:49 - [ERROR]     "code": "InvalidScheduleId",
17:55:49 - [ERROR]     "message": "The schedule should be created in subscription
17:55:49 - [ERROR] 11111111-1111-1111-8888-####ffffeeee, resource group <Storage>
17:55:49 - [ERROR] and with name shutdown-computevm-nanotest."
17:55:49 - [ERROR]   }

The nanotest is the VM name.

APIVersion and region

The sample template above shows apiVersion of schedules '2017-04-26-preview'. It is region specific. Not all regions supporting all API versions. This is again an runtime error. Validation will pass.

There is a URL which tells what are available in what region. There are some programmatic techniques to find out the API version and other details.

The good part is that the error is descriptive, telling us what API version to use. That is really useful.

Rolling back ARM deployment

As mentioned above some errors happen when we deploy/execute ARM template. If the auto shutdown setup fails, does it revert the VM deployment? As software engineers we assume that it will,  same as MSI deployment or there will be some flags to deploy ARM in transaction. But it never roll backs. It is our pain to clean up what is left after a partially failed ARM deployment. Feature request below. It is there for the last one year.


The suggestion is to make our ARM template deployment idempotent. Simply saying even if we redeploy, it should not cause any harm. It should run many times by producing same result as first run. Simple if we are just setting up architecture via ARM. Gets complex if there are custom scripts running as part of deployment.

Debug ARM template

For a simple feature to get working, we may encounter these many errors. As developers we might have started thinking how to debug the ARM templates. In general the error messages are meaningful, if we are familiar with Azure terms. Debugging ARM template itself has scope for separate post. Again, it gets complicated when ARM template uses custom scripts. Below are 2 links talking about troubleshooting ARM template deployments.

1 comment:

viji said...

you are posting a good information for people and keep maintain and give more update too.
seo company in india