From 3bdd5951311b5b5292d9d8de95f083caa1820ac6 Mon Sep 17 00:00:00 2001 From: Seif Bassem <38246040+sebassem@users.noreply.github.com> Date: Thu, 13 Feb 2025 18:46:03 +0200 Subject: [PATCH] fix: enhancements to hub-spoke module (#4443) ## Description Closes #4433 - Added options to specify bastion and route table names - Added values for bastion and firewall Skus in UDT - Added locks to route table - Updated the necessary tests ## Pipeline Reference | Pipeline | | -------- | | [![avm.ptn.network.hub-networking](https://github.com/sebassem/bicep-registry-modules/actions/workflows/avm.ptn.network.hub-networking.yml/badge.svg?branch=hub-spoke-enhancements)](https://github.com/sebassem/bicep-registry-modules/actions/workflows/avm.ptn.network.hub-networking.yml) | ## Type of Change - [ ] Update to CI Environment or utilities (Non-module affecting changes) - [ ] Azure Verified Module updates: - [X] Bugfix containing backwards-compatible bug fixes, and I have NOT bumped the MAJOR or MINOR version in `version.json`: - [X] Someone has opened a bug report issue, and I have included "Closes #{bug_report_issue_number}" in the PR description. - [ ] The bug was found by the module author, and no one has opened an issue to report it yet. - [ ] Feature update backwards compatible feature updates, and I have bumped the MINOR version in `version.json`. - [ ] Breaking changes and I have bumped the MAJOR version in `version.json`. - [X] Update to documentation ## Checklist - [X] I'm sure there are no other open Pull Requests for the same update/change - [X] I have run `Set-AVMModule` locally to generate the supporting module files. - [X] My corresponding pipelines / checks run clean and green without any errors or warnings --- avm/ptn/network/hub-networking/README.md | 69 ++++++++++++++++++- avm/ptn/network/hub-networking/main.bicep | 25 +++++-- avm/ptn/network/hub-networking/main.json | 56 +++++++++++++-- .../tests/e2e/max/main.test.bicep | 6 ++ 4 files changed, 146 insertions(+), 10 deletions(-) diff --git a/avm/ptn/network/hub-networking/README.md b/avm/ptn/network/hub-networking/README.md index b20fa6928b..9151a55c9b 100644 --- a/avm/ptn/network/hub-networking/README.md +++ b/avm/ptn/network/hub-networking/README.md @@ -118,8 +118,14 @@ module hubNetworking 'br/public:avm/ptn/network/hub-networking:' = { name: 'hub1-waf-pip' } threatIntelMode: 'Alert' + zones: [ + 1 + 2 + 3 + ] } bastionHost: { + bastionHostName: 'bastion-hub1' disableCopyPaste: true enableFileCopy: false enableIpConnect: false @@ -298,9 +304,15 @@ module hubNetworking 'br/public:avm/ptn/network/hub-networking:' = { "publicIPAddressObject": { "name": "hub1-waf-pip" }, - "threatIntelMode": "Alert" + "threatIntelMode": "Alert", + "zones": [ + 1, + 2, + 3 + ] }, "bastionHost": { + "bastionHostName": "bastion-hub1", "disableCopyPaste": true, "enableFileCopy": false, "enableIpConnect": false, @@ -480,8 +492,14 @@ param hubVirtualNetworks = { name: 'hub1-waf-pip' } threatIntelMode: 'Alert' + zones: [ + 1 + 2 + 3 + ] } bastionHost: { + bastionHostName: 'bastion-hub1' disableCopyPaste: true enableFileCopy: false enableIpConnect: false @@ -1255,6 +1273,7 @@ The hub virtual networks to create. | [`peeringSettings`](#parameter-hubvirtualnetworks>any_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyAny_other_property<.azureFirewallSettings.azureFirewallName` + +The name of the Azure Firewall. + +- Required: No +- Type: string + ### Parameter: `hubVirtualNetworks.>Any_other_property<.azureFirewallSettings.azureSkuTier` Azure Firewall SKU. - Required: No - Type: string +- Allowed: + ```Bicep + [ + 'Basic' + 'Premium' + 'Standard' + ] + ``` ### Parameter: `hubVirtualNetworks.>Any_other_property<.azureFirewallSettings.diagnosticSettings` @@ -1708,13 +1743,22 @@ The Azure Bastion config. | Parameter | Type | Description | | :-- | :-- | :-- | +| [`bastionHostName`](#parameter-hubvirtualnetworks>any_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyany_other_propertyAny_other_property<.bastionHost.bastionHostName` + +The name of the bastion host. + +- Required: No +- Type: string + ### Parameter: `hubVirtualNetworks.>Any_other_property<.bastionHost.disableCopyPaste` Enable/Disable copy/paste functionality. @@ -1736,6 +1780,13 @@ Enable/Disable IP connect functionality. - Required: No - Type: bool +### Parameter: `hubVirtualNetworks.>Any_other_property<.bastionHost.enableKerberos` + +Enable/Disable Kerberos authentication. + +- Required: No +- Type: bool + ### Parameter: `hubVirtualNetworks.>Any_other_property<.bastionHost.enableShareableLink` Enable/Disable shareable link functionality. @@ -1756,6 +1807,15 @@ The SKU name of the Bastion host. Defaults to Standard. - Required: No - Type: string +- Allowed: + ```Bicep + [ + 'Basic' + 'Developer' + 'Premium' + 'Standard' + ] + ``` ### Parameter: `hubVirtualNetworks.>Any_other_property<.ddosProtectionPlanResourceId` @@ -2151,6 +2211,13 @@ Routes to add to the virtual network route table. - Required: No - Type: array +### Parameter: `hubVirtualNetworks.>Any_other_property<.routeTableName` + +The name of the route table. + +- Required: No +- Type: string + ### Parameter: `hubVirtualNetworks.>Any_other_property<.subnets` The subnets of the virtual network. diff --git a/avm/ptn/network/hub-networking/main.bicep b/avm/ptn/network/hub-networking/main.bicep index b734027146..33573075b5 100644 --- a/avm/ptn/network/hub-networking/main.bicep +++ b/avm/ptn/network/hub-networking/main.bicep @@ -111,13 +111,14 @@ module hubRouteTable 'br/public:avm/res/network/route-table:0.4.0' = [ for (hub, index) in items(hubVirtualNetworks ?? {}): { name: '${uniqueString(deployment().name, location)}-${hub.key}-nrt' params: { - name: hub.key + name: hub.value.?routeTableName ?? hub.key location: hub.value.?location ?? location disableBgpRoutePropagation: true enableTelemetry: hub.value.?enableTelemetry ?? true roleAssignments: hub.value.?roleAssignments ?? [] routes: hub.value.?routes ?? [] tags: hub.value.?tags ?? {} + lock: hub.value.?lock ?? {} } dependsOn: hubVirtualNetwork } @@ -144,7 +145,7 @@ module hubBastion 'br/public:avm/res/network/bastion-host:0.4.0' = [ name: '${uniqueString(deployment().name, location)}-${hub.key}-nbh' params: { // Required parameters - name: hub.key + name: hub.value.?bastionHost.?bastionHostName ?? hub.key virtualNetworkResourceId: hubVirtualNetwork[index].outputs.resourceId // Non-required parameters diagnosticSettings: hub.value.?diagnosticSettings ?? [] @@ -158,6 +159,8 @@ module hubBastion 'br/public:avm/res/network/bastion-host:0.4.0' = [ scaleUnits: hub.value.?bastionHost.?scaleUnits ?? 4 skuName: hub.value.?bastionHost.?skuName ?? 'Standard' tags: hub.value.?tags ?? {} + lock: hub.value.?lock ?? {} + enableKerberos: hub.value.?bastionHost.?enableKerberos ?? false } dependsOn: hubVirtualNetwork } @@ -170,7 +173,7 @@ module hubAzureFirewall 'br/public:avm/res/network/azure-firewall:0.5.1' = [ name: '${uniqueString(deployment().name, location)}-${hub.key}-naf' params: { // Required parameters - name: hub.key + name: hub.value.?azureFirewallSettings.?azureFirewallName ?? hub.key // Conditional parameters hubIPAddresses: hub.value.?azureFirewallSettings.?hubIpAddresses ?? {} virtualHubId: hub.value.?azureFirewallSettings.?virtualHub ?? '' @@ -383,11 +386,17 @@ type hubVirtualNetworkType = { @description('Optional. Enable/Disable shareable link functionality.') enableShareableLink: bool? + @description('Optional. Enable/Disable Kerberos authentication.') + enableKerberos: bool? + @description('Optional. The number of scale units for the Bastion host. Defaults to 4.') scaleUnits: int? @description('Optional. The SKU name of the Bastion host. Defaults to Standard.') - skuName: string? + skuName: 'Basic' | 'Developer' | 'Premium' | 'Standard'? + + @description('Optional. The name of the bastion host.') + bastionHostName: string? }? @description('Optional. Enable/Disable usage telemetry for module.') @@ -429,6 +438,9 @@ type hubVirtualNetworkType = { @description('Optional. Routes to add to the virtual network route table.') routes: array? + @description('Optional. The name of the route table.') + routeTableName: string? + @description('Optional. The subnets of the virtual network.') subnets: array? @@ -461,6 +473,9 @@ type peeringSettingsType = { }[]? type azureFirewallType = { + @description('Optional. The name of the Azure Firewall.') + azureFirewallName: string? + @description('Optional. Hub IP addresses.') hubIpAddresses: object? @@ -474,7 +489,7 @@ type azureFirewallType = { applicationRuleCollections: array? @description('Optional. Azure Firewall SKU.') - azureSkuTier: string? + azureSkuTier: 'Basic' | 'Standard' | 'Premium'? @description('Optional. Diagnostic settings.') diagnosticSettings: diagnosticSettingType? diff --git a/avm/ptn/network/hub-networking/main.json b/avm/ptn/network/hub-networking/main.json index 124c1e8233..0c7284103c 100644 --- a/avm/ptn/network/hub-networking/main.json +++ b/avm/ptn/network/hub-networking/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.33.93.31351", - "templateHash": "10309836000326275731" + "templateHash": "13578022486694565821" }, "name": "Hub Networking", "description": "This module is designed to simplify the creation of multi-region hub networks in Azure. It will create a number of virtual networks and subnets, and optionally peer them together in a mesh topology with routing." @@ -280,6 +280,13 @@ "description": "Optional. Enable/Disable shareable link functionality." } }, + "enableKerberos": { + "type": "bool", + "nullable": true, + "metadata": { + "description": "Optional. Enable/Disable Kerberos authentication." + } + }, "scaleUnits": { "type": "int", "nullable": true, @@ -289,10 +296,23 @@ }, "skuName": { "type": "string", + "allowedValues": [ + "Basic", + "Developer", + "Premium", + "Standard" + ], "nullable": true, "metadata": { "description": "Optional. The SKU name of the Bastion host. Defaults to Standard." } + }, + "bastionHostName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the bastion host." + } } }, "nullable": true, @@ -391,6 +411,13 @@ "description": "Optional. Routes to add to the virtual network route table." } }, + "routeTableName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the route table." + } + }, "subnets": { "type": "array", "nullable": true, @@ -473,6 +500,13 @@ "azureFirewallType": { "type": "object", "properties": { + "azureFirewallName": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. The name of the Azure Firewall." + } + }, "hubIpAddresses": { "type": "object", "nullable": true, @@ -503,6 +537,11 @@ }, "azureSkuTier": { "type": "string", + "allowedValues": [ + "Basic", + "Premium", + "Standard" + ], "nullable": true, "metadata": { "description": "Optional. Azure Firewall SKU." @@ -2406,7 +2445,7 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].key]" + "value": "[coalesce(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'routeTableName'), items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].key)]" }, "location": { "value": "[coalesce(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'location'), parameters('location'))]" @@ -2425,6 +2464,9 @@ }, "tags": { "value": "[coalesce(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'tags'), createObject())]" + }, + "lock": { + "value": "[coalesce(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'lock'), createObject())]" } }, "template": { @@ -2790,7 +2832,7 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].key]" + "value": "[coalesce(tryGet(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'bastionHost'), 'bastionHostName'), items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].key)]" }, "virtualNetworkResourceId": { "value": "[reference(format('hubVirtualNetwork[{0}]', copyIndex())).outputs.resourceId.value]" @@ -2827,6 +2869,12 @@ }, "tags": { "value": "[coalesce(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'tags'), createObject())]" + }, + "lock": { + "value": "[coalesce(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'lock'), createObject())]" + }, + "enableKerberos": { + "value": "[coalesce(tryGet(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'bastionHost'), 'enableKerberos'), false())]" } }, "template": { @@ -4010,7 +4058,7 @@ "mode": "Incremental", "parameters": { "name": { - "value": "[items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].key]" + "value": "[coalesce(tryGet(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'azureFirewallSettings'), 'azureFirewallName'), items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].key)]" }, "hubIPAddresses": { "value": "[coalesce(tryGet(tryGet(items(coalesce(parameters('hubVirtualNetworks'), createObject()))[copyIndex()].value, 'azureFirewallSettings'), 'hubIpAddresses'), createObject())]" diff --git a/avm/ptn/network/hub-networking/tests/e2e/max/main.test.bicep b/avm/ptn/network/hub-networking/tests/e2e/max/main.test.bicep index 4a21691f16..f03c4132ff 100644 --- a/avm/ptn/network/hub-networking/tests/e2e/max/main.test.bicep +++ b/avm/ptn/network/hub-networking/tests/e2e/max/main.test.bicep @@ -71,8 +71,14 @@ module testDeployment '../../../main.bicep' = [ name: 'hub1-waf-pip' } threatIntelMode: 'Alert' + zones: [ + 1 + 2 + 3 + ] } bastionHost: { + bastionHostName: 'bastion-hub1' disableCopyPaste: true enableFileCopy: false enableIpConnect: false