Auto Start Stopped Spot Instance to Get Your VM Running Again - NETSEC

Latest

Learning, Sharing, Creating

Cybersecurity Memo

Sunday, October 22, 2023

Auto Start Stopped Spot Instance to Get Your VM Running Again

Using Azure Spot Virtual Machines allows you to take advantage of Microsoft Azure unused capacity at a significant cost savings. Spot VMs can be up to 90 percent cheaper than regular (pay-as-you-go) VMs.

But there is shortcoming for the availability. At any point in time when Azure needs the capacity back, the Azure infrastructure will evict Azure Spot Virtual Machines. Azure provides a minimum of 30-seconds advance notice before the actual eviction takes place. 

Is there a way we can automatically bring our stopped / evicted VM back online? In this post I am gonna show you how to get your stopped / evicted VM started again in 5 minutes using automation account's runbook.

In this case, we can enjoy 90% off's Azure VM and also get availability as much as we can. 



 

Limitation

VMs can be evicted based on capacity or the max price you set. When creating an Azure Spot Virtual Machine, you can set the eviction policy to Deallocate (default) or Delete.

The following VM sizes aren't supported for Azure Spot Virtual Machines:
  • B-series
  • Promo versions of any size (like Dv2, NV, NC, H promo sizes)
Azure Spot Virtual Machines can be deployed to any region, except Microsoft Azure operated by 21Vianet.

The biggest challenge is how to start the Spot Instance automatically. We will use alert rule to monitor system and use runbook to trigger a PowerShell script to start stopped VM.

Create VM with A Spot Discount Check


1 Enable Spot Discount

Make sure there is no infrastructure redundancy selected.

Make eviction policy is stop/deallocate.





Create An Automation Account and Add A Runbook


2 Search and Create An Automation Account



3 Import a runbook



Here is start.ps1 script:

param (
    [Parameter(Mandatory=$true)]  
    [String] $Action,
    [Parameter(Mandatory=$true)]  
    [String] $TagName,
    [Parameter(Mandatory=$true)]
    [String] $TagValue

Write-Output ""
Write-Output "------------------------ Authentication ------------------------"
Write-Output "Logging into Azure ..."
try {
    "Logging in to Azure..."
    Connect-AzAccount -Identity
}
catch {
    Write-Error -Message $_.Exception
}
$SubscriptionId = "<YOUR SUBSCRIPTION ID>"
Select-AzContext -name ((Get-AzContext -ListAvailable).Name -match $SubscriptionId)[0]
try {
    if ($Action -eq "Start" -or $Action -eq "Stop") {
        Write-Output "Action Selected"
    }
    else { 
        Write-Output "Wrong Action Selection. It should be Start or Stop"
        Exit 
    }
} catch {
    Write-Error -Message $_.Exception
}
try {
Write-Output ""
Write-Output ""
Write-Output "---------------------------- Status ----------------------------"
Write-Output "Getting all virtual machines with Tags ..."
    $myvms = Get-AzVM | Where-Object { $_.Tags[$TagName] -eq $TagValue }
    Write-Output "Total of VMs: $($myvms.Length)"
    foreach ($vm in $myvms) {
        Write-Output $vm.Name
        $status = Get-AzVM -Name $vm.Name -Status
        Write-Output "VM $($vm.Name) status: $($status.PowerState)"
        if ($Action -eq "Start") {
            if ($status.PowerState -eq "VM deallocated") {
                Write-Output "Starting VM: $($vm.Name)"
                try {
                    Start-AzVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -NoWait
                } catch {
                    Write-Error -Message $_.Exception
                }
            
            } else {
                Write-Output "VM: $($vm.Name) is already started"
            }  
        } 
        if ($Action -eq "Stop") {
            if ($status.PowerState -eq "VM running") {
                Write-Output "Stopping VM: $($vm.Name)"
                try {                    
                    Stop-AzVM -Name $vm.Name -ResourceGroupName $vm.ResourceGroupName -Force -NoWait
                } catch {
                    Write-Error -Message $_.Exception
                }
            
            } else {
                Write-Output "VM: $($vm.Name) is already stopped"
            }  
        }
    }
}
catch {
    Write-Error -Message $_.Exception
}


Script Download Address.


The last step is to make sure you publish it. 


Tag VM


4 add tag to Spot VM




Create an Alert Rule

Go to Monitor - Alert page

Create 




Choose “See all signals” then search “VM Availability Metric (Preview)”


Create an alert rule condition, if threshold for VM Aaailabiity Metric is less than 1 (means stopped), the alert will be triggered. The alert will check the condition every minute.



Next step is to create action group. It has to be in same subscription. Action group has to be in same subscription as your monitoring resources.





You even can set up SMS notification to notify you the server is stopped. 

Notitication setting does not matter. SMS is not free anyway. One SMS is about one dime.

Then start to set up action, choose Automation Runbook, then select subscription and automation account. Select the runbook we imported. 




For the parameters, you will need to fill in the label informaiton. 







Videos

 





References

  • https://hostloc.com/thread-1182352-1-5.html







No comments:

Post a Comment