diff --git a/modules/Microsoft.Network/azureFirewalls/.test/hub/dependencies.bicep b/modules/Microsoft.Network/azureFirewalls/.test/hub/dependencies.bicep new file mode 100644 index 0000000000..3981ef362c --- /dev/null +++ b/modules/Microsoft.Network/azureFirewalls/.test/hub/dependencies.bicep @@ -0,0 +1,43 @@ +@description('Optional. The location to deploy to.') +param location string = resourceGroup().location + +param virtualWanName string + +param virtualHubName string + +param firewallPolicyName string + +resource virtualWan 'Microsoft.Network/virtualWans@2021-08-01' = { + name: virtualWanName + location: location + properties: { + disableVpnEncryption: false + allowBranchToBranchTraffic: true + type: 'Standard' + } +} + +resource virtualHub 'Microsoft.Network/virtualHubs@2021-08-01' = { + name: virtualHubName + location: location + properties: { + addressPrefix: '10.1.0.0/16' + virtualWan: { + id: virtualWan.id + } + } +} + +resource policy 'Microsoft.Network/firewallPolicies@2021-08-01' = { + name: firewallPolicyName + location: location + properties: { + threatIntelMode: 'Alert' + } +} + +@description('The resource ID of the created Virtual Hub.') +output virtualHubResourceId string = virtualHub.id + +@description('The resource ID of the created Firewall Policie.') +output firewallPolicyResourceId string = policy.id diff --git a/modules/Microsoft.Network/azureFirewalls/.test/hub/deploy.test.bicep b/modules/Microsoft.Network/azureFirewalls/.test/hub/deploy.test.bicep new file mode 100644 index 0000000000..a159a1e7b6 --- /dev/null +++ b/modules/Microsoft.Network/azureFirewalls/.test/hub/deploy.test.bicep @@ -0,0 +1,58 @@ +targetScope = 'subscription' + +// ========== // +// Parameters // +// ========== // +@description('Optional. The name of the resource group to deploy for a testing purposes.') +@maxLength(90) +param resourceGroupName string = 'ms.network.azurefirewalls-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location 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 = 'nafhub' + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableDefaultTelemetry bool = true + +// =========== // +// Deployments // +// =========== // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module resourceGroupResources 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-paramNested' + params: { + virtualWanName: 'dep-<>-vwan-${serviceShort}' + virtualHubName: 'dep-<>-vhub-${serviceShort}' + firewallPolicyName: 'dep-<>-afwp-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +module testDeployment '../../deploy.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name)}-test-${serviceShort}' + params: { + enableDefaultTelemetry: enableDefaultTelemetry + name: '<>${serviceShort}001' + firewallPolicyId: resourceGroupResources.outputs.firewallPolicyResourceId + virtualHubId: resourceGroupResources.outputs.virtualHubResourceId + hubIPAddresses: { + publicIPs: { + count: 1 + } + } + } +} diff --git a/modules/Microsoft.Network/azureFirewalls/deploy.bicep b/modules/Microsoft.Network/azureFirewalls/deploy.bicep index c497ca5efa..019d69cbe4 100644 --- a/modules/Microsoft.Network/azureFirewalls/deploy.bicep +++ b/modules/Microsoft.Network/azureFirewalls/deploy.bicep @@ -1,13 +1,6 @@ @description('Required. Name of the Azure Firewall.') param name string -@description('Optional. Name of an Azure Firewall SKU.') -@allowed([ - 'AZFW_VNet' - 'AZFW_Hub' -]) -param azureSkuName string = 'AZFW_VNet' - @description('Optional. Tier of an Azure Firewall.') @allowed([ 'Standard' @@ -15,8 +8,8 @@ param azureSkuName string = 'AZFW_VNet' ]) param azureSkuTier string = 'Standard' -@description('Required. Shared services Virtual Network resource ID. The virtual network ID containing AzureFirewallSubnet. If a public ip is not provided, then the public ip that is created as part of this module will be applied with the subnet provided in this variable.') -param vNetId string +@description('Conditional. Shared services Virtual Network resource ID. The virtual network ID containing AzureFirewallSubnet. If a public ip is not provided, then the public ip that is created as part of this module will be applied with the subnet provided in this variable. Required if `virtualHubId` is empty.') +param vNetId string = '' @description('Optional. The public ip resource ID to associate to the AzureFirewallSubnet. If empty, then the public ip that is created as part of this module will be applied to the AzureFirewallSubnet.') param azureFirewallSubnetPublicIpId string = '' @@ -42,6 +35,12 @@ param natRuleCollections array = [] @description('Optional. Resource ID of the Firewall Policy that should be attached.') param firewallPolicyId string = '' +@description('Conditional. IP addresses associated with AzureFirewall. Required if `virtualHubId` is supplied.') +param hubIPAddresses object = {} + +@description('Conditional. The virtualHub resource ID to which the firewall belongs. Required if `vNetId` is empty.') +param virtualHubId string = '' + @allowed([ 'Alert' 'Deny' @@ -148,6 +147,8 @@ var newPip = { } : null } +var azureSkuName = empty(vNetId) ? 'AZFW_Hub' : 'AZFW_VNet' + var ipConfigurations = concat([ { name: !empty(azureFirewallSubnetPublicIpId) ? last(split(azureFirewallSubnetPublicIpId, '/')) : publicIPAddress.outputs.name @@ -190,7 +191,7 @@ resource defaultTelemetry 'Microsoft.Resources/deployments@2021-04-01' = if (ena } // create a public ip address if one is not provided and the flag is true -module publicIPAddress '../../Microsoft.Network/publicIPAddresses/deploy.bicep' = if (empty(azureFirewallSubnetPublicIpId) && isCreateDefaultPublicIP) { +module publicIPAddress '../../Microsoft.Network/publicIPAddresses/deploy.bicep' = if (empty(azureFirewallSubnetPublicIpId) && isCreateDefaultPublicIP && azureSkuName == 'AZFW_VNet') { name: '${uniqueString(deployment().name, location)}-Firewall-PIP' params: { name: contains(publicIPAddressObject, 'name') ? (!(empty(publicIPAddressObject.name)) ? publicIPAddressObject.name : '${name}-pip') : '${name}-pip' @@ -230,7 +231,7 @@ resource azureFirewall 'Microsoft.Network/azureFirewalls@2021-08-01' = { location: location zones: length(zones) == 0 ? null : zones tags: tags - properties: { + properties: azureSkuName == 'AZFW_VNet' ? { threatIntelMode: threatIntelMode firewallPolicy: empty(firewallPolicyId) ? null : { id: firewallPolicyId @@ -243,6 +244,18 @@ resource azureFirewall 'Microsoft.Network/azureFirewalls@2021-08-01' = { applicationRuleCollections: applicationRuleCollections natRuleCollections: natRuleCollections networkRuleCollections: networkRuleCollections + } : { + firewallPolicy: empty(firewallPolicyId) ? null : { + id: firewallPolicyId + } + sku: { + name: azureSkuName + tier: azureSkuTier + } + hubIPAddresses: empty(hubIPAddresses) ? null : hubIPAddresses + virtualHub: empty(virtualHubId) ? null : { + id: virtualHubId + } } dependsOn: [ publicIPAddress @@ -294,10 +307,10 @@ output name string = azureFirewall.name output resourceGroupName string = resourceGroup().name @description('The private IP of the Azure firewall.') -output privateIp string = azureFirewall.properties.ipConfigurations[0].properties.privateIPAddress +output privateIp string = contains(azureFirewall.properties, 'ipConfigurations') ? azureFirewall.properties.ipConfigurations[0].properties.privateIPAddress : '' @description('The public ipconfiguration object for the AzureFirewallSubnet.') -output ipConfAzureFirewallSubnet object = azureFirewall.properties.ipConfigurations[0] +output ipConfAzureFirewallSubnet object = contains(azureFirewall.properties, 'ipConfigurations') ? azureFirewall.properties.ipConfigurations[0] : {} @description('List of Application Rule Collections.') output applicationRuleCollections array = applicationRuleCollections diff --git a/modules/Microsoft.Network/azureFirewalls/readme.md b/modules/Microsoft.Network/azureFirewalls/readme.md index 4ad14c5ad1..4e6a29e6fa 100644 --- a/modules/Microsoft.Network/azureFirewalls/readme.md +++ b/modules/Microsoft.Network/azureFirewalls/readme.md @@ -28,7 +28,14 @@ This module deploys a firewall. | Parameter Name | Type | Description | | :-- | :-- | :-- | | `name` | string | Name of the Azure Firewall. | -| `vNetId` | string | Shared services Virtual Network resource ID. The virtual network ID containing AzureFirewallSubnet. If a public ip is not provided, then the public ip that is created as part of this module will be applied with the subnet provided in this variable. | + +**Conditional parameters** + +| Parameter Name | Type | Default Value | Description | +| :-- | :-- | :-- | :-- | +| `hubIPAddresses` | object | `{object}` | IP addresses associated with AzureFirewall. Required if `virtualHubId` is supplied. | +| `virtualHubId` | string | `''` | The virtualHub resource ID to which the firewall belongs. Required if `vNetId` is empty. | +| `vNetId` | string | `''` | Shared services Virtual Network resource ID. The virtual network ID containing AzureFirewallSubnet. If a public ip is not provided, then the public ip that is created as part of this module will be applied with the subnet provided in this variable. Required if `virtualHubId` is empty. | **Optional parameters** @@ -37,7 +44,6 @@ This module deploys a firewall. | `additionalPublicIpConfigurations` | array | `[]` | | This is to add any additional public ip configurations on top of the public ip with subnet ip configuration. | | `applicationRuleCollections` | array | `[]` | | Collection of application rule collections used by Azure Firewall. | | `azureFirewallSubnetPublicIpId` | string | `''` | | The public ip resource ID to associate to the AzureFirewallSubnet. If empty, then the public ip that is created as part of this module will be applied to the AzureFirewallSubnet. | -| `azureSkuName` | string | `'AZFW_VNet'` | `[AZFW_Hub, AZFW_VNet]` | Name of an Azure Firewall SKU. | | `azureSkuTier` | string | `'Standard'` | `[Premium, Standard]` | Tier of an Azure Firewall. | | `diagnosticEventHubAuthorizationRuleId` | string | `''` | | Resource ID of the diagnostic event hub authorization rule for the Event Hubs namespace in which the event hub should be created or streamed to. | | `diagnosticEventHubName` | string | `''` | | Name of the diagnostic event hub within the namespace to which logs are streamed. Without this, an event hub is created for each log category. | @@ -327,7 +333,6 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { params: { // Required parameters name: '<>nafaddpip001' - vNetId: '' // Non-required parameters additionalPublicIpConfigurations: [ { @@ -336,6 +341,7 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { } ] enableDefaultTelemetry: '' + vNetId: '' } } ``` @@ -356,9 +362,6 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { "name": { "value": "<>nafaddpip001" }, - "vNetId": { - "value": "" - }, // Non-required parameters "additionalPublicIpConfigurations": { "value": [ @@ -370,6 +373,9 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { }, "enableDefaultTelemetry": { "value": "" + }, + "vNetId": { + "value": "" } } } @@ -390,7 +396,6 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { params: { // Required parameters name: '<>nafcom001' - vNetId: '' // Non-required parameters applicationRuleCollections: [ { @@ -490,6 +495,7 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { roleDefinitionIdOrName: 'Reader' } ] + vNetId: '' zones: [ '1' '2' @@ -515,9 +521,6 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { "name": { "value": "<>nafcom001" }, - "vNetId": { - "value": "" - }, // Non-required parameters "applicationRuleCollections": { "value": [ @@ -639,6 +642,9 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { } ] }, + "vNetId": { + "value": "" + }, "zones": { "value": [ "1", @@ -665,7 +671,6 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { params: { // Required parameters name: '<>nafcstpip001' - vNetId: '' // Non-required parameters enableDefaultTelemetry: '' publicIPAddressObject: { @@ -692,6 +697,7 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { skuName: 'Standard' skuTier: 'Regional' } + vNetId: '' } } ``` @@ -712,9 +718,6 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { "name": { "value": "<>nafcstpip001" }, - "vNetId": { - "value": "" - }, // Non-required parameters "enableDefaultTelemetry": { "value": "" @@ -744,6 +747,9 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { "skuName": "Standard", "skuTier": "Regional" } + }, + "vNetId": { + "value": "" } } } @@ -752,7 +758,72 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = {

-

Example 4: Min

+

Example 4: Hub

+ +
+ +via Bicep module + +```bicep +module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { + name: '${uniqueString(deployment().name)}-test-nafhub' + params: { + // Required parameters + name: '<>nafhub001' + // Non-required parameters + enableDefaultTelemetry: '' + firewallPolicyId: '' + hubIPAddresses: { + publicIPs: { + count: 1 + } + } + virtualHubId: '' + } +} +``` + +
+

+ +

+ +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 + "name": { + "value": "<>nafhub001" + }, + // Non-required parameters + "enableDefaultTelemetry": { + "value": "" + }, + "firewallPolicyId": { + "value": "" + }, + "hubIPAddresses": { + "value": { + "publicIPs": { + "count": 1 + } + } + }, + "virtualHubId": { + "value": "" + } + } +} +``` + +
+

+ +

Example 5: Min

@@ -764,9 +835,9 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { params: { // Required parameters name: '<>nafmin001' - vNetId: '' // Non-required parameters enableDefaultTelemetry: '' + vNetId: '' } } ``` @@ -787,12 +858,12 @@ module azureFirewalls './Microsoft.Network/azureFirewalls/deploy.bicep' = { "name": { "value": "<>nafmin001" }, - "vNetId": { - "value": "" - }, // Non-required parameters "enableDefaultTelemetry": { "value": "" + }, + "vNetId": { + "value": "" } } } diff --git a/modules/Microsoft.Network/virtualHubs/deploy.bicep b/modules/Microsoft.Network/virtualHubs/deploy.bicep index 3a24d379f8..46c8f920cd 100644 --- a/modules/Microsoft.Network/virtualHubs/deploy.bicep +++ b/modules/Microsoft.Network/virtualHubs/deploy.bicep @@ -13,9 +13,6 @@ param addressPrefix string @description('Optional. Flag to control transit for VirtualRouter hub.') param allowBranchToBranchTraffic bool = true -@description('Optional. Resource ID of the Azure Firewall to link to.') -param azureFirewallId string = '' - @description('Optional. Resource ID of the Express Route Gateway to link to.') param expressRouteGatewayId string = '' @@ -100,9 +97,6 @@ resource virtualHub 'Microsoft.Network/virtualHubs@2022-05-01' = { properties: { addressPrefix: addressPrefix allowBranchToBranchTraffic: allowBranchToBranchTraffic - azureFirewall: !empty(azureFirewallId) ? { - id: azureFirewallId - } : null expressRouteGateway: !empty(expressRouteGatewayId) ? { id: expressRouteGatewayId } : null diff --git a/modules/Microsoft.Network/virtualHubs/readme.md b/modules/Microsoft.Network/virtualHubs/readme.md index a2edf921d7..3b0518d9d6 100644 --- a/modules/Microsoft.Network/virtualHubs/readme.md +++ b/modules/Microsoft.Network/virtualHubs/readme.md @@ -1,14 +1,18 @@ # Virtual Hubs `[Microsoft.Network/virtualHubs]` This module deploys a Virtual Hub. +If you are planning to deploy a Secure Virtual Hub (with an Azure Firewall integrated), please refer to the Azure Firewall module. ## Navigation -- [Resource Types](#Resource-Types) -- [Parameters](#Parameters) -- [Outputs](#Outputs) -- [Cross-referenced modules](#Cross-referenced-modules) -- [Deployment examples](#Deployment-examples) +- [Virtual Hubs `[Microsoft.Network/virtualHubs]`](#virtual-hubs-microsoftnetworkvirtualhubs) + - [Navigation](#navigation) + - [Resource Types](#resource-types) + - [Parameters](#parameters) + - [Parameter Usage: `tags`](#parameter-usage-tags) + - [Outputs](#outputs) + - [Cross-referenced modules](#cross-referenced-modules) + - [Deployment examples](#deployment-examples) ## Resource Types