Flipping a Spot VM to PAYG in Azure (Without Losing Your Disks, NIC, or Sanity)
- Shannon
- Sep 14
- 3 min read
All code for this blog can be found here.
So you went all-in on Spot VMs to save money, but now you’ve hit that dreaded eviction wall. Whether your instance was deallocated or you’re simply ready to move back to a more predictable setup, this post walks you through how I flipped an existing Azure Spot VM into a PAYG (Pay-As-You-Go) VM. Bonus: I reused the OS disk, data disk, and NIC without rebuilding the whole VM from scratch. #powershellftw
Let’s get into it!
The Goal
I had a Spot VM called sbkWusDc01 running in the westus region using a Standard_B2ls_v2 (2 vCPUs, 4 GiB memory) as a spot VM (hard to pass up, price wise). When it kept getting evicted, it'd deallocate and ruin domain controller replication. For this exercise, I wanted to:
Reuse the existing OS and data disks
Reuse the existing NIC
Flip it from Spot to Pay-As-You-Go
Avoid giving it a public IP (I just built out Tailscale recently)
Preserve the VM name and configuration
No images, no cloning, no snapshots. Just flip the pricing model and get back online.
The Catch
You can't just update a Spot VM to be PAYG using Azure PowerShell or CLI. You have to:
Deallocate the Spot VM
Delete the VM object
Recreate the VM using the same disks and NIC
Ensure Trusted Launch and disk compatibility match (this may not be 100% necessary for your set-up, but with newer generational VMs, pay attention to this feature/requirement)
PowerShell Script to Flip Spot to PAYG
Here’s the full script I used. It’s clean, repeatable, and leaves all your existing resources intact except the VM shell.
# Variables
$resourceGroup = "sbkWusHub"
$oldVmName = "sbkWusDc01" # Original Spot VM name
$newVmName = "sbkWusDc01" # New PAYG VM (can be same name if deleted)
$location = "westus"
$nicName = "sbkWusDc-nic01"
$vmSize = "Standard_B2ls_v2"
$osDiskName = "sbkWusDc01-osDisk"
$dataDiskName = "sbkWusDc01-dataDisk"
# Step 1: Deallocate existing Spot VM
Stop-AzVM -ResourceGroupName $resourceGroup -Name $oldVmName -Force -NoWait
Write-Host "Waiting for VM to fully deallocate..."
do {
Start-Sleep -Seconds 5
$vm = Get-AzVM -ResourceGroupName $resourceGroup -Name $oldVmName -Status
} while ($vm.Statuses[-1].Code -ne "PowerState/deallocated")
# Step 2: Delete just the VM object (retain NIC + disks)
Remove-AzVM -ResourceGroupName $resourceGroup -Name $oldVmName -Force
Write-Host "Old VM deleted. Retaining disks and NIC..."
# Step 3: Get existing resources
$osDisk = Get-AzDisk -ResourceGroupName $resourceGroup -DiskName $osDiskName
$dataDisk = Get-AzDisk -ResourceGroupName $resourceGroup -DiskName $dataDiskName
$nic = Get-AzNetworkInterface -Name $nicName -ResourceGroupName $resourceGroup
# Step 4: Configure new VM
$vmConfig = New-AzVMConfig -VMName $newVmName -VMSize $vmSize
# Attach existing OS disk
$vmConfig = Set-AzVMOSDisk -VM $vmConfig `
-ManagedDiskId $osDisk.Id `
-CreateOption Attach `
-Windows
# Attach existing NIC
$vmConfig = Add-AzVMNetworkInterface -VM $vmConfig -Id $nic.Id
# Set Trusted Launch security profile
$securityProfile = New-Object -TypeName ` Microsoft.Azure.Management.Compute.Models.SecurityProfile
$securityProfile.SecurityType = "TrustedLaunch"
$vmConfig.SecurityProfile = $securityProfile
# Attach existing data disk
$vmConfig = Add-AzVMDataDisk -VM $vmConfig `
-Name $dataDiskName `
-CreateOption Attach `
-ManagedDiskId $dataDisk.Id `
-Lun 1
# Step 5: Create new PAYG VM
New-AzVM -ResourceGroupName $resourceGroup -Location $location -VM $vmConfigWhy This Works
You're not relying on images or re-imaging disks. You're simply deleting the VM metadata object, not the underlying resources. Then you're rebuilding the VM config using the same pieces.
This avoids surprises like:
Reinstalling software
Reconfiguring networking
Losing persistent data
Running into Trusted Launch mismatches
Watchouts
If your OS disk was built with Trusted Launch, your new VM must match that setting.
Your NIC must still be valid (not auto-deleted with the VM).
Check your VM size compatibility. Some sizes don’t support Trusted Launch.
Bonus: How I Verified (and How You Can Verify)
After recreating the VM, I ran:
Get-AzVM -Name sbkWusDc01 -ResourceGroupName sbkWusHubI verified the OS disk was correctly attached, and the VM came back online like nothing happened.
Wrapping It Up
If your Spot VM gets evicted or you just want to make it persistent, this script is a great way to rehydrate the same configuration in a PAYG model. It's clean, preserves your disks and data, and gives you control over sizing and pricing.
I'll probably wrap this into a GitHub repo next with all the variables, error handling, and maybe even a preview mode. Until then, feel free to copy-paste and modify.
Happy flipping!
