A few days ago I was thinking about the best way to power off and on all the virtual machines I have in my subscription in order to save unnecessary expenses. This can also be a very common cloud scenario for development, staging, QA, etc.: If I know the time where I are making use of certain machines Why not turn them off when not needed and thus save costs?
The service planning for this type of automated tasks within the Microsoft Azure platform is known as Automation (still in preview). Basically what allows us to create PowerShell scripts called runbooks to help us to create automatic tasks. In this post I would like to show how to manage the state of our virtual machines on a scheduled basis.
Create and upload a certificate to the Azure portal
The first thing to do is upload a certificate to provide access to the runbooks. For this demo just create a self-signed certificate, using the tool makecert.exe:
makecert.exe -n "CN=AutomationCert" -pe -ss My -sr CurrentUser -r -a sha1 -sy 24 -sky exchange -len 2048
We need to export it with and without the private password (selecting the certificate in Personal > Certificates and right click on it – All Tasks > Export):
In the section Settings > MANAGEMENT CERTIFICATES upload the cer file:
Create an Azure Automation service
Creating an Azure Automation service is simple. The first thing you need to check is you have access to the preview service through Preview features page:
Within the portal pick the AUTOMATION section and click on CREATE AN ACCOUNT AUTOMATION:
You need to choose an account name and a location. During the preview you can only create the service in East US:
This will take just a few seconds. The new account has 3 different sections:
- DASHBOARD: shows the status of the account, number of jobs, number of runbooks, connections, variables, and so on.
- RUNBOOKS: it’s used to manage the list of procedures or runbooks.
- ASSETS: allows us to add different types of elements, such as certificates, connections, variables, etc.
Associate the certificate with Automation
If you remember the first step, we had to create a certificate and export it with and without the private key. The .cer I uploaded to the portal (Settings section) and now we need to bind the certificate with private key with our new Automation Azure account. To do this, select ASSETS tab and click on the SETTING ADD option from the menu below. In the new dialog box, select ADD CREDENTIAL in order to associate the certificate:
When we create a credential we have two possibilities: Windows Powershell Credential and Certificate. The first one allows us to use Azure Active Directory to connect to Azure Automation. In this example we will use the second option based on certificates.
Create a Connection
Once we have uploaded the certificate we need to use a new element called Connection. This element is going to allow us to link the certificate, which corresponds to the certificate that we uploaded into the Settings section, and the subscription which it belongs. To do this, we use SETTING ADD again, but this time choose the ADD CONNECTION:
In the first step of the wizard is very important to use the name as the name of the subscription to which is associated, since otherwise it won’t work:
Finally, we put the name of the certificate that added to our Automation Azure account and the subscription ID:
Runbooks
Once you have created and configured the new features we are ready to build or import runbooks. A runbook is basically a Powershell script which we can launch one or more actions. Ideally, each module should be as simple and concrete as possible, so that several of them can be reused within other runbooks. In this example we’ll create 3 scripts: one that connects to the subscription, other to stop virtual machines and the last one to start them.
Runbook #1: Connection with the subscription
Before starting to create our own scripts is important to know that there is a place called Script Center , where the product team itself and other developers share their own runbooks. For this example I have used one called Connect to an Azure Subscription using Certificates. When you download or create on premise a runbook the only action we perform is to import the file into the account. To do this, we need to access the runbooks section and use the IMPORT option from the menu below:
If you click on the EDIT Runbook option or select the new item in the list you can access the script and even testing before publishing. In this case, click on the PUBLISH option from the menu below:
Runbook #2: Turning off machines
For the runbook which turns the virtual machines off we’re going to create it from scratch. To do this, in the runbooks section click on NEW > APP SERVICES > AUTOMATION PREVIEW > Runbook > QUICK CREATE and name it Stop-VMs:
Once the new element is created it will appear in the list with Connect-Azure. We click on it and select the AUTHOR tab. Being a new script, we’ll find the following structure:
workflow Stop-VMs { }
All runbooks must be encapsulated within a workflow with the name you have chosen. In this script we will use the previous module, Connect-Azure, to access to the elements of the subscription on which we want to operate. Once you have access, recover all existing virtual machines and use the Stop-AzureVM command for each one. The script code would look like this:
workflow Stop-VMs { #Connect-Azure -AzureConnectionName $subscriptionName = "Internal Consumption" Connect-Azure -AzureConnectionName $subscriptionName Select-AzureSubscription $subscriptionName # Get VMs $VMs = Get-AzureVM $VerbosePreference = "Continue" if( $VMs.Count -gt 0 ){ Foreach($vm in $VMs){ $vmName = $vm.Name Write-Verbose "Stopping $vmName" Stop-AzureVM -ServiceName $vm.ServiceName -Name $vm.Name -Force } "All machines are now stopped!" } else{ "You don't have machines in this subscription" } }
Before publishing the above code, we can test it and see the result through the Output section, using the TEST button on the bottom menu:
Runbook #3: Turning on virtual machines
This script is exactly the same as above except the command to use, since in this case will use Start-AzureVM:
workflow Start-VMs { #Connect-Azure -AzureConnectionName $subscriptionName = "Internal Consumption" Connect-Azure -AzureConnectionName $subscriptionName Select-AzureSubscription $subscriptionName # Get VMs $VMs = Get-AzureVM if( $VMs.Count -gt 0 ){ Foreach($vm in $VMs){ $vmName = $vm.Name Write-Verbose "Starting $vmName" Start-AzureVM -ServiceName $vm.ServiceName -Name $vm.Name } "All machines are now started!" } else{ "You don't have machines in this subscription" } }
Once we have taken the necessary tests we have to publish the Stop-VMs and Start-VMs runbooks.
Schedule runbooks
Now we can create a schedule for turning on and off our virtual machines. For Stop-VMs, We access the runbook, select the Schedule tab and click on Link to a new schedule:
All we need is to choose a name and optionally a description:
Finally we choose when and how often you want to be launched:
For starting the machines would be exactly the same but in my case, changing the execution time at 8:00.
I hope this helps.
Happy weekend!