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 with existing disks.
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
}
}
}