diff --git a/avm/res/network/virtual-hub/README.md b/avm/res/network/virtual-hub/README.md index 2c7b689a6a..78f0828fa9 100644 --- a/avm/res/network/virtual-hub/README.md +++ b/avm/res/network/virtual-hub/README.md @@ -10,6 +10,7 @@ If you are planning to deploy a Secure Virtual Hub (with an Azure Firewall integ - [Parameters](#Parameters) - [Outputs](#Outputs) - [Cross-referenced modules](#Cross-referenced-modules) +- [Notes](#Notes) - [Data Collection](#Data-Collection) ## Resource Types @@ -19,7 +20,8 @@ If you are planning to deploy a Secure Virtual Hub (with an Azure Firewall integ | `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | | `Microsoft.Network/virtualHubs` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualHubs) | | `Microsoft.Network/virtualHubs/hubRouteTables` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/virtualHubs/hubRouteTables) | -| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/virtualHubs/hubVirtualNetworkConnections) | +| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualHubs/hubVirtualNetworkConnections) | +| `Microsoft.Network/virtualHubs/routingIntent` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualHubs/routingIntent) | ## Usage examples @@ -31,7 +33,8 @@ The following section provides usage examples for the module, which were used to - [Using only defaults](#example-1-using-only-defaults) - [Using large parameter set](#example-2-using-large-parameter-set) -- [WAF-aligned](#example-3-waf-aligned) +- [Using Routing Intent](#example-3-using-routing-intent) +- [WAF-aligned](#example-4-waf-aligned) ### Example 1: _Using only defaults_ @@ -223,7 +226,121 @@ module virtualHub 'br/public:avm/res/network/virtual-hub:' = {

-### Example 3: _WAF-aligned_ +### Example 3: _Using Routing Intent_ + +This instance deploys the module the Virtual WAN hub with Routing Intent enabled; requires an existing Virtual Hub, as well the firewall Resource ID. + + +

+ +via Bicep module + +```bicep +module virtualHub 'br/public:avm/res/network/virtual-hub:' = { + name: 'virtualHubDeployment' + params: { + // Required parameters + addressPrefix: '10.10.0.0/23' + name: 'nvhrtint' + virtualWanId: '' + // Non-required parameters + azureFirewallResourceId: '' + hubRouteTables: [] + hubRoutingPreference: 'ASPath' + hubVirtualNetworkConnections: [ + { + name: 'connection1' + remoteVirtualNetworkId: '' + routingConfiguration: {} + } + ] + internetToFirewall: false + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + privateToFirewall: true + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "addressPrefix": { + "value": "10.10.0.0/23" + }, + "name": { + "value": "nvhrtint" + }, + "virtualWanId": { + "value": "" + }, + // Non-required parameters + "azureFirewallResourceId": { + "value": "" + }, + "hubRouteTables": { + "value": [] + }, + "hubRoutingPreference": { + "value": "ASPath" + }, + "hubVirtualNetworkConnections": { + "value": [ + { + "name": "connection1", + "remoteVirtualNetworkId": "", + "routingConfiguration": {} + } + ] + }, + "internetToFirewall": { + "value": false + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "privateToFirewall": { + "value": true + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + } + } +} +``` + +
+

+ +### Example 4: _WAF-aligned_ This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. @@ -379,10 +496,12 @@ module virtualHub 'br/public:avm/res/network/virtual-hub:' = { | [`hubRouteTables`](#parameter-hubroutetables) | array | Route tables to create for the virtual hub. | | [`hubRoutingPreference`](#parameter-hubroutingpreference) | string | The preferred routing preference for this virtual hub. | | [`hubVirtualNetworkConnections`](#parameter-hubvirtualnetworkconnections) | array | Virtual network connections to create for the virtual hub. | +| [`internetToFirewall`](#parameter-internettofirewall) | bool | Configures Routing Intent to forward Internet traffic (0.0.0.0/0) to Azure Firewall. Default is true. | | [`location`](#parameter-location) | string | Location for all resources. | | [`lock`](#parameter-lock) | object | The lock settings of the service. | | [`p2SVpnGatewayId`](#parameter-p2svpngatewayid) | string | Resource ID of the Point-to-Site VPN Gateway to link to. | | [`preferredRoutingGateway`](#parameter-preferredroutinggateway) | string | The preferred routing gateway types. | +| [`privateToFirewall`](#parameter-privatetofirewall) | bool | Configures Routing Intent to forward Private traffic (RFC 1918) to Azure Firewall. Default is true. | | [`routeTableRoutes`](#parameter-routetableroutes) | array | VirtualHub route tables. | | [`securityPartnerProviderId`](#parameter-securitypartnerproviderid) | string | ID of the Security Partner Provider to link to. | | [`securityProviderName`](#parameter-securityprovidername) | string | The Security Provider name. | @@ -479,6 +598,14 @@ Virtual network connections to create for the virtual hub. - Type: array - Default: `[]` +### Parameter: `internetToFirewall` + +Configures Routing Intent to forward Internet traffic (0.0.0.0/0) to Azure Firewall. Default is true. + +- Required: No +- Type: bool +- Default: `True` + ### Parameter: `location` Location for all resources. @@ -548,6 +675,14 @@ The preferred routing gateway types. ] ``` +### Parameter: `privateToFirewall` + +Configures Routing Intent to forward Private traffic (RFC 1918) to Azure Firewall. Default is true. + +- Required: No +- Type: bool +- Default: `True` + ### Parameter: `routeTableRoutes` VirtualHub route tables. @@ -639,6 +774,12 @@ Resource ID of the VPN Gateway to link to. _None_ +## Notes + +**Configuring Routing Intent** + +Due to limitations with the virtual hub resource provider, to fully enable routing intent this resource will need to be invoked twice within the virtual WAN pattern. The first invocation will create the Virtual Hub, after which the resource creating the firewall can be called; then the second invocation can configure routing intent. This ensures that the resources are created in the correct order, and that the required resource ID parameters are available when they are needed. + ## Data Collection The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/network/virtual-hub/hub-route-table/main.json b/avm/res/network/virtual-hub/hub-route-table/main.json index d84fdbe0d2..574eb2230e 100644 --- a/avm/res/network/virtual-hub/hub-route-table/main.json +++ b/avm/res/network/virtual-hub/hub-route-table/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "7178717349327479453" + "version": "0.29.47.4906", + "templateHash": "2767725465951482406" }, "name": "Virtual Hub Route Tables", "description": "This module deploys a Virtual Hub Route Table.", diff --git a/avm/res/network/virtual-hub/hub-routing-intent/README.md b/avm/res/network/virtual-hub/hub-routing-intent/README.md new file mode 100644 index 0000000000..f26802847e --- /dev/null +++ b/avm/res/network/virtual-hub/hub-routing-intent/README.md @@ -0,0 +1,84 @@ +# Virtual Hub Routing Intent `[Microsoft.Network/virtualHubs]` + +This module configures Routing Intent for a Virtual Hub; this module requires an existing Virtual Hub, as well the firewall Resource ID. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Notes](#Notes) +- [Data Collection](#Data-Collection) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/virtualHubs/routingIntent` | [2023-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-11-01/virtualHubs/routingIntent) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`azureFirewallResourceId`](#parameter-azurefirewallresourceid) | string | Hub firewall Resource ID. | +| [`internetToFirewall`](#parameter-internettofirewall) | bool | Configures Routing Intent to Forward Internet traffic to the firewall (0.0.0.0/0). | +| [`privateToFirewall`](#parameter-privatetofirewall) | bool | Configures Routing Intent to forward Private traffic to the firewall (RFC1918). | +| [`virtualHubName`](#parameter-virtualhubname) | string | Name of the Virtual Hub. | + +### Parameter: `azureFirewallResourceId` + +Hub firewall Resource ID. + +- Required: Yes +- Type: string + +### Parameter: `internetToFirewall` + +Configures Routing Intent to Forward Internet traffic to the firewall (0.0.0.0/0). + +- Required: Yes +- Type: bool + +### Parameter: `privateToFirewall` + +Configures Routing Intent to forward Private traffic to the firewall (RFC1918). + +- Required: Yes +- Type: bool + +### Parameter: `virtualHubName` + +Name of the Virtual Hub. + +- Required: Yes +- Type: string + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the Routing Intent configuration. | +| `resourceGroupName` | string | The resource group the Routing Intent configuration was deployed into. | +| `resourceId` | string | The resource ID of the Routing Intent configuration. | + +## Cross-referenced modules + +_None_ + +## Notes + +The use of Routing Intent in a Virtual Hub requires the hub be made 'secure' by associating a firewall (to serve as the next-hop for the routing policy). + +The 'azureFirewall' parameter in Microsoft.Network/virtualHubs is *read-only*; in order to properly deploy a Virtual Hub using Routing Intent, the hub's Resource ID must first be passed to the firewall in order for it to be properly associated. In order for this resource to work properly, the resources need to be created in the following order: + +- **Virtual Hub**: Suggest minimal hub configuration; name/location/addressPrefix/virtualWan.id +- **Firewall**: Including Virtual Hub Resource ID in the firewall configuration +- **Virtual Hub**: Including all remaining parameters + Routing Intent + +## Data Collection + +The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the [repository](https://aka.ms/avm/telemetry). There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at . You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices. diff --git a/avm/res/network/virtual-hub/hub-routing-intent/main.bicep b/avm/res/network/virtual-hub/hub-routing-intent/main.bicep new file mode 100644 index 0000000000..aed6123d50 --- /dev/null +++ b/avm/res/network/virtual-hub/hub-routing-intent/main.bicep @@ -0,0 +1,68 @@ +metadata name = 'Virtual Hub Routing Intent' +metadata description = 'This module configures Routing Intent for a Virtual Hub; this module requires an existing Virtual Hub, as well the firewall Resource ID.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Hub firewall Resource ID.') +param azureFirewallResourceId string + +@description('Required. Name of the Virtual Hub.') +param virtualHubName string + +@description('Required. Configures Routing Intent to forward Private traffic to the firewall (RFC1918).') +param privateToFirewall bool + +@description('Required. Configures Routing Intent to Forward Internet traffic to the firewall (0.0.0.0/0).') +param internetToFirewall bool + +resource virtualHub 'Microsoft.Network/virtualHubs@2022-11-01' existing = { + name: virtualHubName +} + +resource routingIntent 'Microsoft.Network/virtualHubs/routingIntent@2023-11-01' = { + name: 'defaultRouteTable' + parent : virtualHub + properties: { + routingPolicies: (internetToFirewall == true && privateToFirewall == true) ? [ + { + name: '_policy_PublicTraffic' + destinations: [ + 'Internet' + ] + nextHop: azureFirewallResourceId + } + { + name: '_policy_PrivateTraffic' + destinations: [ + 'PrivateTraffic' + ] + nextHop: azureFirewallResourceId + } + ] : (internetToFirewall == true && privateToFirewall == false) ? [ + { + name: '_policy_PublicTraffic' + destinations: [ + 'Internet' + ] + nextHop: azureFirewallResourceId + } + ] : (internetToFirewall == false && privateToFirewall == true) ? [ + { + name: '_policy_PrivateTraffic' + destinations: [ + 'PrivateTraffic' + ] + nextHop: azureFirewallResourceId + } + ] + : null + } +} + +@description('The name of the Routing Intent configuration.') +output name string = routingIntent.name + +@description('The resource ID of the Routing Intent configuration.') +output resourceId string = routingIntent.id + +@description('The resource group the Routing Intent configuration was deployed into.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/virtual-hub/hub-routing-intent/main.json b/avm/res/network/virtual-hub/hub-routing-intent/main.json new file mode 100644 index 0000000000..f540aae020 --- /dev/null +++ b/avm/res/network/virtual-hub/hub-routing-intent/main.json @@ -0,0 +1,73 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "9080948373192033748" + }, + "name": "Virtual Hub Routing Intent", + "description": "This module configures Routing Intent for a Virtual Hub; this module requires an existing Virtual Hub, as well the firewall Resource ID.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "azureFirewallResourceId": { + "type": "string", + "metadata": { + "description": "Required. Hub firewall Resource ID." + } + }, + "virtualHubName": { + "type": "string", + "metadata": { + "description": "Required. Name of the Virtual Hub." + } + }, + "privateToFirewall": { + "type": "bool", + "metadata": { + "description": "Required. Configures Routing Intent to forward Private traffic to the firewall (RFC1918)." + } + }, + "internetToFirewall": { + "type": "bool", + "metadata": { + "description": "Required. Configures Routing Intent to Forward Internet traffic to the firewall (0.0.0.0/0)." + } + } + }, + "resources": [ + { + "type": "Microsoft.Network/virtualHubs/routingIntent", + "apiVersion": "2023-11-01", + "name": "[format('{0}/{1}', parameters('virtualHubName'), 'defaultRouteTable')]", + "properties": { + "routingPolicies": "[if(and(equals(parameters('internetToFirewall'), true()), equals(parameters('privateToFirewall'), true())), createArray(createObject('name', '_policy_PublicTraffic', 'destinations', createArray('Internet'), 'nextHop', parameters('azureFirewallResourceId')), createObject('name', '_policy_PrivateTraffic', 'destinations', createArray('PrivateTraffic'), 'nextHop', parameters('azureFirewallResourceId'))), if(and(equals(parameters('internetToFirewall'), true()), equals(parameters('privateToFirewall'), false())), createArray(createObject('name', '_policy_PublicTraffic', 'destinations', createArray('Internet'), 'nextHop', parameters('azureFirewallResourceId'))), if(and(equals(parameters('internetToFirewall'), false()), equals(parameters('privateToFirewall'), true())), createArray(createObject('name', '_policy_PrivateTraffic', 'destinations', createArray('PrivateTraffic'), 'nextHop', parameters('azureFirewallResourceId'))), null())))]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the Routing Intent configuration." + }, + "value": "defaultRouteTable" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Routing Intent configuration." + }, + "value": "[resourceId('Microsoft.Network/virtualHubs/routingIntent', parameters('virtualHubName'), 'defaultRouteTable')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the Routing Intent configuration was deployed into." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md b/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md index 43d153f7a7..41874c8b1e 100644 --- a/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md +++ b/avm/res/network/virtual-hub/hub-virtual-network-connection/README.md @@ -14,7 +14,7 @@ This module deploys a Virtual Hub Virtual Network Connection. | Resource Type | API Version | | :-- | :-- | -| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2022-11-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2022-11-01/virtualHubs/hubVirtualNetworkConnections) | +| `Microsoft.Network/virtualHubs/hubVirtualNetworkConnections` | [2024-01-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/virtualHubs/hubVirtualNetworkConnections) | ## Parameters diff --git a/avm/res/network/virtual-hub/hub-virtual-network-connection/main.bicep b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.bicep index f9751898ec..0dadaaf142 100644 --- a/avm/res/network/virtual-hub/hub-virtual-network-connection/main.bicep +++ b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.bicep @@ -17,11 +17,11 @@ param remoteVirtualNetworkId string @description('Optional. Routing Configuration indicating the associated and propagated route tables for this connection.') param routingConfiguration object = {} -resource virtualHub 'Microsoft.Network/virtualHubs@2022-11-01' existing = { +resource virtualHub 'Microsoft.Network/virtualHubs@2024-01-01' existing = { name: virtualHubName } -resource hubVirtualNetworkConnection 'Microsoft.Network/virtualHubs/hubVirtualNetworkConnections@2022-11-01' = { +resource hubVirtualNetworkConnection 'Microsoft.Network/virtualHubs/hubVirtualNetworkConnections@2024-01-01' = { name: name parent: virtualHub properties: { diff --git a/avm/res/network/virtual-hub/hub-virtual-network-connection/main.json b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.json index 83f863e837..ac1b70d82e 100644 --- a/avm/res/network/virtual-hub/hub-virtual-network-connection/main.json +++ b/avm/res/network/virtual-hub/hub-virtual-network-connection/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "3505452198428635330" + "version": "0.29.47.4906", + "templateHash": "12641692391238745355" }, "name": "Virtual Hub Virtual Network Connections", "description": "This module deploys a Virtual Hub Virtual Network Connection.", @@ -48,7 +48,7 @@ "resources": [ { "type": "Microsoft.Network/virtualHubs/hubVirtualNetworkConnections", - "apiVersion": "2022-11-01", + "apiVersion": "2024-01-01", "name": "[format('{0}/{1}', parameters('virtualHubName'), parameters('name'))]", "properties": { "enableInternetSecurity": "[parameters('enableInternetSecurity')]", diff --git a/avm/res/network/virtual-hub/main.bicep b/avm/res/network/virtual-hub/main.bicep index ae570f0f50..c21158f265 100644 --- a/avm/res/network/virtual-hub/main.bicep +++ b/avm/res/network/virtual-hub/main.bicep @@ -76,6 +76,12 @@ param virtualWanId string @description('Optional. Resource ID of the VPN Gateway to link to.') param vpnGatewayId string = '' +@description('Optional. Configures Routing Intent to forward Internet traffic (0.0.0.0/0) to Azure Firewall. Default is true.') +param internetToFirewall bool = true + +@description('Optional. Configures Routing Intent to forward Private traffic (RFC 1918) to Azure Firewall. Default is true.') +param privateToFirewall bool = true + @description('Optional. Route tables to create for the virtual hub.') param hubRouteTables array = [] @@ -171,8 +177,18 @@ resource virtualHub_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty scope: virtualHub } +module virtualHub_routingIntent 'hub-routing-intent/main.bicep' = if (!empty(azureFirewallResourceId) && (internetToFirewall || privateToFirewall)) { + name: '${uniqueString(deployment().name, location)}-routingIntent' + params: { + virtualHubName: virtualHub.name + azureFirewallResourceId: azureFirewallResourceId + internetToFirewall: internetToFirewall + privateToFirewall: privateToFirewall + } +} + module virtualHub_routeTables 'hub-route-table/main.bicep' = [ - for (routeTable, index) in hubRouteTables: { + for (routeTable, index) in (hubRouteTables ?? []): { name: '${uniqueString(deployment().name, location)}-routeTable-${index}' params: { virtualHubName: virtualHub.name diff --git a/avm/res/network/virtual-hub/main.json b/avm/res/network/virtual-hub/main.json index 5404500f8e..036e31e882 100644 --- a/avm/res/network/virtual-hub/main.json +++ b/avm/res/network/virtual-hub/main.json @@ -5,8 +5,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "13594058281073706360" + "version": "0.29.47.4906", + "templateHash": "14437175207078546495" }, "name": "Virtual Hubs", "description": "This module deploys a Virtual Hub.\nIf you are planning to deploy a Secure Virtual Hub (with an Azure Firewall integrated), please refer to the Azure Firewall module.", @@ -186,6 +186,20 @@ "description": "Optional. Resource ID of the VPN Gateway to link to." } }, + "internetToFirewall": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Configures Routing Intent to forward Internet traffic (0.0.0.0/0) to Azure Firewall. Default is true." + } + }, + "privateToFirewall": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Configures Routing Intent to forward Private traffic (RFC 1918) to Azure Firewall. Default is true." + } + }, "hubRouteTables": { "type": "array", "defaultValue": [], @@ -276,10 +290,112 @@ "virtualHub" ] }, + "virtualHub_routingIntent": { + "condition": "[and(not(empty(parameters('azureFirewallResourceId'))), or(parameters('internetToFirewall'), parameters('privateToFirewall')))]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-routingIntent', uniqueString(deployment().name, parameters('location')))]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "virtualHubName": { + "value": "[parameters('name')]" + }, + "azureFirewallResourceId": { + "value": "[parameters('azureFirewallResourceId')]" + }, + "internetToFirewall": { + "value": "[parameters('internetToFirewall')]" + }, + "privateToFirewall": { + "value": "[parameters('privateToFirewall')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.29.47.4906", + "templateHash": "9080948373192033748" + }, + "name": "Virtual Hub Routing Intent", + "description": "This module configures Routing Intent for a Virtual Hub; this module requires an existing Virtual Hub, as well the firewall Resource ID.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "azureFirewallResourceId": { + "type": "string", + "metadata": { + "description": "Required. Hub firewall Resource ID." + } + }, + "virtualHubName": { + "type": "string", + "metadata": { + "description": "Required. Name of the Virtual Hub." + } + }, + "privateToFirewall": { + "type": "bool", + "metadata": { + "description": "Required. Configures Routing Intent to forward Private traffic to the firewall (RFC1918)." + } + }, + "internetToFirewall": { + "type": "bool", + "metadata": { + "description": "Required. Configures Routing Intent to Forward Internet traffic to the firewall (0.0.0.0/0)." + } + } + }, + "resources": [ + { + "type": "Microsoft.Network/virtualHubs/routingIntent", + "apiVersion": "2023-11-01", + "name": "[format('{0}/{1}', parameters('virtualHubName'), 'defaultRouteTable')]", + "properties": { + "routingPolicies": "[if(and(equals(parameters('internetToFirewall'), true()), equals(parameters('privateToFirewall'), true())), createArray(createObject('name', '_policy_PublicTraffic', 'destinations', createArray('Internet'), 'nextHop', parameters('azureFirewallResourceId')), createObject('name', '_policy_PrivateTraffic', 'destinations', createArray('PrivateTraffic'), 'nextHop', parameters('azureFirewallResourceId'))), if(and(equals(parameters('internetToFirewall'), true()), equals(parameters('privateToFirewall'), false())), createArray(createObject('name', '_policy_PublicTraffic', 'destinations', createArray('Internet'), 'nextHop', parameters('azureFirewallResourceId'))), if(and(equals(parameters('internetToFirewall'), false()), equals(parameters('privateToFirewall'), true())), createArray(createObject('name', '_policy_PrivateTraffic', 'destinations', createArray('PrivateTraffic'), 'nextHop', parameters('azureFirewallResourceId'))), null())))]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the Routing Intent configuration." + }, + "value": "defaultRouteTable" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the Routing Intent configuration." + }, + "value": "[resourceId('Microsoft.Network/virtualHubs/routingIntent', parameters('virtualHubName'), 'defaultRouteTable')]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The resource group the Routing Intent configuration was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "virtualHub" + ] + }, "virtualHub_routeTables": { "copy": { "name": "virtualHub_routeTables", - "count": "[length(parameters('hubRouteTables'))]" + "count": "[length(coalesce(parameters('hubRouteTables'), createArray()))]" }, "type": "Microsoft.Resources/deployments", "apiVersion": "2022-09-01", @@ -294,10 +410,10 @@ "value": "[parameters('name')]" }, "name": { - "value": "[parameters('hubRouteTables')[copyIndex()].name]" + "value": "[coalesce(parameters('hubRouteTables'), createArray())[copyIndex()].name]" }, - "labels": "[if(contains(parameters('hubRouteTables')[copyIndex()], 'labels'), createObject('value', parameters('hubRouteTables')[copyIndex()].labels), createObject('value', createArray()))]", - "routes": "[if(contains(parameters('hubRouteTables')[copyIndex()], 'routes'), createObject('value', parameters('hubRouteTables')[copyIndex()].routes), createObject('value', createArray()))]" + "labels": "[if(contains(coalesce(parameters('hubRouteTables'), createArray())[copyIndex()], 'labels'), createObject('value', coalesce(parameters('hubRouteTables'), createArray())[copyIndex()].labels), createObject('value', createArray()))]", + "routes": "[if(contains(coalesce(parameters('hubRouteTables'), createArray())[copyIndex()], 'routes'), createObject('value', coalesce(parameters('hubRouteTables'), createArray())[copyIndex()].routes), createObject('value', createArray()))]" }, "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", @@ -305,8 +421,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "7178717349327479453" + "version": "0.29.47.4906", + "templateHash": "2767725465951482406" }, "name": "Virtual Hub Route Tables", "description": "This module deploys a Virtual Hub Route Table.", @@ -412,8 +528,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.28.1.47646", - "templateHash": "3505452198428635330" + "version": "0.29.47.4906", + "templateHash": "12641692391238745355" }, "name": "Virtual Hub Virtual Network Connections", "description": "This module deploys a Virtual Hub Virtual Network Connection.", @@ -456,7 +572,7 @@ "resources": [ { "type": "Microsoft.Network/virtualHubs/hubVirtualNetworkConnections", - "apiVersion": "2022-11-01", + "apiVersion": "2024-01-01", "name": "[format('{0}/{1}', parameters('virtualHubName'), parameters('name'))]", "properties": { "enableInternetSecurity": "[parameters('enableInternetSecurity')]", diff --git a/avm/res/network/virtual-hub/tests/e2e/routing-intent/dependencies.bicep b/avm/res/network/virtual-hub/tests/e2e/routing-intent/dependencies.bicep new file mode 100644 index 0000000000..39fc4c0351 --- /dev/null +++ b/avm/res/network/virtual-hub/tests/e2e/routing-intent/dependencies.bicep @@ -0,0 +1,81 @@ +@description('Required. The name of the Virtual WAN to create.') +param virtualWANName string + +@description('Required. The name of the Virtual Hub to create.') +param virtualHubName string + +@description('Required. The name of the Virtual Network to create.') +param virtualNetworkName string + +@description('Required. The name of the Azure Firewall to create.') +param azureFirewallName string + +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +var addressPrefix = '10.0.0.0/16' + +resource virtualWan 'Microsoft.Network/virtualWans@2023-04-01' = { + name: virtualWANName + location: location +} + +resource virtualHub 'Microsoft.Network/virtualHubs@2023-11-01' = { + name: virtualHubName + location: location + properties: { + addressPrefix: '10.10.0.0/23' + virtualWan: { + id: virtualWan.id + } + } +} + +resource virtualNetwork 'Microsoft.Network/virtualNetworks@2023-04-01' = { + name: virtualNetworkName + location: location + properties: { + addressSpace: { + addressPrefixes: [ + addressPrefix + ] + } + subnets: [ + { + name: 'defaultSubnet' + properties: { + addressPrefix: cidrSubnet(addressPrefix, 16, 0) + } + } + ] + } +} + +resource azureFirewall 'Microsoft.Network/azureFirewalls@2023-04-01' = { + name: azureFirewallName + location: location + properties: { + sku: { + name: 'AZFW_Hub' + tier: 'Premium' + } + hubIPAddresses: { + publicIPs: { + count: 1 + } + } + virtualHub: { + id: virtualHub.id + } + } +} + + +@description('The resource ID of the created Virtual WAN.') +output virtualWANResourceId string = virtualWan.id + +@description('The resource ID of the created Virtual Network.') +output virtualNetworkResourceId string = virtualNetwork.id + +@description('The resource ID of the created Azure Firewall') +output azureFirewallResourceId string = azureFirewall.id diff --git a/avm/res/network/virtual-hub/tests/e2e/routing-intent/main.test.bicep b/avm/res/network/virtual-hub/tests/e2e/routing-intent/main.test.bicep new file mode 100644 index 0000000000..737caa3be1 --- /dev/null +++ b/avm/res/network/virtual-hub/tests/e2e/routing-intent/main.test.bicep @@ -0,0 +1,84 @@ +targetScope = 'subscription' + +metadata name = 'Using Routing Intent' +metadata description = 'This instance deploys the module the Virtual WAN hub with Routing Intent enabled; requires an existing Virtual Hub, as well the firewall Resource ID.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.virtualHub-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param resourceLocation string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'nvhrtint' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: resourceLocation +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-nestedDependencies' + params: { + virtualWANName: 'dep-${namePrefix}-vw-${serviceShort}' + virtualHubName: '${namePrefix}-${serviceShort}' + virtualNetworkName: 'dep-${namePrefix}-vnet-${serviceShort}' + azureFirewallName: 'dep-${namePrefix}-azfw-${serviceShort}' + location: resourceLocation + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [ + for iteration in ['init', 'idem']: { + dependsOn: [nestedDependencies] + scope: resourceGroup + name: '${uniqueString(deployment().name, resourceLocation)}-test-${serviceShort}-${iteration}' + params: { + location: resourceLocation + name: '${namePrefix}-${serviceShort}' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + addressPrefix: '10.10.0.0/23' + virtualWanId: nestedDependencies.outputs.virtualWANResourceId + hubRouteTables: [] + hubVirtualNetworkConnections: [ + { + name: 'connection1' + remoteVirtualNetworkId: nestedDependencies.outputs.virtualNetworkResourceId + routingConfiguration: {} + } + ] + hubRoutingPreference: 'ASPath' + azureFirewallResourceId: nestedDependencies.outputs.azureFirewallResourceId + internetToFirewall: false + privateToFirewall: true + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } + } +]