Azure Compute Cost savings
Tags: azure, azureapril, cost, cloud
Published: 2022-07-28 09:36:51

## Start/Stop VMs and Scale-sets during off-hours or Non-working 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 parameterized 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
Optimize virtual machine spend by resizing or shutting down under-utilized instances Although certain application scenarios can result in low utilization 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% utilization 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 analyzing the CPU utilization 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 ?

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1ajm5o5pm9u7jtm3ts9y.png)

---

### 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:
- main
always: true
name: $(Build.BuildId)_STOP_VMs  # build numbering format
parameters:
- name: Action
  displayName: Action
  type: string
  default: Stop
values:
- Start
- Stop
- Restart
trigger:
- main
pool:
vmImage: windows-latest
steps:
- task: AzureVMStartStop@1
  inputs:
   ResourceGroupName: $(ResourceGroupName)
   Action: 'Stop'
   ConnectedServiceName: 'sc-cbsed-lab'
   Simulate: false
   vmsExcludedFromAction: '$(vmsExcludedFromAction)'
  displayName: 'VM - Stop Schedule'
```
Variables for pipeline

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hng9jnobw7zxlunbq93b.png)
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

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gj9cddocb5fctbg6rivz.gif)

#### STAR VMs schedule

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wy77jj2ww57u3l3z0jn4.gif)