modules/ValidateScenario/ValidateScenario.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 |
# Load Modules Import-Module ((Split-Path $PSScriptRoot -Parent) + "\Log\Log.psd1") Function Test-SupportedMigrationScenario { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $true)] [ValidatePattern("^[A-Za-z0-9](?:[A-Za-z0-9._-]{0,78}[A-Za-z0-9_])?$")] [string] $StdLoadBalancerName ) $scenario = @{ 'ExternalOrInternal' = '' } # checking source load balance SKU log -Message "[Test-SupportedMigrationScenario] Verifying if Load Balancer $($BasicLoadBalancer.Name) is valid for migration" log -Message "[Test-SupportedMigrationScenario] Verifying source load balancer SKU" If ($BasicLoadBalancer.Sku.Name -ne 'Basic') { log -ErrorAction Stop -Severity 'Error' -Message "[Test-SupportedMigrationScenario] The load balancer '$($BasicLoadBalancer.Name)' in resource group '$($BasicLoadBalancer.ResourceGroupName)' is SKU '$($BasicLoadBalancer.SKU.Name)'. SKU must be Basic!" return } log -Message "[Test-SupportedMigrationScenario] Source load balancer SKU is type Basic" # Detecting if there are any backend pools that is not virtualMachineScaleSets, if so, exit log -Message "[Test-SupportedMigrationScenario] Checking if there are any backend pool members which are not virtualMachineScaleSets and that all backend pools are not empty" $backendPoolHasMembers = $false foreach ($backendAddressPool in $BasicLoadBalancer.BackendAddressPools) { foreach ($backendIpConfiguration in $backendAddressPool.BackendIpConfigurations) { $backendPoolHasMembers = $true if ($backendIpConfiguration.Id.split("/")[7] -ne "virtualMachineScaleSets") { log -ErrorAction Stop -Message "[Test-SupportedMigrationScenario] Basic Load Balancer has backend pools that is not virtualMachineScaleSets, exiting" -Severity 'Error' return } } } If (!$backendPoolHasMembers) { log -ErrorAction Stop -Severity 'Error' -Message "[Test-SupportedMigrationScenario] Load balancer '$($BasicLoadBalancer.Name)' has no backend pool membership, which is not supported for migration!" return } log -Message "[Test-SupportedMigrationScenario] All backend pools members virtualMachineScaleSets!" # Detecting if there are more than one VMSS in the backend pool, if so, exit # Basic Load Balancers doesn't allow more than one VMSS as a backend pool becuase they would be under different availability sets. # This is a sanity check to make sure that the script is not run on a Basic Load Balancer that has more than one VMSS in the backend pool. log -Message "[Test-SupportedMigrationScenario] Checking if there are more than one VMSS in the backend pool" $vmssIds = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object { $_.split("virtualMachines")[0] } | Select-Object -Unique if ($vmssIds.count -gt 1) { log -ErrorAction Stop -Message "[Test-SupportedMigrationScenario] Basic Load Balancer has more than one VMSS in the backend pool, exiting" -Severity 'Error' return } log -message "[Test-SupportedMigrationScenario] Basic Load Balancer has only one VMSS in the backend pool" # checking that source load balancer has sub-resource configurations log -Message "[Test-SupportedMigrationScenario] Checking that source load balancer is configured" If ($BasicLoadBalancer.LoadBalancingRules.count -eq 0) { log -ErrorAction Stop -Severity 'Error' -Message "[Test-SupportedMigrationScenario] Load balancer '$($BasicLoadBalancer.Name)' has no front end configurations, so there is nothing to migrate!" return } log -Message "[Test-SupportedMigrationScenario] Load balancer has at least 1 frontend IP configuration" # check if the load balancer name should be re-used, if so check if it's not standard already log -Message "[Test-SupportedMigrationScenario] Checking that standard load balancer name '$StdLoadBalancerName'" $chkStdLB = (Get-AzLoadBalancer -Name $StdLoadBalancerName -ResourceGroupName $BasicLoadBalancer.ResourceGroupName -ErrorAction SilentlyContinue) If ($chkStdLB) { log -Message "[Test-SupportedMigrationScenario] Load balancer resource '$($chkStdLB.Name)' already exists. Checking if it is a Basic SKU for migration" If ($chkStdLB.Sku.Name -ne 'Basic') { log -ErrorAction Stop -Severity 'Error' -Message "[Test-SupportedMigrationScenario] Load balancer resource '$($chkStdLB.Name)' is not a Basic SKU, so it cannot be migrated!" return } log -Message "[Test-SupportedMigrationScenario] Load balancer resource '$($chkStdLB.Name)' is a Basic Load Balancer. The same name will be re-used." } # check if load balancer backend pool contains VMSSes which are part of another LBs backend pools log -Message "[Test-SupportedMigrationScenario] Checking if backend pools contain members which are members of another load balancer's backend pools..." $vmssIds = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object{$_.split("virtualMachines")[0]} | Select-Object -Unique ForEach ($vmssId in $vmssIds) { $vmss = Get-AzResource -ResourceId $vmssId | Get-AzVMSS $loadBalancerAssociations = @() ForEach ($nicConfig in $vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations) { ForEach ($ipConfig in $nicConfig.ipConfigurations) { ForEach ($bepMembership in $ipConfig.LoadBalancerBackendAddressPools) { $loadBalancerAssociations += $bepMembership.id.split('/')[0..8] -join '/' } } } If (($beps = $loadBalancerAssociations | Sort-Object | Get-Unique).Count -gt 1) { $message = @" [Test-SupportedMigrationScenario] One (or more) backend address pool VMSS members on basic load balancer '$($BasicLoadBalancer.Name)' is also member of the backend address pool on another load balancer. `nVMSS: '$($vmssId)'; `nMember of load balancer backend pools on: $beps "@ log 'Error' $message Exit } } # check if any VMSS instances have instance protection enabled log -Message "[Test-SupportedMigrationScenario] Checking for instances in backend pool member VMSS '$($vmssIds.split('/')[-2])' with Instance Protection configured" $vmssInstances = Get-AzVmssVM -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmssIds.split('/')[-2] ForEach ($instance in $vmssInstances) { If ($instance.ProtectionPolicy.ProtectFromScaleSetActions) { $message = @" [Test-SupportedMigrationScenario] VMSS '$($vmss.Name)' contains 1 or more instances with a ProtectFromScaleSetActions Instance Protection configured. This module cannot upgrade the associated load balancer because a VMSS cannot be a backend member of both basic and standard SKU load balancers. Remove the Instance Protection policy and re-run the module. "@ log -Severity 'Error' $vmssInstances.Remove($instance) } } log -Message "[Test-SupportedMigrationScenario] No VMSS instances with Instance Protection found" # detecting if source load balancer is internal or external-facing log -Message "[Test-SupportedMigrationScenario] Determining if LB is internal or external based on FrontEndIPConfiguration[0]'s IP configuration" If (![string]::IsNullOrEmpty($BasicLoadBalancer.FrontendIpConfigurations[0].PrivateIpAddress)) { log -Message "[Test-SupportedMigrationScenario] FrontEndIPConfiguiration[0] is assigned a private IP address '$($BasicLoadBalancer.FrontendIpConfigurations[0].PrivateIpAddress)', so this LB is Internal" $scenario.ExternalOrInternal = 'Internal' } ElseIf (![string]::IsNullOrEmpty($BasicLoadBalancer.FrontendIpConfigurations[0].PublicIpAddress)) { log -Message "[Test-SupportedMigrationScenario] FrontEndIPConfiguiration[0] is assigned a public IP address '$($BasicLoadBalancer.FrontendIpConfigurations[0].PublicIpAddress.Id)', so this LB is External" # Detecting if there is a frontend IPV6 configuration, if so, exit log -Message "[Test-SupportedMigrationScenario] Determining if there is a frontend IPV6 configuration" foreach ($frontendIP in $BasicLoadBalancer.FrontendIpConfigurations) { $pip = Get-azPublicIpAddress -Name $frontendIP.PublicIpAddress.Id.split("/")[8] -ResourceGroupName $frontendIP.PublicIpAddress.Id.split("/")[4] if ($pip.PublicIpAddressVersion -eq "IPv6") { log -ErrorAction Stop -Message "[Test-SupportedMigrationScenario] Basic Load Balancer is using IPV6. This is not a supported scenario. PIP Name: $($pip.Name) RG: $($pip.ResourceGroupName)" -Severity "Error" return } } $scenario.ExternalOrInternal = 'External' } ElseIf (![string]::IsNullOrEmpty($BasicLoadBalancer.FrontendIpConfigurations[0].PublicIPPrefix.Id)) { log -ErrorAction Stop -Severity 'Error' "[Test-SupportedMigrationScenario] FrontEndIPConfiguration[0] is assigned a public IP prefix '$($BasicLoadBalancer.FrontendIpConfigurations[0].PublicIPPrefixText)', which is not supported for migration!" return } log -Message "[Test-SupportedMigrationScenario] Load Balancer $($BasicLoadBalancer.Name) is valid for migration" return $scenario } Export-ModuleMember -Function Test-SupportedMigrationScenario |