Setup the Auto-shutdown on VM using Bicep template
Tags: bicep, azure, iac
Published: 2022-11-23 10:30:00

In this post I would like to show you how you can setup and configure the Auto-shutdown feature in a Azure VM.
First of all, if you don't know what the Auto-shutdown feature is, I would like to tell you that you can configure your Azure VM to shutdown at a specifica day, hour and so on.
If you go on the portal and you open a VM resource, you can find, in the blade's column, the "**Auto-shutdown**" blade:

![The Auto-shutdown blade in the Azure portal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4poleorda9lylnzop5ck.png)

As you can see in the previous picture, you can configure the time (and time zone) and, if you want, you send a notification before the shutdown of the VM. 
Regarding the notification, you can send a mail (to different mail addresses using the semicolon in the textbox) or a make an Http POST request to a webhook endpoint.
In the notification email, you can find some urls to skip the shutdown, snooze for 60 minute or 120 minutes.
You can also find the same urls in the POST body. In the next JSON you can see the schema of the POST body:

```json
{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "properties": {
        "delayUrl120": {
            "type": "string"
        },
        "delayUrl60": {
            "type": "string"
        },
        "eventType": {
            "type": "string"
        },
        "guid": {
            "type": "string"
        },
        "labName": {
            "type": "string"
        },
        "owner": {
            "type": "string"
        },
        "resourceGroupName": {
            "type": "string"
        },
        "skipUrl": {
            "type": "string"
        },
        "subscriptionId": {
            "type": "string"
        },
        "text": {
            "type": "string"
        },
        "vmName": {
            "type": "string"
        },
        "vmUrl": {
            "type": "string"
        },
        "minutesUntilShutdown": {
            "type": "string"
        }
    },
    "required": [
        "skipUrl",
        "delayUrl60",
        "delayUrl120",
        "vmName",
        "guid",
        "owner",
        "eventType",
        "text",
        "subscriptionId",
        "resourceGroupName",
        "labName",
        "vmUrl",
        "minutesUntilShutdown"
    ],
    "type": "object"
}
```

You can use `skipUrl`, `delayUrl60` or `delayUrl120` to automate the behavior of your webhook and snooze or delay the shutdown.
Of course you can set the shutdown configuration after the VM creation using the portal, but often, you want to setup it during the VM creation using Bicep.

The resource you need to create using Bicep is the `Microsoft.DevTestLab/schedules` and, as you can see in the [official documentation](https://learn.microsoft.com/en-us/azure/templates/microsoft.devtestlab/schedules?pivots=deployment-language-bicep), you can configure more parameters than in the portal.

For example, the `notificationSettings` section contains the following properties:

```
notificationSettings: {
  emailRecipient: 'string'
  notificationLocale: 'string'
  status: 'string'
  timeInMinutes: int
  webhookUrl: 'string'
}
```

`emailRecipient` contains the email addresses (separated by semicolon) to wich send the notification while `webhookUrl` is the http webhook to send notification to. 
The `notificationLocale` property allows you to set the language used for the notification (the portal set it, by default, to 'en'), and `timeInMinute` property allows you to set the minutes (between 15 and 120) before shutdown when Azure sends the notification (the default value is 30).

Another difference between the Bicep configuration and the portal configuration is about when you can deallocate the VM. Using the portal, you can only choose a time during the day, while using Bicep you can choose between a specific time every day, every amount of minute for each hour or a specific time during specific week day:

```
dailyRecurrence: {
  time: 'string'
}
hourlyRecurrence: {
  minute: int
}
weeklyRecurrence: {
  time: 'string'
  weekdays: [
    'string'
  ]
}
```

For example, if you want to shutdown the VM every Monday, Thursday and Saturday at 17:00, you can use:

```
weeklyRecurrence: {
    time: '1700'
    weekdays: [
     'monday'
     'thursday'
     'saturday'
    ]
}
```

The following template allow you to set the shutdown task for a VM passing the time and email recipient as parameters (and using UTC timezone):

```
@description('Location for the deployment')
param location string = resourceGroup().location

@description('Name of the VM to setup')
param vmName string

@description('Time of the shutdown')
param shutdownTime string

@description('Email recipient')
param emailRecipient string

resource vm 'Microsoft.Compute/virtualMachines@2021-03-01' existing = {
  name: vmName
}

resource autoShutdownConfig 'Microsoft.DevTestLab/schedules@2018-09-15' = {
  name: 'shutdown-computevm-${vmName}'
  location: location
  properties: {
    status: 'Enabled'
    notificationSettings: {
      status: 'Enabled'
      timeInMinutes: 15
      notificationLocale: 'en'
      emailRecipient: emailRecipient
    }
    dailyRecurrence: {
       time: shutdownTime
    }
     timeZoneId: 'UTC'
     taskType: 'ComputeVmShutdownTask'
     targetResourceId: vm.id
  }
}
```
Remember that the name of the `Microsoft.DevTestLab/schedules` resource must be in the form `shutdown-computevm-<vmName>` (where `<vmName>` is the name of the VM you want to configure) otherwise you receive an error.