diff --git a/AzureBasicLoadBalancerUpgrade/README.md b/AzureBasicLoadBalancerUpgrade/README.md index d2018fdf..0e8b53a5 100644 --- a/AzureBasicLoadBalancerUpgrade/README.md +++ b/AzureBasicLoadBalancerUpgrade/README.md @@ -18,6 +18,7 @@ The PowerShell module performs the following functions: - Migrates Virtual Machine Scale Set and Virtual Machine backend pool members from the Basic Load Balancer to the Standard Load Balancer. - 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. - Upgrades instance-level Public IP addresses associated with Virtual Machine Scale Set or Virtual Machine instances +- Upgrades Inbound NAT Pools to Inbound NAT Rules for Virtual Machine Scale Set backends. Specify -skipUpgradeNATPoolsToNATRules to skip this upgrade. - Logs the upgrade operation for easy audit and failure recovery. >[!WARNING] @@ -207,7 +208,8 @@ The script migrates the following from the Basic Load Balancer to the Standard L - Inbound NAT Rules: - All user-created NAT rules are migrated to the new Standard Load Balancer - Inbound NAT Pools: - - All inbound NAT Pools will be migrated to the new Standard Load Balancer + - By default, NAT Pools are upgraded to NAT Rules + - To migrate NAT Pools instead, specify the -skipUpgradeNATPoolsToNATRules parameter when upgrading - Backend pools: - All backend pools are migrated to the new Standard Load Balancer - All Virtual Machine Scale Set and Virtual Machine network interfaces and IP configurations are migrated to the new Standard Load Balancer diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/AzureBasicLoadBalancerUpgrade.psd1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/AzureBasicLoadBalancerUpgrade.psd1 index 6d08ec91..1bbb9d76 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/AzureBasicLoadBalancerUpgrade.psd1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/AzureBasicLoadBalancerUpgrade.psd1 @@ -12,7 +12,7 @@ RootModule = 'AzureBasicLoadBalancerUpgrade' # Version number of this module. - ModuleVersion = '2.3.4' + ModuleVersion = '2.4.0' # Supported PSEditions # CompatiblePSEditions = @() @@ -107,7 +107,7 @@ # IconUri = '' # ReleaseNotes of this module - ReleaseNotes = 'Fix spurious error when calling _HardCopyObject when an IPConfig has no pool membership' + ReleaseNotes = 'Fix NAT Rule backend migration, Add NAT Pool to NAT Rule migration' # Prerelease string of this module # Prerelease = '' diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackendPoolMigration/BackendPoolMigration.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackendPoolMigration/BackendPoolMigration.psm1 index 4b7fbf81..75578020 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackendPoolMigration/BackendPoolMigration.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackendPoolMigration/BackendPoolMigration.psm1 @@ -197,6 +197,7 @@ function BackendPoolMigrationVM { $lbBeNicId = ($BackendIpConfiguration.Id -split '/ipConfigurations/')[0] $ipConfigName = ($BackendIpConfiguration.Id -split '/ipConfigurations/')[1] + # create empty array for this Nic ID if it doesn't exist If (!$backendPoolNicTable[$lbBeNicId]) { $backendPoolNicTable[$lbBeNicId] = @(@{ipConfigs = @{} }) } diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupBasicLoadBalancer/BackupBasicLoadBalancer.psd1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupResources/BackupResources.psd1 similarity index 97% rename from AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupBasicLoadBalancer/BackupBasicLoadBalancer.psd1 rename to AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupResources/BackupResources.psd1 index c479c28a..c8cdf369 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupBasicLoadBalancer/BackupBasicLoadBalancer.psd1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupResources/BackupResources.psd1 @@ -1,5 +1,5 @@ # -# Module manifest for module 'BackupBasicLoadBalancer' +# Module manifest for module 'BackupResources' # # Generated by: Victor Santana # @@ -9,7 +9,7 @@ @{ # Script module or binary module file associated with this manifest. -RootModule = 'BackupBasicLoadBalancer' +RootModule = 'BackupResources' # Version number of this module. ModuleVersion = '0.1.4' diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupBasicLoadBalancer/BackupBasicLoadBalancer.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupResources/BackupResources.psm1 similarity index 96% rename from AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupBasicLoadBalancer/BackupBasicLoadBalancer.psm1 rename to AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupResources/BackupResources.psm1 index dd2f32c8..f35b6e68 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupBasicLoadBalancer/BackupBasicLoadBalancer.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/BackupResources/BackupResources.psm1 @@ -1,5 +1,6 @@ # Load Modules Import-Module ((Split-Path $PSScriptRoot -Parent) + "/Log/Log.psd1") +Import-Module ((Split-Path $PSScriptRoot -Parent) + "/GetVmssFromBasicLoadBalancer/GetVmssFromBasicLoadBalancer.psd1") function RestoreLoadBalancer { [CmdletBinding()] @@ -96,8 +97,9 @@ Function BackupVmss { log -Message "[BackupVmss] Initiating Backup of VMSS to path '$RecoveryBackupPath'" # Backup VMSS Object - $vmssIds = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object { ($_ -split '/virtualMachines/')[0].ToLower() } | Select-Object -Unique - foreach ($vmssId in $vmssIds) { + $vmsses = GetVmssFromBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + foreach ($vmss in $vmsses) { + $vmssId = $vmss.Id $message = "[BackupVmss] Attempting to create a file-based backup VMSS with id '$vmssId'" log -Severity Information -Message $message @@ -105,7 +107,6 @@ Function BackupVmss { try { $ErrorActionPreference = 'Stop' - $vmss = Get-AzResource -ResourceId $vmssId | Get-AzVmss $outputFileNameVMSS = ('State_VMSS_' + $vmss.Name + "_" + $vmss.ResourceGroupName + "_" + $backupDateTime + ".json") $outputFilePathVSS = Join-Path -Path $RecoveryBackupPath -ChildPath $outputFileNameVMSS diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/GetVmssFromBasicLoadBalancer/GetVmssFromBasicLoadBalancer.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/GetVmssFromBasicLoadBalancer/GetVmssFromBasicLoadBalancer.psm1 index 1949d73c..77d95dd7 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/GetVmssFromBasicLoadBalancer/GetVmssFromBasicLoadBalancer.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/GetVmssFromBasicLoadBalancer/GetVmssFromBasicLoadBalancer.psm1 @@ -9,7 +9,12 @@ function GetVmssFromBasicLoadBalancer { try { $ErrorActionPreference = 'Stop' - $vmssId = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object { ($_ -split '/virtualMachines/')[0].ToLower() } | Select-Object -Unique + + # check backend pools and nat rules for vmssids + $vmssId = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id + $BasicLoadBalancer.inboundNatRules.BackendIpConfiguration.id | Foreach-Object { + If (![string]::IsNullOrEmpty($_)) { + ($_ -split '/virtualMachines/')[0].ToLower() } + } | Select-Object -Unique log -Message "[GetVmssFromBasicLoadBalancer] Getting VMSS object '$vmssId' from Azure" $vmss = Get-AzResource -ResourceId $vmssId | Get-AzVmss diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/InboundNatPoolsMigration/InboundNatPoolsMigration.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/InboundNatPoolsMigration/InboundNatPoolsMigration.psm1 index 4f8c4ed7..7d7df34c 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/InboundNatPoolsMigration/InboundNatPoolsMigration.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/InboundNatPoolsMigration/InboundNatPoolsMigration.psm1 @@ -83,11 +83,17 @@ function InboundNatPoolsMigration { 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 + [Parameter(Mandatory = $False)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $refVmss ) log -Message "[InboundNatPoolsMigration] Initiating Inbound NAT Pools Migration" $inboundNatPools = $BasicLoadBalancer.InboundNatPools + + If ($inboundNatPools.count -eq 0) { + log -Message "[InboundNatPoolsMigration] Load balancer has no NAT Pools to migrate" + return + } + foreach ($pool in $inboundNatPools) { log -Message "[InboundNatPoolsMigration] Adding Inbound NAT Pool $($pool.Name) to Standard Load Balancer" $frontEndIPConfig = Get-AzLoadBalancerFrontendIpConfig -LoadBalancer $StdLoadBalancer -Name ($pool.FrontEndIPConfiguration.Id.split('/')[-1]) @@ -132,40 +138,49 @@ function InboundNatPoolsMigration { log 'Warning' $message } - $vmss = GetVmssFromBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + If ($refVmss) { + log -Message "[InboundNatPoolsMigration] Associating Inbound NAT Pools to VMSS" - _MigrateNetworkInterfaceConfigurations -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -vmss $vmss -refVmss $refVmss + $vmss = GetVmssFromBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer - # Update VMSS on Azure - log -Message "[InboundNatPoolsMigration] Saving VMSS $($vmss.Name)" - try { - $ErrorActionPreference = 'Stop' + _MigrateNetworkInterfaceConfigurations -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -vmss $vmss -refVmss $refVmss - Update-Vmss -Vmss $vmss - } - catch { - $exceptionType = (($_.Exception.Message -split 'ErrorCode:')[1] -split 'ErrorMessage:')[0].Trim() - if($exceptionType -eq "MaxUnhealthyInstancePercentExceededBeforeRollingUpgrade"){ - $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: $_" - log 'Error' $message -terminateOnError + # Update VMSS on Azure + log -Message "[InboundNatPoolsMigration] Saving VMSS $($vmss.Name)" + try { + $ErrorActionPreference = 'Stop' + + Update-Vmss -Vmss $vmss } - else { - $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: $_" - log 'Error' $message -terminateOnError + catch { + $exceptionType = (($_.Exception.Message -split 'ErrorCode:')[1] -split 'ErrorMessage:')[0].Trim() + if($exceptionType -eq "MaxUnhealthyInstancePercentExceededBeforeRollingUpgrade"){ + $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: $_" + log 'Error' $message -terminateOnError + } + else { + $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: $_" + log 'Error' $message -terminateOnError + } } - } - # Update Instances - UpdateVmssInstances -vmss $vmss + # Update Instances + UpdateVmssInstances -vmss $vmss + + <# + This will happen in the backend pool migration... + # Restore VMSS Upgrade Policy Mode + #_RestoreUpgradePolicyMode -vmss $vmss -refVmss $refVmss - <# - This will happen in the backend pool migration... - # Restore VMSS Upgrade Policy Mode - #_RestoreUpgradePolicyMode -vmss $vmss -refVmss $refVmss + # Update VMSS on Azure + #Update-Vmss -vmss $vmss + #> - # Update VMSS on Azure - #Update-Vmss -vmss $vmss - #> + log -Message "[InboundNatPoolsMigration] Finished associating Inbound NAT Pools to VMSS" + } + Else { + log -Message "[InboundNatPoolsMigration] No VMSS found associated with Basic Load Balancer (VM or empty backend). Skipping VMSS Inbound NAT Pool association" + } log -Message "[InboundNatPoolsMigration] Inbound NAT Pools Migration Completed" } diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatPoolToNatRuleMigration/NatPoolToNatRuleMigration.psd1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatPoolToNatRuleMigration/NatPoolToNatRuleMigration.psd1 new file mode 100644 index 00000000..ad23136b --- /dev/null +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatPoolToNatRuleMigration/NatPoolToNatRuleMigration.psd1 @@ -0,0 +1,133 @@ +# +# Module manifest for module 'Start-AzNATPoolMigration' +# +# Generated by: Matthew Bratschun +# +# Generated on: 3/21/2023 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'NatPoolToNatRuleMigration' + +# Version number of this module. +ModuleVersion = '0.0.0' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = 'ed27ddb0-e430-484e-81b9-1bbeec966b0d' + +# Author of this module +Author = 'Matthew Bratschun at FastTrack for Azure' + +# Company or vendor of this module +CompanyName = 'Microsoft' + +# Copyright statement for this module +Copyright = '(c) 2023 Microsoft. All rights reserved.' + +# Description of the functionality provided by this module +Description = 'Migrates an Azure Standard Load Balancer Inbound NAT Pools to Inbound NAT Rules' + +# Minimum version of the PowerShell engine required by this module +# PowerShellVersion = '' + +# Name of the PowerShell host required by this module +# PowerShellHostName = '' + +# Minimum version of the PowerShell host required by this module +# PowerShellHostVersion = '' + +# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# DotNetFrameworkVersion = '' + +# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only. +# ClrVersion = '' + +# Processor architecture (None, X86, Amd64) required by this module +# ProcessorArchitecture = '' + +# Modules that must be imported into the global environment prior to importing this module +# RequiredModules = @() + +# Assemblies that must be loaded prior to importing this module +# RequiredAssemblies = @() + +# Script files (.ps1) that are run in the caller's environment prior to importing this module. +# ScriptsToProcess = @() + +# Type files (.ps1xml) to be loaded when importing this module +# TypesToProcess = @() + +# Format files (.ps1xml) to be loaded when importing this module +# FormatsToProcess = @() + +# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess +# NestedModules = @() + +# 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. +FunctionsToExport = @('Start-NatPoolToNatRuleMigration') + +# 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. +CmdletsToExport = @() + +# Variables to export from this module +VariablesToExport = @() + +# 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. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# 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. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = 'AzureBasicLoadBalancerUpgrade', 'Azure', 'LoadBalancer', 'Upgrade', + 'VMSS', 'Migrate', 'NATPool' + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + ProjectUri = 'https://github.com/Azure/AzLoadBalancerMigration' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + # Prerelease string of this module + # Prerelease = '' + + # Flag to indicate whether the module requires explicit user acceptance for install/update/save + # RequireLicenseAcceptance = $false + + # External dependent modules of this module + # ExternalModuleDependencies = @() + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} + diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatPoolToNatRuleMigration/NatPoolToNatRuleMigration.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatPoolToNatRuleMigration/NatPoolToNatRuleMigration.psm1 new file mode 100644 index 00000000..f4e58a9e --- /dev/null +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatPoolToNatRuleMigration/NatPoolToNatRuleMigration.psm1 @@ -0,0 +1,258 @@ +Import-Module ((Split-Path $PSScriptRoot -Parent) + "/Log/Log.psd1") +Import-Module ((Split-Path $PSScriptRoot -Parent) + "/UpdateVmssInstances/UpdateVmssInstances.psd1") +Function Start-NatPoolToNatRuleMigration { + <# +.SYNOPSIS + Migrates an Azure Standard Load Balancer's Inbound NAT Pools to Inbound NAT Rules +.DESCRIPTION + This script creates a new NAT Rule for each NAT Pool, then adds a new Backend Pool with membership corresponding to the NAT Pool's original membership. + + For every NAT Pool, a new NAT Rule and backend pool will be created on the Load Balancer. Names will follow these patterns: + natrule_migrated_ + be_migrated_ + + The script reassociated NAT Pool VMSSes with the new NAT Rules, requiring multiple updates to the VMSS model and instance upgrades, which may cause service disruption during the migration. + + Backend port mapping for pool members will not necessarily be the same for NAT Pools with multiple associated VMSSes. +.NOTES + Please report issues at: https://github.com/Azure/AzLoadBalancerMigration/issues + +.LINK + https://github.com/Azure/AzLoadBalancerMigration + +.EXAMPLE + Import-Module AzureLoadBalancerNATPoolMigration + Start-NatPoolToNatRuleMigration -LoadBalancerName lb-standard-01 -verbose -ResourceGroupName rg-natpoollb + + # Migrates all NAT Pools on Load Balance 'lb-standard-01' to new NAT Rules. + +.EXAMPLE + Import-Module AzureLoadBalancerNATPoolMigration + $lb = Get-AzLoadBalancer | ? name -eq 'my-standard-lb-01' + $lb | Start-NatPoolToNatRuleMigration -LoadBalancerName lb-standard-01 -verbose -ResourceGroupName rg-natpoollb + + # Migrates all NAT Pools on Load Balance 'lb-standard-01' to new NAT Rules, passing the Load Balancer to the function through the pipeline. +#> + + [CmdletBinding()] + param( + [Parameter(Mandatory = $True, ValueFromPipeline, ParameterSetName = 'ByObject')][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $basicLoadBalancer, + [Parameter(Mandatory = $True, ValueFromPipeline, ParameterSetName = 'ByObject')][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $standardLoadBalancer + ) + + Function Wait-VMSSInstanceUpdate { + [CmdletBinding()] + param ( + [Parameter()] + [Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] + $vmss + ) + + $vmssInstances = Get-AzVmssVM -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name + + If ($vmssInstances.LatestModelApplied -contains $false) { + log -message "[Start-NatPoolToNatRuleMigration] `tWaiting for VMSS '$($vmss.Name)' to update all instances..." + Start-Sleep -Seconds 15 + Wait-VMSSInstanceUpdate -vmss $vmss + } + } + + $ErrorActionPreference = 'Stop' + + log -message "[Start-NatPoolToNatRuleMigration] Starting NAT Pool to NAT Rule migration..." + + # check load balancer sku + If ($standardLoadBalancer.sku.name -ne 'Standard') { + log -Severity Error -terminateOnError -message "[Start-NatPoolToNatRuleMigration] In order to migrate to NAT Rules, the Load Balancer must be a Standard SKU. Upgrade the Load Balancer first. See: https://learn.microsoft.com/azure/load-balancer/load-balancer-basic-upgrade-guidance" + } + + # check load balancer has inbound nat pools + If ($basicLoadBalancer.InboundNatPools.count -lt 1) { + log -message "[Start-NatPoolToNatRuleMigration] Load Balancer '$($basicLoadBalancer.Name)' does not have any Inbound NAT Pools to migrate" + return + } + + # create a hard copy of NAT Pool configs for later reference + $inboundNatPoolConfigs = $basicLoadBalancer.InboundNatPools | ConvertTo-Json | ConvertFrom-Json + + try { + $ErrorActionPreference = 'Stop' + + # get add virtual machine scale sets associated with the LB NAT Pools (via NAT Pool-create NAT Rules) + $vmssIds = $basicLoadBalancer.InboundNatRules.BackendIPConfiguration.Id | Foreach-Object { ($_ -split '/virtualMachines/')[0].ToLower() } | Select-Object -Unique + + If (![string]::IsNullOrEmpty($vmssIds)) { + log -message "[Start-NatPoolToNatRuleMigration] The following VMSSes are associated with the NAT Pools: $($vmssIds -join ', ')" + + $vmssObjects = $vmssIds | ForEach-Object { Get-AzResource -ResourceId $_ | Get-AzVmss } + + # build vmss table + $vmsses = @() + ForEach ($vmss in $vmssObjects) { + $vmsses += @{ + vmss = $vmss + updateRequired = $false + } + } + } + } + catch { + log -Severity Error -message "[Start-NatPoolToNatRuleMigration] An error occured while getting the VMSSes associated with the NAT Pools. Migration will continue. If VMSSes were associated with NAT Pools, they will need to be manually reassociated post-migration!: $_" + } + + # check that vmsses use Manual or Automatic upgrade policy + $incompatibleUpgradePolicyVMSSes = $vmsses.vmss | Where-Object { $_.UpgradePolicy.Mode -notIn 'Manual', 'Automatic' } + If ($incompatibleUpgradePolicyVMSSes.count -gt 0) { + log -Severity Error -terminateOnError -message "[Start-NatPoolToNatRuleMigration] The following VMSSes have upgrade policies which are not Manual or Automatic: $($incompatibleUpgradePolicyVMSSes.id)" + } + + try { + log -Message "[Start-NatPoolToNatRuleMigration] Starting adding new NAT Rules and Backend Pools to load balancer..." + + $ErrorActionPreference = 'Stop' + + # update load balancer with nat rule configurations + $natPoolToBEPMap = @{} # { natPoolId = backendPoolId, ... } + ForEach ($inboundNATPool in $inboundNatPoolConfigs) { + + # add a new backend pool for the NAT rule + $newBackendPoolName = "be_migrated_$($inboundNATPool.Name)" + + log -message "[Start-NatPoolToNatRuleMigration] Adding new Backend Pool '$newBackendPoolName' to LB for NAT Pool '$($inboundNATPool.Name)'" + $standardLoadBalancer = $standardLoadBalancer | Add-AzLoadBalancerBackendAddressPoolConfig -Name $newBackendPoolName + $natPoolToBEPMap[$inboundNATPool.Id] = '{0}/backendAddressPools/{1}' -f $standardLoadBalancer.Id, $newBackendPoolName + + # update the load balancer config + $standardLoadBalancer = $standardLoadBalancer | Set-AzLoadBalancer + + # add a NAT rule config + $frontendIPConfiguration = New-Object Microsoft.Azure.Commands.Network.Models.PSFrontendIPConfiguration + $frontendIPConfiguration.id = $inboundNATPool.FrontendIPConfiguration.Id -replace $basicLoadBalancer.Id, $standardLoadBalancer.Id + + $backendAddressPool = $standardLoadBalancer.BackendAddressPools | Where-Object { $_.name -eq $newBackendPoolName } + + $newNatRuleName = "natrule_migrated_$($inboundNATPool.Name)" + + log -message "[Start-NatPoolToNatRuleMigration] Adding new NAT Rule '$newNatRuleName' to LB..." + $standardLoadBalancer = $standardLoadBalancer | Add-AzLoadBalancerInboundNatRuleConfig -Name $newNatRuleName ` + -Protocol $inboundNATPool.Protocol ` + -FrontendPortRangeStart $inboundNATPool.FrontendPortRangeStart ` + -FrontendPortRangeEnd $inboundNATPool.FrontendPortRangeEnd ` + -BackendPort $inboundNATPool.BackendPort ` + -FrontendIpConfiguration $frontendIPConfiguration ` + -BackendAddressPool $backendAddressPool + + # update the load balancer config + $standardLoadBalancer = $standardLoadBalancer | Set-AzLoadBalancer + } + + log -Message "[Start-NatPoolToNatRuleMigration] Finished adding new NAT Rules and Backend Pools to load balancer." + } + catch { + log -Severity Error -Message "[Start-NatPoolToNatRuleMigration] An error occured while updating the Load Balancer with new NAT Rules and additional Backend Pools. To recover, address the cause of the following error, then follow the steps at https://aka.ms/basiclbupgradefailure to retry the migration. Error: $_" -terminateOnError + } + + If ($vmsses) { + # add vmss model ip configs to new backend pools + log -message "[Start-NatPoolToNatRuleMigration] Adding new backend pools to VMSS model ipConfigs..." + + try { + $ErrorActionPreference = 'Stop' + ForEach ($vmssItem in $vmsses) { + ForEach ($nicConfig in $vmssItem.vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations) { + ForEach ($ipConfig in $nicConfig.ipConfigurations) { + + # if there is an existing ipconfig to nat pool association, add the ipconfig to the new backend pool for the nat rule + If ($ipconfigRecord = $ipConfigNatPoolMap | Where-Object { + $_.vmssId -eq $vmssItem.vmss.id -and + $_.nicName -eq $nicConfig.Name -and + $_.ipConfigName -eq $ipConfig.Name + }) { + + #$backendPoolList = New-Object System.Collections.Generic.List[Microsoft.Azure.Commands.Network.Models.PSBackendAddressPool] + $backendPoolList = New-Object System.Collections.Generic.List[Microsoft.Azure.Management.Compute.Models.SubResource] + + # add existing backend pools to pool list to maintain existing membership + ForEach ($existingBackendPoolId in $ipConfig.LoadBalancerBackendAddressPools.id) { + $backendPoolObj = new-object Microsoft.Azure.Management.Compute.Models.SubResource + $backendPoolObj.id = $existingBackendPoolId + + $backendPoolList.Add($backendPoolObj) + } + #$backendPoolObj = new-object Microsoft.Azure.Commands.Network.Models.PSBackendAddressPool + $backendPoolObj = New-Object Microsoft.Azure.Management.Compute.Models.SubResource + $backendPoolObj.id = $natPoolToBEPMap[$ipconfigRecord.inboundNatPoolId] + + log -message "[Start-NatPoolToNatRuleMigration] Adding VMSS '$($vmssItem.vmss.Name)' NIC '$($nicConfig.Name)' ipConfig '$($ipConfig.Name)' to new backend pool '$($backendPoolObj.id)'" + $backendPoolList.Add($backendPoolObj) + + $ipConfig.LoadBalancerBackendAddressPools = $backendPoolList + + $vmssItem.updateRequired = $true + } + } + } + } + + # update each vmss to add the backend pool membership to the model + $vmssModelUpdateAddBackendPoolJobs = @() + ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { + $vmss = $vmssItem.vmss + $job = $vmss | Update-AzVmss -AsJob + $job.Name = $vmss.vmss.Name + '_modelUpdateAddBackendPool' + $vmssModelUpdateAddBackendPoolJobs += $job + } + + log -message "[Start-NatPoolToNatRuleMigration] Waiting for VMSS model to update to include the new Backend Pools..." + While ($vmssModelUpdateAddBackendPoolJobs.State -contains 'Running') { + Start-Sleep -Seconds 15 + log -message "[Start-NatPoolToNatRuleMigration] `t[$(Get-Date -Format 'yyyy-MM-ddTHH:mm:sszz')]Waiting for VMSS model update jobs to complete..." + } + + $vmssModelUpdateAddBackendPoolJobs | Foreach-Object { + $job = $_ + If ($job.Error -or $job.State -eq 'Failed') { + log -Severity Error -terminateOnError -message "[Start-NatPoolToNatRuleMigration] An error occured while updating the VMSS model to add the NAT Rules: $($job.error; $job | Receive-Job)." + } + } + + # update all vmss instances to include the backend pool + log -message "[Start-NatPoolToNatRuleMigration] Waiting for VMSS instances to update to include the new Backend Pools..." + $vmssInstanceUpdateAddBackendPoolJobs = @() + ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { + + If ($vmss.UpgradePolicy.Mode -eq 'Automatic') { + Wait-VMSSInstanceUpdate -vmss $vmss + } + Else { + $vmss = $vmssItem.vmss + $vmssInstances = Get-AzVmssVM -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name + + $job = Update-AzVmssInstance -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name -InstanceId $vmssInstances.InstanceId -AsJob + $job.Name = $vmss.vmss.Name + '_instanceUpdateAddBackendPool' + $vmssInstanceUpdateAddBackendPoolJobs += $job + } + } + + # for manual update vmsses, wait for the instance update jobs to complete + If ($vmssInstanceUpdateAddBackendPoolJobs.count -gt 0) { + $vmssInstanceUpdateAddBackendPoolJobs | Wait-Job | Foreach-Object { + $job = $_ + If ($job.Error -or $job.State -eq 'Failed') { + log -Severity Error -terminateOnError -message "[Start-NatPoolToNatRuleMigration] An error occured while updating the VMSS instanaces to add the NAT Rules: $($job.error; $job | Receive-Job)." + } + } + } + } + catch { + log -Severity Error -message "[Start-NatPoolToNatRuleMigration] An error occured while updating the VMSS model to add the new Backend Pools. Migration will attempt to continue; if successful, VMSSes will need to be manually associated with new NAT Rules. If continuing fails, address the cause of the following error, then follow the steps at https://aka.ms/basiclbupgradefailure to retry the migration.: $_" + } + } + Else { + log -message "[Start-NatPoolToNatRuleMigration] No VMSSes are associated with the NAT Pools, migrated as empty" + } + + log -Message "[Start-NatPoolToNatRuleMigration] NAT Pool to NAT Rule migration complete." +} + +Export-ModuleMember -Function Start-NatPoolToNatRuleMigration \ No newline at end of file diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatRulesMigration/NatRulesMigration.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatRulesMigration/NatRulesMigration.psm1 index f0818c7b..6e67a4a7 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatRulesMigration/NatRulesMigration.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NatRulesMigration/NatRulesMigration.psm1 @@ -1,5 +1,85 @@ # Load Modules Import-Module ((Split-Path $PSScriptRoot -Parent) + "/Log/Log.psd1") + +function _NatRuleNicMembershipMigration { + [CmdletBinding()] + param ( + [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, + [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $StdLoadBalancer + ) + log -Message "[NatRuleNicMembershipMigration] Initiating NAT rule VM membership migration" + + log -Message "[NatRuleNicMembershipMigration] Adding original VMs to the new Standard Load Balancer NAT rules" + + # build table of NICs and their ipconfigs and associate them to backend pools + # this is used to associate the ipconfigs to the backend pools on the NICs in a single operation per NIC + $natRuleNicTable = @{} + ForEach ($InboundNATRule in $BasicLoadBalancer.InboundNATRules) { + + # create a subresource to represent the nat rule + $subResource = New-Object Microsoft.Azure.Commands.Network.Models.PSInboundNatRule + $subResource.Id = ($StdLoadBalancer.InboundNatRules | Where-Object { $_.Name -eq $InboundNATRule.Name }).Id + + If ($InboundNATRule.BackendIpConfiguration.id) { + $NatRuleIpConfiguration = $InboundNATRule.BackendIpConfiguration + + $lbNatRuleNicId = ($NatRuleIpConfiguration.Id -split '/ipConfigurations/')[0] + $ipConfigName = ($NatRuleIpConfiguration.Id -split '/ipConfigurations/')[1] + + # create empty list of ip configs for this NIC if it doesn't exist + If (!$natRuleNicTable[$lbNatRuleNicId]) { + $natRuleNicTable[$lbNatRuleNicId] = @(@{ipConfigs = @{} }) + } + # add ip config with associated nat rule to list + # create new nat rule list for this ipconfig if one doesn't exist + If (!$natRuleNicTable[$lbNatRuleNicId].ipConfigs[$ipConfigName]) { + + $natRulesList = New-Object 'System.Collections.Generic.List[Microsoft.Azure.Commands.Network.Models.PSInboundNatRule]' + $natRulesList.Add($subResource) + + $natRuleNicTable[$lbNatRuleNicId].ipConfigs[$ipConfigName] = @{natRulesList = $natRulesList} + } + # add nat rule to existing nat rule list for this ipconfig if the list already exists + Else { + $natRuleNicTable[$lbNatRuleNicId].ipConfigs[$ipConfigName].natRulesList.add($subResource) + } + } + Else { + log -Message "[NatRuleNicMembershipMigration] NAT rule '$($InboundNATRule.Name)' does not have a backend ip configuration, skipping NIC association" + } + } + + # loop though nics and associate ipconfigs to backend pools + $jobs = @() + ForEach ($nicRecord in $natRuleNicTable.GetEnumerator()) { + + log -Message "[NatRuleNicMembershipMigration] Adding ipconfigs on NIC $($nicRecord.Name.split('/')[-1]) to NAT rules" + + try { + $nic = Get-AzNetworkInterface -ResourceId $nicRecord.Name + } + catch { + $message = "[NatRuleNicMembershipMigration] An error occured getting the Network Interface '$($nicRecord.Name)'. Check that the NIC exists. To recover, address the cause of the following error, then follow the steps at https://aka.ms/basiclbupgradefailure to retry the migration. Error: $_" + log 'Error' $message -terminateOnError + } + + ForEach ($nicIPConfig in $nic.IpConfigurations) { + $nicIPConfig.loadBalancerInboundNatRules = $natRuleNicTable[$nicRecord.Name].ipConfigs[$nicIPConfig.Name].natRulesList + } + + $jobs += Set-AzNetworkInterface -NetworkInterface $nic -AsJob + } + + log -Message "[NatRuleNicMembershipMigration] Waiting for all '$($jobs.count)' NIC NAT Rule association jobs to complete" + $jobs | Wait-Job -Timeout $defaultJobWaitTimeout | Foreach-Object { + $job = $_ + If ($job.Error -or $job.State -eq 'Failed') { + log -Severity Error -Message "Associating NIC with LB NAT Rule failed with the following errors: $($job.error; $job | Receive-Job). Migration will continue--to recover, manually associate NICs with the backend pool after the script completes. See association table: `n $($backendPoolNicTable | ConvertTo-Json -depth 10)" + } + } + + log -Message "[NatRuleNicMembershipMigration] NAT Rule Migration Completed" +} function NatRulesMigration { [CmdletBinding()] param ( @@ -67,25 +147,33 @@ function NatRulesMigration { } log -Message "[NatRulesMigration] Saving Standard Load Balancer $($StdLoadBalancer.Name)" - try { - $ErrorActionPreference = 'Stop' + if ($StdLoadBalancer.InboundNatRules.Count -eq 0) { + log -Message "[NatRulesMigration] No NAT Rules to migrate. Skipping save." + return + } + else { + try { + $ErrorActionPreference = 'Stop' - $UpdateLBNATRulesJob = Set-AzLoadBalancer -LoadBalancer $StdLoadBalancer -AsJob + $UpdateLBNATRulesJob = Set-AzLoadBalancer -LoadBalancer $StdLoadBalancer -AsJob - While ($UpdateLBNATRulesJob.State -eq 'Running') { - Start-Sleep -Seconds 15 - log -Message "[NatRulesMigration] Waiting for saving standard load balancer $($StdLoadBalancer.Name) job to complete..." - } + While ($UpdateLBNATRulesJob.State -eq 'Running') { + Start-Sleep -Seconds 15 + log -Message "[NatRulesMigration] Waiting for saving standard load balancer $($StdLoadBalancer.Name) job to complete..." + } - If ($UpdateLBNATRulesJob.Error -or $UpdateLBNATRulesJob.State -eq 'Failed') { - Write-Error $UpdateLBNATRulesJob.Error + If ($UpdateLBNATRulesJob.Error -or $UpdateLBNATRulesJob.State -eq 'Failed') { + Write-Error $UpdateLBNATRulesJob.Error + } + } + catch { + $message = "[NatRulesMigration] Failed to update new standard load balancer '$($stdLoadBalancer.Name)' in resource group '$($StdLoadBalancer.ResourceGroupName)' after attempting to add migrated inbound NAT rule configurations. Migration will continue, INBOUND NAT RULES WILL NEED TO BE MANUALLY ADDED to the load balancer. Error: $_" + log "Error" $message } - } - catch { - $message = "[NatRulesMigration] Failed to update new standard load balancer '$($stdLoadBalancer.Name)' in resource group '$($StdLoadBalancer.ResourceGroupName)' after attempting to add migrated inbound NAT rule configurations. Migration will continue, INBOUND NAT RULES WILL NEED TO BE MANUALLY ADDED to the load balancer. Error: $_" - log "Error" $message } log -Message "[NatRulesMigration] Nat Rules Migration Completed" + + _NatRuleNicMembershipMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer } Export-ModuleMember -Function NatRulesMigration diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NsgCreation/NsgCreation.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NsgCreation/NsgCreation.psm1 index dcdf64ba..8cee84a8 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NsgCreation/NsgCreation.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/NsgCreation/NsgCreation.psm1 @@ -1,6 +1,7 @@ # 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 _AddLBNSGSecurityRules { [CmdletBinding()] @@ -143,9 +144,12 @@ function _GetVMNSG { } log -Message "[NsgCreationVM] Looping all VMs in the backend pool of the Load Balancer" - $nicIds = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object { ($_ -split '/ipConfigurations/')[0].ToLower() } | Select-Object -Unique + $nicIds = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id + $BasicLoadBalancer.inboundNatRules.BackendIpConfiguration.id | Foreach-Object { + if (![string]::IsNullOrEmpty($_)) {($_ -split '/ipConfigurations/')[0].ToLower() } + } | Select-Object -Unique - $joinedIPConfigIDs = ($BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | ForEach-Object { "'$_'" }) -join ',' + $joinedIPConfigIDs = ($BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id + $BasicLoadBalancer.inboundNatRules.BackendIpConfiguration.id | ForEach-Object { + if (![string]::IsNullOrEmpty($_)) {"'$_'" }}) -join ',' $joinedNicIDs = ($nicIDs | ForEach-Object { "'$_'" }) -join ',' # NOTE: the resource graph data will lag behind ARM by a couple minutes, so creating resource and immediately @@ -232,11 +236,9 @@ function NsgCreationVmss { log -Message "[NsgCreationVmss] Initiating NSG Creation for VMSS" log -Message "[NsgCreationVmss] Looping all VMSS in the backend pool of the Load Balancer" - $vmssIds = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object { ($_ -split '/virtualMachines/')[0].ToLower() } | Select-Object -Unique + $vmsses = GetVmssFromBasicLoadBalancer -BasicLoadBalancer $basicLoadBalancer - foreach ($vmssId in $vmssIds) { - $vmss = Get-AzResource -ResourceId $vmssId | Get-AzVmss - + foreach ($vmss in $vmsses) { log -Message "[NSGCreationVmss] Checking if VMSS $($vmss.Name) has a NSG" $vmssHasNSG = _GetVMSSNSG -vmss $vmss diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/PublicFEMigration/PublicFEMigration.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/PublicFEMigration/PublicFEMigration.psm1 index 2f17066a..02d8be11 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/PublicFEMigration/PublicFEMigration.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/PublicFEMigration/PublicFEMigration.psm1 @@ -12,7 +12,7 @@ function PublicIPToStatic { foreach ($feConfig in $basicLoadBalancerFeConfig) { $pip = Get-AzPublicIpAddress -ResourceGroupName $feConfig.PublicIpAddress.Id.Split('/')[4] -Name $feConfig.PublicIpAddress.Id.Split('/')[-1] if ($pip.PublicIpAllocationMethod -ne "Static") { - log -Message "[LBPublicIPToStatic] '$($pip.Name)' ('$($pip.IpAddress)') was using Dynamic IP, changing to Static IP allocation method." -Severity "Warning" + log -Message "[LBPublicIPToStatic] '$($pip.Name)' ('$($pip.IpAddress)') was using Dynamic IP, changing to Static IP allocation method." -Severity "Information" $pip.PublicIpAllocationMethod = "Static" try { @@ -43,7 +43,7 @@ function PublicFEMigration { foreach ($feConfig in $basicLoadBalancerFeConfig) { $pip = Get-AzPublicIpAddress -ResourceGroupName $feConfig.PublicIpAddress.Id.Split('/')[4] -Name $feConfig.PublicIpAddress.Id.Split('/')[-1] if ($pip.Sku.Name -ne "Standard") { - log -Message "[PublicFEMigration] '$($pip.Name)' ('$($pip.IpAddress)') is using Basic SKU, changing Standard SKU." -Severity "Warning" + log -Message "[PublicFEMigration] '$($pip.Name)' ('$($pip.IpAddress)') is using Basic SKU, changing Standard SKU." -Severity "Information" $pip.Sku.Name = "Standard" try { diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ScenariosMigration/ScenariosMigration.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ScenariosMigration/ScenariosMigration.psm1 index a1038315..ac9890ea 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ScenariosMigration/ScenariosMigration.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ScenariosMigration/ScenariosMigration.psm1 @@ -41,7 +41,7 @@ # Load Modules Import-Module ((Split-Path $PSScriptRoot -Parent) + "/AddLoadBalancerBackendAddressPool/AddLoadBalancerBackendAddressPool.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "/BackendPoolMigration/BackendPoolMigration.psd1") -Import-Module ((Split-Path $PSScriptRoot -Parent) + "/BackupBasicLoadBalancer/BackupBasicLoadBalancer.psd1") +Import-Module ((Split-Path $PSScriptRoot -Parent) + "/BackupResources/BackupResources.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "/GetVmssFromBasicLoadBalancer/GetVmssFromBasicLoadBalancer.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "/InboundNatPoolsMigration/InboundNatPoolsMigration.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "/LoadBalacingRulesMigration/LoadBalacingRulesMigration.psd1") @@ -56,6 +56,7 @@ Import-Module ((Split-Path $PSScriptRoot -Parent) + "/RemoveBasicLoadBalancer/Re Import-Module ((Split-Path $PSScriptRoot -Parent) + "/ValidateMigration/ValidateMigration.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "/VMPublicIPConfigMigration/VMPublicIPConfigMigration.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "/VmssPublicIPConfigMigration/VmssPublicIPConfigMigration.psd1") +Import-Module ((Split-Path $PSScriptRoot -Parent) + "/NatPoolToNatRuleMigration/NatPoolToNatRuleMigration.psd1") function _CreateStandardLoadBalancer { [CmdletBinding()] @@ -99,6 +100,7 @@ function PublicLBMigrationVmss { [Parameter(Mandatory = $true)][string] $RecoveryBackupPath, [Parameter(Mandatory = $true)][psobject] $scenario, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $false)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $refVmss ) @@ -156,9 +158,16 @@ function PublicLBMigrationVmss { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((10 / 14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer - # Migration of Inbound NAT Pools - Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams - InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } # Creating NSG for Standard Load Balancer Write-Progress -Status "Creating NSG for Standard Load Balancer" -PercentComplete ((12 / 14) * 100) @progressParams @@ -170,7 +179,7 @@ function PublicLBMigrationVmss { # validate the new standard load balancer configuration against the original basic load balancer configuration Write-Progress -Status "Validating the new standard load balancer configuration against the original basic load balancer configuration" -Completed @progressParams - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules.isPresent) } function InternalLBMigrationVmss { @@ -181,6 +190,7 @@ function InternalLBMigrationVmss { [Parameter(Mandatory = $true)][string] $RecoveryBackupPath, [Parameter(Mandatory = $true)][psobject] $scenario, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $false)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $refVmss ) @@ -230,9 +240,16 @@ function InternalLBMigrationVmss { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((10/14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer - # Migration of Inbound NAT Pools - Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11/14) * 100) @progressParams - InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } # Migration of Backend Address Pools Write-Progress -Status "Migrating Backend Address Pools" -PercentComplete ((12/14) * 100) @progressParams @@ -240,7 +257,7 @@ function InternalLBMigrationVmss { # validate the new standard load balancer configuration against the original basic load balancer configuration Write-Progress -Status "Validating the new standard load balancer configuration against the original basic load balancer configuration" -Completed @progressParams - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules.isPresent) } function RestoreExternalLBMigrationVmss { @@ -249,6 +266,7 @@ function RestoreExternalLBMigrationVmss { [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $vmss, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $true)][psobject] $scenario, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -303,6 +321,17 @@ function RestoreExternalLBMigrationVmss { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((10/14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # Migration of Inbound NAT Pools Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11/14) * 100) @progressParams InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss @@ -317,7 +346,7 @@ function RestoreExternalLBMigrationVmss { # validate the new standard load balancer configuration against the original basic load balancer configuration Write-Progress -Status "Validating the new standard load balancer configuration against the original basic load balancer configuration" -Completed @progressParams - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules.isPresent) } function RestoreInternalLBMigrationVmss { @@ -326,6 +355,7 @@ function RestoreInternalLBMigrationVmss { [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Compute.Automation.Models.PSVirtualMachineScaleSet] $vmss, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $true)][psobject] $scenario, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -372,6 +402,17 @@ function RestoreInternalLBMigrationVmss { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((8/14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # Migration of Inbound NAT Pools Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((9/14) * 100) @progressParams InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss @@ -382,7 +423,7 @@ function RestoreInternalLBMigrationVmss { # validate the new standard load balancer configuration against the original basic load balancer configuration Write-Progress -Status "Validating the new standard load balancer configuration against the original basic load balancer configuration" -Completed @progressParams - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules.isPresent) } function PublicLBMigrationVM { @@ -391,6 +432,7 @@ function PublicLBMigrationVM { [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, [Parameter(Mandatory = $true)][string] $RecoveryBackupPath, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $true)][psobject] $scenario, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -434,6 +476,17 @@ function PublicLBMigrationVM { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((8 / 14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # Creating NSG for Standard Load Balancer Write-Progress -Status "Creating NSG for Standard Load Balancer" -PercentComplete ((9 / 14) * 100) @progressParams NsgCreationVM -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer @@ -444,7 +497,7 @@ function PublicLBMigrationVM { # validate the new standard load balancer configuration against the original basic load balancer configuration Write-Progress -Status "Validating the new standard load balancer configuration against the original basic load balancer configuration" -Completed @progressParams - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules.isPresent) } function InternalLBMigrationVM { @@ -454,6 +507,7 @@ function InternalLBMigrationVM { [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, [Parameter(Mandatory = $true)][string] $RecoveryBackupPath, [Parameter(Mandatory = $true)][psobject] $scenario, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -492,6 +546,17 @@ function InternalLBMigrationVM { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((7 / 14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # Migration of Backend Address Pools Write-Progress -Status "Migrating Backend Address Pools" -PercentComplete ((8 / 14) * 100) @progressParams BackendPoolMigrationVM -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer @@ -507,6 +572,7 @@ function RestoreExternalLBMigrationVM { [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, [Parameter(Mandatory = $true)][psobject] $scenario, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -549,6 +615,17 @@ function RestoreExternalLBMigrationVM { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((8 / 14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # Creating NSG for Standard Load Balancer Write-Progress -Status "Creating NSG for Standard Load Balancer" -PercentComplete ((9 / 14) * 100) @progressParams NsgCreationVm -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer @@ -568,6 +645,7 @@ function RestoreInternalLBMigrationVM { [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, [Parameter(Mandatory = $true)][psobject] $scenario, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -602,6 +680,17 @@ function RestoreInternalLBMigrationVM { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((6 / 14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # Migration of Backend Address Pools Write-Progress -Status "Migrating Backend Address Pools" -PercentComplete ((7 / 14) * 100) @progressParams BackendPoolMigrationVM -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer @@ -617,6 +706,7 @@ function PublicLBMigrationEmpty { [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, [Parameter(Mandatory = $true)][string] $RecoveryBackupPath, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $true)][psobject] $scenario, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -656,9 +746,20 @@ function PublicLBMigrationEmpty { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((7/14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # validate the new standard load balancer configuration against the original basic load balancer configuration Write-Progress -Status "Validating the new standard load balancer configuration against the original basic load balancer configuration" -Completed @progressParams - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules.isPresent) } function InternalLBMigrationEmpty { @@ -667,6 +768,7 @@ function InternalLBMigrationEmpty { [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, [Parameter(Mandatory = $true)][string] $RecoveryBackupPath, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $true)][psobject] $scenario, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -678,14 +780,6 @@ function InternalLBMigrationEmpty { log -Message "[InternalLBMigrationEmpty] Internal Load Balancer with empty detected. Initiating Internal Load Balancer Migration" - # Backup Basic Load Balancer Configurations - Write-Progress -Status "Backup Basic Load Balancer Configurations" -PercentComplete ((1/14) * 100) @progressParams - BackupBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer -RecoveryBackupPath $RecoveryBackupPath - - # Deletion of Basic Load Balancer and Delete Basic Load Balancer - Write-Progress -Status "Deletion of Basic Load Balancer and Delete Basic Load Balancer" -PercentComplete ((2/14) * 100) @progressParams - RemoveBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer -BackendType 'Empty' - # Creation of Standard Load Balancer Write-Progress -Status "Creation of Standard Load Balancer" -PercentComplete ((3/14) * 100) @progressParams $StdLoadBalancer = _CreateStandardLoadBalancer -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancerName $StandardLoadBalancerName @@ -710,9 +804,20 @@ function InternalLBMigrationEmpty { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((8/14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer -refVmss $refVmss + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # validate the new standard load balancer configuration against the original basic load balancer configuration Write-Progress -Status "Validating the new standard load balancer configuration against the original basic load balancer configuration" -Completed @progressParams - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules.isPresent) } function RestoreExternalLBMigrationEmpty { @@ -720,6 +825,7 @@ function RestoreExternalLBMigrationEmpty { Param( [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $true)][psobject] $scenario, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -763,9 +869,20 @@ function RestoreExternalLBMigrationEmpty { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((8/14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # validate the new standard load balancer configuration against the original basic load balancer configuration Write-Progress -Status "Validating the new standard load balancer configuration against the original basic load balancer configuration" -Completed @progressParams - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules.isPresent) } function RestoreInternalLBMigrationEmpty { @@ -774,6 +891,7 @@ function RestoreInternalLBMigrationEmpty { [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $True)][string] $StandardLoadBalancerName, [Parameter(Mandatory = $true)][psobject] $scenario, + [Parameter(Mandatory = $false)][switch]$skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $false)][switch]$outputMigrationValiationObj ) @@ -808,9 +926,20 @@ function RestoreInternalLBMigrationEmpty { Write-Progress -Status "Migrating NAT Rules" -PercentComplete ((6/14) * 100) @progressParams NatRulesMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + If ($skipUpgradeNATPoolsToNATRules.IsPresent) { + # Migration of Inbound NAT Pools + Write-Progress -Status "Migrating Inbound NAT Pools" -PercentComplete ((11 / 14) * 100) @progressParams + InboundNatPoolsMigration -BasicLoadBalancer $BasicLoadBalancer -StdLoadBalancer $StdLoadBalancer + } + Else { + # upgrade NAT Pools to NAT Rules instead of migrating them + Write-Progress -Status "Upgrading NAT Pools to NAT Rules" -PercentComplete ((11 / 14) * 100) @progressParams + Start-NatPoolToNatRuleMigration -StandardLoadBalancer $StdLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + } + # validate the new standard load balancer configuration against the original basic load balancer configuration Write-Progress -Status "Validating the new standard load balancer configuration against the original basic load balancer configuration" -Completed @progressParams - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StdLoadBalancer.Name -outputMigrationValiationObj:$outputMigrationValiationObj -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules.isPresent) } function LBMigrationPrep { diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/Start-AzBasicLoadBalancerUpgrade/Start-AzBasicLoadBalancerUpgrade.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/Start-AzBasicLoadBalancerUpgrade/Start-AzBasicLoadBalancerUpgrade.psm1 index 478abc60..3bf6a440 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/Start-AzBasicLoadBalancerUpgrade/Start-AzBasicLoadBalancerUpgrade.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/Start-AzBasicLoadBalancerUpgrade/Start-AzBasicLoadBalancerUpgrade.psm1 @@ -3,7 +3,7 @@ Import-Module ((Split-Path $PSScriptRoot -Parent) + "\Log\Log.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "\ScenariosMigration\ScenariosMigration.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "\ValidateScenario\ValidateScenario.psd1") Import-Module ((Split-Path $PSScriptRoot -Parent) + "\ValidateMigration\ValidateMigration.psd1") -Import-Module ((Split-Path $PSScriptRoot -Parent) + "\BackupBasicLoadBalancer\BackupBasicLoadBalancer.psd1") +Import-Module ((Split-Path $PSScriptRoot -Parent) + "\BackupResources\BackupResources.psd1") <# .SYNOPSIS @@ -53,6 +53,9 @@ Use in combination with -validateCompletedMigration to validate a completed migr .PARAMETER StandardLoadBalancerName Name of the new Standard Load Balancer. If not specified, the name of the Basic load balancer will be reused. +.PARAMETER skipUpgradeNATPoolsToNATRules + If specified, the migration will skip upgrading NAT Pools to NAT Rules. NAT Rules are more managable and functional than NAT Pools, while providing the same functionality + .PARAMETER MultiLBConfig Array of objects containing the basic load balancer and standard load balancer name to migrate. Use this parameter to migrate multiple load balancers with shared backend pool members. Optionally, specify a new standard load balancer name for each basic load balancers. Example value: $multiLBConfig = @( @@ -110,12 +113,12 @@ Use in combination with -validateCompletedMigration to validate a completed migr # migrate multiple load balancers with shared backend pool members PS C:\> $multiLBConfig = @( @{ - 'standardLoadBalancerName' = 'myStandardLB01' 'basicLoadBalancer' = (Get-AzLoadBalancer -ResourceGroupName myRG -Name myBasicLB01) + 'standardLoadBalancerName' = 'myStandardLB01' # optional new standard load balancer name }, @{ - 'standardLoadBalancerName' = 'myStandardLB02' 'basicLoadBalancer' = (Get-AzLoadBalancer -ResourceGroupName myRG -Name myBasicLB02) + 'standardLoadBalancerName' = 'myStandardLB02' } ) PS C:\> Start-AzBasicLoadBalancerUpgrade -MultiLBConfig $multiLBConfig @@ -161,7 +164,13 @@ function Start-AzBasicLoadBalancerUpgrade { [Parameter(Mandatory = $false)][string] $RecoveryBackupPath = $pwd, [Parameter(Mandatory = $false)][switch] $FollowLog, [Parameter(Mandatory = $false)][switch] $validateScenarioOnly, - [Parameter(Mandatory = $True, ParameterSetName = 'MultiLB')][psobject[]] $multiLBConfig, # @(@{standardLoadBalancerName='lb-standard-01';basicLoadBalancer=<[Microsoft.Azure.Commands.Network.Models.PSLoadBalancer]>}) + [Parameter(Mandatory = $True, ParameterSetName = 'MultiLB')][psobject[]] $multiLBConfig, # @(@{basicLoadBalancer=<[Microsoft.Azure.Commands.Network.Models.PSLoadBalancer]>[;standardLoadBalancerName='lb-standard-01']}) + [Parameter(Mandatory = $false, ParameterSetName = 'ByName')][switch] + [Parameter(Mandatory = $false, ParameterSetName = 'ByObject')][switch] + [Parameter(Mandatory = $false, ParameterSetName = 'ByJsonVmss')][switch] + [Parameter(Mandatory = $false, ParameterSetName = 'MultiLB')][switch] + [Parameter(Mandatory = $false, ParameterSetName = 'ValidateCompletedMigration')][switch] + $skipUpgradeNATPoolsToNATRules, [Parameter(Mandatory = $true, ParameterSetName = 'ValidateCompletedMigration')][switch] $validateCompletedMigration, [Parameter(Mandatory = $true, ParameterSetName = 'ValidateCompletedMigration')][string] $basicLoadBalancerStatePath, [Parameter(Mandatory = $false)][switch] $outputMigrationValiationObj, @@ -207,7 +216,7 @@ function Start-AzBasicLoadBalancerUpgrade { # import basic LB from file $BasicLoadBalancer = RestoreLoadBalancer -BasicLoadBalancerJsonFile $basicLoadBalancerStatePath - ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StandardLoadBalancerName -OutputMigrationValiationObj:$($OutputMigrationValiationObj.IsPresent) + ValidateMigration -BasicLoadBalancer $BasicLoadBalancer -StandardLoadBalancerName $StandardLoadBalancerName -OutputMigrationValiationObj:$($OutputMigrationValiationObj.IsPresent) -natPoolsMigratedToNatRules:(!$skipUpgradeNATPoolsToNATRules) return } @@ -328,10 +337,11 @@ function Start-AzBasicLoadBalancerUpgrade { log -Message "[Start-AzBasicLoadBalancerUpgrade] Starting migration for Basic Load Balancer '$($migrationConfig.BasicLoadBalancer.Name)' in Resource Group '$($migrationConfig.BasicLoadBalancer.ResourceGroupName)'" $standardScenarioParams = @{ - BasicLoadBalancer = $migrationConfig.BasicLoadBalancer - StandardLoadBalancerName = $migrationConfig.StandardLoadBalancerName - Scenario = $migrationConfig.scenario - outputMigrationValiationObj = $outputMigrationValiationObj.IsPresent + BasicLoadBalancer = $migrationConfig.BasicLoadBalancer + StandardLoadBalancerName = $migrationConfig.StandardLoadBalancerName + Scenario = $migrationConfig.scenario + outputMigrationValiationObj = $outputMigrationValiationObj.IsPresent + skipUpgradeNATPoolsToNATRules = $skipUpgradeNATPoolsToNATRules.IsPresent } switch ($migrationConfig.scenario.BackendType) { diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/VMPublicIPConfigMigration/VMPublicIPConfigMigration.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/VMPublicIPConfigMigration/VMPublicIPConfigMigration.psm1 index fa69d97b..1fcbe9e1 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/VMPublicIPConfigMigration/VMPublicIPConfigMigration.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/VMPublicIPConfigMigration/VMPublicIPConfigMigration.psm1 @@ -14,6 +14,11 @@ Function UpgradeVMPublicIP { $nicIDs += "'$(($backendIpConfiguration.Id -split '/ipconfigurations/')[0])'" } } + foreach ($inboundNatRule in $BasicLoadBalancer.inboundNatRules) { + foreach ($backendIpConfiguration in ($inboundNatRule.BackendIpConfiguration | Select-Object -Property Id -Unique)) { + $nicIDs += "'$(($backendIpConfiguration.Id -split '/ipconfigurations/')[0])'" + } + } $joinedNicIDs = $nicIDs -join ',' diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ValidateMigration/ValidateMigration.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ValidateMigration/ValidateMigration.psm1 index 5c47f9fa..880a4322 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ValidateMigration/ValidateMigration.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ValidateMigration/ValidateMigration.psm1 @@ -7,7 +7,9 @@ Function ValidateMigration { param( [Parameter(Mandatory = $True)][Microsoft.Azure.Commands.Network.Models.PSLoadBalancer] $BasicLoadBalancer, [Parameter(Mandatory = $false)][string] $StandardLoadBalancerName, - [Parameter(Mandatory = $false)][switch] $OutputMigrationValiationObj + [Parameter(Mandatory = $false)][switch] $OutputMigrationValiationObj, + # in the default LB upgrade, NAT pools are migrated. Specify $false for this parameter if you did not migrate NAT Pools to NAT Rules + [Parameter(Mandatory = $false)][boolean] $natPoolsMigratedToNatRules = $true ) log -Message "[ValidateMigration] Initiating Validation of Migration for basic LB '$($BasicLoadBalancer.Name)' to standard LB '$($standardLoadBalancerName)')'" @@ -76,13 +78,30 @@ Function ValidateMigration { } # validate the standard load balancer has the same number of backend pools as the basic load balancer - If ($standardLoadBalancer.BackendAddressPools.Count -ne $BasicLoadBalancer.BackendAddressPools.Count) { - log -Message "[ValidateMigration] Standard Load Balancer does not have the same number of backend pools ('$($standardLoadBalancer.BackendAddressPools.Count)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" -Severity Error - $validationResult.failedValidations += "Standard Load Balancer does not have the same number of backend pools ('$($standardLoadBalancer.BackendAddressPools.Count)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" + ## when nat pools where not migrated to nat rules + If (!$natPoolsMigratedToNatRules) { + If ($standardLoadBalancer.BackendAddressPools.Count -ne $BasicLoadBalancer.BackendAddressPools.Count) { + log -Message "[ValidateMigration] Standard Load Balancer does not have the same number of backend pools ('$($standardLoadBalancer.BackendAddressPools.Count)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" -Severity Error + $validationResult.failedValidations += "Standard Load Balancer does not have the same number of backend pools ('$($standardLoadBalancer.BackendAddressPools.Count)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" + } + Else { + log -Message "[ValidateMigration] Standard Load Balancer has the same number of backend pools ('$($standardLoadBalancer.BackendAddressPools.Count)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" -Severity Information + $validationResult.passedValidations += "Standard Load Balancer has the same number of backend pools ('$($standardLoadBalancer.BackendAddressPools.Count)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" + } } + ## when nat pools were migrated to nat rules Else { - log -Message "[ValidateMigration] Standard Load Balancer has the same number of backend pools ('$($standardLoadBalancer.BackendAddressPools.Count)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" -Severity Information - $validationResult.passedValidations += "Standard Load Balancer has the same number of backend pools ('$($standardLoadBalancer.BackendAddressPools.Count)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" + # add the number of backend pools created for NAT Pool migration to NAT rules + $targetBackendPoolCount = $BasicLoadBalancer.BackendAddressPools.Count + $BasicLoadBalancer.InboundNatPools.Count + + If ($standardLoadBalancer.BackendAddressPools.Count -ne $targetBackendPoolCount) { + log -Message "[ValidateMigration] Standard Load Balancer does not have the same number of backend pools plus the count added for NAT Pool migration ('$($targetBackendPoolCount)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" -Severity Error + $validationResult.failedValidations += "Standard Load Balancer does not have the same number of backend pools plus the count added for NAT Pool migration ('$($stbBackendPoolCountMinusNATPools)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" + } + Else { + log -Message "[ValidateMigration] Standard Load Balancer has the same number of backend pools plus the count added for NAT Pool migration ('$($stbBackendPoolCountMinusNATPools)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" -Severity Information + $validationResult.passedValidations += "Standard Load Balancer has the same number of backend pools plus the count added for NAT Pool migration ('$($stbBackendPoolCountMinusNATPools)') as the Basic Load Balancer ('$($BasicLoadBalancer.BackendAddressPools.Count)')" + } } # validate the standard load balancer has the same number of load balancing rules as the basic load balancer @@ -106,23 +125,95 @@ Function ValidateMigration { } # validate the standard load balancer has the same number of inbound NAT rules as the basic load balancer - If ($standardLoadBalancer.InboundNatRules.Count -ne $BasicLoadBalancer.InboundNatRules.Count) { - log -Message "[ValidateMigration] Standard Load Balancer does not have the same number of inbound NAT rules ('$($standardLoadBalancer.InboundNatRules.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatRules.Count)') " -Severity Error - $validationResult.failedValidations += "Standard Load Balancer does not have the same number of inbound NAT rules ('$($standardLoadBalancer.InboundNatRules.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatRules.Count)')" + If ($natPoolsMigratedToNatRules) { + # each non nat pool nat rule will be migrated - may be less than the count of nat pools if nat pools are empty + # each nat pool will create a nat rule + $nonNATPoolNATRulesCount = $BasicLoadBalancer.InboundNatRules | Where-Object { $_.BackendIPConfiguration -and $_.BackendIPConfiguration.Id -notlike '*Microsoft.Compute/virtualMachineScaleSets*' } | Measure-Object | Select-Object -ExpandProperty Count + $natPoolCount = $BasicLoadBalancer.InboundNatPools.Count + + $targetNatRuleCount = $nonNATPoolNATRulesCount + $natPoolCount + + If ($standardLoadBalancer.InboundNatRules.Count -ne $targetNatRuleCount) { + log -Message "[ValidateMigration] Standard Load Balancer does not have the expected number of NAT Rules ('$($targetNatRuleCount)') when NAT Pools are migrated to NAT Rules (one per NAT Pool plus original NAT Rules). Standard load balancer has: '$($standardLoadBalancer.InboundNatRules.Count)'" + $validationResult.failedValidations += "Standard Load Balancer does not have the expected number of NAT Rules ('$($targetNatRuleCount)') when NAT Pools are migrated to NAT Rules (one per NAT Pool plus original NAT Rules). Standard load balancer has: '$($standardLoadBalancer.InboundNatRules.Count)'" + } + Else { + log -Message "[ValidateMigration] Standard Load Balancer has the expected number of NAT Rules ('$($targetNatRuleCount)') when NAT Pools are migrated to NAT Rules (one per NAT Pool plus original NAT Rules). Standard load balancer has: '$($standardLoadBalancer.InboundNatRules.Count)'" + $validationResult.passedValidations += "Standard Load Balancer has the expected number of NAT Rules ('$($targetNatRuleCount)') when NAT Pools are migrated to NAT Rules (one per NAT Pool plus original NAT Rules). Standard load balancer has: '$($standardLoadBalancer.InboundNatRules.Count)'" + } } Else { - log -Message "[ValidateMigration] Standard Load Balancer has the same number of inbound NAT rules ('$($standardLoadBalancer.InboundNatRules.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatRules.Count)') " -Severity Information - $validationResult.passedValidations += "Standard Load Balancer has the same number of inbound NAT rules ('$($standardLoadBalancer.InboundNatRules.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatRules.Count)')" + If ($standardLoadBalancer.InboundNatRules.Count -ne $BasicLoadBalancer.InboundNatRules.Count) { + log -Message "[ValidateMigration] Standard Load Balancer does not have the same number of inbound NAT rules ('$($standardLoadBalancer.InboundNatRules.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatRules.Count)') " -Severity Error + $validationResult.failedValidations += "Standard Load Balancer does not have the same number of inbound NAT rules ('$($standardLoadBalancer.InboundNatRules.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatRules.Count)')" + } + Else { + log -Message "[ValidateMigration] Standard Load Balancer has the same number of inbound NAT rules ('$($standardLoadBalancer.InboundNatRules.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatRules.Count)') " -Severity Information + $validationResult.passedValidations += "Standard Load Balancer has the same number of inbound NAT rules ('$($standardLoadBalancer.InboundNatRules.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatRules.Count)')" + } + } + + # validate the standard load balancer inbound nat rules have the same backend ip configurations as the basic load balancer + $stdLoadBalancerNatRuleBackendIPConfigs = $standardLoadBalancer.InboundNatRules.BackendIpConfiguration.Id + $basicLoadBalancerNatRuleBackendIPConfigs = $basicLoadBalancer.InboundNatRules.BackendIpConfiguration.Id + If (!$natPoolsMigratedToNatRules) { + # check that all basic load balancer nat rule backend ip configs are in the standard load balancer nat rule backend ip configs + ForEach ($basicLoadBalancerNatRuleBackendIPConfig in $basicLoadBalancerNatRuleBackendIPConfigs) { + If ($stdLoadBalancerNatRuleBackendIPConfigs -notcontains $basicLoadBalancerNatRuleBackendIPConfig) { + log -Message "[ValidateMigration] Standard Load Balancer is missing Basic Load Balancer NAT rule backend IP configuration '$basicLoadBalancerNatRuleBackendIPConfig'" -Severity Error + $validationResult.failedValidations += "Standard Load Balancer is missing Basic Load Balancer NAT rule backend IP configuration '$basicLoadBalancerNatRuleBackendIPConfig'" + } + Else { + log -Message "[ValidateMigration] Standard Load Balancer has Basic Load Balancer NAT rule backend IP configuration '$basicLoadBalancerNatRuleBackendIPConfig'" -Severity Information + $validationResult.passedValidations += "Standard Load Balancer has Basic Load Balancer NAT rule backend IP configuration '$basicLoadBalancerNatRuleBackendIPConfig'" + } + } + # check that all standard load balancer nat rule backend ip configs are in the basic load balancer nat rule backend ip configs + ForEach ($stdLoadBalancerNatRuleBackendIPConfig in $stdLoadBalancerNatRuleBackendIPConfigs) { + If ($basicLoadBalancerNatRuleBackendIPConfigs -notcontains $stdLoadBalancerNatRuleBackendIPConfig) { + log -Message "[ValidateMigration] Basic Load Balancer is missing Standard Load Balancer NAT rule backend IP configuration '$stdLoadBalancerNatRuleBackendIPConfig'" -Severity Error + $validationResult.failedValidations += "Basic Load Balancer is missing Standard Load Balancer NAT rule backend IP configuration '$stdLoadBalancerNatRuleBackendIPConfig'" + } + Else { + log -Message "[ValidateMigration] Basic Load Balancer has Standard Load Balancer NAT rule backend IP configuration '$stdLoadBalancerNatRuleBackendIPConfig'" -Severity Information + $validationResult.passedValidations += "Basic Load Balancer has Standard Load Balancer NAT rule backend IP configuration '$stdLoadBalancerNatRuleBackendIPConfig'" + } + } + } + Else { + # compare count of nat rule backend IP configs plus the count of migrated nat pools + ## nat rule ip configs except for those created by NAT Pool members--which don't exist after NAT Pool to NAT rule migration + $basicLoadBalancerNatRuleBackendIPConfigsAdj = $basicLoadBalancerNatRuleBackendIPConfigs | Where-Object { $_ -notlike '*Microsoft.Compute/virtualMachineScaleSets*' } + If ($basicLoadBalancerNatRuleBackendIPConfigsAdj.count -ne $stdLoadBalancerNatRuleBackendIPConfigs.count) { + log -Message "[ValidateMigration] Standard Load Balancer's count of NAT rule backend IP configurations ('$($stdLoadBalancerNatRuleBackendIPConfigs.count)') does not match the expected count ('$($basicLoadBalancerNatRuleBackendIPConfigsAdj.count)'), adjusted for NAT Pool migrations. Basic LB NAT Rule IP Configs: '$($basicLoadBalancerNatRuleBackendIPConfigsAdj -join ';')' Standard LB NAT Rule IP Configs: '$($stdLoadBalancerNatRuleBackendIPConfigs -join ';')'" -Severity Error + $validationResult.failedValidations += "Standard Load Balancer's count of NAT rule backend IP configurations ('$($stdLoadBalancerNatRuleBackendIPConfigs.count)') does not match the expected count ('$($basicLoadBalancerNatRuleBackendIPConfigsAdj.count)'), adjusted for NAT Pool migrations. Basic LB NAT Rule IP Configs: '$($basicLoadBalancerNatRuleBackendIPConfigsAdj -join ';')' Standard LB NAT Rule IP Configs: '$($stdLoadBalancerNatRuleBackendIPConfigs -join ';')'" + } + Else { + log -Message "[ValidateMigration] Standard Load Balancer's NAT Rules have the same backend IP configurations count as Basic Load Balancer's NAT rules" -Severity Information + $validationResult.passedValidations += "Standard Load Balancer's NAT Rules have the same backend IP configurations count as Basic Load Balancer's NAT rules" + } } # validate the standard load balancer has the same number of inbound NAT pools as the basic load balancer - If ($standardLoadBalancer.InboundNatPools.Count -ne $BasicLoadBalancer.InboundNatPools.Count) { - log -Message "[ValidateMigration] Standard Load Balancer does not have the same number of inbound NAT pools ('$($standardLoadBalancer.InboundNatPools.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatPools.Count)')" -Severity Error - $validationResult.failedValidations += "Standard Load Balancer does not have the same number of inbound NAT pools ('$($standardLoadBalancer.InboundNatPools.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatPools.Count)')" + If (!$natPoolsMigratedToNatRules) { + If ($standardLoadBalancer.InboundNatPools.Count -ne $BasicLoadBalancer.InboundNatPools.Count) { + log -Message "[ValidateMigration] Standard Load Balancer does not have the same number of inbound NAT pools ('$($standardLoadBalancer.InboundNatPools.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatPools.Count)')." -Severity Error + $validationResult.failedValidations += "Standard Load Balancer does not have the same number of inbound NAT pools ('$($standardLoadBalancer.InboundNatPools.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatPools.Count)'). If the Basic Load Balancer had NAT Pools with no membership and NAT Pools were migrated to NAT Rules, this could be expected." + } + Else { + log -Message "[ValidateMigration] Standard Load Balancer has the same number of inbound NAT pools ('$($standardLoadBalancer.InboundNatPools.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatPools.Count)')" -Severity Information + $validationResult.passedValidations += "Standard Load Balancer has the same number of inbound NAT pools ('$($standardLoadBalancer.InboundNatPools.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatPools.Count)')" + } } Else { - log -Message "[ValidateMigration] Standard Load Balancer has the same number of inbound NAT pools ('$($standardLoadBalancer.InboundNatPools.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatPools.Count)')" -Severity Information - $validationResult.passedValidations += "Standard Load Balancer has the same number of inbound NAT pools ('$($standardLoadBalancer.InboundNatPools.Count)') as the Basic Load Balancer ('$($basicLoadBalancer.InboundNatPools.Count)')" + If ($standardLoadBalancer.InboundNatPools.Count -ne 0) { + log -Message "[ValidateMigration] Standard Load Balancer has inbound NAT pools, but migration was configured to upgrade them to NAT Rules" -Severity Error + $validationResult.failedValidations += "Standard Load Balancer has inbound NAT pools, but migration was configured to upgrade them to NAT Rules" + } + Else { + log -Message "[ValidateMigration] Standard Load Balancer has no inbound NAT pools--migration was configured to upgrade them to NAT Rules" -Severity Information + $validationResult.passedValidations += "Standard Load Balancer has no inbound NAT pools--migration was configured to upgrade them to NAT Rules" + } } # validate the standard load balancer has outbound rules @@ -232,11 +323,9 @@ Function ValidateMigration { } } 'VMSS' { - $vmssIDs = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object { ($_ -split '/virtualMachines/')[0].ToLower() } | Select-Object -Unique - - ForEach ($vmssId in $vmssIds) { - $vmss = Get-AzResource -ResourceId $vmssId | Get-AzVmss + $vmsses = GetVmssFromBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer + ForEach ($vmss in $vmsses) { $vmssHasNSG = _GetVMSSNSG -vmss $vmss -skipLogging If (!$vmssHasNSG) { diff --git a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ValidateScenario/ValidateScenario.psm1 b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ValidateScenario/ValidateScenario.psm1 index ea16347c..3ac6ab1a 100644 --- a/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ValidateScenario/ValidateScenario.psm1 +++ b/AzureBasicLoadBalancerUpgrade/module/AzureBasicLoadBalancerUpgrade/modules/ValidateScenario/ValidateScenario.psm1 @@ -1,5 +1,6 @@ # Load Modules Import-Module ((Split-Path $PSScriptRoot -Parent) + "/Log/Log.psd1") +Import-Module ((Split-Path $PSScriptRoot -Parent) + "/GetVmssFromBasicLoadBalancer/GetVmssFromBasicLoadBalancer.psd1") function _GetScenarioBackendType { param( @@ -19,45 +20,63 @@ function _GetScenarioBackendType { # Detecting if there are any backend pools that is not virtualMachineScaleSets or virtualMachines log -Message "[Test-SupportedMigrationScenario] Checking backend pool member types and that all backend pools are not empty" - $backendPoolMemberTypes = @() + $backendMemberTypes = @() + + # get backend types from backend pools foreach ($backendAddressPool in $BasicLoadBalancer.BackendAddressPools) { foreach ($backendIpConfiguration in $backendAddressPool.BackendIpConfigurations) { - $backendPoolMemberType = $backendIpConfiguration.Id.split("/")[7] + $backendMemberType = $backendIpConfiguration.Id.split("/")[7] # check that backend pool NIC members is attached to a VM - If ($backendPoolMemberType -eq 'networkInterfaces') { - $backendPoolMemberTypes += 'virtualMachines' + If ($backendMemberType -eq 'networkInterfaces') { + $backendMemberTypes += 'virtualMachines' } Else { - $backendPoolMemberTypes += $backendPoolMemberType + $backendMemberTypes += $backendMemberType } } + } - - If (($backendPoolMemberTypes | Sort-Object | Get-Unique).count -gt 1) { - log -ErrorAction Stop -Message "[Test-SupportedMigrationScenario] Basic Load Balancer backend pools can contain only VMs or VMSSes, contains: '$($backendPoolMemberTypes -join ',')'" -Severity 'Error' - return - } - If ($backendPoolMemberTypes[0] -eq 'virtualMachines') { - log -Message "[Test-SupportedMigrationScenario] All backend pools members are virtualMachines!" - $backendType = 'VM' - } - ElseIf ($backendPoolMemberTypes[0] -eq 'virtualMachineScaleSets') { - log -Message "[Test-SupportedMigrationScenario] All backend pools members are virtualMachineScaleSets!" - $backendType = 'VMSS' - } - ElseIf ([string]::IsNullOrEmpty($backendPoolMemberTypes[0])) { - log -Message "[Test-SupportedMigrationScenario] Basic Load Balancer backend pools are empty" - $backendType = 'Empty' - } - Else { - log -ErrorAction Stop -Message "[Test-SupportedMigrationScenario] Basic Load Balancer backend pools can contain only VMs or VMSSes, contains: '$($backendPoolMemberTypes -join ',')'" -Severity 'Error' - return + # get backend types from NAT rules + foreach ($inboundNatRule in $BasicLoadBalancer.InboundNatRules) { + foreach ($backendIpConfiguration in $inboundNatRule.BackendIpConfiguration) { + $backendMemberType = $backendIpConfiguration.Id.split("/")[7] + + # check that nat rule NIC members is attached to a VM + If ($backendMemberType -eq 'networkInterfaces') { + $backendMemberTypes += 'virtualMachines' + } + + Else { + $backendMemberTypes += $backendMemberType + } } + } + - return $backendType + If (($backendMemberTypes | Sort-Object | Get-Unique).count -gt 1) { + log -ErrorAction Stop -Message "[Test-SupportedMigrationScenario] Basic Load Balancer backend pools can contain only VMs or VMSSes, contains: '$($backendMemberTypes -join ',')'" -Severity 'Error' + return + } + If ($backendMemberTypes[0] -eq 'virtualMachines') { + log -Message "[Test-SupportedMigrationScenario] All backend pools members are virtualMachines!" + $backendType = 'VM' } + ElseIf ($backendMemberTypes[0] -eq 'virtualMachineScaleSets') { + log -Message "[Test-SupportedMigrationScenario] All backend pools members are virtualMachineScaleSets!" + $backendType = 'VMSS' + } + ElseIf ([string]::IsNullOrEmpty($backendMemberTypes[0])) { + log -Message "[Test-SupportedMigrationScenario] Basic Load Balancer backend pools are empty" + $backendType = 'Empty' + } + Else { + log -ErrorAction Stop -Message "[Test-SupportedMigrationScenario] Basic Load Balancer backend pools can contain only VMs or VMSSes, contains: '$($backendMemberTypes -join ',')'" -Severity 'Error' + return + } + + return $backendType } Function Test-SupportedMigrationScenario { @@ -96,7 +115,13 @@ Function Test-SupportedMigrationScenario { 'SkipOutboundRuleCreationMultiBE' = $false } + $progressParams = @{ + Activity = "Validating Migration Scenario" + ParentId = 2 + } + # checking source load balance SKU + Write-Progress -Status "[Test-SupportedMigrationScenario] Verifying if Load Balancer $($BasicLoadBalancer.Name) is valid for migration" -PercentComplete 0 @progressParams log -Message "[Test-SupportedMigrationScenario] Verifying if Load Balancer $($BasicLoadBalancer.Name) is valid for migration" log -Message "[Test-SupportedMigrationScenario] Verifying source load balancer SKU" @@ -150,18 +175,16 @@ Function Test-SupportedMigrationScenario { } If ($scenario.BackendType -eq 'VMSS') { + Write-Progress -Status "Validating VMSS backend scenario parameters" -PercentComplete 50 @progressParams + # create array of VMSSes associated with the load balancer for following checks - $vmssIds = $BasicLoadBalancer.BackendAddressPools.BackendIpConfigurations.id | Foreach-Object { ($_ -split '/virtualMachines/')[0].ToLower() } | Select-Object -Unique - $basicLBVMSSs = @() - ForEach ($vmssId in $vmssIds) { - $basicLBVMSSs += Get-AzResource -ResourceId $vmssId | Get-AzVMSS - } + $basicLBVMSSs = GetVmssFromBasicLoadBalancer -BasicLoadBalancer $BasicLoadBalancer # 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].ToLower() } | Select-Object -Unique + $vmssIds = $basicLBVMSSs.id 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 @@ -284,7 +307,7 @@ Function Test-SupportedMigrationScenario { } If (!$vmssVMsHavePublicIPs -and $scenario.ExternalOrInternal -eq 'Internal') { - $message = "[Test-SupportedMigrationScenario] Internal load balancer backend VMs do not have Public IPs and will not have outbound internet connectivity after migration to a Standard LB. VMSS: '$($vmssId)'" + $message = "[Test-SupportedMigrationScenario] Internal load balancer backend VMs do not have Public IPs and will not have outbound internet connectivity after migration to a Standard LB. VMSS: '$($vmss.Name)'" log -Message $message -Severity 'Warning' Write-Host "In order for your VMSS instances to access the internet, you'll need to take additional action post-migration. Either add Public IPs to each VMSS instance (see: https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/virtual-machine-scale-sets-networking#public-ipv4-per-virtual-machine) or assign a NAT Gateway to the VMSS instances' subnet (see: https://learn.microsoft.com/en-us/azure/virtual-network/ip-services/default-outbound-access)." -ForegroundColor Yellow @@ -344,6 +367,7 @@ Function Test-SupportedMigrationScenario { } If ($scenario.BackendType -eq 'VM') { + Write-Progress -Status "Validating VM backend scenario parameters" -PercentComplete 50 @progressParams # create array of VMs associated with the load balancer for following checks and verify that NICs are associated to VMs $basicLBVMs = @() @@ -554,6 +578,8 @@ Function Test-SupportedMigrationScenario { } } + Write-Progress -Status "Finished VMSS backend scenario validation" -PercentComplete 100 @progressParams + log -Message "[Test-SupportedMigrationScenario] Detected migration scenario: $($scenario | ConvertTo-Json -Depth 10 -Compress)" log -Message "[Test-SupportedMigrationScenario] Load Balancer '$($BasicLoadBalancer.Name)' is valid for migration" return $scenario diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/018-vmss-roll-upgrade-policy.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/018-vmss-roll-upgrade-policy.bicep index fc2f6e86..156eb230 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/018-vmss-roll-upgrade-policy.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/018-vmss-roll-upgrade-policy.bicep @@ -110,6 +110,9 @@ module storageAccounts '../modules/Microsoft.Storage/storageAccounts/deploy.bice storageAccountSku: 'Standard_LRS' storageAccountKind: 'StorageV2' } + dependsOn: [ + rg + ] } module virtualMachineScaleSets '../modules/Microsoft.Compute/virtualMachineScaleSets_custom/deploy.bicep' = { @@ -169,3 +172,24 @@ module virtualMachineScaleSets '../modules/Microsoft.Compute/virtualMachineScale ] } +// resource installinspectorgadget 'Microsoft.Compute/virtualMachines/runCommands@2022-03-01' = { +// name: '${wthhubvm01.name}/wth-runcmd-installinspectorgadget' +// location: location +// properties: { +// asyncExecution: true +// source: { + +// /* +// To generate encoded command in PowerShell: + +// $s = @' +// Install-WindowsFeature Web-Server,Web-Asp-Net45 -IncludeManagementTools +// [System.Net.WebClient]::new().DownloadFile('https://raw.githubusercontent.com/jelledruyts/InspectorGadget/main/Page/default.aspx','c:\inetpub\wwwroot\default.aspx') +// '@ +// $bytes = [System.Text.Encoding]::Unicode.GetBytes($s) +// [convert]::ToBase64String($bytes) */ +// script: 'powershell.exe -ep bypass -encodedcommand IAAgACAAIAAgACAAIAAgAEkAbgBzAHQAYQBsAGwALQBXAGkAbgBkAG8AdwBzAEYAZQBhAHQAdQByAGUAIABXAGUAYgAtAFMAZQByAHYAZQByACwAVwBlAGIALQBBAHMAcAAtAE4AZQB0ADQANQAgAC0ASQBuAGMAbAB1AGQAZQBNAGEAbgBhAGcAZQBtAGUAbgB0AFQAbwBvAGwAcwAKACAAIAAgACAAIAAgACAAIABbAFMAeQBzAHQAZQBtAC4ATgBlAHQALgBXAGUAYgBDAGwAaQBlAG4AdABdADoAOgBuAGUAdwAoACkALgBEAG8AdwBuAGwAbwBhAGQARgBpAGwAZQAoACcAaAB0AHQAcABzADoALwAvAHIAYQB3AC4AZwBpAHQAaAB1AGIAdQBzAGUAcgBjAG8AbgB0AGUAbgB0AC4AYwBvAG0ALwBqAGUAbABsAGUAZAByAHUAeQB0AHMALwBJAG4AcwBwAGUAYwB0AG8AcgBHAGEAZABnAGUAdAAvAG0AYQBpAG4ALwBQAGEAZwBlAC8AZABlAGYAYQB1AGwAdAAuAGEAcwBwAHgAJwAsACcAYwA6AFwAaQBuAGUAdABwAHUAYgBcAHcAdwB3AHIAbwBvAHQAXABkAGUAZgBhAHUAbAB0AC4AYQBzAHAAeAAnACkA' +// } +// timeoutInSeconds: 600 +// } +// } diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/028-service-fabric-basic-lb-no-mr-bronze.json b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/028-service-fabric-basic-lb-no-mr-bronze.json index 9dc4dcc7..a7d1876f 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/028-service-fabric-basic-lb-no-mr-bronze.json +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/028-service-fabric-basic-lb-no-mr-bronze.json @@ -21,7 +21,7 @@ }, "clusterName": { "type": "string", - "defaultValue": "[concat('clu',uniqueString(newGuid()))]", + "defaultValue": "[concat('cluster',substring(uniqueString(newguid()),0,4))]", "metadata": { "description": "Name of your cluster - Between 3 and 23 characters. Letters and numbers only" } @@ -94,18 +94,21 @@ }, "certificateThumbprint": { "type": "string", + "defaultValue": "F28CE76CBD99AF46245942B05C9B368BAE9BF226", "metadata": { "description": "Certificate Thumbprint" } }, "sourceVaultResourceId": { "type": "string", + "defaultValue": "/subscriptions/24730882-456b-42df-a6f8-8590ca6e4e37/resourceGroups/rg-core/providers/Microsoft.KeyVault/vaults/mtbintkv01", "metadata": { "description": "Resource Id of the key vault, is should be in the format of /subscriptions//resourceGroups//providers/Microsoft.KeyVault/vaults/" } }, "certificateUrlValue": { "type": "string", + "defaultValue": "https://mtbintkv01.vault.azure.net/secrets/sf/43c3671760204b429ac24fdaf95e01a3", "metadata": { "description": "Refers to the location URL in your key vault where the certificate was uploaded" } diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/033-std-lb-nat-pool.json b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/033-std-lb-nat-pool.json index 58dc2042..4a8a0050 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/033-std-lb-nat-pool.json +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/033-std-lb-nat-pool.json @@ -8,6 +8,9 @@ }, "location": { "type": "string" + }, + "resourceGroupName": { + "type": "string" } }, "variables": {}, @@ -40,8 +43,7 @@ "name": "pip-01", "location": "[parameters('location')]", "sku": { - "name": "Standard", - "tier": "Regional" + "name": "Basic" }, "properties": { "publicIPAddressVersion": "IPv4", @@ -56,8 +58,7 @@ "name": "pip-02", "location": "[parameters('location')]", "sku": { - "name": "Standard", - "tier": "Regional" + "name": "Basic" }, "properties": { "publicIPAddressVersion": "IPv4", @@ -102,7 +103,7 @@ "location": "[parameters('location')]", "dependsOn": [ "vnet-01", - "lb-standard-01", + "lb-basic-01", "[concat('bootdiag',uniqueString(resourceGroup().id))]" ], "sku": { @@ -191,12 +192,12 @@ "privateIPAddressVersion": "IPv4", "loadBalancerBackendAddressPools": [ { - "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', 'lb-standard-01', 'be-01')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', 'lb-basic-01', 'be-01')]" } ], "loadBalancerInboundNatPools": [ { - "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', 'lb-standard-01', 'natpool-01')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', 'lb-basic-01', 'natpool-01')]" } ] } @@ -212,7 +213,7 @@ "loadBalancerBackendAddressPools": [], "loadBalancerInboundNatPools": [ { - "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', 'lb-standard-01', 'natpool-02')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', 'lb-basic-01', 'natpool-02')]" } ] } @@ -242,7 +243,7 @@ "loadBalancerBackendAddressPools": [], "loadBalancerInboundNatPools": [ { - "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', 'lb-standard-01', 'natpool-03')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', 'lb-basic-01', 'natpool-03')]" } ] } @@ -282,20 +283,19 @@ { "type": "Microsoft.Network/loadBalancers", "apiVersion": "2022-05-01", - "name": "lb-standard-01", + "name": "lb-basic-01", "location": "[parameters('location')]", "dependsOn": [ "pip-01" ], "sku": { - "name": "Standard", - "tier": "Regional" + "name": "Basic" }, "properties": { "frontendIPConfigurations": [ { "name": "fe-01", - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-standard-01'), '/frontendIPConfigurations/fe-01')]", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]", "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { @@ -305,7 +305,7 @@ }, { "name": "fe-02", - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-standard-01'), '/frontendIPConfigurations/fe-02')]", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-02')]", "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { @@ -323,10 +323,10 @@ "loadBalancingRules": [ { "name": "rule-01", - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-standard-01'), '/loadBalancingRules/rule-01')]", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/loadBalancingRules/rule-01')]", "properties": { "frontendIPConfiguration": { - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-standard-01'), '/frontendIPConfigurations/fe-01')]" + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" }, "frontendPort": 80, "backendPort": 80, @@ -336,15 +336,15 @@ "enableTcpReset": false, "loadDistribution": "Default", "backendAddressPool": { - "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', 'lb-standard-01', 'be-01')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', 'lb-basic-01', 'be-01')]" }, "backendAddressPools": [ { - "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', 'lb-standard-01', 'be-01')]" + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', 'lb-basic-01', 'be-01')]" } ], "probe": { - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-standard-01'), '/probes/probe-01')]" + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/probes/probe-01')]" } } } @@ -352,7 +352,7 @@ "probes": [ { "name": "probe-01", - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-standard-01'), '/probes/probe-01')]", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/probes/probe-01')]", "properties": { "protocol": "Tcp", "port": 80, @@ -375,7 +375,7 @@ "enableFloatingIP": false, "enableTcpReset": false, "frontendIPConfiguration": { - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-standard-01'), '/frontendIPConfigurations/fe-01')]" + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" } } }, @@ -390,7 +390,7 @@ "enableFloatingIP": false, "enableTcpReset": false, "frontendIPConfiguration": { - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-standard-01'), '/frontendIPConfigurations/fe-01')]" + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" } } }, @@ -405,7 +405,7 @@ "enableFloatingIP": false, "enableTcpReset": false, "frontendIPConfiguration": { - "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-standard-01'), '/frontendIPConfigurations/fe-01')]" + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" } } } diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/039-basic-lb-nat-pool-empty-be.json b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/039-basic-lb-nat-pool-empty-be.json new file mode 100644 index 00000000..c55a966d --- /dev/null +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/039-basic-lb-nat-pool-empty-be.json @@ -0,0 +1,447 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "randomGuid": { + "type": "string", + "defaultValue": "[newGuid()]" + }, + "location": { + "type": "string" + }, + "resourceGroupName": { + "type": "string" + } + }, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2020-10-01", + "name": "[parameters('resourceGroupName')]", + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "securestring" + }, + "location": { + "type": "string" + } + }, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2022-05-01", + "name": "pip-01", + "location": "[parameters('location')]", + "sku": { + "name": "Basic", + "tier": "Regional" + }, + "properties": { + "publicIPAddressVersion": "IPv4", + "publicIPAllocationMethod": "Dynamic", + "idleTimeoutInMinutes": 4, + "ipTags": [] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2022-05-01", + "name": "pip-02", + "location": "[parameters('location')]", + "sku": { + "name": "Basic", + "tier": "Regional" + }, + "properties": { + "publicIPAddressVersion": "IPv4", + "publicIPAllocationMethod": "Dynamic", + "idleTimeoutInMinutes": 4, + "ipTags": [] + } + }, + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2022-05-01", + "name": "vnet-01", + "location": "[parameters('location')]", + "dependsOn": [], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "10.0.0.0/16" + ] + }, + "subnets": [ + { + "name": "subnet1", + "properties": { + "addressPrefix": "10.0.1.0/24", + "serviceEndpoints": [], + "delegations": [], + "privateEndpointNetworkPolicies": "Disabled", + "privateLinkServiceNetworkPolicies": "Enabled" + }, + "type": "Microsoft.Network/virtualNetworks/subnets" + } + ], + "virtualNetworkPeerings": [], + "enableDdosProtection": false + } + }, + { + "type": "Microsoft.Compute/virtualMachineScaleSets", + "apiVersion": "2022-08-01", + "name": "vmss-01", + "location": "[parameters('location')]", + "dependsOn": [ + "vnet-01", + "lb-basic-01", + "[concat('bootdiag',uniqueString(resourceGroup().id))]" + ], + "sku": { + "name": "Standard_DS1_v2", + "tier": "Standard", + "capacity": 1 + }, + "properties": { + "singlePlacementGroup": true, + "orchestrationMode": "Uniform", + "upgradePolicy": { + "mode": "Manual", + "rollingUpgradePolicy": { + "maxBatchInstancePercent": 20, + "maxUnhealthyInstancePercent": 20, + "maxUnhealthyUpgradedInstancePercent": 20, + "pauseTimeBetweenBatches": "PT0S" + }, + "automaticOSUpgradePolicy": { + "enableAutomaticOSUpgrade": false, + "useRollingUpgradePolicy": false, + "disableAutomaticRollback": false + } + }, + "scaleInPolicy": { + "rules": [ + "Default" + ] + }, + "virtualMachineProfile": { + "osProfile": { + "computerNamePrefix": "vmssvm", + "adminUsername": "admin-vmss", + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "provisionVMAgent": true, + "enableAutomaticUpdates": true, + "enableVMAgentPlatformUpdates": false + }, + "secrets": [], + "allowExtensionOperations": true + }, + "storageProfile": { + "osDisk": { + "osType": "Windows", + "createOption": "FromImage", + "caching": "None", + "managedDisk": { + "storageAccountType": "Standard_LRS" + }, + "diskSizeGB": 128 + }, + "imageReference": { + "publisher": "MicrosoftWindowsServer", + "offer": "WindowsServer", + "sku": "2022-Datacenter", + "version": "latest" + } + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true, + "storageUri": "[reference(concat('bootdiag',uniqueString(resourceGroup().id)), '2021-04-01').primaryEndpoints.blob]" + } + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "vmss-01-nic-01", + "properties": { + "primary": true, + "enableAcceleratedNetworking": true, + "disableTcpStateTracking": false, + "dnsSettings": { + "dnsServers": [] + }, + "enableIPForwarding": false, + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "primary": true, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet-01', 'subnet1')]" + }, + "privateIPAddressVersion": "IPv4", + "loadBalancerBackendAddressPools": [], + "loadBalancerInboundNatPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', 'lb-basic-01', 'natpool-01')]" + } + ] + } + }, + { + "name": "ipconfig2", + "properties": { + "primary": false, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet-01', 'subnet1')]" + }, + "privateIPAddressVersion": "IPv4", + "loadBalancerBackendAddressPools": [], + "loadBalancerInboundNatPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', 'lb-basic-01', 'natpool-02')]" + } + ] + } + } + ] + } + }, + { + "name": "vmss-01-nic-02", + "properties": { + "primary": false, + "enableAcceleratedNetworking": false, + "disableTcpStateTracking": false, + "dnsSettings": { + "dnsServers": [] + }, + "enableIPForwarding": false, + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "primary": true, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet-01', 'subnet1')]" + }, + "privateIPAddressVersion": "IPv4", + "loadBalancerBackendAddressPools": [], + "loadBalancerInboundNatPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/inboundNatPools', 'lb-basic-01', 'natpool-03')]" + } + ] + } + }, + { + "name": "ipconfig2", + "properties": { + "primary": false, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet-01', 'subnet1')]" + }, + "privateIPAddressVersion": "IPv4", + "loadBalancerBackendAddressPools": [], + "loadBalancerInboundNatPools": [] + } + } + ] + } + } + ] + }, + "priority": "Regular", + "scheduledEventsProfile": {} + }, + "additionalCapabilities": { + "ultraSSDEnabled": false + }, + "overprovision": false, + "doNotRunExtensionsOnOverprovisionedVMs": false, + "platformFaultDomainCount": 2, + "automaticRepairsPolicy": { + "enabled": false, + "gracePeriod": "PT30M" + } + } + }, + { + "type": "Microsoft.Network/loadBalancers", + "apiVersion": "2022-05-01", + "name": "lb-basic-01", + "location": "[parameters('location')]", + "dependsOn": [ + "pip-01" + ], + "sku": { + "name": "Basic", + "tier": "Regional" + }, + "properties": { + "frontendIPConfigurations": [ + { + "name": "fe-01", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'pip-01')]" + } + } + }, + { + "name": "fe-02", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-02')]", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'pip-02')]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "be-01", + "properties": {} + } + ], + "loadBalancingRules": [ + { + "name": "rule-01", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/loadBalancingRules/rule-01')]", + "properties": { + "frontendIPConfiguration": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" + }, + "frontendPort": 80, + "backendPort": 80, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 4, + "protocol": "Tcp", + "enableTcpReset": false, + "loadDistribution": "Default", + "backendAddressPool": { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', 'lb-basic-01', 'be-01')]" + }, + "backendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', 'lb-basic-01', 'be-01')]" + } + ], + "probe": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/probes/probe-01')]" + } + } + } + ], + "probes": [ + { + "name": "probe-01", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/probes/probe-01')]", + "properties": { + "protocol": "Tcp", + "port": 80, + "intervalInSeconds": 5, + "numberOfProbes": 2, + "probeThreshold": 1 + } + } + ], + "inboundNatRules": [], + "inboundNatPools": [ + { + "name": "natpool-01", + "properties": { + "frontendPortRangeStart": 9080, + "frontendPortRangeEnd": 9085, + "backendPort": 8080, + "protocol": "Tcp", + "idleTimeoutInMinutes": 4, + "enableFloatingIP": false, + "enableTcpReset": false, + "frontendIPConfiguration": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" + } + } + }, + { + "name": "natpool-02", + "properties": { + "frontendPortRangeStart": 9180, + "frontendPortRangeEnd": 9185, + "backendPort": 8180, + "protocol": "Tcp", + "idleTimeoutInMinutes": 4, + "enableFloatingIP": false, + "enableTcpReset": false, + "frontendIPConfiguration": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" + } + } + }, + { + "name": "natpool-03", + "properties": { + "frontendPortRangeStart": 9280, + "frontendPortRangeEnd": 9285, + "backendPort": 3389, + "protocol": "Tcp", + "idleTimeoutInMinutes": 4, + "enableFloatingIP": false, + "enableTcpReset": false, + "frontendIPConfiguration": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2021-06-01", + "name": "[concat('bootdiag',uniqueString(resourceGroup().id))]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard_LRS" + }, + "kind": "StorageV2", + "properties": { + "supportsHttpsTrafficOnly": true, + "networkAcls": { + "bypass": "AzureServices", + "virtualNetworkRules": [], + "ipRules": [], + "defaultAction": "Allow" + }, + "accessTier": "Hot" + } + } + ] + }, + "parameters": { + "adminPassword": { + "value": "[concat(uniqueString(parameters('randomGuid')),'aKJL5')]" + }, + "location": { + "value": "[parameters('location')]" + } + } + } + } + ] +} \ No newline at end of file diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/040-basic-lb-int-empty-nat-pool.json b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/040-basic-lb-int-empty-nat-pool.json new file mode 100644 index 00000000..a138d209 --- /dev/null +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/040-basic-lb-int-empty-nat-pool.json @@ -0,0 +1,411 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "randomGuid": { + "type": "string", + "defaultValue": "[newGuid()]" + }, + "resourceGroupName": { + "type": "string" + } + }, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Resources/deployments", + "apiVersion": "2020-10-01", + "name": "[parameters('resourceGroupName')]", + "properties": { + "mode": "Incremental", + "expressionEvaluationOptions": { + "scope": "inner" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "adminPassword": { + "type": "securestring" + }, + "location": { + "type": "string" + } + }, + "variables": {}, + "resources": [ + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2022-05-01", + "name": "pip-01", + "location": "[parameters('location')]", + "sku": { + "name": "Basic", + "tier": "Regional" + }, + "properties": { + "publicIPAddressVersion": "IPv4", + "publicIPAllocationMethod": "Dynamic", + "idleTimeoutInMinutes": 4, + "ipTags": [] + } + }, + { + "type": "Microsoft.Network/publicIPAddresses", + "apiVersion": "2022-05-01", + "name": "pip-02", + "location": "[parameters('location')]", + "sku": { + "name": "Basic", + "tier": "Regional" + }, + "properties": { + "publicIPAddressVersion": "IPv4", + "publicIPAllocationMethod": "Dynamic", + "idleTimeoutInMinutes": 4, + "ipTags": [] + } + }, + { + "type": "Microsoft.Network/virtualNetworks", + "apiVersion": "2022-05-01", + "name": "vnet-01", + "location": "[parameters('location')]", + "dependsOn": [], + "properties": { + "addressSpace": { + "addressPrefixes": [ + "10.0.0.0/16" + ] + }, + "subnets": [ + { + "name": "subnet1", + "properties": { + "addressPrefix": "10.0.1.0/24", + "serviceEndpoints": [], + "delegations": [], + "privateEndpointNetworkPolicies": "Disabled", + "privateLinkServiceNetworkPolicies": "Enabled" + }, + "type": "Microsoft.Network/virtualNetworks/subnets" + } + ], + "virtualNetworkPeerings": [], + "enableDdosProtection": false + } + }, + { + "type": "Microsoft.Compute/virtualMachineScaleSets", + "apiVersion": "2022-08-01", + "name": "vmss-01", + "location": "[parameters('location')]", + "dependsOn": [ + "vnet-01", + "lb-basic-01", + "[concat('bootdiag',uniqueString(resourceGroup().id))]" + ], + "sku": { + "name": "Standard_DS1_v2", + "tier": "Standard", + "capacity": 1 + }, + "properties": { + "singlePlacementGroup": true, + "orchestrationMode": "Uniform", + "upgradePolicy": { + "mode": "Manual", + "rollingUpgradePolicy": { + "maxBatchInstancePercent": 20, + "maxUnhealthyInstancePercent": 20, + "maxUnhealthyUpgradedInstancePercent": 20, + "pauseTimeBetweenBatches": "PT0S" + }, + "automaticOSUpgradePolicy": { + "enableAutomaticOSUpgrade": false, + "useRollingUpgradePolicy": false, + "disableAutomaticRollback": false + } + }, + "scaleInPolicy": { + "rules": [ + "Default" + ] + }, + "virtualMachineProfile": { + "osProfile": { + "computerNamePrefix": "vmssvm", + "adminUsername": "admin-vmss", + "adminPassword": "[parameters('adminPassword')]", + "windowsConfiguration": { + "provisionVMAgent": true, + "enableAutomaticUpdates": true, + "enableVMAgentPlatformUpdates": false + }, + "secrets": [], + "allowExtensionOperations": true + }, + "storageProfile": { + "osDisk": { + "osType": "Windows", + "createOption": "FromImage", + "caching": "None", + "managedDisk": { + "storageAccountType": "Standard_LRS" + }, + "diskSizeGB": 128 + }, + "imageReference": { + "publisher": "MicrosoftWindowsServer", + "offer": "WindowsServer", + "sku": "2022-Datacenter", + "version": "latest" + } + }, + "diagnosticsProfile": { + "bootDiagnostics": { + "enabled": true, + "storageUri": "[reference(concat('bootdiag',uniqueString(resourceGroup().id)), '2021-04-01').primaryEndpoints.blob]" + } + }, + "networkProfile": { + "networkInterfaceConfigurations": [ + { + "name": "vmss-01-nic-01", + "properties": { + "primary": true, + "enableAcceleratedNetworking": true, + "disableTcpStateTracking": false, + "dnsSettings": { + "dnsServers": [] + }, + "enableIPForwarding": false, + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "primary": true, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet-01', 'subnet1')]" + }, + "privateIPAddressVersion": "IPv4", + "loadBalancerBackendAddressPools": [ + { + "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', 'lb-basic-01', 'be-01')]" + } + ], + "loadBalancerInboundNatPools": [] + } + }, + { + "name": "ipconfig2", + "properties": { + "primary": false, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet-01', 'subnet1')]" + }, + "privateIPAddressVersion": "IPv4", + "loadBalancerBackendAddressPools": [], + "loadBalancerInboundNatPools": [] + } + } + ] + } + }, + { + "name": "vmss-01-nic-02", + "properties": { + "primary": false, + "enableAcceleratedNetworking": false, + "disableTcpStateTracking": false, + "dnsSettings": { + "dnsServers": [] + }, + "enableIPForwarding": false, + "ipConfigurations": [ + { + "name": "ipconfig1", + "properties": { + "primary": true, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet-01', 'subnet1')]" + }, + "privateIPAddressVersion": "IPv4", + "loadBalancerBackendAddressPools": [], + "loadBalancerInboundNatPools": [] + } + }, + { + "name": "ipconfig2", + "properties": { + "primary": false, + "subnet": { + "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', 'vnet-01', 'subnet1')]" + }, + "privateIPAddressVersion": "IPv4", + "loadBalancerBackendAddressPools": [], + "loadBalancerInboundNatPools": [] + } + } + ] + } + } + ] + }, + "priority": "Regular", + "scheduledEventsProfile": {} + }, + "additionalCapabilities": { + "ultraSSDEnabled": false + }, + "overprovision": false, + "doNotRunExtensionsOnOverprovisionedVMs": false, + "platformFaultDomainCount": 2, + "automaticRepairsPolicy": { + "enabled": false, + "gracePeriod": "PT30M" + } + } + }, + { + "type": "Microsoft.Network/loadBalancers", + "apiVersion": "2022-05-01", + "name": "lb-basic-01", + "location": "[parameters('location')]", + "dependsOn": [ + "pip-01" + ], + "sku": { + "name": "Basic", + "tier": "Regional" + }, + "properties": { + "frontendIPConfigurations": [ + { + "name": "fe-01", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'pip-01')]" + } + } + }, + { + "name": "fe-02", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-02')]", + "properties": { + "privateIPAllocationMethod": "Dynamic", + "publicIPAddress": { + "id": "[resourceId('Microsoft.Network/publicIPAddresses', 'pip-02')]" + } + } + } + ], + "backendAddressPools": [ + { + "name": "be-01", + "properties": {} + } + ], + "loadBalancingRules": [], + "probes": [ + { + "name": "probe-01", + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/probes/probe-01')]", + "properties": { + "protocol": "Tcp", + "port": 80, + "intervalInSeconds": 5, + "numberOfProbes": 2, + "probeThreshold": 1 + } + } + ], + "inboundNatRules": [], + "inboundNatPools": [ + { + "name": "natpool-01", + "properties": { + "frontendPortRangeStart": 9080, + "frontendPortRangeEnd": 9085, + "backendPort": 8080, + "protocol": "Tcp", + "idleTimeoutInMinutes": 4, + "enableFloatingIP": false, + "enableTcpReset": false, + "frontendIPConfiguration": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" + } + } + }, + { + "name": "natpool-02", + "properties": { + "frontendPortRangeStart": 9180, + "frontendPortRangeEnd": 9185, + "backendPort": 8180, + "protocol": "Tcp", + "idleTimeoutInMinutes": 4, + "enableFloatingIP": false, + "enableTcpReset": false, + "frontendIPConfiguration": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" + } + } + }, + { + "name": "natpool-03", + "properties": { + "frontendPortRangeStart": 9280, + "frontendPortRangeEnd": 9285, + "backendPort": 3389, + "protocol": "Tcp", + "idleTimeoutInMinutes": 4, + "enableFloatingIP": false, + "enableTcpReset": false, + "frontendIPConfiguration": { + "id": "[concat(resourceId('Microsoft.Network/loadBalancers', 'lb-basic-01'), '/frontendIPConfigurations/fe-01')]" + } + } + } + ] + } + }, + { + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2021-06-01", + "name": "[concat('bootdiag',uniqueString(resourceGroup().id))]", + "location": "[parameters('location')]", + "sku": { + "name": "Standard_LRS" + }, + "kind": "StorageV2", + "properties": { + "supportsHttpsTrafficOnly": true, + "networkAcls": { + "bypass": "AzureServices", + "virtualNetworkRules": [], + "ipRules": [], + "defaultAction": "Allow" + }, + "accessTier": "Hot" + } + } + ] + }, + "parameters": { + "adminPassword": { + "value": "[concat(uniqueString(parameters('randomGuid')),'aKJL5')]" + }, + "location": { + "value": "[parameters('location')]" + } + } + } + } + ] +} diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/101-vms-lb-int.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/101-vms-lb-int.bicep index 86f6505c..a794b44a 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/101-vms-lb-int.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/101-vms-lb-int.bicep @@ -107,6 +107,9 @@ module availabilitySet '../modules/Microsoft.Compute/availabilitySets/deploy.bic location: location name: 'as-01' } + dependsOn: [ + rg + ] } module vm '../modules/Microsoft.Compute/virtualMachines_custom/deploy.bicep' = { diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/102-vms-multivm-lb-int.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/102-vms-multivm-lb-int.bicep index 71e12f5c..6667ff5f 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/102-vms-multivm-lb-int.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/102-vms-multivm-lb-int.bicep @@ -105,6 +105,9 @@ module availabilitySet '../modules/Microsoft.Compute/availabilitySets/deploy.bic location: location name: 'as-01' } + dependsOn: [ + rg + ] } module vm '../modules/Microsoft.Compute/virtualMachines_custom/deploy.bicep' = { diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/103-vms-multi-be.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/103-vms-multi-be.bicep index c2d889ab..1bcf48ab 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/103-vms-multi-be.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/103-vms-multi-be.bicep @@ -35,6 +35,22 @@ module virtualNetworks '../modules/Microsoft.Network/virtualNetworks/deploy.bice ] } +module publicIp01 '../modules/Microsoft.Network/publicIPAddresses/deploy.bicep' = { + name: 'pip-01' + params: { + name: 'pip-01' + location: location + publicIPAddressVersion: 'IPv4' + skuTier: 'Regional' + skuName: 'Basic' + publicIPAllocationMethod: 'Dynamic' + } + scope: resourceGroup(resourceGroupName) + dependsOn: [ + rg + ] +} + // basic lb module loadbalancer '../modules/Microsoft.Network/loadBalancers_custom/deploy.bicep' = { name: 'lb-basic-01' @@ -45,7 +61,7 @@ module loadbalancer '../modules/Microsoft.Network/loadBalancers_custom/deploy.bi frontendIPConfigurations: [ { name: 'fe-01' - subnetId: virtualNetworks.outputs.subnetResourceIds[0] + publicIPAddressId: publicIp01.outputs.resourceId } ] backendAddressPools: [ diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/104-vms-lb-ext.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/104-vms-lb-ext.bicep index 23682770..d02a85d6 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/104-vms-lb-ext.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/104-vms-lb-ext.bicep @@ -121,6 +121,9 @@ module availabilitySet '../modules/Microsoft.Compute/availabilitySets/deploy.bic location: location name: 'as-01' } + dependsOn: [ + rg + ] } module vm '../modules/Microsoft.Compute/virtualMachines_custom/deploy.bicep' = { diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/109-vms-multivm-mix-pip-lb-ext.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/109-vms-multivm-mix-pip-lb-ext.bicep index bedd109d..4dbafdbe 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/109-vms-multivm-mix-pip-lb-ext.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/109-vms-multivm-mix-pip-lb-ext.bicep @@ -121,6 +121,9 @@ module availabilitySet '../modules/Microsoft.Compute/availabilitySets/deploy.bic location: location name: 'as-01' } + dependsOn: [ + rg + ] } module vm '../modules/Microsoft.Compute/virtualMachines_custom/deploy.bicep' = { diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/111-vms-multi-lb-mix.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/111-vms-multi-lb-mix.bicep index 5fe2f6ec..24072dc0 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/111-vms-multi-lb-mix.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/111-vms-multi-lb-mix.bicep @@ -163,12 +163,25 @@ module storageAccounts '../modules/Microsoft.Storage/storageAccounts/deploy.bice ] } +module availabilitySet '../modules/Microsoft.Compute/availabilitySets/deploy.bicep' = { + scope: resourceGroup(resourceGroupName) + name: 'as-01' + params: { + location: location + name: 'as-01' + } + dependsOn: [ + rg + ] +} + module vm '../modules/Microsoft.Compute/virtualMachines_custom/deploy.bicep' = { scope: resourceGroup(resourceGroupName) name: 'vm-01' params: { adminUsername: 'admin-vmss' adminPassword: '${uniqueString(randomGuid)}rpP@340' + availabilitySetResourceId: availabilitySet.outputs.resourceId location: location imageReference: { offer: 'WindowsServer' diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/112-vms-lb-int-no-rules.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/112-vms-lb-int-no-rules.bicep index 7b36719d..1cc8c825 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/112-vms-lb-int-no-rules.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/112-vms-lb-int-no-rules.bicep @@ -95,6 +95,9 @@ module availabilitySet '../modules/Microsoft.Compute/availabilitySets/deploy.bic location: location name: 'as-01' } + dependsOn: [ + rg + ] } module vm '../modules/Microsoft.Compute/virtualMachines_custom/deploy.bicep' = { diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/113-vms-lb-ext-no-rules.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/113-vms-lb-ext-no-rules.bicep index e7941fbe..2254b7ff 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/113-vms-lb-ext-no-rules.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/113-vms-lb-ext-no-rules.bicep @@ -102,12 +102,25 @@ module storageAccounts '../modules/Microsoft.Storage/storageAccounts/deploy.bice ] } +module availabilitySet '../modules/Microsoft.Compute/availabilitySets/deploy.bicep' = { + scope: resourceGroup(resourceGroupName) + name: 'as-01' + params: { + location: location + name: 'as-01' + } + dependsOn: [ + rg + ] +} + module vm '../modules/Microsoft.Compute/virtualMachines_custom/deploy.bicep' = { scope: resourceGroup(resourceGroupName) name: 'vm-01' params: { adminUsername: 'admin-vm' adminPassword: '${uniqueString(randomGuid)}rpP@340' + availabilitySetResourceId: availabilitySet.outputs.resourceId location: location imageReference: { offer: 'WindowsServer' diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/025-vmss-flex.bicep b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/114-vms-lb-nat-rules-empty-be.bicep similarity index 50% rename from AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/025-vmss-flex.bicep rename to AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/114-vms-lb-nat-rules-empty-be.bicep index 782fd1bd..d7c0b52b 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/025-vmss-flex.bicep +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scenarios/114-vms-lb-nat-rules-empty-be.bicep @@ -1,8 +1,7 @@ targetScope = 'subscription' param location string param resourceGroupName string -param keyVaultName string -param keyVaultResourceGroupName string +param randomGuid string = newGuid() // Resource Group module rg '../modules/Microsoft.Resources/resourceGroups/deploy.bicep' = { @@ -26,7 +25,7 @@ module virtualNetworks '../modules/Microsoft.Network/virtualNetworks/deploy.bice name: 'vnet-01' subnets: [ { - name: 'subnet1' + name: 'subnet-01' addressPrefix: '10.0.1.0/24' } ] @@ -43,8 +42,8 @@ module publicIp01 '../modules/Microsoft.Network/publicIPAddresses/deploy.bicep' location: location publicIPAddressVersion: 'IPv4' skuTier: 'Regional' - skuName: 'Standard' - publicIPAllocationMethod: 'Static' + skuName: 'Basic' + publicIPAllocationMethod: 'Dynamic' } scope: resourceGroup(resourceGroupName) dependsOn: [ @@ -54,10 +53,10 @@ module publicIp01 '../modules/Microsoft.Network/publicIPAddresses/deploy.bicep' // basic lb module loadbalancer '../modules/Microsoft.Network/loadBalancers_custom/deploy.bicep' = { - name: 'lb-standard01' + name: 'lb-basic01' scope: resourceGroup(resourceGroupName) params: { - name: 'lb-standard-01' + name: 'lb-basic-01' location: location frontendIPConfigurations: [ { @@ -70,8 +69,16 @@ module loadbalancer '../modules/Microsoft.Network/loadBalancers_custom/deploy.bi name: 'be-01' } ] - inboundNatRules: [] - loadBalancerSku: 'Standard' + inboundNatRules: [ + { + name: 'nat-01' + frontendIPConfigurationName: 'fe-01' + frontendPort: 81 + backendPort: 81 + protocol: 'Tcp' + } + ] + loadBalancerSku: 'Basic' loadBalancingRules: [ { backendAddressPoolName: 'be-01' @@ -100,28 +107,65 @@ module loadbalancer '../modules/Microsoft.Network/loadBalancers_custom/deploy.bi ] } -resource kv1 'Microsoft.KeyVault/vaults@2019-09-01' existing = { - name: keyVaultName - scope: resourceGroup(keyVaultResourceGroupName) +module storageAccounts '../modules/Microsoft.Storage/storageAccounts/deploy.bicep' = { + name: 'bootdiag-storage-01' + scope: resourceGroup(resourceGroupName) + params: { + name: 'bootdiag${uniqueString(deployment().name)}' + location: location + storageAccountSku: 'Standard_LRS' + storageAccountKind: 'StorageV2' + supportsHttpsTrafficOnly: true + } + dependsOn: [ + rg + ] } -module virtualMachineScaleSets '../modules/Microsoft.Compute/virtualMachineScaleSetsFlex_custom/deploy.bicep' = { - name: 'vmss-01' +module availabilitySet '../modules/Microsoft.Compute/availabilitySets/deploy.bicep' = { scope: resourceGroup(resourceGroupName) + name: 'as-01' params: { location: location - // Required parameters - encryptionAtHost: false + name: 'as-01' + } + dependsOn: [ + rg + ] +} + +module vm '../modules/Microsoft.Compute/virtualMachines_custom/deploy.bicep' = { + scope: resourceGroup(resourceGroupName) + name: 'vm-01' + params: { + name: 'vm-01' adminUsername: 'admin-vm' - skuCapacity: 1 - upgradePolicyMode: 'Manual' + adminPassword: '${uniqueString(randomGuid)}rpP@340' + availabilitySetResourceId: availabilitySet.outputs.resourceId + location: location imageReference: { offer: 'WindowsServer' publisher: 'MicrosoftWindowsServer' sku: '2022-Datacenter' version: 'latest' } - name: 'vmss-01' + nicConfigurations: [ + { + location: location + ipConfigurations: [ + { + name: 'ipconfig1' + subnetResourceId: virtualNetworks.outputs.subnetResourceIds[0] + loadBalancerInboundNatRules: [ + { + id: '${loadbalancer.outputs.resourceId}/inboundNatRules/nat-01' + } + ] + } + ] + nicSuffix: 'nic' + } + ] osDisk: { createOption: 'fromImage' diskSizeGB: '128' @@ -130,32 +174,47 @@ module virtualMachineScaleSets '../modules/Microsoft.Compute/virtualMachineScale } } osType: 'Windows' - skuName: 'Standard_DS1_v2' - // Non-required parameters + vmSize: 'Standard_DS1_v2' + } +} + +module vm2 '../modules/Microsoft.Compute/virtualMachines_custom/deploy.bicep' = { + scope: resourceGroup(resourceGroupName) + name: 'vm-02' + params: { + name: 'vm-02' + adminUsername: 'admin-vm' + availabilitySetResourceId: availabilitySet.outputs.resourceId adminPassword: '${uniqueString(randomGuid)}rpP@340' - orchestrationMode: 'Flexible' + location: location + imageReference: { + offer: 'WindowsServer' + publisher: 'MicrosoftWindowsServer' + sku: '2022-Datacenter' + version: 'latest' + } nicConfigurations: [ { + location: location ipConfigurations: [ { name: 'ipconfig1' - properties: { - subnet: { - id: virtualNetworks.outputs.subnetResourceIds[0] - } - loadBalancerBackendAddressPools: [ - { - id: loadbalancer.outputs.backendpools[0].id - } - ] - } + subnetResourceId: virtualNetworks.outputs.subnetResourceIds[0] + loadBalancerBackendAddressPools: [ + ] } ] - nicSuffix: '-nic-01' + nicSuffix: 'nic' } ] + osDisk: { + createOption: 'fromImage' + diskSizeGB: '128' + managedDisk: { + storageAccountType: 'Standard_LRS' + } + } + osType: 'Windows' + vmSize: 'Standard_DS1_v2' } - dependsOn: [ - rg - ] } diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scripts/GeneratePSD1.ps1 b/AzureBasicLoadBalancerUpgrade/testEnvs/scripts/GeneratePSD1.ps1 index 20f8ea4b..9653ac16 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scripts/GeneratePSD1.ps1 +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scripts/GeneratePSD1.ps1 @@ -1,5 +1,5 @@ cd .\modules\BacakupBasicLoadBalancer -New-ModuleManifest -Path BackupBasicLoadBalancer.psd1 -RootModule BackupBasicLoadBalancer -Author "Victor Santana" -CompanyName "Microsoft" -Copyright "(c) 2022 Microsoft. All rights reserved." -FunctionsToExport '*' -CmdletsToExport '*' -AliasesToExport '*' -PassThru +New-ModuleManifest -Path BackupResources.psd1 -RootModule BackupResources -Author "Victor Santana" -CompanyName "Microsoft" -Copyright "(c) 2022 Microsoft. All rights reserved." -FunctionsToExport '*' -CmdletsToExport '*' -AliasesToExport '*' -PassThru cd ../../ New-ModuleManifest -Path Start-AzBasicLoadBalancerUpgrade.psd1 -RootModule Start-AzBasicLoadBalancerUpgrade -Author "Victor Santana" -CompanyName "Microsoft" -Copyright "(c) 2022 Microsoft. All rights reserved." -FunctionsToExport '*' -CmdletsToExport '*' -AliasesToExport '*' -PassThru diff --git a/AzureBasicLoadBalancerUpgrade/testEnvs/scripts/deploy.ps1 b/AzureBasicLoadBalancerUpgrade/testEnvs/scripts/deploy.ps1 index 58806b32..1a9d3f41 100644 --- a/AzureBasicLoadBalancerUpgrade/testEnvs/scripts/deploy.ps1 +++ b/AzureBasicLoadBalancerUpgrade/testEnvs/scripts/deploy.ps1 @@ -5,6 +5,7 @@ Param ( [switch]$includeManualConfigScenarios, [switch]$Cleanup, # removes all test environments (in parallel) [switch]$RunMigration, # executes the migration module against all test environments (in parallel), + [boolean]$skipUpgradeNATPoolsToNATRules = $false, [parameter(Mandatory = $false)][string[]]$resourceGroupSuffix = @('') ) @@ -56,7 +57,7 @@ Foreach ($resourceGroupSuffixI in $resourceGroupSuffix) { } # if -RunMigration switch is supplied, the VMSS Load Balancer migration modules is run against all environments -if ($RunMigration -and $null -ne $filteredTemplates) { +if ($RunMigration.IsPresent -and $null -ne $filteredTemplates) { $ScriptBlock = { param($RGName) @@ -66,7 +67,7 @@ if ($RunMigration -and $null -ne $filteredTemplates) { $path = "$env:HOMEPATH/temp/AzLoadBalancerMigration/$RGName" New-Item -ItemType Directory -Path $path -ErrorAction SilentlyContinue Set-Location $path - Start-AzBasicLoadBalancerUpgrade -ResourceGroupName $RGName -BasicLoadBalancerName lb-basic-01 -StandardLoadBalancerName lb-standard-01 -Pre -Force + Start-AzBasicLoadBalancerUpgrade -ResourceGroupName $RGName -BasicLoadBalancerName lb-basic-01 -StandardLoadBalancerName lb-standard-01 -Pre -Force -outputMigrationValiationObj -skipUpgradeNATPoolsToNATRules:$skipUpgradeNATPoolsToNATRules } $scriptBlockMultiLB = { @@ -80,7 +81,7 @@ if ($RunMigration -and $null -ne $filteredTemplates) { $multiLBConfig = @() get-AzLoadBalancer -ResourceGroupName $RGName | ? {$_.sku.name -eq 'basic'} | select -First 2 | %{ $multiLBConfig += @{BasicLoadBalancer=$_;StandardLoadBalancerName=$_.name.replace('basic','standard')}} - Start-AzBasicLoadBalancerUpgrade -MultiLBConfig $multiLBConfig -Pre -Force + Start-AzBasicLoadBalancerUpgrade -MultiLBConfig $multiLBConfig -Pre -Force -outputMigrationValiationObj -skipUpgradeNATPoolsToNATRules:$skipUpgradeNATPoolsToNATRules } $rgNamesToMigrate = $filteredTemplates | ForEach-Object { diff --git a/AzureLoadBalancerNATPoolMigration/module/AzureLoadBalancerNATPoolMigration/AzureLoadBalancerNATPoolMigration.psd1 b/AzureLoadBalancerNATPoolMigration/module/AzureLoadBalancerNATPoolMigration/AzureLoadBalancerNATPoolMigration.psd1 index 65bc082f..c8bd8d9e 100644 --- a/AzureLoadBalancerNATPoolMigration/module/AzureLoadBalancerNATPoolMigration/AzureLoadBalancerNATPoolMigration.psd1 +++ b/AzureLoadBalancerNATPoolMigration/module/AzureLoadBalancerNATPoolMigration/AzureLoadBalancerNATPoolMigration.psd1 @@ -12,7 +12,7 @@ RootModule = 'AzureLoadBalancerNATPoolMigration' # Version number of this module. -ModuleVersion = '0.0.4' +ModuleVersion = '1.0.0' # Supported PSEditions # CompatiblePSEditions = @() @@ -108,7 +108,7 @@ PrivateData = @{ # IconUri = '' # ReleaseNotes of this module - # ReleaseNotes = '' + ReleaseNotes = 'Added support for LBs without associated VMSS' # Prerelease string of this module # Prerelease = '' diff --git a/AzureLoadBalancerNATPoolMigration/module/AzureLoadBalancerNATPoolMigration/AzureLoadBalancerNATPoolMigration.psm1 b/AzureLoadBalancerNATPoolMigration/module/AzureLoadBalancerNATPoolMigration/AzureLoadBalancerNATPoolMigration.psm1 index cc274473..d4e06e36 100644 --- a/AzureLoadBalancerNATPoolMigration/module/AzureLoadBalancerNATPoolMigration/AzureLoadBalancerNATPoolMigration.psm1 +++ b/AzureLoadBalancerNATPoolMigration/module/AzureLoadBalancerNATPoolMigration/AzureLoadBalancerNATPoolMigration.psm1 @@ -87,95 +87,98 @@ Function Start-AzNATPoolMigration { Write-Error "Load Balancer '$($loadBalancer.Name)' does not have any Inbound NAT Rules. This is unexpected. NAT Rules are created automatically when the VMSS Network Profile is updated to include an Inbound NAT Pool and the VMSS instances are updated with the VMSS mode." } $vmssIds = $LoadBalancer.InboundNatRules.BackendIpConfiguration.id | Foreach-Object { ($_ -split '/virtualMachines/')[0].ToLower() } | Select-Object -Unique - If ($vmssIds.count -lt 1) { - # this error should not be hit... but just in case - Write-Error "Load Balancer '$($loadBalancer.Name)' does not have any VMSSes associated with its NAT Pools." + If ([string]::IsNullOrEmpty($vmssIds)) { + Write-Host "Load Balancer '$($loadBalancer.Name)' does not have any VMSSes associated with its NAT Pools." } - $vmssObjects = $vmssIds | ForEach-Object { Get-AzResource -ResourceId $_ | Get-AzVmss } - - # build vmss table - $vmsses = @() - ForEach ($vmss in $vmssObjects) { - $vmsses += @{ - vmss = $vmss - updateRequired = $false + Else { + $vmssObjects = $vmssIds | ForEach-Object { Get-AzResource -ResourceId $_ | Get-AzVmss } + + # build vmss table + $vmsses = @() + ForEach ($vmss in $vmssObjects) { + $vmsses += @{ + vmss = $vmss + updateRequired = $false + } } - } - # check that vmsses use Manual or Automatic upgrade policy - $incompatibleUpgradePolicyVMSSes = $vmsses.vmss | Where-Object { $_.UpgradePolicy.Mode -notIn 'Manual', 'Automatic' } - If ($incompatibleUpgradePolicyVMSSes.count -gt 0) { - Write-Error "The following VMSSes have upgrade policies which are not Manual or Automatic: $($incompatibleUpgradePolicyVMSSes.id)" + # check that vmsses use Manual or Automatic upgrade policy + $incompatibleUpgradePolicyVMSSes = $vmsses.vmss | Where-Object { $_.UpgradePolicy.Mode -notIn 'Manual', 'Automatic' } + If ($incompatibleUpgradePolicyVMSSes.count -gt 0) { + Write-Error "The following VMSSes have upgrade policies which are not Manual or Automatic: $($incompatibleUpgradePolicyVMSSes.id)" + } } - # remove each vmss model's ipconfig from the load balancer's inbound nat pool - Write-Host "Removing the NAT Pool from the VMSS model ipConfigs." - $ipConfigNatPoolMap = @() - ForEach ($inboundNATPool in $LoadBalancer.InboundNatPools) { - ForEach ($vmssItem in $vmsses) { - ForEach ($nicConfig in $vmssItem.vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations) { - ForEach ($ipConfig in $nicConfig.ipConfigurations) { - If ($ipConfig.loadBalancerInboundNatPools.id -contains $inboundNATPool.id) { - - Write-Host "Removing NAT Pool '$($inboundNATPool.id)' from VMSS '$($vmssItem.vmss.Name)' NIC '$($nicConfig.Name)' ipConfig '$($ipConfig.Name)'" - $ipConfigParams = @{vmssId = $vmssItem.vmss.id; nicName = $nicConfig.Name; ipconfigName = $ipConfig.Name; inboundNatPoolId = $inboundNatPool.id } - $ipConfigNatPoolMap += $ipConfigParams - $ipConfig.loadBalancerInboundNatPools = $ipConfig.loadBalancerInboundNatPools | Where-Object { $_.id -ne $inboundNATPool.Id } - - $vmssItem.updateRequired = $true + If (![string]::IsNullOrEmpty($vmssIds)) { + # remove each vmss model's ipconfig from the load balancer's inbound nat pool + Write-Host "Removing the NAT Pool from the VMSS model ipConfigs." + $ipConfigNatPoolMap = @() + ForEach ($inboundNATPool in $LoadBalancer.InboundNatPools) { + ForEach ($vmssItem in $vmsses) { + ForEach ($nicConfig in $vmssItem.vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations) { + ForEach ($ipConfig in $nicConfig.ipConfigurations) { + If ($ipConfig.loadBalancerInboundNatPools.id -contains $inboundNATPool.id) { + + Write-Host "Removing NAT Pool '$($inboundNATPool.id)' from VMSS '$($vmssItem.vmss.Name)' NIC '$($nicConfig.Name)' ipConfig '$($ipConfig.Name)'" + $ipConfigParams = @{vmssId = $vmssItem.vmss.id; nicName = $nicConfig.Name; ipconfigName = $ipConfig.Name; inboundNatPoolId = $inboundNatPool.id } + $ipConfigNatPoolMap += $ipConfigParams + $ipConfig.loadBalancerInboundNatPools = $ipConfig.loadBalancerInboundNatPools | Where-Object { $_.id -ne $inboundNATPool.Id } + + $vmssItem.updateRequired = $true + } } } } } - } - # update each vmss to remove the nat pools from the model - $vmssModelUpdateRemoveNATPoolJobs = @() - ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { - $vmss = $vmssItem.vmss - $job = $vmss | Update-AzVmss -AsJob - $job.Name = $vmss.vmss.Name + '_modelUpdateRemoveNATPool' - $vmssModelUpdateRemoveNATPoolJobs += $job - } + # update each vmss to remove the nat pools from the model + $vmssModelUpdateRemoveNATPoolJobs = @() + ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { + $vmss = $vmssItem.vmss + $job = $vmss | Update-AzVmss -AsJob + $job.Name = $vmss.vmss.Name + '_modelUpdateRemoveNATPool' + $vmssModelUpdateRemoveNATPoolJobs += $job + } - Write-Host "Waiting for VMSS model to update to remove the NAT Pool references..." - While ($vmssModelUpdateRemoveNATPoolJobs.State -contains 'Running') { - Start-Sleep -Seconds 15 - Write-Host "`t[$(Get-Date -Format 'yyyy-MM-ddTHH:mm:sszz')]Waiting for VMSS model update jobs to complete..." - } - - $vmssModelUpdateRemoveNATPoolJobs | Foreach-Object { - $job = $_ - If ($job.Error -or $job.State -eq 'Failed') { - Write-Error "An error occured while updating the VMSS model to remove the NAT Pools: $($job.error; $job | Receive-Job)." + Write-Host "Waiting for VMSS model to update to remove the NAT Pool references..." + While ($vmssModelUpdateRemoveNATPoolJobs.State -contains 'Running') { + Start-Sleep -Seconds 15 + Write-Host "`t[$(Get-Date -Format 'yyyy-MM-ddTHH:mm:sszz')]Waiting for VMSS model update jobs to complete..." + } + + $vmssModelUpdateRemoveNATPoolJobs | Foreach-Object { + $job = $_ + If ($job.Error -or $job.State -eq 'Failed') { + Write-Error "An error occured while updating the VMSS model to remove the NAT Pools: $($job.error; $job | Receive-Job)." + } } - } - # update all vmss instances - Write-Host "Updating VMSS instances to remove the NAT Pool references..." - $vmssInstanceUpdateRemoveNATPoolJobs = @() - ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { - $vmss = $vmssItem.vmss + # update all vmss instances + Write-Host "Updating VMSS instances to remove the NAT Pool references..." + $vmssInstanceUpdateRemoveNATPoolJobs = @() + ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { + $vmss = $vmssItem.vmss - If ($vmss.UpgradePolicy.Mode -eq 'Automatic') { - Wait-VMSSInstanceUpdate -vmss $vmss - } - Else { - $vmssInstances = Get-AzVmssVM -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name + If ($vmss.UpgradePolicy.Mode -eq 'Automatic') { + Wait-VMSSInstanceUpdate -vmss $vmss + } + Else { + $vmssInstances = Get-AzVmssVM -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name - $job = Update-AzVmssInstance -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name -InstanceId $vmssInstances.InstanceId -AsJob - $job.Name = $vmss.vmss.Name + '_instanceUpdateRemoveNATPool' - $vmssInstanceUpdateRemoveNATPoolJobs += $job + $job = Update-AzVmssInstance -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name -InstanceId $vmssInstances.InstanceId -AsJob + $job.Name = $vmss.vmss.Name + '_instanceUpdateRemoveNATPool' + $vmssInstanceUpdateRemoveNATPoolJobs += $job + } } - } - # for manual update vmsses, wait for the instance update jobs to complete - If ($vmssInstanceUpdateRemoveNATPoolJobs.count -gt 0) { - Write-Host "`tWaiting for VMSS instances to update to remove the NAT Pool references..." - $vmssInstanceUpdateRemoveNATPoolJobs | Wait-Job | Foreach-Object { - $job = $_ - If ($job.Error -or $job.State -eq 'Failed') { - Write-Error "An error occured while updating the VMSS instances to remove the NAT Pools: $($job.error; $job | Receive-Job)." + # for manual update vmsses, wait for the instance update jobs to complete + If ($vmssInstanceUpdateRemoveNATPoolJobs.count -gt 0) { + Write-Host "`tWaiting for VMSS instances to update to remove the NAT Pool references..." + $vmssInstanceUpdateRemoveNATPoolJobs | Wait-Job | Foreach-Object { + $job = $_ + If ($job.Error -or $job.State -eq 'Failed') { + Write-Error "An error occured while updating the VMSS instances to remove the NAT Pools: $($job.error; $job | Receive-Job)." + } } } } @@ -222,91 +225,93 @@ Function Start-AzNATPoolMigration { } - # add vmss model ip configs to new backend pools - Write-Host "Adding new backend pools to VMSS model ipConfigs..." + If (![string]::IsNullOrEmpty($vmssIds)) { + # add vmss model ip configs to new backend pools + Write-Host "Adding new backend pools to VMSS model ipConfigs..." - ForEach ($vmssItem in $vmsses) { - ForEach ($nicConfig in $vmssItem.vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations) { - ForEach ($ipConfig in $nicConfig.ipConfigurations) { + ForEach ($vmssItem in $vmsses) { + ForEach ($nicConfig in $vmssItem.vmss.VirtualMachineProfile.NetworkProfile.NetworkInterfaceConfigurations) { + ForEach ($ipConfig in $nicConfig.ipConfigurations) { - # if there is an existing ipconfig to nat pool association, add the ipconfig to the new backend pool for the nat rule - If ($ipconfigRecord = $ipConfigNatPoolMap | Where-Object { - $_.vmssId -eq $vmssItem.vmss.id -and - $_.nicName -eq $nicConfig.Name -and - $_.ipConfigName -eq $ipConfig.Name - }) { - - #$backendPoolList = New-Object System.Collections.Generic.List[Microsoft.Azure.Commands.Network.Models.PSBackendAddressPool] - $backendPoolList = New-Object System.Collections.Generic.List[Microsoft.Azure.Management.Compute.Models.SubResource] - - # add existing backend pools to pool list to maintain existing membership - ForEach ($existingBackendPoolId in $ipConfig.LoadBalancerBackendAddressPools.id) { - $backendPoolObj = new-object Microsoft.Azure.Management.Compute.Models.SubResource - $backendPoolObj.id = $existingBackendPoolId - + # if there is an existing ipconfig to nat pool association, add the ipconfig to the new backend pool for the nat rule + If ($ipconfigRecord = $ipConfigNatPoolMap | Where-Object { + $_.vmssId -eq $vmssItem.vmss.id -and + $_.nicName -eq $nicConfig.Name -and + $_.ipConfigName -eq $ipConfig.Name + }) { + + #$backendPoolList = New-Object System.Collections.Generic.List[Microsoft.Azure.Commands.Network.Models.PSBackendAddressPool] + $backendPoolList = New-Object System.Collections.Generic.List[Microsoft.Azure.Management.Compute.Models.SubResource] + + # add existing backend pools to pool list to maintain existing membership + ForEach ($existingBackendPoolId in $ipConfig.LoadBalancerBackendAddressPools.id) { + $backendPoolObj = new-object Microsoft.Azure.Management.Compute.Models.SubResource + $backendPoolObj.id = $existingBackendPoolId + + $backendPoolList.Add($backendPoolObj) + } + #$backendPoolObj = new-object Microsoft.Azure.Commands.Network.Models.PSBackendAddressPool + $backendPoolObj = New-Object Microsoft.Azure.Management.Compute.Models.SubResource + $backendPoolObj.id = $natPoolToBEPMap[$ipconfigRecord.inboundNatPoolId] + + Write-Host "Adding VMSS '$($vmssItem.vmss.Name)' NIC '$($nicConfig.Name)' ipConfig '$($ipConfig.Name)' to new backend pool '$($backendPoolObj.id)'" $backendPoolList.Add($backendPoolObj) - } - #$backendPoolObj = new-object Microsoft.Azure.Commands.Network.Models.PSBackendAddressPool - $backendPoolObj = New-Object Microsoft.Azure.Management.Compute.Models.SubResource - $backendPoolObj.id = $natPoolToBEPMap[$ipconfigRecord.inboundNatPoolId] - Write-Host "Adding VMSS '$($vmssItem.vmss.Name)' NIC '$($nicConfig.Name)' ipConfig '$($ipConfig.Name)' to new backend pool '$($backendPoolObj.id)'" - $backendPoolList.Add($backendPoolObj) + $ipConfig.LoadBalancerBackendAddressPools = $backendPoolList - $ipConfig.LoadBalancerBackendAddressPools = $backendPoolList - - $vmssItem.updateRequired = $true + $vmssItem.updateRequired = $true + } } } } - } - # update each vmss to add the backend pool membership to the model - $vmssModelUpdateAddBackendPoolJobs = @() - ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { - $vmss = $vmssItem.vmss - $job = $vmss | Update-AzVmss -AsJob - $job.Name = $vmss.vmss.Name + '_modelUpdateAddBackendPool' - $vmssModelUpdateAddBackendPoolJobs += $job - } + # update each vmss to add the backend pool membership to the model + $vmssModelUpdateAddBackendPoolJobs = @() + ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { + $vmss = $vmssItem.vmss + $job = $vmss | Update-AzVmss -AsJob + $job.Name = $vmss.vmss.Name + '_modelUpdateAddBackendPool' + $vmssModelUpdateAddBackendPoolJobs += $job + } - Write-Host "Waiting for VMSS model to update to include the new Backend Pools..." - While ($vmssModelUpdateAddBackendPoolJobs.State -contains 'Running') { - Start-Sleep -Seconds 15 - Write-Host "`t[$(Get-Date -Format 'yyyy-MM-ddTHH:mm:sszz')]Waiting for VMSS model update jobs to complete..." - } + Write-Host "Waiting for VMSS model to update to include the new Backend Pools..." + While ($vmssModelUpdateAddBackendPoolJobs.State -contains 'Running') { + Start-Sleep -Seconds 15 + Write-Host "`t[$(Get-Date -Format 'yyyy-MM-ddTHH:mm:sszz')]Waiting for VMSS model update jobs to complete..." + } - $vmssModelUpdateAddBackendPoolJobs | Foreach-Object { - $job = $_ - If ($job.Error -or $job.State -eq 'Failed') { - Write-Error "An error occured while updating the VMSS model to add the NAT Rules: $($job.error; $job | Receive-Job)." + $vmssModelUpdateAddBackendPoolJobs | Foreach-Object { + $job = $_ + If ($job.Error -or $job.State -eq 'Failed') { + Write-Error "An error occured while updating the VMSS model to add the NAT Rules: $($job.error; $job | Receive-Job)." + } } - } - # update all vmss instances to include the backend pool - Write-Host "Waiting for VMSS instances to update to include the new Backend Pools..." - $vmssInstanceUpdateAddBackendPoolJobs = @() - ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { + # update all vmss instances to include the backend pool + Write-Host "Waiting for VMSS instances to update to include the new Backend Pools..." + $vmssInstanceUpdateAddBackendPoolJobs = @() + ForEach ($vmssItem in ($vmsses | Where-Object { $_.updateRequired })) { - If ($vmss.UpgradePolicy.Mode -eq 'Automatic') { - Wait-VMSSInstanceUpdate -vmss $vmss - } - Else { - $vmss = $vmssItem.vmss - $vmssInstances = Get-AzVmssVM -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name + If ($vmss.UpgradePolicy.Mode -eq 'Automatic') { + Wait-VMSSInstanceUpdate -vmss $vmss + } + Else { + $vmss = $vmssItem.vmss + $vmssInstances = Get-AzVmssVM -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name - $job = Update-AzVmssInstance -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name -InstanceId $vmssInstances.InstanceId -AsJob - $job.Name = $vmss.vmss.Name + '_instanceUpdateAddBackendPool' - $vmssInstanceUpdateAddBackendPoolJobs += $job + $job = Update-AzVmssInstance -ResourceGroupName $vmss.ResourceGroupName -VMScaleSetName $vmss.Name -InstanceId $vmssInstances.InstanceId -AsJob + $job.Name = $vmss.vmss.Name + '_instanceUpdateAddBackendPool' + $vmssInstanceUpdateAddBackendPoolJobs += $job + } } - } - # for manual update vmsses, wait for the instance update jobs to complete - If ($vmssInstanceUpdateAddBackendPoolJobs.count -gt 0) { - $vmssInstanceUpdateAddBackendPoolJobs | Wait-Job | Foreach-Object { - $job = $_ - If ($job.Error -or $job.State -eq 'Failed') { - Write-Error "An error occured while updating the VMSS instanaces to add the NAT Rules: $($job.error; $job | Receive-Job)." + # for manual update vmsses, wait for the instance update jobs to complete + If ($vmssInstanceUpdateAddBackendPoolJobs.count -gt 0) { + $vmssInstanceUpdateAddBackendPoolJobs | Wait-Job | Foreach-Object { + $job = $_ + If ($job.Error -or $job.State -eq 'Failed') { + Write-Error "An error occured while updating the VMSS instanaces to add the NAT Rules: $($job.error; $job | Receive-Job)." + } } } }