I have created the PS script to convert PYUG to SPOT VMs. It will not work for VMs with extensions as we will be recreating from existing disks. After verifying succesful conversion delete the backup snapshots.
Function Convert-PYUG2SPOT {
Param (
# Set variables to your specifics
$resourceGroup,
$vmName,
$subscriptionName,
[switch]$force
)
$WarningPreference = 'SilentlyContinue'
$context = Set-AzContext $subscriptionName
Write-Output "Setting context to $($subscriptionName)"
# Get the details of the VM to be moved to the Availability Set
$originalVM = Get-AzVM `
-ResourceGroupName $resourceGroup `
-Name $vmName
try {
# Check whether already logged-in
$setAzContext = (az account set --name $subscriptionName)
$updateresource = (az resource update --resource-group $resourceGroup --name $vmName --resource-type virtualMachines --namespace Microsoft.Compute --set properties.storageProfile.osDisk.deleteOption=detach)
}
catch {
Write-Host 'You need to login'
if ($LASTEXITCODE -ne 0) { exit 1 }
}
# checking for dependencies
$vm = Get-AzVM -ResourceGroupName $resourceGroup -VMName $vmName
$extensionExist = ($vm.Extensions | Select-Object Publisher, VirtualMachineExtensionType, TypeHandlerVersion)
if ($extensionExist) {
$extensionExist
Write-Host 'Make sure you note the installed extensions, that you can configure later on the converted VM.'
Write-Host 'Please re-run the automation with the -force switch to initiate the conversion.'
}
if ($extensionExist -and $force) {
Write-Host 'Initiating the conversion.'
# Create the basic configuration for the replacement VM.
$newVM = New-AzVMConfig `
-VMName $originalVM.Name `
-VMSize $originalVM.HardwareProfile.VmSize `
-Priority 'Spot' -MaxPrice -1
# Confgure OS Disk
Set-AzVMOSDisk `
-VM $newVM -CreateOption Attach `
-ManagedDiskId $originalVM.StorageProfile.OsDisk.ManagedDisk.Id `
-Name $originalVM.StorageProfile.OsDisk.Name
if ($originalVM.OSProfile.WindowsConfiguration) {
$newVM.StorageProfile.OsDisk.OsType = 'Windows'
}
else {
$newVM.StorageProfile.OsDisk.OsType = 'Linux'
}
# Taking backup of OSdisks
$osDiskid = $originalVM.StorageProfile.OsDisk.ManagedDisk.Id
$osDiskName = $originalVM.StorageProfile.OsDisk.Name
# Create Disk Snapshot
$snapshot = New-AzSnapshotConfig -SourceUri $osDiskid -Location $originalVM.Location -CreateOption copy
$newsnap = New-AzSnapshot `
-Snapshot $snapshot `
-SnapshotName "$($osDiskName)_snapshot" `
-ResourceGroupName $resourceGroup
$randomNumber = Get-Random -Maximum 100
foreach ($disk in $originalVM.StorageProfile.DataDisks) {
# Taking backup of disks
# Get Current VM Data Disk metadata.
$dataDiskid = $disk.ManagedDisk.Id
$dataDiskName = ($disk.Name).ToLower()
# Create Disk Snapshot
$snapshot = New-AzSnapshotConfig -SourceUri $dataDiskid -Location $originalVM.Location -CreateOption copy
$newsnap = New-AzSnapshot `
-Snapshot $snapshot `
-SnapshotName "$($dataDiskName)_$($randomNumber)" `
-ResourceGroupName $resourceGroup
}
# Add NIC(s) and keep the same NIC as primary
foreach ($nic in $originalVM.NetworkProfile.NetworkInterfaces) {
if ($nic.Primary -eq 'True') {
Add-AzVMNetworkInterface `
-VM $newVM `
-Id $nic.Id -Primary
}
else {
Add-AzVMNetworkInterface `
-VM $newVM `
-Id $nic.Id
}
}
if ($originalVM.AvailabilitySetReference.Id) {
Write-Output "Warning: VM $originalVM.Name is in an availability set. Spot VMs cannot run in availability sets."
}
# Remove the original VM
Remove-AzVM -ResourceGroupName $resourceGroup -Name $vmName -Force
New-AzVM `
-ResourceGroupName $resourceGroup `
-Location $originalVM.Location `
-VM $newVM `
-DisableBginfoExtension
foreach ($attachDisk in $originalVM.StorageProfile.DataDisks) {
$dataDiskid = ($attachDisk.ManagedDisk.Id).ToLower()
$dataDiskName = ($attachDisk.Name).ToLower()
Write-Output "Attaching $($dataDiskName)"
Write-Output $dataDiskid
Write-Output $dataDiskName
$vm = Get-AzVM -Name $vmName -ResourceGroupName $resourceGroup
$vm = Add-AzVMDataDisk -VM $vm `
-Name $dataDiskName `
-ManagedDiskId $dataDiskid `
-Lun $attachDisk.Lun `
-CreateOption Attach
Write-Output " --- Adding data disk $($dataDiskName) to $($vmName)"
Update-AzVM -ResourceGroupName $resourceGroup -VM $vm
}
}
}