Using Azure Automation to run VMs during office hours only
There is an updated version of this post. Please read the new version, which guides you through similar steps using the latest and greatest Azure Portal and Azure Automation features:
Endjin have been using Microsoft Azure to host our ALM infrastructure for some time. This includes TeamCity, YouTrack and UpSource (all from JetBrains).
TeamCity and YouTrack are running on an A2 instance each (£67.27). UpSource is running on an A3 instance (£134.54). Our current total cost is £269.08 per month (as of Jan 2015).
We'd like to ensure usage costs are minimised by only running servers when they are going to be needed, generally in normal office hours. This post shows how to schedule starting and stopping of virtual machines in Azure. The cost saving made is detailed at the end!
Azure Automation
Azure Automation was released to General Availability in October 2014. This feature allows you to automate many common aspects of using the Azure platform, integrating with other features such as web sites, cloud services and virtual machines.
To use this feature, you will need to create an automation account, create Runbooks which contain PowerShell Workflows with the functionality you want to implement (e.g. starting and stopping a virtual machine or cloud service), and link those Runbooks to Schedules so that they get automatically run at pre-defined times.
A note on Daylight Savings Time
EDIT 02/04/2015: Recently I discovered that the schedules are in UTC only and do not take into account local time zone shifts, e.g. for Daylight Savings Time. See this new post for more details: /2015/04/azure-automation-scheduler-and-daylight-saving-time/
Step-by-step guide to only running VMs during office hours
Create an Automation Account in the Azure Management portal. This has it's own section in the and is where you define PowerShell Workflow Runbooks and Schedules for those Runbooks.
If you have no automation accounts set up, it prompts you to create a new one.
The account will be in the "Creating" status for a short while, before changing to "Ready".
First a number of Assets related to the Automation account need to be created. These are essentially variables that can be used in your PowerShell Runbooks.
Click on the automation account just created, then changed to the Assets tab. Click the "Add Setting" button at the bottom of the screen.
Choose "Add Credential".
Choose "Certificate" for the Credential Type and enter a name.
Browse to a suitable certificate .pfx file, and enter the certificate password. You'll need to make sure this certificate (the .cer file) is uploaded to the subscriptions management certificates. This certificate is what will be used in the PowerShell script to authenticate.
(You can find out how to create an appropriate certificate file in Alice's blog over here.)
Next we need to create string variable assets for CertificateName, SubscriptionId and SubscriptionName. Click the Add Setting button again but choose Add Variable this time. Set the Variable Type to String and enter a name (CertificateName etc), then on the next screen enter a Value (the variable names should be self explanatory as to what to put as the value in your specific case).
This is what your Assets page should look like at this stage:
Create a new Runbook by clicking on the New button (bottom left of the portal), and choosing "App Services > Automation > Runbook > Quick Create".
Choose a Runbook name, relevant to the what it will do e.g. "Start-VM". Select the Automation account that was just made, then hit "Create".
Once it has finished creating, change to the Runbooks tab in the Automation account, and click on the Runbook.
Change to the Author tab, and click Edit.
Paste in the following PowerShell Workflow script. It checks if it is a weekend and exits early, otherwise it sets up the Azure subscription for the current PowerShell session, then Starts a VM based on input parameters for the cloud service name and VM name. These parameters are set when you later define a Schedule for this Runbook.
The script checks for a weekend because when creating a Schedule, you can select One Time, Hourly or Daily. Using Daily would run this script every day, even at weekends, but for maximum cost saving we only want it to run during the week. Hopefully the built in scheduling will be improved to allow this in the future.
You can test the Runbook once the Draft is complete by using the Test button. It will ask you to put in the parameters the script needs, which in the case of our script are a cloud service and VM name.
Once you are happy with the script, and it is doing what you want/expect, Publish the Runbook.
Change to the Schedule tab and select the "Link" button, then "Link to a New Schedule". Give the schedule an appropriate name, e.g. Start-MyVm123.
Define the schedule by setting the Type to Daily, and the Start Time to a time appropriate for the VM, e.g. start it at 08:00. The time is in your current time zone, i.e. whatever your computer is using.
Follow the same set of instructions to create a Stop-VM Runbook, but change values where appropriate e.g. call it Stop-VM and changing the schedule time.
The script is also different, but very similar. The command changes to stop a VM, and a Force parameter is added (so that the VM is stopped even if it is the last one running in the Cloud Service).
Test, publish and set up a schedule in the same way as before.
Wrapping up
After a few days of running the setup we just went through, the automation dashboard looks like this:
You can see the individual jobs that have run as well as the total job run time. You get 500 minutes for free, so it looks like we'll be able to run the current setup entirely for free. After the free 500 minutes have been used, it currently costs £0.0013 per minute, so the 78 minutes used so far would have cost about 10p.
Wrapping up
Scheduling when VMs should run is applicable any time you only need them during certain hours. Running a VM for a third of a day saves two thirds of the cost, so it's a no-brainer!
Applying this to endjin's ALM VM infrastructure and only running the VMs from 08:00 to 19:00 on week days, lowers daily usage from 24 hours to 11 hours. In January 2015 there are 26 working days, so our new usage for each VM is 286 hours compared to 744 hours.
Therefore the previous total cost was £269.08 and the new total cost is £103.44. Roughly a 62% saving which is fantastic! We will be rolling this same process out to other parts of our infrastructure where possible, and to our clients infrastructure.