Save costs without manual effort
Managing cloud costs efficiently is crucial. One of the biggest cost drivers in cloud is idle Virtual Machines (VMs) that keep running even when they’re not needed.
Instead of manually stopping these VMs, you can use Azure Automation and Azure Monitor Alerts to automatically shut down any VM with low CPU usage.
This guide walks you through setting up Azure’s built-in automation to stop idle VMs—and how to apply it to multiple VMs, resource groups, or entire subscriptions.
Step 1: Create an Azure Automation Account
Azure Automation Accounts allow you to execute built-in Runbooks, which are pre-configured scripts that automate common tasks like stopping a VM.
How to create an Automation Account
1. Go to the Azure Portal and select Create a Resource.
2. Search for Automation Account and click Create.
3. Fill in the Basics:
-
- Subscription: Choose your Azure subscription.
- Resource Group: Select an existing one or create a new one.
- Automation Account Name: Choose a unique name (e.g., automationaccount01).
- Region: Pick the same region as your VMs.
4. Under Advanced, enable System Assigned Managed Identity.
5. Under Networking, choose Public Access (or configure private access if needed).
6. Click Review + Create, then Create once validation passes.
Step 2: Create a metric alert to detect idle VMs
We need an Azure Monitor Alert that detects low CPU usage and triggers automation to stop the VM.
How to create a metric alert rule (See the reference in the Microsoft Docs here)
Pro tip! See also how to create an activity log, service health or resource health alert rule here.
1. Navigate to your Virtual Machine in the Azure Portal.
2. Under Monitoring, go to Alerts → Create custom alert rule.
3. Under the Condition tab:
- Choose Percentage CPU as the signal.
- Select Aggregation type: Average.
- Set Threshold: Less than 2%.
- Set Check every: 15 minutes and Lookback period: 15 minutes.
4. Click Next: Actions to define what happens when the alert is triggered.
Step 3: Create an action group
An action group defines what action to take when the alert is triggered. We have to create an action group before going ahead.
How to create an action group
1. Click Create Action Group in the Alert Rule setup.
2. Configure:
- Subscription: Select your subscription.
- Resource Group: Choose the one used earlier.
- Action Group Name: Name it (e.g., action01).
3. In the Notifications tab, choose between:
- Send an email to specific roles:
- Send a combination of email, sms, mobile notification and voice messages:
Pro tip: Slack user? See here how to alert to a slack channel.
4. In the Actions tab:
- Choose Automation Runbook.
- Click Edit and select:
- Runbook Name: Stop VM (built-in Runbook).
- Subscription: Select your subscription.
- Automation Account: Choose automationaccount01.
5. Click OK, then Review + Create.
Step 4: Continue the creation of the metric alert rule
Step 5: Validate that the alert fires when the VM is idle
After setting up the automation, Azure monitors the VM's CPU usage and triggers the alert when the usage is below 2% for 15 minutes.
What happens next?
1. After 15 minutes of low CPU usage, the alert fires, indicating that the VM meets the idle condition.
2. You can verify this by navigating to Monitoring → Alerts, where you will see:
- Total Alerts: The count of alerts triggered.
- Alert Name: The Stop VM alert.
- Severity: Marked as Informational.
- Alert Condition: Fired (indicating the rule was met).
Example of a Triggered Alert:
3. The following email will be sent to the people with Contributor role (in this example where this was the choice in the step 3.3):
4. The VM will be deallocated:
Step 6: Expanding the scope – apply to multiple VMs or entire Subscriptions
By default, the alert was created for a single VM (vm01), but you can apply it to an entire subscription, a resource group, or multiple VMs.
How to modify the scope
1. Go to Azure Monitor → Alerts.
2. Click on the Alert Rules, then select the Stop VM:
3. Click Edit
4. In the Scope section, click Edit Scope.
5. Select:
- A specific VM (default setting).
- A resource group (to apply the rule to all VMs within a group).
- An entire subscription (to monitor and stop all idle VMs in your Azure environment).
6. Click Apply and Save
This flexibility allows you to scale the automation across your environment, making it a powerful cost-saving strategy.
By following this simple setup, you can:
- Reduce cloud costs by shutting down unused VMs.
- Eliminate manual effort with fully automated alerts.
- Leverage built-in Azure automation without writing custom scripts.
- Expand the scope to monitor multiple VMs, resource groups, or full subscriptions.
Bonus: Alternative methods for automating VM shutdown & startup
While the above solution works great for stopping idle VMs based on CPU usage, you might need other automation methods, including ways to start VMs automatically when needed.
Option 1: Built-in Auto-shutdown Feature
Azure provides a simple Auto-shutdown feature that allows you to schedule daily shutdown times for VMs.
Best for:
- Shutting down VMs at a fixed time every day (e.g., after work hours).
- Quick setup for cost savings with minimal configuration.
- Non-production workloads, test environments, or predictable workloads.
How to Enable Auto-shutdown
- Go to your Virtual Machine in the Azure Portal.
- In the left menu, select Operations → Auto-shutdown.
- Set:
- Scheduled Time: Choose when the VM should shut down daily.
- Time Zone: Select your preferred time zone.
- Notification Settings (optional): Send reminders before shutdown.
- Click Save.
Option 2: Azure Functions for Start/Stop VMs
Azure Functions provide serverless automation to start and stop VMs using custom triggers, such as HTTP requests, schedules, or alerts.
Best for:
- Start/Stop VMs using advanced triggers (e.g., business hours, user activity, API calls).
- Automating large-scale VM operations without running a dedicated Automation Account.
- Flexible execution based on specific business rules.
How It Works:
- Create an Azure Function App in the Azure Portal.
- Use the Start/Stop VMs function to trigger shutdowns at specific times or conditions.
- Configure Triggers such as:
- Time-based schedules (e.g., start at 8 AM, stop at 8 PM).
- HTTP requests (e.g., a web app can trigger a start or stop request).
- Event-driven triggers (e.g., only start VMs when a specific process runs).
Which method should you choose?
Feature | Azure Monitor Alerts & Automation | Built-in Auto-shutdown | Azure Functions (Start/Stop VMs) |
Shuts down dynamically based on usage | ✅ Yes | ❌ No (fixed time only) | ✅ Yes (custom triggers) |
Can apply to multiple VMs, resource groups, or subscriptions | ✅ Yes | ❌ No (fixed time only) | ✅ Yes |
Requires additional setup | ✅ Yes | ✅ No (simple toggle) | ✅ Yes (serverless setup) |
Best for unpredictable workloads | ✅ Yes | ❌ No | ✅ Yes |
Best for fixed schedules | ❌ No | ✅ Yes | ✅ Yes |
Can start VMs automatically | ❌ No | ❌ No | ✅ Yes |
Conclusion
- Use Azure Monitor Alerts & Automation if your VMs have unpredictable usage patterns and you need dynamic cost savings.
- Use Auto-shutdown if you simply need to shut down VMs at a fixed time every day without worrying about CPU usage.
- Use Azure Functions if you need serverless automation with custom triggers such as time schedules, HTTP requests, or event-based actions, including automatically starting VMs.
No matter which method you choose, automating VM shutdowns helps you control cloud costs and optimize resources efficiently! 🚀
Updated Feb 11, 2025
Version 7.0rmmartins
Microsoft
Joined June 01, 2017
Startups at Microsoft
Follow this blog board to get notified when there's new activity