Control your Virtual Machine Spend with Azure Automation

In this post I will cover how I’m using Azure Automation to automate starting and stopping of virtual machines to save you from unnecessary costs. Like many I have some Azure subscriptions that I manage using my Microsoft account and others using my organizational account. Reason why I mention this is because it effects the way you authenticate from your Azure automation runbooks. If you are completely new to Azure automation I suggest you head over to this link before you read the rest of the post.

If you are new to Azure automation you might also want to check this post by Keith Mayer, Keith does a good job walking through various steps involved. If your Azure subscription is linked to a Microsoft account you’ll need to follow steps in there to create and upload a management certificate to Azure portal and also steps to add credential to azure automation. That article how ever doesn’t talk about scenario where you don’t want to use a management certificate to authenticate with your azure subscription but want to use Azure AD and organizational authentication. To use organizational authentication you have to specify “Windows Powershell Credentials” for credential type instead of certificate and enter your organizational account user name and password.  One important point to note here is that you cannot have multi factor authentication enabled for the user account you will be using as “Add-AzureAccount” with –Credential option just doesn’t seem to work when you have MFA enabled.

You can also create a new PowerShell credential using PowerShell below

$user = "{replace with organization account}"
$pw = Read-Host "Enter password" -AsSecureString
$cred = New-Object –TypeName System.Management.Automation.PSCredential –ArgumentList $user, $pw
New-AzureAutomationCredential -AutomationAccountName "{replace}" -Name "{replace}" -Value $cred

At this point you should have set up an new Azure automation account and added a credential setting to assets. Credential setting can be certificate or windows powershell credentials depending on your specific scenario. Next thing we’ll need to do is add another setting named “settingsJSON” to assets. To perform this steps select the automation account in management portal and click on “assets” option and then “add setting” as shown in screen shot below

image

Next you will see a dialog where you’ll need to specify the type of setting to be added, select add variable.

image

In the define variable screen select “String” variable type and enter “settingsJSON” for variable name

image

In the define variable value screen we’ll need to paste JSON shown below

image

Sample JSON template to be pasted as variable value. Before you use the JSON below you will need to replace the subscriptionID, subscriptionName, credentialName and also the list of virtual machines you want to automate starting and stopping.

{
     subscriptionID: {replace}’,
     subscriptionName: ‘{replace}’,
     credentialName: ‘{replace with name used when credential was setup}’,
     virtualMachines:[
         { name: ‘vm1’, serviceName: ‘vm2’ },
         { name: ‘vm2’, serviceName: ‘vm2’}
     ]
}

Next we need to create a new Azure automation runbook. Click New and select Runbook and quick create, enter “startstopvms” for runbook name and select automation account you want to use and click create.

image 

Select the newly created runbook “startandstopvms” and click on “Author” and paste the script below inside the workflow

param(
        [parameter(Mandatory=$true)]
        [String] $action
    )

     
    $json = Get-AutomationVariable -Name "settingsJSON"
    Write-Output "json string : $json"
    $settings = ConvertFrom-JSON $json
    Write-Output "Retrieving Credential : $($settings.credentialName)"
    $psCred = Get-AutomationPSCredential -Name $settings.credentialName
    if($psCred -eq $null) {
        Write-Output "No stored credentials, trying to load certificate for authenticating with subscription"
        $certificate = Get-AutomationCertificate -Name $settings.credentialName 
        Write-Output "Setting azure subscription : $($settings.subscriptionName)"
        Set-AzureSubscription -SubscriptionName $settings.subscriptionName -SubscriptionId $settings.subscriptionID -Certificate $certificate 
    } else {
        Write-Output "organizational authentication, using stored powershell credentials with Add-AzureAccount"
        Add-AzureAccount -Credential $psCred
    }
    
    Select-AzureSubscription $settings.subscriptionName  
    
    foreach($virtualMachine in $settings.virtualMachines) {   
        if($action.ToUpper() -eq "START"){ 
            Write-Output "Starting virtual machine : $($virtualMachine.name)"
            Start-AzureVM -Name  $virtualMachine.name -ServiceName $virtualMachine.serviceName -ErrorAction SilentlyContinue
        } else {
            Write-Output "Stopping virtual machine : $($virtualMachine.name)"
            Stop-AzureVM -Name $virtualMachine.name -ServiceName $virtualMachine.serviceName -Force -ErrorAction SilentlyContinue
        }
    }

At this point you should be able to test the RUN book by clicking on test option to ensure things are working correctly. Passing “start” for action parameter should start all virtual machines specified in the JSON settings template, similarly to stop virtual machines you can simply specify “stop” for action parameter value.

Next we need to create a schedule to start the virtual machines

Select the “startstopvms” runbook we created earlier and click on “schedule” option and then “link to a new schedule”

image

In the “Add Schedule” screen I’ll name the new schedule “start-virtualmachines” and click next

image

In the configure schedule screen, since I want this to run daily I’ll select the “daily” option and specify a start time. In my case I want the virtual machines to come up at 9AM every morning

image

Next we specify the runbook parameter value, in this case it’s the “action” parameter value, since this is a schedule for starting virtual machines, we’ll need to specify “start”

image

Clicking the “check” button will create the schedule. Similarly you can create a schedule to stop the virtual machines, repeat the steps we performed earlier to create schedule and specify “stop” for action parameter value

That’s it. You should now be able to control unnecessary expenses resulting from leaving your virtual machines on using Azure Automation feature. Obviously azure automation has many other scenarios and use cases.

Hope this helps.

</Ram>