Azure Compute Cost savings
Start/Stop VMs and Scale-sets during off-hours
The Start/Stop VMs or VM Scalesets during off-hours (for development, test, lab env) feature start or stops enabled Azure VMs and VM Scaliest (VMSS).
It is nothing new or something similar to a out of the box idea.
We all are already practising it with Runbook (Automation account), Azure provided feature within VM scope or via pipelines.
But I have experience only complexity to make it more flexible as parameterised that can be changed anytime and whenever required.
For example if my RG consist of 14 VMs but I just want to enable STOP schedule for 12 VMs, how I can exclude the rest of 2 from the schedule ?
Every time change in schedule requires to go and change the parameters or schedules for the automation in Runbooks or Azure internal feature.
How to set the same schedule for 50+ VMs across 7 subscription and 15 different RGs, with a single pipeline and automation schedule.
Etc etc…
What if we have a single extension for Azure DevOps or GitHub that take care of all such small cosmetics changes to keep the Start/Stop schedule more flexible.
Extension link for Azure VM(s) Start/Stop schedule Link
Extension link for Azure VMSS (Scale set) Start/Stop Link
Introducing Azure VM Start/Stop extension
It starts or stops machines on user-defined schedules. The feature can be enabled on Azure Resource Manager VMs for most scenarios.
Microsoft best practice (recommendation) for cost saving
Optimise virtual machine spend by resizing or shutting down under-utilised instances Although certain application scenarios can result in low utilisation by design, you can often save money by scheduling shutdown of your virtual machines.
The recommended actions are shut down or resize, specific to the resource being evaluated.
The advanced evaluation model in Advisor considers shutting down virtual machines when all of these statements are true:
The current load doesn’t go above 80% utilisation for workloads that aren’t user facing. The load doesn’t go above 40% for user-facing workloads. Here, Advisor determines the type of workload by analysing the CPU utilisation characteristics of the workload.
Also, extension supports Startup of the VMs which can be schedules as the same way like Shut down
Automate schedule with Azure DevOps pipeline using AzureVMStart/Stop task. It can reduce the overhead of maintaining / modifying individual Virtual Machine schedules every now and then from Portal or AzCLI. By scheduling the AzDO pipeline with this extension we can Shutdown / Startup computes based on requirement.
Extension also provides flexibility to manage VMs based on below possible condition:
- Run for all VMs within the listed ResourceGroup(s), using the resource group field, with exclude list of VMs option (if required) for exclusion of VMs in the RG.
- Run for all VMs listed in VM List (applicable for single RG only)
- If no arguments (neither ResourceGroup nor VM List) is provided, it will run for all the RGs and VMs within the scope of Service Connection with exclude list of VMs option (if required)
Sample evaluation of cost saving within a week
How much could you save shutting down Non-Production VMs ?

Pipeline and execution example
Running a Start schedule for the Azure VMs within multiple RGs, including exclusion on some VMs.
schedules:- cron: "0 18, * * *" #Run pipeline to STOP the VMs at 06PM displayName: Daily turnoff schedule branches:include:- mainalways: truename: $(Build.BuildId)_STOP_VMs # build numbering formatparameters:- name: Action displayName: Action type: string default: Stopvalues:- Start- Stop- Restarttrigger:- mainpool:vmImage: windows-lateststeps:- task: AzureVMStartStop@1 inputs: ResourceGroupName: $(ResourceGroupName) Action: 'Stop' ConnectedServiceName: 'sc-cbsed-lab' Simulate: false vmsExcludedFromAction: '$(vmsExcludedFromAction)' displayName: 'VM - Stop Schedule'
Variables for pipeline

ResourceGroupName: list of RGs, for which cost saving accross VMs is running. In my case all the 3 RGs are from lower environment and I don't want them running after evening 1800, so I created a single pipeline for all of them.
vmsExcludedFromAction: list of VMs for which you don't want to take any action. Which means that they will be continue running.
GIF for reference
STOP VMs schedule

STAR VMs schedule
