Skip to content

Commit c238420

Browse files
authored
Add NAT Pool to NAT Rule Upgrade + Fix NAT Rule Migrations (#98)
* remove IP conversion warnings * remove unnecessary update when no NAT pools * add and fix nat scenarios * fixed as rg dependency * renamed backup module * added nat pool migration function * support for nat rule only configs * comment clarity * nat pool migration with emtpy backend * nat rule ipconfig migration * nat pool migration validation and param changes * release notes * add param -skipMigrateNATPoolsToNATRules to deploy.ps1 * fix skip nat pool upgrade param pass * add nat pool param * rename param skipUpgradeNATPoolsToNATRules * nat rule count validation, empty nat pools * docs update
1 parent 7315fc5 commit c238420

35 files changed

+2121
-350
lines changed

AzureBasicLoadBalancerUpgrade/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ The PowerShell module performs the following functions:
1818
- Migrates Virtual Machine Scale Set and Virtual Machine backend pool members from the Basic Load Balancer to the Standard Load Balancer.
1919
- Creates and associates a network security group with the Virtual Machine Scale Set or Virtual Machine to ensure load balanced traffic reaches backend pool members, following Standard Load Balancer's move to a default-deny network policy.
2020
- Upgrades instance-level Public IP addresses associated with Virtual Machine Scale Set or Virtual Machine instances
21+
- Upgrades Inbound NAT Pools to Inbound NAT Rules for Virtual Machine Scale Set backends. Specify -skipUpgradeNATPoolsToNATRules to skip this upgrade.
2122
- Logs the upgrade operation for easy audit and failure recovery.
2223

2324
>[!WARNING]
@@ -207,7 +208,8 @@ The script migrates the following from the Basic Load Balancer to the Standard L
207208
- Inbound NAT Rules:
208209
- All user-created NAT rules are migrated to the new Standard Load Balancer
209210
- Inbound NAT Pools:
210-
- All inbound NAT Pools will be migrated to the new Standard Load Balancer
211+
- By default, NAT Pools are upgraded to NAT Rules
212+
- To migrate NAT Pools instead, specify the -skipUpgradeNATPoolsToNATRules parameter when upgrading
211213
- Backend pools:
212214
- All backend pools are migrated to the new Standard Load Balancer
213215
- All Virtual Machine Scale Set and Virtual Machine network interfaces and IP configurations are migrated to the new Standard Load Balancer

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.3.4'
15+
ModuleVersion = '2.4.0'
1616

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

109109
# ReleaseNotes of this module
110-
ReleaseNotes = 'Fix spurious error when calling _HardCopyObject when an IPConfig has no pool membership'
110+
ReleaseNotes = 'Fix NAT Rule backend migration, Add NAT Pool to NAT Rule migration'
111111

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

AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackendPoolMigration/BackendPoolMigration.psm1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ function BackendPoolMigrationVM {
197197
$lbBeNicId = ($BackendIpConfiguration.Id -split '/ipConfigurations/')[0]
198198
$ipConfigName = ($BackendIpConfiguration.Id -split '/ipConfigurations/')[1]
199199

200+
# create empty array for this Nic ID if it doesn't exist
200201
If (!$backendPoolNicTable[$lbBeNicId]) {
201202
$backendPoolNicTable[$lbBeNicId] = @(@{ipConfigs = @{} })
202203
}

AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupBasicLoadBalancer/BackupBasicLoadBalancer.psd1 renamed to AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupResources/BackupResources.psd1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#
2-
# Module manifest for module 'BackupBasicLoadBalancer'
2+
# Module manifest for module 'BackupResources'
33
#
44
# Generated by: Victor Santana
55
#
@@ -9,7 +9,7 @@
99
@{
1010

1111
# Script module or binary module file associated with this manifest.
12-
RootModule = 'BackupBasicLoadBalancer'
12+
RootModule = 'BackupResources'
1313

1414
# Version number of this module.
1515
ModuleVersion = '0.1.4'

AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupBasicLoadBalancer/BackupBasicLoadBalancer.psm1 renamed to AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupResources/BackupResources.psm1

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Load Modules
22
Import-Module ((Split-Path $PSScriptRoot -Parent) + "/Log/Log.psd1")
3+
Import-Module ((Split-Path $PSScriptRoot -Parent) + "/GetVmssFromBasicLoadBalancer/GetVmssFromBasicLoadBalancer.psd1")
34

45
function RestoreLoadBalancer {
56
[CmdletBinding()]
@@ -96,16 +97,16 @@ Function BackupVmss {
9697
log -Message "[BackupVmss] Initiating Backup of VMSS to path '$RecoveryBackupPath'"
9798

9899
# Backup VMSS Object
99-
$vmssIds = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object { ($_ -split '/virtualMachines/')[0].ToLower() } | Select-Object -Unique
100-
foreach ($vmssId in $vmssIds) {
100+
$vmsses = GetVmssFromBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer
101+
foreach ($vmss in $vmsses) {
102+
$vmssId = $vmss.Id
101103
$message = "[BackupVmss] Attempting to create a file-based backup VMSS with id '$vmssId'"
102104
log -Severity Information -Message $message
103105

104106
$backupDateTime = Get-Date -Format FileDateTime
105107

106108
try {
107109
$ErrorActionPreference = 'Stop'
108-
$vmss = Get-AzResource -ResourceId $vmssId | Get-AzVmss
109110
$outputFileNameVMSS = ('State_VMSS_' + $vmss.Name + "_" + $vmss.ResourceGroupName + "_" + $backupDateTime + ".json")
110111
$outputFilePathVSS = Join-Path -Path $RecoveryBackupPath -ChildPath $outputFileNameVMSS
111112

AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/GetVmssFromBasicLoadBalancer/GetVmssFromBasicLoadBalancer.psm1

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ function GetVmssFromBasicLoadBalancer {
99

1010
try {
1111
$ErrorActionPreference = 'Stop'
12-
$vmssId = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object { ($_ -split '/virtualMachines/')[0].ToLower() } | Select-Object -Unique
12+
13+
# check backend pools and nat rules for vmssids
14+
$vmssId = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id + $BasicLoadBalancer.inboundNatRules.BackendIpConfiguration.id | Foreach-Object {
15+
If (![string]::IsNullOrEmpty($_)) {
16+
($_ -split '/virtualMachines/')[0].ToLower() }
17+
} | Select-Object -Unique
1318

1419
log -Message "[GetVmssFromBasicLoadBalancer] Getting VMSS object '$vmssId' from Azure"
1520
$vmss = Get-AzResource -ResourceId $vmssId | Get-AzVmss

AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/InboundNatPoolsMigration/InboundNatPoolsMigration.psm1

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,17 @@ function InboundNatPoolsMigration {
8383
param (
8484
[Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer,
8585
[Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $StdLoadBalancer,
86-
[Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $refVmss
86+
[Parameter(Mandatory = $False)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $refVmss
8787
)
8888
log -Message "[InboundNatPoolsMigration] Initiating Inbound NAT Pools Migration"
8989

9090
$inboundNatPools = $BasicLoadBalancer.InboundNatPools
91+
92+
If ($inboundNatPools.count -eq 0) {
93+
log -Message "[InboundNatPoolsMigration] Load balancer has no NAT Pools to migrate"
94+
return
95+
}
96+
9197
foreach ($pool in $inboundNatPools) {
9298
log -Message "[InboundNatPoolsMigration] Adding Inbound NAT Pool $($pool.Name) to Standard Load Balancer"
9399
$frontEndIPConfig = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $StdLoadBalancer -Name ($pool.FrontEndIPConfiguration.Id.split('/')[-1])
@@ -132,40 +138,49 @@ function InboundNatPoolsMigration {
132138
log 'Warning' $message
133139
}
134140

135-
$vmss = GetVmssFromBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer
141+
If ($refVmss) {
142+
log -Message "[InboundNatPoolsMigration] Associating Inbound NAT Pools to VMSS"
136143

137-
_MigrateNetworkInterfaceConfigurations -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -vmss $vmss -refVmss $refVmss
144+
$vmss = GetVmssFromBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer
138145

139-
# Update VMSS on Azure
140-
log -Message "[InboundNatPoolsMigration] Saving VMSS $($vmss.Name)"
141-
try {
142-
$ErrorActionPreference = 'Stop'
146+
_MigrateNetworkInterfaceConfigurations -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -vmss $vmss -refVmss $refVmss
143147

144-
Update-Vmss -Vmss $vmss
145-
}
146-
catch {
147-
$exceptionType = (($_.Exception.Message -split 'ErrorCode:')[1] -split 'ErrorMessage:')[0].Trim()
148-
if($exceptionType -eq "MaxUnhealthyInstancePercentExceededBeforeRollingUpgrade"){
149-
$message = "[InboundNatPoolsMigration] 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: $_"
150-
log 'Error' $message -terminateOnError
148+
# Update VMSS on Azure
149+
log -Message "[InboundNatPoolsMigration] Saving VMSS $($vmss.Name)"
150+
try {
151+
$ErrorActionPreference = 'Stop'
152+
153+
Update-Vmss -Vmss $vmss
151154
}
152-
else {
153-
$message = "[InboundNatPoolsMigration] An error occured when attempting to update VMSS network config on the 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: $_"
154-
log 'Error' $message -terminateOnError
155+
catch {
156+
$exceptionType = (($_.Exception.Message -split 'ErrorCode:')[1] -split 'ErrorMessage:')[0].Trim()
157+
if($exceptionType -eq "MaxUnhealthyInstancePercentExceededBeforeRollingUpgrade"){
158+
$message = "[InboundNatPoolsMigration] 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: $_"
159+
log 'Error' $message -terminateOnError
160+
}
161+
else {
162+
$message = "[InboundNatPoolsMigration] An error occured when attempting to update VMSS network config on the 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: $_"
163+
log 'Error' $message -terminateOnError
164+
}
155165
}
156-
}
157166

158-
# Update Instances
159-
UpdateVmssInstances -vmss $vmss
167+
# Update Instances
168+
UpdateVmssInstances -vmss $vmss
169+
170+
<#
171+
This will happen in the backend pool migration...
172+
# Restore VMSS Upgrade Policy Mode
173+
#_RestoreUpgradePolicyMode -vmss $vmss -refVmss $refVmss
160174
161-
<#
162-
This will happen in the backend pool migration...
163-
# Restore VMSS Upgrade Policy Mode
164-
#_RestoreUpgradePolicyMode -vmss $vmss -refVmss $refVmss
175+
# Update VMSS on Azure
176+
#Update-Vmss -vmss $vmss
177+
#>
165178

166-
# Update VMSS on Azure
167-
#Update-Vmss -vmss $vmss
168-
#>
179+
log -Message "[InboundNatPoolsMigration] Finished associating Inbound NAT Pools to VMSS"
180+
}
181+
Else {
182+
log -Message "[InboundNatPoolsMigration] No VMSS found associated with Basic Load Balancer (VM or empty backend). Skipping VMSS Inbound NAT Pool association"
183+
}
169184

170185
log -Message "[InboundNatPoolsMigration] Inbound NAT Pools Migration Completed"
171186
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#
2+
# Module manifest for module 'Start-AzNATPoolMigration'
3+
#
4+
# Generated by: Matthew Bratschun
5+
#
6+
# Generated on: 3/21/2023
7+
#
8+
9+
@{
10+
11+
# Script module or binary module file associated with this manifest.
12+
RootModule = 'NatPoolToNatRuleMigration'
13+
14+
# Version number of this module.
15+
ModuleVersion = '0.0.0'
16+
17+
# Supported PSEditions
18+
# CompatiblePSEditions = @()
19+
20+
# ID used to uniquely identify this module
21+
GUID = 'ed27ddb0-e430-484e-81b9-1bbeec966b0d'
22+
23+
# Author of this module
24+
Author = 'Matthew Bratschun at FastTrack for Azure'
25+
26+
# Company or vendor of this module
27+
CompanyName = 'Microsoft'
28+
29+
# Copyright statement for this module
30+
Copyright = '(c) 2023 Microsoft. All rights reserved.'
31+
32+
# Description of the functionality provided by this module
33+
Description = 'Migrates an Azure Standard Load Balancer Inbound NAT Pools to Inbound NAT Rules'
34+
35+
# Minimum version of the PowerShell engine required by this module
36+
# PowerShellVersion = ''
37+
38+
# Name of the PowerShell host required by this module
39+
# PowerShellHostName = ''
40+
41+
# Minimum version of the PowerShell host required by this module
42+
# PowerShellHostVersion = ''
43+
44+
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
45+
# DotNetFrameworkVersion = ''
46+
47+
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
48+
# ClrVersion = ''
49+
50+
# Processor architecture (None, X86, Amd64) required by this module
51+
# ProcessorArchitecture = ''
52+
53+
# Modules that must be imported into the global environment prior to importing this module
54+
# RequiredModules = @()
55+
56+
# Assemblies that must be loaded prior to importing this module
57+
# RequiredAssemblies = @()
58+
59+
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
60+
# ScriptsToProcess = @()
61+
62+
# Type files (.ps1xml) to be loaded when importing this module
63+
# TypesToProcess = @()
64+
65+
# Format files (.ps1xml) to be loaded when importing this module
66+
# FormatsToProcess = @()
67+
68+
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
69+
# NestedModules = @()
70+
71+
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
72+
FunctionsToExport = @('Start-NatPoolToNatRuleMigration')
73+
74+
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
75+
CmdletsToExport = @()
76+
77+
# Variables to export from this module
78+
VariablesToExport = @()
79+
80+
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
81+
AliasesToExport = @()
82+
83+
# DSC resources to export from this module
84+
# DscResourcesToExport = @()
85+
86+
# List of all modules packaged with this module
87+
# ModuleList = @()
88+
89+
# List of all files packaged with this module
90+
# FileList = @()
91+
92+
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
93+
PrivateData = @{
94+
95+
PSData = @{
96+
97+
# Tags applied to this module. These help with module discovery in online galleries.
98+
Tags = 'AzureBasicLoadBalancerUpgrade', 'Azure', 'LoadBalancer', 'Upgrade',
99+
'VMSS', 'Migrate', 'NATPool'
100+
101+
# A URL to the license for this module.
102+
# LicenseUri = ''
103+
104+
# A URL to the main website for this project.
105+
ProjectUri = 'https://github.com/Azure/AzLoadBalancerMigration'
106+
107+
# A URL to an icon representing this module.
108+
# IconUri = ''
109+
110+
# ReleaseNotes of this module
111+
# ReleaseNotes = ''
112+
113+
# Prerelease string of this module
114+
# Prerelease = ''
115+
116+
# Flag to indicate whether the module requires explicit user acceptance for install/update/save
117+
# RequireLicenseAcceptance = $false
118+
119+
# External dependent modules of this module
120+
# ExternalModuleDependencies = @()
121+
122+
} # End of PSData hashtable
123+
124+
} # End of PrivateData hashtable
125+
126+
# HelpInfo URI of this module
127+
# HelpInfoURI = ''
128+
129+
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
130+
# DefaultCommandPrefix = ''
131+
132+
}
133+

0 commit comments

Comments
 (0)