Virtual machines (VM) are used in most solutions nowadays as a [ProcessName] server, temporary machine to run tests or make demos, and sometimes even as a development machine. One of the great benefits of the cloud is that you only pay for what you use. So unlike the old server, that you keep paying for, you won pay virtual machine's CPU for when you turned off! In this post, I explain how to do it with your existing machines and also what to do with all the future one that you will be creating.
(Ce billet en aussi disponible en français.)
Already have a VM up and running, here what to do
From the Azure portal (portal.azure.com), select the Virtual Machine (VM) that you which to edit. Then look at the option panel, on the left, for
Auto-Shutdown
in the Operations section. You should have something that looks like this:At any time you can enable and disable that functionality, it won’t affect the running VM.
Now, to activate it click on the
Enabled
. Then Select the time you would like to see the VM shutdown. Be sure to select the good time zone, by default it’s UTC. You can adjust the at for UTC of change the time zone, both options are valid.Now you could decide to enable the notification. That could be useful if you may want to postpone the shutdown for one or two hours, or integrate the shutdown to another process like backup, cleaning…
To activate the notification option just click on the enabled, and enter the email address. If you want to attach the shutdown to a Logic App or an Azure Functions use the webhook. Here an example of notification email, see the Postpone options link.
What if you have many VMs running
Let's say you have already twenty (or more) VMs running, you could have executed a PowerShell script like:
$myMVsName = @("franDev1", "frankBuildserver", "demo_sales2018")
For ($i=0; $i -lt $myMVsName.Length; $i++) {
Set-AzureRmDtlAutoShutdownPolicy $myMVsName[$i]
[...]
}
Update - 2018-03-14
Multiple VMs that already exist, no problem
Obviously, if you have multiple virtual machines that already exist it is not very efficient to change their configuration one by one via the portal. Here is a small script to change the configuration of a large amount of VM in one shot.
'# Login-AzureRmAccount
$Subscription = Get-AzureRmSubscription -SubscriptionName 'YOUR_SUBSCRIPTION_NAME'
Select-AzureRmSubscription -Subscription $Subscription.Id
$selectedVMs = Get-Azurermvm -ResourceGroupName cloud5mins
foreach($vm in $selectedVMs)
{
$ResourceGroup = $vm.ResourceGroupName
$vmName = $vm.Name
$ScheduledShutdownResourceId = "/subscriptions/$Subscription/resourceGroups/$ResourceGroup/providers/microsoft.devtestlab/schedules/shutdown-computevm-$vmName"
$Properties = @{}
$Properties.Add('status', 'Enabled')
$Properties.Add('targetResourceId', $vm.Id)
$Properties.Add('taskType', 'ComputeVmShutdownTask')
$Properties.Add('dailyRecurrence', @{'time'= 2100})
$Properties.Add('timeZoneId', 'Eastern Standard Time')
$Properties.Add('notificationSettings', @{status='Disabled'; timeInMinutes=60})
New-AzureRmResource -Location $vm.Location -ResourceId $ScheduledShutdownResourceId -Properties $Properties -Force
}
The variable
$selectedVMs
contains all the VMS that we wish to edit. In this sample, I only get VMs contained in the RessourceGroup cloud5mins, but there are no limits to what you can do. You could select all VMs with a specific OS, tags, location, name, etc.The variable $ScheduledShutdownResourceId will be the identity for the configuration for the auto-shutdown we wish to inject. Note that the provider is
microsoft.devtestlab
.Next, we create a collection of properties in
$Properties
. status
the one that active or deactivate the auto-shutdonw. targetResourceId
is the resourceID of the VM we target.The only things left is to specify the time and timezone.
If you prefer, I also have a video version that explains all the steps.
How to shutdown automatically all your existing VMs
End Update
Let's create a VM with the auto-shutdown pre-configured with ARM
Of course, a much more efficient way to set the auto-shutdown is at the creation time by adding a new resource of type
Microsoft.DevTestLab/schedules
to your template. This option was previously only accessible for DevTestLab, but recently was made available to any VMs.Here an example of the variables that could be added to your template.
"variables": {
"ShutdowTime": "21:00",
"TimeZone": "UTC",
"emailRecipient": "frank@frankysnotes.com",
"notificationLocale": "en",
"timeInMinutes": 30
}
And here an example of
Microsoft.DevTestLab/schedules
resource. One of these should be added for every VM you wish to auto-shutdown. Because your script is for one server, however, only one instance is required.{
"name": "[concat('autoshutdown-', variables('vmName'))]",
"type": "Microsoft.DevTestLab/schedules",
"apiVersion": "2017-04-26-preview",
"location": "[resourceGroup().location]",
"properties": {
"status": "Enabled",
"taskType": "ComputeVmShutdownTask",
"dailyRecurrence": {
"time": "[variables('ShutdowTime')]"
},
"timeZoneId": "[variables('TimeZone')]",
"targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', variables('vmName'))]",
"notificationSettings": {
"status": "Enabled",
"emailRecipient": "[variables('emailRecipient')]",
"notificationLocale": "[variables('notificationLocale')]",
"timeInMinutes": "[variables('timeInMinutes')]"
}
},
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
]
}