modules/BackendPoolMigration/BackendPoolMigration.psm1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# Load Modules Import-Module ((Split-Path $PSScriptRoot -Parent) + "\Log\Log.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "\UpdateVmssInstances\UpdateVmssInstances.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "\GetVMSSFromBasicLoadBalancer\GetVMSSFromBasicLoadBalancer.psd1") function _HardCopyObject { [CmdletBinding()] param ( [Parameter(Mandatory = $True)][System.Collections.Generic.List[Microsoft.Azure.Management.Compute.Models.SubResource]] $listSubResource ) $options = [System.Text.Json.JsonSerializerOptions]::new() $options.WriteIndented = $true $options.IgnoreReadOnlyProperties = $true $cgenericListSubResource = [System.Text.Json.JsonSerializer]::Serialize($listSubResource, "System.Collections.Generic.List[Microsoft.Azure.Management.Compute.Models.SubResource]", $options) $cgenericListSubResource = [System.Text.Json.JsonSerializer]::Deserialize($cgenericListSubResource, "System.Collections.Generic.List[Microsoft.Azure.Management.Compute.Models.SubResource]") # To preserve the original object type in the return we must use a , before the object to be returned return , [System.Collections.Generic.List[Microsoft.Azure.Management.Compute.Models.SubResource]]$cgenericListSubResource } function _MigrateHealthProbe{ [CmdletBinding()] param ( [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $StdLoadBalancer, [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $vmss, [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $refVmss ) log -Message "[_MigrateHealthProbe] Migrating Health Probes" try { $refHealthProbe = $refVmss.VirtualMachineProfile.NetworkProfile.HealthProbe if(![string]::IsNullOrEmpty($refHealthProbe)){ $refProbeName = $refHealthProbe.Id.Split('/')[-1] log -Message "[_MigrateHealthProbe] Health Probes found in reference VMSS $($refProbeName)" $refProbeId = ($StdLoadBalancer.Probes | Where-Object{$_.Name -eq $refProbeName}).id $vmss.VirtualMachineProfile.NetworkProfile.HealthProbe = $refProbeId } else{ log -Message "[_MigrateHealthProbe] Health Probes not found in reference VMSS $($refVmss.Name)" } } catch { $message = @" [_MigrateHealthProbe] An error occured migrating a health probe to the VMSS. To recover address the following error, and try again specifying the -FailedMigrationRetryFilePath parameter and Basic Load Balancer backup State file located either in this directory or the directory specified with -RecoveryBackupPath. `nError message: $_ "@ log 'Error' $message Exit } log -Message "[_MigrateHealthProbe] Migrating Health Probes completed" } function _RestoreUpgradePolicyMode{ param ( [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $vmss, [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $refVmss ) log -Message "[_RestoreUpgradePolicyMode] Restoring VMSS Upgrade Policy Mode" if ($vmss.UpgradePolicy.Mode -ne $refVmss.UpgradePolicy.Mode) { log -Message "[_RestoreUpgradePolicyMode] Restoring VMSS Upgrade Policy Mode to $($refVmss.UpgradePolicy.Mode)" $vmss.UpgradePolicy.Mode = $refVmss.UpgradePolicy.Mode } else { log -Message "[_RestoreUpgradePolicyMode] VMSS Upgrade Policy Mode not changed" } log -Message "[_RestoreUpgradePolicyMode] Restoring VMSS Upgrade Policy Mode completed" } function _MigrateNetworkInterfaceConfigurations { param ( [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $StdLoadBalancer, [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $vmss ) log -Message "[_MigrateNetworkInterfaceConfigurations] Adding BackendAddressPool to VMSS $($vmss.Name)" foreach ($networkInterfaceConfiguration in $vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations) { $genericListSubResource = New-Object System.Collections.Generic.List[Microsoft.Azure.Management.Compute.Models.SubResource] foreach ($ipConfiguration in $networkInterfaceConfiguration.IpConfigurations) { If (![string]::IsNullOrEmpty($ipConfiguration.LoadBalancerBackendAddressPools)) { $genericListSubResource.AddRange($ipConfiguration.LoadBalancerBackendAddressPools) } foreach($BackendAddressPool in $BasicLoadBalancer.BackendAddressPools){ foreach($BackendIpConfiguration in $BackendAddressPool.BackendIpConfigurations){ $lbBeNicName = $BackendIpConfiguration.Id.Split('/')[-3] $lbBeipConfigName = $BackendIpConfiguration.Id.Split('/')[-1] if($lbBeNicName -eq $networkInterfaceConfiguration.Name -and $lbBeipConfigName -eq $ipConfiguration.Name){ try { $subResource = New-Object Microsoft.Azure.Management.Compute.Models.SubResource $subResource.Id = ($StdLoadBalancer.BackendAddressPools | Where-Object { $_.Name -eq $BackendAddressPool.Name }).Id log -Message "[_MigrateNetworkInterfaceConfigurations] Adding BackendAddressPool $($subResource.Id.Split('/')[-1]) to VMSS Nic: $lbBeNicName ipConfig: $lbBeipConfigName" $genericListSubResource.Add($subResource) } catch { $message = @" [_MigrateNetworkInterfaceConfigurations] An error occured creating a new VMSS IP Config. To recover address the following error, and try again specifying the -FailedMigrationRetryFilePath parameter and Basic Load Balancer backup State file located either in this directory or the directory specified with -RecoveryBackupPath. `nError message: $_ "@ log 'Error' $message Exit } } } } # Taking a hard copy of the object and assigning, it's important because the object was passed by reference $ipConfiguration.LoadBalancerBackendAddressPools = _HardCopyObject -listSubResource $genericListSubResource $genericListSubResource.Clear() } } log -Message "[_MigrateNetworkInterfaceConfigurations] Migrate NetworkInterface Configurations completed" } function _UpdateAzVmss { param ( [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $vmss ) log -Message "[_UpdateAzVmss] Saving VMSS $($vmss.Name)" try { $ErrorActionPreference = 'Stop' Update-AzVmss -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name -VirtualMachineScaleSet $vmss > $null } catch { $exceptionType = $_.Exception.Message.Split('ErrorCode:')[1].Split('ErrorMessage:')[0].Trim() if($exceptionType -eq "MaxUnhealthyInstancePercentExceededBeforeRollingUpgrade"){ $message = @" [_UpdateAzVmss] An error occured when attempting to update VMSS upgrade policy back to $($vmss.UpgradePolicy.Mode). Looks like some instances were not healthy and in orther to change the VMSS upgra policy the majority of instances must be healthy according to the upgrade policy. The module will continue but it will be required to change the VMSS Upgrade Policy manually. `nError message: $_ "@ log 'Error' $message } else { $message = @" [_UpdateAzVmss] An error occured when attempting to update VMSS network config new Standard LB backend pool membership. To recover address the following error, and try again specifying the -FailedMigrationRetryFilePath parameter and Basic Load Balancer backup State file located either in this directory or the directory specified with -RecoveryBackupPath. `nError message: $_ "@ log 'Error' $message Exit } } } function BackendPoolMigration { [CmdletBinding()] param ( [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $StdLoadBalancer, [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $refVmss ) log -Message "[BackendPoolMigration] Initiating Backend Pool Migration" log -Message "[BackendPoolMigration] Adding Standard Load Balancer back to the VMSS" log -Message "[BackendPoolMigration] Building VMSS object from Basic Load Balancer $($BasicLoadBalancer.Name)" $vmss = GetVMSSFromBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer # Migrating Health Probe in case it exist _MigrateHealthProbe -StdLoadBalancer $StdLoadBalancer -vmss $vmss -refVmss $refVmss # Migrating Network Interface Configurations back to the VMSS _MigrateNetworkInterfaceConfigurations -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -vmss $vmss # Update VMSS on Azure _UpdateAzVmss -vmss $vmss # Update Instances UpdateVmssInstances -vmss $vmss # Restore VMSS Upgrade Policy Mode _RestoreUpgradePolicyMode -vmss $vmss -refVmss $refVmss # Update VMSS on Azure _UpdateAzVmss -vmss $vmss #log -Message "[BackendPoolMigration] Updating VMSS Instances $($vmss.Name)" #UpdateVmssInstances -vmss $vmss #log -Message "[BackendPoolMigration] StackTrace $($StackTrace)" -Severity "Debug" log -Message "[BackendPoolMigration] Backend Pool Migration Completed" } Export-ModuleMember -Function BackendPoolMigration |