scripts/deployments/Functions/HubNetworkWithNVA.ps1 (157 lines of code) (raw):

<# ---------------------------------------------------------------------------------- Copyright (c) Microsoft Corporation. Licensed under the MIT license. THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. ---------------------------------------------------------------------------------- #> function Set-HubNetwork-With-NVA { param ( [Parameter(Mandatory = $true)] $Context, [Parameter(Mandatory = $true)] [String]$Region, [Parameter(Mandatory = $true)] [String]$ManagementGroupId, [Parameter(Mandatory = $true)] [String]$SubscriptionId, [Parameter(Mandatory = $true)] [String]$ConfigurationFilePath, [Parameter(Mandatory = $true)] [String]$LogAnalyticsWorkspaceResourceId, [Parameter(Mandatory = $false)] [SecureString]$NvaUsername = $null, [Parameter(Mandatory = $false)] [SecureString]$NvaPassword = $null, [Parameter(HelpMessage = "Number of retries to deploy the Hub Network")] [int]$RetryCount = 5, [Parameter(HelpMessage = "Delay, in seconds, between retries to deploy the Hub Network")] [double]$RetryDelay = 60 ) Set-AzContext -Subscription $SubscriptionId $SchemaFilePath = "$($Context.SchemaDirectory)/landingzones/lz-platform-connectivity-hub-nva.json" Write-Output "Validation JSON parameter configuration using $SchemaFilePath" Get-Content -Raw $ConfigurationFilePath | Test-Json -SchemaFile $SchemaFilePath # Load networking configuration $Configuration = Get-Content $ConfigurationFilePath | ConvertFrom-Json -Depth 100 #region Check if Log Analytics Workspace Id is provided. Otherwise set it. $LogAnalyticsWorkspaceResourceIdInFile = $Configuration.parameters | Get-Member -Name logAnalyticsWorkspaceResourceId if ($null -eq $LogAnalyticsWorkspaceResourceIdInFile -or $Configuration.parameters.logAnalyticsWorkspaceResourceId.value -eq "") { Write-Output "Log Analytics Workspace Resource Id is not provided in the configuration file. Setting it to the default value." $LogAnalyticsWorkspaceIdElement = @{ logAnalyticsWorkspaceResourceId = @{ value = $LogAnalyticsWorkspaceResourceId } } $Configuration.parameters | Add-Member $LogAnalyticsWorkspaceIdElement -Force } #endregion #region Check if NVA username and password are provided. if (-not [string]::IsNullOrEmpty($NvaUsername)) { Write-Output "NVA username is provided. Setting NVA username in configuration." $NvaUsernameElement = @{ fwUsername = @{ value = ($NvaUsername | ConvertFrom-SecureString -AsPlainText) } } $Configuration.parameters | Add-Member $NvaUsernameElement -Force } if (-not [string]::IsNullOrEmpty($NvaPassword)) { Write-Output "NVA password is provided. Setting NVA password in configuration." $NvaPasswordElement = @{ fwPassword = @{ value = ($NvaPassword | ConvertFrom-SecureString -AsPlainText) } } $Configuration.parameters | Add-Member $NvaPasswordElement -Force } #endregion $PopulatedParametersFilePath = $ConfigurationFilePath.Split('.')[0] + '-populated.json' Write-Output "Creating new file with runtime populated parameters: $PopulatedParametersFilePath" $Configuration | ConvertTo-Json -Depth 100 | Set-Content $PopulatedParametersFilePath Write-Output "Moving Subscription ($SubscriptionId) to Management Group ($ManagementGroupId)" New-AzManagementGroupDeployment ` -ManagementGroupId $ManagementGroupId ` -Location $Context.DeploymentRegion ` -TemplateFile "$($Context.WorkingDirectory)/landingzones/utils/mg-move/move-subscription.bicep" ` -TemplateParameterObject @{ managementGroupId = $ManagementGroupId subscriptionId = $SubscriptionId } <# This 'New-AzSubscriptionDeployment` command to deploy the hub network has been observed to fail with a transient error condition. It is wrapped in a retry loop to solve for transient errors. #> $deployAttempt = 1 $deployed = $false while (($deployAttempt -le $RetryCount) -and (-not $deployed)) { if ($deployAttempt -gt 1) { Write-Output "Waiting $RetryDelay seconds before retrying deployment" Start-Sleep -Seconds $RetryDelay } try { Write-Output "Deploying $PopulatedParametersFilePath to $SubscriptionId in $Region - Attempt $deployAttempt of $RetryCount" New-AzSubscriptionDeployment ` -Name "main-$Region" ` -Location $Region ` -TemplateFile "$($Context.WorkingDirectory)/landingzones/lz-platform-connectivity-hub-nva/main.bicep" ` -TemplateParameterFile $PopulatedParametersFilePath ` -Verbose $deployed = $true } catch { if ($deployAttempt -eq $RetryCount) { throw } else { Write-Output "Error deploying $PopulatedParametersFilePath to $SubscriptionId in $Region" Write-Output $_.Exception.Message Write-Output $_.Exception.StackTrace } } $deployAttempt++ } #region Check if Private DNS Zones are managed in the Hub. If so, enable Private DNS Zones policy assignment if ($Configuration.parameters.privateDnsZones.value.enabled -eq $true) { $PolicyAssignmentFilePath = "$($Context.PolicySetCustomAssignmentsDirectory)/DNSPrivateEndpoints.bicep" Write-Output "Hub Network will manage private dns zones, creating Azure Policy assignment to automatically create Private Endpoint DNS Zones." Write-Output "Deploying policy assignment using $PolicyAssignmentFilePath" $Parameters = @{ policyAssignmentManagementGroupId = $Context.TopLevelManagementGroupId policyDefinitionManagementGroupId = $Context.TopLevelManagementGroupId privateDNSZoneSubscriptionId = $SubscriptionId privateDNSZoneResourceGroupName = $Configuration.parameters.privateDnsZones.value.resourceGroupName } New-AzManagementGroupDeployment ` -ManagementGroupId $Context.TopLevelManagementGroupId ` -Location $Context.DeploymentRegion ` -TemplateFile $PolicyAssignmentFilePath ` -TemplateParameterObject $Parameters } else { Write-Output "Hub Network will not manage private dns zones. Azure Policy assignment will be skipped." } #endregion #region Check if DDOS Standard is deployed in the Hub. If so, enable DDOS Standard policy assignment if ($Configuration.parameters.ddosStandard.value.enabled -eq $true) { $DDoSPlan = Get-AzDdosProtectionPlan ` -ResourceGroupName $Configuration.parameters.ddosStandard.value.resourceGroupName ` -Name $Configuration.parameters.ddosStandard.value.planName $PolicyAssignmentFilePath = "$($Context.PolicySetCustomAssignmentsDirectory)/DDoS.bicep" Write-Output "DDoS Standard is enabled, creating Azure Policy assignment to protect for all Virtual Networks in '$($Context.TopLevelManagementGroupId)' management group." Write-Output "Deploying policy assignment using $PolicyAssignmentFilePath" $Parameters = @{ policyAssignmentManagementGroupId = $Context.TopLevelManagementGroupId policyDefinitionManagementGroupId = $Context.TopLevelManagementGroupId ddosStandardPlanId = $DDoSPlan.Id } New-AzManagementGroupDeployment ` -ManagementGroupId $Context.TopLevelManagementGroupId ` -Location $Context.DeploymentRegion ` -TemplateFile $PolicyAssignmentFilePath ` -TemplateParameterObject $Parameters } else { Write-Output "DDoS Standard is not enabled. Azure Policy assignment will be skipped." } #endregion Remove-Item $PopulatedParametersFilePath }