Skip to content

Commit 39e3aeb

Browse files
authored
#136 block floating ip on secondary ipconfig (#137)
* floating ip validation check * check for secondary ipconfig with floating ip * readme note
1 parent 60ba2f1 commit 39e3aeb

File tree

6 files changed

+464
-5
lines changed

6 files changed

+464
-5
lines changed

AzureBasicLoadBalancerUpgrade/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ The PowerShell module performs the following functions:
3737
- Basic Load Balancers with IPV6 frontend IP configurations
3838
- Basic Load Balancers with a Virtual Machine Scale Set backend pool member where one or more Virtual Machine Scale Set instances have ProtectFromScaleSetActions Instance Protection policies enabled
3939
- Migrating a Basic Load Balancer to an existing Standard Load Balancer
40+
- Migrating LBs with Floating IP enabled where backend pool member is a secondary IP config
4041

4142
## Install the 'AzureBasicLoadBalancerUpgrade' module
4243

AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/AzureBasicLoadBalancerUpgrade.psd1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
RootModule = 'AzureBasicLoadBalancerUpgrade'
1313

1414
# Version number of this module.
15-
ModuleVersion = '2.4.21'
15+
ModuleVersion = '2.4.22'
1616

1717
# Supported PSEditions
1818
# CompatiblePSEditions = @()
@@ -107,7 +107,7 @@
107107
# IconUri = ''
108108

109109
# ReleaseNotes of this module
110-
ReleaseNotes = 'Clarified downtime warning when running validation only'
110+
ReleaseNotes = 'Added validation check for customers using floating IP and non-primary IP configurations.'
111111

112112
# Prerelease string of this module
113113
# Prerelease = 'beta'

AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/Start-AzBasicLoadBalancerUpgrade/Start-AzBasicLoadBalancerUpgrade.psm1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Import-Module ((Split-Path $PSScriptRoot -Parent) + "\BackupResources\BackupReso
1818
- Basic load balancers with IPV6 frontend IP configurations
1919
- Basic load balancers with a VMSS backend pool member where one or more VMSS instances have ProtectFromScaleSetActions Instance Protection policies enabled
2020
- Migrating a Basic load balancer to an existing Standard load balancer
21+
- Migrating a Basic load balancer with floating IP enabled on load balancing rules, where the backend pool members are secondary IP configurations
2122
2223
Multi-load balancer support:
2324
In a situation where multiple Basic load balancers are configured with the same backend pool members (internal and external load balancers), the migration can be performed in a single operation by specifying the

AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ValidateScenario/ValidateScenario.psm1

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,30 @@ Function Test-SupportedMigrationScenario {
225225
log -Message "[Test-SupportedMigrationScenario] All VMSS load balancer associations are with the Basic LB(s) to be migrated." -Severity Information
226226
}
227227
}
228+
229+
# check if load balancing rule has floating IP enabled and associated NIC IP config is not primary. See: https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-floating-ip
230+
log -Message "[Test-SupportedMigrationScenario] Checking if load balancing rule has floating IP enabled and associated VMSS IP config is not primary..."
231+
if ($floatingIPRules = $BasicLoadBalancer.LoadBalancingRules | Where-Object { $_.EnableFloatingIP -eq $true }) {
232+
# check if floating IP rules contain non-primary IP configurations
233+
ForEach ($rule in $floatingIPRules) {
234+
log -message "[Test-SupportedMigrationScenario] Load balancing rule '$($rule.Name)' has floating IP enabled, checking for IP configuration which is not primary..."
235+
$backendPool = $BasicLoadBalancer.BackendAddressPools | Where-Object { $_.Id -eq $rule.BackendAddressPool.Id }
236+
if ($null -ne $backendPool -and $null -ne $backendPool.BackendIpConfigurations) {
237+
238+
# check if ipconfig lb backend pools contains this backend pool
239+
ForEach ($vmssNic in $basicLBVMSSs.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations) {
240+
# ip config does not need to specify a .primary value unless there is more than one
241+
$isOnlyIpConfig = $vmssNic.IpConfigurations.Count -eq 1
242+
ForEach ($ipConfig in $vmssNic.IpConfigurations) {
243+
if ($ipConfig.LoadBalancerBackendAddressPools.id -contains $backendPool.id -and ($ipConfig.Primary -ne $true -and !$isOnlyIpConfig)) {
244+
$message = "[Test-SupportedMigrationScenario] Load balancing rule '$($rule.Name)' has floating IP enabled and associated IP configuration '$($ipConfig.Name)' from VMSS '$($vmssNic.Name)' is not primary. This is not supported for migration--change the IP config in the backend pool associated with the load balancing rule '$($rule.Name)' to a primary IP configuration and re-run the module. See: https://learn.microsoft.com/azure/load-balancer/load-balancer-floating-ip"
245+
log -Message $message -Severity 'Error' -terminateOnError
246+
}
247+
}
248+
}
249+
}
250+
}
251+
}
228252

229253
# check if any VMSS instances have instance protection enabled
230254
log -Message "[Test-SupportedMigrationScenario] Checking for instances in backend pool member VMSS '$($vmssIds.split('/')[-1])' with Instance Protection configured"
@@ -388,7 +412,7 @@ Function Test-SupportedMigrationScenario {
388412
}
389413
Else {
390414
# add VM resources to array for later validation
391-
try{
415+
try {
392416
$basicLBVMs += Get-AzVM -ResourceId $nic.VirtualMachine.id -ErrorAction Stop
393417
}
394418
catch {
@@ -528,6 +552,28 @@ Function Test-SupportedMigrationScenario {
528552
log -Message $message -Severity 'Warning'
529553
}
530554
}
555+
556+
# check if load balancing rule has floating IP enabled and associated NIC IP config is not primary. See: https://learn.microsoft.com/en-us/azure/load-balancer/load-balancer-floating-ip
557+
log -Message "[Test-SupportedMigrationScenario] Checking if load balancing rule has floating IP enabled and associated IP config is not primary..."
558+
if ($floatingIPRules = $BasicLoadBalancer.LoadBalancingRules | Where-Object { $_.EnableFloatingIP -eq $true }) {
559+
# check if floating IP rules contain non-primary IP configurations
560+
ForEach ($rule in $floatingIPRules) {
561+
log -message "[Test-SupportedMigrationScenario] Load balancing rule '$($rule.Name)' has floating IP enabled, checking for IP configuration which is not primary..."
562+
$backendPool = $BasicLoadBalancer.BackendAddressPools | Where-Object { $_.Id -eq $rule.BackendAddressPool.Id }
563+
if ($null -ne $backendPool -and $null -ne $backendPool.BackendIpConfigurations) {
564+
$backendIpConfigs = $backendPool.BackendIpConfigurations
565+
566+
ForEach ($nic in $basicLBVMNics) {
567+
ForEach ($ipConfig in $nic.IpConfigurations) {
568+
If ($null -ne $backendIpConfigs -and $ipConfig.Id -in $backendIpConfigs.id -and ($ipConfig.Primary -eq $false)) {
569+
$message = "[Test-SupportedMigrationScenario] Load balancing rule '$($rule.Name)' has floating IP enabled and associated IP configuration '$($ipConfig.Name)' from NIC '$($nic.Name)' is not primary. This is not supported for migration--change the IP config in the backend pool associated with the load balancing rule '$($rule.Name)' to a primary IP configuration and re-run the module. See: https://learn.microsoft.com/azure/load-balancer/load-balancer-floating-ip"
570+
log -Message $message -Severity 'Error' -terminateOnError
571+
}
572+
}
573+
}
574+
}
575+
}
576+
}
531577
}
532578

533579

@@ -623,7 +669,7 @@ Function Test-SupportedMultiLBScenario {
623669
If ($multiLBConfig[0].scenario.backendType -eq 'VMSS') {
624670
$basicLBBackends = @()
625671
ForEach ($config in $multiLBConfig) {
626-
$basicLBBackends += $config.BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | ForEach-Object {$_.split('/virtualMachines/')[0]}
672+
$basicLBBackends += $config.BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | ForEach-Object { $_.split('/virtualMachines/')[0] }
627673
}
628674
$groupedBackends = $basicLBBackends | Sort-Object | Get-Unique
629675

@@ -684,7 +730,7 @@ Function Test-SupportedMultiLBScenario {
684730
}
685731

686732
# VMs must share an availability set or the backend must be a single VM with no availability set ('NO_AVAILABILITY_SET')
687-
If (($VMAvailabilitySets.availabilitySetId | Sort-Object | Get-Unique).count -gt 1 -or ($VMAvailabilitySets.availabilitySetId | Where-Object {$_ -eq 'NO_AVAILABILITY_SET'}).count -gt 1) {
733+
If (($VMAvailabilitySets.availabilitySetId | Sort-Object | Get-Unique).count -gt 1 -or ($VMAvailabilitySets.availabilitySetId | Where-Object { $_ -eq 'NO_AVAILABILITY_SET' }).count -gt 1) {
688734
log -Severity Error -Message "[Test-SupportedMultiLBScenario] The provided Basic Load Balancers do not share backend pool members (VMs are in different or no Availability Sets: '$($VMAvailabilitySets.availabilitySetId -join ',')'). Using -multiLBConfig when backend is not shared adds risk and complexity in recovery." -terminateOnError
689735
}
690736
Else {
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
targetScope = 'subscription'
2+
param randomGuid string = newGuid()
3+
param location string
4+
param resourceGroupName string
5+
6+
7+
// Resource Group
8+
module rg '../modules/Microsoft.Resources/resourceGroups/deploy.bicep' = {
9+
name: '${resourceGroupName}-${location}'
10+
params: {
11+
name: resourceGroupName
12+
location: location
13+
}
14+
}
15+
16+
// vnet
17+
module virtualNetworks '../modules/Microsoft.Network/virtualNetworks/deploy.bicep' = {
18+
name: '${uniqueString(deployment().name)}-virtualNetworks'
19+
scope: resourceGroup(resourceGroupName)
20+
params: {
21+
// Required parameters
22+
location: location
23+
addressPrefixes: [
24+
'10.0.0.0/16'
25+
]
26+
name: 'vnet-01'
27+
subnets: [
28+
{
29+
name: 'subnet1'
30+
addressPrefix: '10.0.1.0/24'
31+
}
32+
]
33+
}
34+
dependsOn: [
35+
rg
36+
]
37+
}
38+
39+
module publicIp01 '../modules/Microsoft.Network/publicIPAddresses/deploy.bicep' = {
40+
name: 'pip-01'
41+
params: {
42+
name: 'pip-01'
43+
location: location
44+
publicIPAddressVersion: 'IPv4'
45+
skuTier: 'Regional'
46+
skuName: 'Basic'
47+
publicIPAllocationMethod: 'Dynamic'
48+
}
49+
scope: resourceGroup(resourceGroupName)
50+
dependsOn: [
51+
rg
52+
]
53+
}
54+
55+
// basic lb
56+
module loadbalancer '../modules/Microsoft.Network/loadBalancers_custom/deploy.bicep' = {
57+
name: 'lb-basic01'
58+
scope: resourceGroup(resourceGroupName)
59+
params: {
60+
name: 'lb-basic-01'
61+
location: location
62+
frontendIPConfigurations: [
63+
{
64+
name: 'fe-01'
65+
publicIPAddressId: publicIp01.outputs.resourceId
66+
}
67+
]
68+
backendAddressPools: [
69+
{
70+
name: 'be-01'
71+
}
72+
]
73+
inboundNatRules: []
74+
loadBalancerSku: 'Basic'
75+
loadBalancingRules: [
76+
{
77+
backendAddressPoolName: 'be-01'
78+
backendPort: 80
79+
frontendIPConfigurationName: 'fe-01'
80+
frontendPort: 80
81+
idleTimeoutInMinutes: 4
82+
loadDistribution: 'Default'
83+
name: 'rule-01'
84+
probeName: 'probe-01'
85+
protocol: 'Tcp'
86+
enableFloatingIp: true
87+
}
88+
]
89+
probes: [
90+
{
91+
intervalInSeconds: 5
92+
name: 'probe-01'
93+
numberOfProbes: 2
94+
port: '80'
95+
protocol: 'Tcp'
96+
}
97+
]
98+
}
99+
dependsOn: [
100+
rg
101+
]
102+
}
103+
104+
105+
module virtualMachineScaleSets '../modules/Microsoft.Compute/virtualMachineScaleSets/deploy.bicep' = {
106+
name: 'vmss-01'
107+
scope: resourceGroup(resourceGroupName)
108+
params: {
109+
location: location
110+
// Required parameters
111+
encryptionAtHost: false
112+
adminUsername: 'admin-vmss'
113+
skuCapacity: 1
114+
upgradePolicyMode: 'Manual'
115+
imageReference: {
116+
offer: 'WindowsServer'
117+
publisher: 'MicrosoftWindowsServer'
118+
sku: '2022-Datacenter'
119+
version: 'latest'
120+
}
121+
name: 'vmss-01'
122+
osDisk: {
123+
createOption: 'fromImage'
124+
diskSizeGB: '128'
125+
managedDisk: {
126+
storageAccountType: 'Standard_LRS'
127+
}
128+
}
129+
osType: 'Windows'
130+
skuName: 'Standard_DS1_v2'
131+
// Non-required parameters
132+
adminPassword: '${uniqueString(randomGuid)}rpP@340'
133+
nicConfigurations: [
134+
{
135+
ipConfigurations: [
136+
{
137+
name: 'ipconfig1'
138+
properties: {
139+
subnet: {
140+
id: virtualNetworks.outputs.subnetResourceIds[0]
141+
}
142+
loadBalancerBackendAddressPools: [
143+
]
144+
primary: true
145+
}
146+
}
147+
{
148+
name: 'ipconfig2'
149+
properties: {
150+
subnet: {
151+
id: virtualNetworks.outputs.subnetResourceIds[0]
152+
}
153+
loadBalancerBackendAddressPools: [
154+
{
155+
id: loadbalancer.outputs.backendpools[0].id
156+
}
157+
]
158+
}
159+
}
160+
]
161+
nicSuffix: '-nic-01'
162+
}
163+
]
164+
}
165+
dependsOn: [
166+
rg
167+
]
168+
}

0 commit comments

Comments
 (0)