Skip to content

Take Azure resources offline using a simple Azure function. Works with VMs and Container Instances (ACI)

Notifications You must be signed in to change notification settings

alanta/azure_scheduler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Azure Scheduler

Automagically Start/Stop Azure Virtual Machines (VM) and Azure Container Instances (ACI) using Azure Functions with a timer trigger.

This is intended to reduce costs for resources that are only used for development and testing.

One function starts all deallocated (stopped) VMs at 7:00 AM. The other function stops all VMs at 22:00. Same thing is supported for ACIs. You can enable the functions you need. VMs tagged with powerstate=alwayson are ignored. Additional filtering can be done by setting tags on resources.

Requirements

You'll need Azure CLI and a development environment (VS Code or VS 2019) with Azure Functions support installed. If you want to try it out on your machine, please also install the Azure Storage Emulator.

Local testing

You can run this Function App in the function app emulator using dev storage. Check the local.settings.sample.json file for details on how to set it up.

Installation

In a nutshell, this is what you need to do to get this running for an Azure Subscription:

  • Create a service account with appropriate rights in the Azure AD (AAD) that controls the subscription
  • Deploy the Function App ( you can right-click deploy from VisualStudio, I won't tell a soul ;) ) or run it on a develepment machine from VS.
  • Adjust the App Settings with the Client ID, Client Secret and AAD Tenant ID collected in the first step
  • Ensure the Function App has the correct time zone. For example for West Europe, set WEBSITE_TIME_ZONE to W. Europe Standard Time.

Note that:

  • The function app does NOT need to run within the subscription where the VMs and ACIs are running.
  • ACIs lose all state after stopping them, you'll have to setup persistance if you need it (for example an Azure File Share)
  • This was tested with small numbers of ACIs and VMs (Up to 5)

Assigning permissions with PowerShell

There's a poweshell script in the deploy folder: create-service-principal.ps1. It'll ask you to login and provide details. It used the VM manager role to enable the functions to start and stop VMs. There is no such role for ACIs, so the ACI-manager-role.json file contains an AAD role definition for such a role.

You'll need lots of rights in AAD to run the script and perform all the AAD actions. If you need to get an IT person involved in your org, be sure to send them both files from the deploy folder.

Manually assigning permissions to a service account

First login to azure (if you haven't already). Please ensure you have the right subscription selected.

  az login

Then add an App to the Azure AD. Make sure to come up with a better password. This will be the clientSecret for the Function app.

  az ad app create --display-name vm-scheduler --password myReallyGoodPassword --identifier-uris vm-scheduler

Note the applicationId in the output. It's a GUID and you'll need it in the next step and to configure the Azure function. Next, create a service principal in the AAD.

  az ad sp create --id <applicationId>

Note the objectId in the output. It's a GUID again and you need it to assign the correct role to the service principal:

  az role assignment create --assignee-object-id <objectId> --role "Virtual Machine Contributor"

Create a custom role for ACI management. Make sure you set the correct subscription id in that file

 az role definition create --role-definition ACI-manager-role.json

Assign the custom role:

  az role assignment create --assignee-object-id <objectId> --role "Container Instance Manager"

Finally, get the AAD tenant id:

  az account list --query "[].[name, tenantId]"

Now, deploy this Azure Functions App and configure the following app settings using the data collected above:

  • ClientId
  • ClientSecret
  • TenantId

Finally, ensure the WEBSITE_TIME_ZONE is set to W. Europe Standard Time.

Controlling what resources to schedule

Any resource with the tag powerstate=alwayson will be skipped, both for starting and stopping.

You can control what resources to consider using the Tags app setting. For example:

{ "team":"development" }

Will only consider resources tagged by the development team.

Futher reading

License

This repo is available under the MIT license, so go ahead and fork / clone / do whatever you want.

Please, don't call me when you accidentally shut down Prod resources...

Contributing

Please send a pull request if you have improvements. Please keep PRs small and explain what you're fixing or adding. I'll do my best to follow up asap but I have other stuff to do as well...

About

Take Azure resources offline using a simple Azure function. Works with VMs and Container Instances (ACI)

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published