Automating Azure VM with Runbooks and Webhooks

Today, I run all of my Windows-based production and development systems in Azure or Office 365. For development environments, you want to have these running on-demand to optimize costs and, for those who can, make the mot of the credits included in your MSDN subscription.

I did spend a lot of money this year when I forgot to turn off my dev farm over a weekend, so I wrote a PowerShell script to automate the process. You can run this locally using Azure Powershell but I want it completely automated and want Azure itself to run and schedule it.

Create an Automation  Account

Azure provides the automation service straight from the portal. You pay for the storage that is used for the service, which really is negligible. To create the service:

  1. Open the Azure Portal
  2. Click the New link on the left hand side
  3. In “Search the marketplace”, enter Automation and press enter
  4. Click the item named Automation and click Create
  5. In the next pane, enter the name for your automation account and click Create
  6. You will be redirected to the dashboard and the automation service will be created

2015-12-04_14-44-21

Create a new Azure Active Directory user to manage an Azure subscription

  1. Log in to the Azure classic portal as a service administrator for the Azure subscription you want to manage.
  2. Select Active Directory
  3. Select the directory name that is associated with your Azure subscription. If necessary, you can change this association from Settings > Subscriptions > Edit Directory.
  4. Create a new Active Directory user. Select New user in your organization for the Type of user and do not Enable Multi-Factor Authentication.
  5. Note the user’s full name and temporary password.
  6. Select Settings > Administrators > Add.
  7. Type the full user name of the user that you created.
  8. Select the subscription that you want the user to manage.
  9. Log out of Azure and then log back in with the account you just created. You will be prompted to change the user’s password.

Create a new Azure Automation Credential alias

The PowerShell commands needs credentials to logon to the system. Instead of storing passwords in the PowerShell file, we will use Azure Automation Assets to create a specific PowerShell credential. To do this, we

  1. Click the Assets tile
  2. Click Credentials
  3. Click Add a credential
  4. Here, add a pseudo-name for the account, such as “Azure Automation Creds”, enter the actual username as created in Azure Active Directory previously and the new password.
  5. Click Create.

2015-12-04_14-47-14

PowerShell Start/Stop Script

We will now publish our PowerShell script in the automation account. First, create the Runbook by

  1. From the automation account pane, click the Runbooks tile
  2. Click Add a Runbook
  3. Click “Quick Create: Create an new runbook”
  4. Give the runbook a name, for example StartVMs. Set the runbook type to PowerShell Workflow and click Create.
  5. Once created, you are redirected to the edit pane for the PowerShell Workflow.

The PowerShell script for starting a VM is as follows:

workflow Start-VM
{
 $cred = Get-AutomationPSCredential –Name "AZURE AUTOMATION ASSET PSEUDO NAME"
 Add-AzureAccount –Credential $cred
 Get-AzureAccount
 
 $subscription = "YOUR AZURE SUBSCRIPTION NAME"
 Set-AzureSubscription -SubscriptionName $subscription
 Select-AzureSubscription -SubscriptionName $subscription
 
 function StartVm ($serviceName, $vmName) {
 $vm = Get-AzureVM -ServiceName $serviceName -Name $vmName 
 $vm | Start-AzureVM | Out-Null
 }
 StartVm 'lekman-DC' 'lekman-DC'
 StartVm 'lekman-SQL' 'lekman-SQL'
 StartVm 'lekman' 'lekman-SP'
}

Here, you need to

  1. Change the workflow name from Start-VM to the name of your runbook – these must match
  2. Change the automaton name in line 3 to the pseudo name you gave the asset in the previous step
  3. Provide the literal name for your Azure subscription name, such as “Pay-as-you-go” or “Visual Studio Ultimate with MSDN” at line 7. You can find this info under your subscription settings.
  4. Specify the servers to start in desired order. Here, I am starting the domain controller, then the SQL server and last my SharePoint server. I provide the service name and VM name separately as these may differ.

To complete the setup, paste the script after you have modified the settings and

  1. Click Test pane
  2. Click Start and ensure the script runs without problems. If any errors occur, investigate the error messages and correct. This is normally due to incorrect service names and account names.
  3. When done, click Publish in the Edit pane

For stopping VMs, the script is as follows. Create just as the start script by adding another runbook to the existing automation account. Note that I stop the servers in the reverse order here.

workflow Stop-VMs
{
$cred = Get-AutomationPSCredential –Name "AZURE AUTOMATION ASSET PSEUDO NAME"
Add-AzureAccount –Credential $cred
Get-AzureAccount
$subscription = "YOUR AZURE SUBSCRIPTION NAME"
Set-AzureSubscription -SubscriptionName $subscription
Select-AzureSubscription -SubscriptionName $subscription
function StopVm ($serviceName, $vmName) {
$vm = Get-AzureVM -ServiceName $serviceName -Name $vmName $vm | Stop-AzureVM -Force | Out-Null
}
StopVm 'lekman' 'lekman-SP' StopVm 'lekman-SQL' 'lekman-SQL'
StopVm 'lekman-DC' 'lekman-DC'
}

Creating Schedules

Just in case I forget to stop the servers again, I automatically run the Stop-VMs workflow every day. To do this, I:

  1. Click the Schedules tile from the Runbook page
  2. Click Add a schedule then “Link to a schedule to your runbook”
  3. Click create a new schedule
  4. Give it a name, such as Daily, and set a start time, such as 18:00
  5. Set recurrence to Daily and click Create

2015-12-04_15-10-14

The runbook will now execute every day and make sure you don’t get billed over night.

Creating Webhooks

The web hook allows a POST message to a tokenized URL to start the runbook. I use these as bookmarks so that I can start them from my phone or browser. This is very handy when you need to quickly start the service. To create the webhook:

  1. From the Runbook pane, click Webhooks
  2. Click Create new webhook
  3. Fill in the details and be sure to copy the URL to the webhook as you will never see it again for security reasons

2015-12-04_15-15-41

Now, the webhook cannot readily be used as a bookmark as it needs a POST message. For this reason, I wrote a small MVC package with a few lines in a controller.

The webname is the one given for my Azure website where I publish the project. The post URL is the URL for the webhook above. The redirect URL is where I want the bookmark to go after the runbook has started, in my case the Azure dashboard. To encode the URLs you could use the online encoder from Meyer and then contruct the bookmark URL this way.

https://www.lekman.com/api/webhook?post=encodeurlhere&redirect=encodedurlhere

Conclusion

Azure automations are really cool and can be configured with a huge amount of flexibility. They save me from over spending on my Azure account and also allows me to start and stop services directly from my phone with one click.