diff --git a/.github/linters/.markdown-lint.yml b/.github/linters/.markdown-lint.yml index d71deb169..764e93077 100644 --- a/.github/linters/.markdown-lint.yml +++ b/.github/linters/.markdown-lint.yml @@ -22,7 +22,7 @@ MD004: false # Unordered list style MD007: indent: 2 # Unordered list indentation MD013: - line_length: 850 # Line length 80 is far to short + line_length: 900 # Line length 80 is far to short MD026: punctuation: ".,;:!。,;:" # List of not allowed MD029: false # Ordered list item prefix diff --git a/infra-as-code/bicep/modules/hubNetworking/README.md b/infra-as-code/bicep/modules/hubNetworking/README.md index 5957fa0bf..9942ec487 100644 --- a/infra-as-code/bicep/modules/hubNetworking/README.md +++ b/infra-as-code/bicep/modules/hubNetworking/README.md @@ -16,33 +16,36 @@ Module deploys the following resources: The module requires the following inputs: - | Parameter | Type | Default | Description | Requirement | Example | - | ------------------------------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | ---------------------------------------------- | - | parLocation | string | `resourceGroup().location` | The Azure Region to deploy the resources into | None | `eastus` | - | parBastionEnabled | bool | true | Switch to enable deployment of Bastion Service | None | true | - | parDdosEnabled | bool | true | Switch to enable deployment of distributed denial of service attacks service | None | true | - | parAzureFirewallEnabled | bool | true | Switch to enable deployment of Azure Firewall | None | true | - | parPrivateDnsZonesEnabled | bool | true | Switch to enable deployment of Azure Private DNS Zones | None | true | - | parPrivateDnsZonesResourceGroup | string | `resourceGroup().name` | Target Resource Group Name for Azure Private DNS Zones | 1-90 char | `Hub_PrivateDNS_POC` - Must already be present | - | parPrivateDnsZones | array | See example parameters file [`hubNetworking.parameters.json`](hubNetworking.parameters.example.json) | Array of DNS Zones to provision in Hub Virtual Network. Default: All known Azure Private DNS Zones except for: `privatelink.batch.azure.com`, `privatelink.azmk8s.io` and `privatelink.siterecovery.windowsazure.com` as these are region specific and `privatelink.{dnsPrefix}.database.windows.net` as the DNS Prefix is individual, which you can add to the parameters file with the required region and DNS Prefix in the zone name that you wish to deploy for. For more details on private DNS Zones please refer to the above link. | None | See Default | - | parCompanyPrefix | string | alz | Prefix value which will be pre-appended to all resource names | 1-10 char | alz | - | parDdosPlanName | string | ${parCompanyPrefix}-ddos-plan | Name which will be associated with distributed denial of service protection plan | 1-80 char | alz-ddos-plan | - | parBastionName | string | ${parCompanyPrefix}-bastion | Name which will be associated with Bastion Service. | 1-80 char | alz-bastion | - | parBastionSku | string | Standard | SKU or Tier of Bastion Service to deploy | Standard or Basic | Standard | - | parPublicIPSku | string | Standard | SKU or Tier of Public IP to deploy | Standard or Basic | Standard | - | parTags | object | Empty Array [] | List of tags (Key Value Pairs) to be applied to resources | None | environment: 'development' | - | parHubNetworkAddressPrefix | string | 10.10.0.0/16 | CIDR range for Hub Network | CIDR Notation | 10.10.0.0/16 | - | parHubNetworkName | string | `${parCompanyPrefix}-hub-${parLocation}` | Name prefix for Virtual Network. Prefix will be appended with the region. | 2-50 char | alz-hub-eastus | - | parAzureFirewallName | string | `${parCompanyPrefix}-azure-firewall` | Name associated with Azure Firewall | 1-80 char | alz-azure-firewall | - | parAzureFirewallTier | string | Standard | Tier associated with the Firewall to be deployed. | Standard or Premium | Premium | - | parHubRouteTableName | string | `${parCompanyPrefix}-hub-routetable` | Name of route table to be associated with Hub Network | 1-80 char | alz-hub-routetable | - | parVpnGatewayConfig | object | See example parameters file [`hubNetworking.parameters.json`](hubNetworking.parameters.example.json) | Configuration for VPN virtual network gateway to be deployed. If a VPN virtual network gateway is not desired an empty object should be used as the input parameter in the parameter file, i.e. "parVpnGatewayConfig": {"value": {} }''' | None | See Default | - | parExpressRouteGatewayConfig | object | See example parameters file [`hubNetworking.parameters.json`](hubNetworking.parameters.example.json) | Configuration for ExpressRoute virtual network gateway to be deployed. If a ExpressRoute virtual network gateway is not desired an empty object should be used as the input parameter in the parameter file, i.e. "parExpressRouteGatewayConfig": {"value": {} }''' | None | See Default | - | parSubnets | array | See example parameters file [`hubNetworking.parameters.json`](hubNetworking.parameters.example.json) | Array of objects to provide for a dynamic set of subnets | Must provide array of objects | See Default | - | parDNSServerIPArray | array | Empty Array [] | Array of DNS Server IP addresses for VNet. | None | `['10.10.1.4', '10.10.2.4']` | - | parNetworkDNSEnableProxy | bool | true | Switch which enables DNS Proxy to be enabled on the Azure Firewall | None | true | - | parDisableBGPRoutePropagation | bool | false | Switch which allows BGP Propagation to be disabled on the route tables | None | false | - | parTelemetryOptOut | bool | false | Set Parameter to true to Opt-out of deployment telemetry | None | false | + | Parameter | Type | Default | Description | Requirement | Example | + | --------------------------------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | ---------------------------------------------- | + | parLocation | string | `resourceGroup().location` | The Azure Region to deploy the resources into | None | `eastus` | + | parBastionEnabled | bool | true | Switch to enable deployment of Bastion Service | None | true | + | parDdosEnabled | bool | true | Switch to enable deployment of distributed denial of service attacks service | None | true | + | parAzureFirewallEnabled | bool | true | Switch to enable deployment of Azure Firewall | None | true | + | parPrivateDnsZonesEnabled | bool | true | Switch to enable deployment of Azure Private DNS Zones | None | true | + | parPrivateDnsZonesResourceGroup | string | `resourceGroup().name` | Target Resource Group Name for Azure Private DNS Zones | 1-90 char | `Hub_PrivateDNS_POC` - Must already be present | + | parPrivateDnsZones | array | See example parameters file [`hubNetworking.parameters.json`](hubNetworking.parameters.example.json) | Array of DNS Zones to provision in Hub Virtual Network. Default: All known Azure Private DNS Zones except for: `privatelink.batch.azure.com`, `privatelink.azmk8s.io` and `privatelink.siterecovery.windowsazure.com` as these are region specific and `privatelink.{dnsPrefix}.database.windows.net` as the DNS Prefix is individual, which you can add to the parameters file with the required region and DNS Prefix in the zone name that you wish to deploy for. For more details on private DNS Zones please refer to the above link. | None | See Default | + | parCompanyPrefix | string | alz | Prefix value which will be pre-appended to all resource names | 1-10 char | alz | + | parDdosPlanName | string | ${parCompanyPrefix}-ddos-plan | Name which will be associated with distributed denial of service protection plan | 1-80 char | alz-ddos-plan | + | parBastionName | string | ${parCompanyPrefix}-bastion | Name which will be associated with Bastion Service. | 1-80 char | alz-bastion | + | parBastionSku | string | Standard | SKU or Tier of Bastion Service to deploy | Standard or Basic | Standard | + | parPublicIPSku | string | Standard | SKU or Tier of Public IP to deploy | Standard or Basic | Standard | + | parTags | object | Empty Array [] | List of tags (Key Value Pairs) to be applied to resources | None | environment: 'development' | + | parHubNetworkAddressPrefix | string | 10.10.0.0/16 | CIDR range for Hub Network | CIDR Notation | 10.10.0.0/16 | + | parHubNetworkName | string | `${parCompanyPrefix}-hub-${parLocation}` | Name prefix for Virtual Network. Prefix will be appended with the region. | 2-50 char | alz-hub-eastus | + | parAzureFirewallName | string | `${parCompanyPrefix}-azfw-${parLocation}` | Name associated with Azure Firewall | 1-80 char | alz-azfw-eastus | + | parFirewallPoliciesName | string | `${parCompanyPrefix}-azfwpolicy-${resourceGroup().location}` | Name associated with Azure Firewall Policy | 1-80 char | alz-azfwpolicy-eastus | + | parAzureFirewallTier | string | Standard | Tier associated with the Firewall to be deployed. | Standard or Premium | Premium | + | parAzureFirewallAvailabilityZones | array | Empty Array [] | Availability Zones to deploy the Azure Firewall across. Region must support Availability Zones to use. If it does not then leave empty. | None | `['1']` or `['1' ,'2', '3']` | + | parHubRouteTableName | string | `${parCompanyPrefix}-hub-routetable` | Name of route table to be associated with Hub Network | 1-80 char | alz-hub-routetable | + | parVpnGatewayConfig | object | See example parameters file [`hubNetworking.parameters.json`](hubNetworking.parameters.example.json) | Configuration for VPN virtual network gateway to be deployed. If a VPN virtual network gateway is not desired an empty object should be used as the input parameter in the parameter file, i.e. "parVpnGatewayConfig": {"value": {} }''' | None | See Default | + | parExpressRouteGatewayConfig | object | See example parameters file [`hubNetworking.parameters.json`](hubNetworking.parameters.example.json) | Configuration for ExpressRoute virtual network gateway to be deployed. If a ExpressRoute virtual network gateway is not desired an empty object should be used as the input parameter in the parameter file, i.e. "parExpressRouteGatewayConfig": {"value": {} }''' | None | See Default | + | parSubnets | array | See example parameters file [`hubNetworking.parameters.json`](hubNetworking.parameters.example.json) | Array of objects to provide for a dynamic set of subnets | Must provide array of objects | See Default | + | parDNSServerIPArray | array | Empty Array [] | Array of DNS Server IP addresses for VNet. | None | `['10.10.1.4', '10.10.2.4']` | + | parNetworkDNSEnableProxy | bool | true | Switch which enables DNS Proxy to be enabled on the Azure Firewall | None | true | + | parDisableBGPRoutePropagation | bool | false | Switch which allows BGP Propagation to be disabled on the route tables | None | false | + | parTelemetryOptOut | bool | false | Set Parameter to true to Opt-out of deployment telemetry | None | false | + ## Outputs @@ -75,7 +78,7 @@ There are two different sets of input parameters; one for deploying to Azure glo ```bash # For Azure global regions # Set Platform connectivity subscription ID as the the current subscription -ConnectivitySubscriptionId="[your platform management subscription ID]" +ConnectivitySubscriptionId="[your platform connectivity subscription ID]" az account set --subscription $ConnectivitySubscriptionId az group create --location eastus \ @@ -90,7 +93,7 @@ OR ```bash # For Azure China regions # Set Platform connectivity subscription ID as the the current subscription -ConnectivitySubscriptionId="[your platform management subscription ID]" +ConnectivitySubscriptionId="[your platform connectivity subscription ID]" az account set --subscription $ConnectivitySubscriptionId az group create --location chinaeast2 \ @@ -107,7 +110,7 @@ az deployment group create \ ```powershell # For Azure global regions # Set Platform connectivity subscription ID as the the current subscription -$ConnectivitySubscriptionId = "[your platform management subscription ID]" +$ConnectivitySubscriptionId = "[your platform connectivity subscription ID]" Select-AzSubscription -SubscriptionId $ConnectivitySubscriptionId @@ -123,7 +126,7 @@ OR ```powershell # For Azure China regions # Set Platform connectivity subscription ID as the the current subscription -$ConnectivitySubscriptionId = "[your platform management subscription ID]" +$ConnectivitySubscriptionId = "[your platform connectivity subscription ID]" Select-AzSubscription -SubscriptionId $ConnectivitySubscriptionId @@ -135,12 +138,6 @@ New-AzResourceGroupDeployment ` -TemplateParameterFile infra-as-code/bicep/modules/hubNetworking/mc-hubNetworking.parameters.example.json ` -ResourceGroupName 'Hub_Networking_POC' ``` -## Example Output in Azure global regions - -![Example Deployment Output](media/hubNetworkExampleDeploymentOutput.png "Example Deployment Output in Azure global regions") - -## Example Output in Azure China regions -![Example Deployment Output](media/mc-hubNetworkExampleDeploymentOutput.png "Example Deployment Output in Azure China") ## Bicep Visualizer diff --git a/infra-as-code/bicep/modules/hubNetworking/hubNetworking.bicep b/infra-as-code/bicep/modules/hubNetworking/hubNetworking.bicep index cf1b407dd..f98245335 100644 --- a/infra-as-code/bicep/modules/hubNetworking/hubNetworking.bicep +++ b/infra-as-code/bicep/modules/hubNetworking/hubNetworking.bicep @@ -55,7 +55,10 @@ param parDdosPlanName string = '${parCompanyPrefix}-ddos-plan' param parAzureFirewallEnabled bool = true @description('Azure Firewall Name. Default: {parCompanyPrefix}-azure-firewall ') -param parAzureFirewallName string = '${parCompanyPrefix}-azure-firewall' +param parAzureFirewallName string = '${parCompanyPrefix}-azfw-${parLocation}' + +@description('Azure Firewall Policies Name. Default: {parCompanyPrefix}-fwpol-{parLocation}') +param parFirewallPoliciesName string = '${parCompanyPrefix}-azfwpolicy-${parLocation}' @description('Azure Firewall Tier associated with the Firewall to deploy. Default: Standard ') @allowed([ @@ -64,6 +67,14 @@ param parAzureFirewallName string = '${parCompanyPrefix}-azure-firewall' ]) param parAzureFirewallTier string = 'Standard' +@allowed([ + '1' + '2' + '3' +]) +@description('Availability Zones to deploy the Azure Firewall across. Region must support Availability Zones to use. If it does not then leave empty.') +param parAzureFirewallAvailabilityZones array = [] + @description('Switch which enables DNS Proxy to be enabled on the Azure Firewall. Default: true') param parNetworkDNSEnableProxy bool = true @@ -351,6 +362,7 @@ module modAzureFirewallPublicIP '../publicIp/publicIp.bicep' = if (parAzureFirew name: 'deploy-Firewall-Public-IP' params: { parLocation: parLocation + parAvailabilityZones: parAzureFirewallAvailabilityZones parPublicIPName: '${parAzureFirewallName}-PublicIP' parPublicIPProperties: { publicIPAddressVersion: 'IPv4' @@ -364,43 +376,28 @@ module modAzureFirewallPublicIP '../publicIp/publicIp.bicep' = if (parAzureFirew } } +resource resFirewallPolicies 'Microsoft.Network/firewallPolicies@2021-05-01' = if (parAzureFirewallEnabled) { + name: parFirewallPoliciesName + location: parLocation + tags: parTags + properties: { + dnsSettings: { + enableProxy: parNetworkDNSEnableProxy + } + sku: { + tier: parAzureFirewallTier + } + } +} + // AzureFirewallSubnet is required to deploy Azure Firewall . This subnet must exist in the parsubnets array if you deploy. // There is a minimum subnet requirement of /26 prefix. -resource resAzureFirewall 'Microsoft.Network/azureFirewalls@2021-02-01' = if (parAzureFirewallEnabled) { +resource resAzureFirewall 'Microsoft.Network/azureFirewalls@2021-05-01' = if (parAzureFirewallEnabled) { name: parAzureFirewallName location: parLocation tags: parTags + zones: (!empty(parAzureFirewallAvailabilityZones) ? parAzureFirewallAvailabilityZones : json('null')) properties: { - networkRuleCollections: [ - { - name: 'VmInternetAccess' - properties: { - priority: 101 - action: { - type: 'Allow' - } - rules: [ - { - name: 'AllowVMAppAccess' - description: 'Allows VM access to the web' - protocols: [ - 'TCP' - ] - sourceAddresses: [ - parHubNetworkAddressPrefix - ] - destinationAddresses: [ - '*' - ] - destinationPorts: [ - '80' - '443' - ] - } - ] - } - } - ] ipConfigurations: [ { name: 'ipconfig1' @@ -414,13 +411,12 @@ resource resAzureFirewall 'Microsoft.Network/azureFirewalls@2021-02-01' = if (pa } } ] - threatIntelMode: 'Alert' sku: { name: 'AZFW_VNet' tier: parAzureFirewallTier } - additionalProperties: { - 'Network.DNS.EnableProxy': '${parNetworkDNSEnableProxy}' + firewallPolicy: { + id: resFirewallPolicies.id } } } @@ -451,7 +447,7 @@ module modPrivateDnsZones '../privateDnsZones/privateDnsZones.bicep' = if (parPr params: { parLocation: parLocation parTags: parTags - parHubVirtualNetworkId: resHubVirtualNetwork.id + parVirtualNetworkIdToLink: resHubVirtualNetwork.id parPrivateDnsZones: parPrivateDnsZones } } diff --git a/infra-as-code/bicep/modules/hubNetworking/hubNetworking.parameters.example.json b/infra-as-code/bicep/modules/hubNetworking/hubNetworking.parameters.example.json index 8057f73bb..7cb1a6314 100644 --- a/infra-as-code/bicep/modules/hubNetworking/hubNetworking.parameters.example.json +++ b/infra-as-code/bicep/modules/hubNetworking/hubNetworking.parameters.example.json @@ -55,11 +55,14 @@ "value": true }, "parAzureFirewallName": { - "value": "alz-azure-firewall" + "value": "alz-azfw-eastus" }, "parAzureFirewallTier": { "value": "Standard" }, + "parAzureFirewallAvailabilityZones": { + "value": [] + }, "parNetworkDNSEnableProxy": { "value": true }, diff --git a/infra-as-code/bicep/modules/hubNetworking/mc-hubNetworking.parameters.example.json b/infra-as-code/bicep/modules/hubNetworking/mc-hubNetworking.parameters.example.json index 2089f00cd..1b46df4f5 100644 --- a/infra-as-code/bicep/modules/hubNetworking/mc-hubNetworking.parameters.example.json +++ b/infra-as-code/bicep/modules/hubNetworking/mc-hubNetworking.parameters.example.json @@ -55,11 +55,14 @@ "value": true }, "parAzureFirewallName": { - "value": "alz-azure-firewall" + "value": "alz-azfw-chinaeast2" }, "parAzureFirewallTier": { "value": "Standard" }, + "parAzureFirewallAvailabilityZones": { + "value": [] + }, "parNetworkDNSEnableProxy": { "value": true }, diff --git a/infra-as-code/bicep/modules/hubNetworking/media/hubNetworkingBicepVisualizer.png b/infra-as-code/bicep/modules/hubNetworking/media/hubNetworkingBicepVisualizer.png index a42317614..e41ce74db 100644 Binary files a/infra-as-code/bicep/modules/hubNetworking/media/hubNetworkingBicepVisualizer.png and b/infra-as-code/bicep/modules/hubNetworking/media/hubNetworkingBicepVisualizer.png differ diff --git a/infra-as-code/bicep/modules/privateDnsZones/README.md b/infra-as-code/bicep/modules/privateDnsZones/README.md index 52faaf912..66eb0949f 100644 --- a/infra-as-code/bicep/modules/privateDnsZones/README.md +++ b/infra-as-code/bicep/modules/privateDnsZones/README.md @@ -11,13 +11,13 @@ Module deploys the following resources: The module requires the following inputs: - | Parameter | Type | Default | Description | Requirement | Example | - | ---------------------- | ------ | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | - | parLocation | string | `resourceGroup().location` | The Azure Region to deploy the resources into | None | `eastus` | - | parPrivateDnsZones | array | See example parameters file [`privateDnsZones.parameters.example.json`](privateDnsZones.parameters.example.json) | Array of DNS Zones to provision in Hub Virtual Network. Default: All known Azure Private DNS Zones - See [DNS Zones](#dns-zones) for more info | None | See Default | - | parTags | object | Empty Array [] | List of tags (Key Value Pairs) to be applied to resources | None | environment: 'development' | - | parHubVirtualNetworkId | string | | Resource ID of the Hub Virtual Network | Valid Resource ID of the Virtual Network | /subscriptions/[your platform management subscription ID]/resourceGroups/Hub_PrivateDNS_POC/providers/Microsoft.Network/virtualNetworks/alz-hub-eastus | - | parTelemetryOptOut | bool | false | Set Parameter to true to Opt-out of deployment telemetry | None | false | + | Parameter | Type | Default | Description | Requirement | Example | + | ------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | + | parLocation | string | `resourceGroup().location` | The Azure Region to deploy the resources into | None | `eastus` | + | parPrivateDnsZones | array | See example parameters file [`privateDnsZones.parameters.example.json`](privateDnsZones.parameters.example.json) | Array of DNS Zones to provision in Hub Virtual Network. Default: All known Azure Private DNS Zones - See [DNS Zones](#dns-zones) for more info | None | See Default | + | parTags | object | Empty Array [] | List of tags (Key Value Pairs) to be applied to resources | None | environment: 'development' | + | parVirtualNetworkIdToLink | string | Empty String | Resource ID of VNet for Private DNS Zone VNet Links | Valid Resource ID of the Virtual Network | /subscriptions/[your platform connectivity subscription ID]/resourceGroups/Hub_PrivateDNS_POC/providers/Microsoft.Network/virtualNetworks/alz-hub-eastus | + | parTelemetryOptOut | bool | false | Set Parameter to true to Opt-out of deployment telemetry | None | false | ## DNS Zones @@ -70,7 +70,7 @@ There are two different sets of input parameters; one for deploying to Azure glo ```bash # For Azure global regions # Set Platform connectivity subscription ID as the the current subscription -ConnectivitySubscriptionId="[your platform management subscription ID]" +ConnectivitySubscriptionId="[your platform connectivity subscription ID]" az account set --subscription $ConnectivitySubscriptionId az group create --location eastus \ @@ -85,7 +85,7 @@ OR ```bash # For Azure China regions # Set Platform connectivity subscription ID as the the current subscription -ConnectivitySubscriptionId="[your platform management subscription ID]" +ConnectivitySubscriptionId="[your platform connectivity subscription ID]" az account set --subscription $ConnectivitySubscriptionId az group create --location chinaeast2 \ @@ -102,7 +102,7 @@ az deployment group create \ ```powershell # For Azure global regions # Set Platform connectivity subscription ID as the the current subscription -$ConnectivitySubscriptionId = "[your platform management subscription ID]" +$ConnectivitySubscriptionId = "[your platform connectivity subscription ID]" Select-AzSubscription -SubscriptionId $ConnectivitySubscriptionId @@ -118,7 +118,7 @@ OR ```powershell # For Azure China regions # Set Platform connectivity subscription ID as the the current subscription -$ConnectivitySubscriptionId = "[your platform management subscription ID]" +$ConnectivitySubscriptionId = "[your platform connectivity subscription ID]" Select-AzSubscription -SubscriptionId $ConnectivitySubscriptionId diff --git a/infra-as-code/bicep/modules/privateDnsZones/mc-privateDnsZones.parameters.example.json b/infra-as-code/bicep/modules/privateDnsZones/mc-privateDnsZones.parameters.example.json index b72428cf2..dfbe83ef3 100644 --- a/infra-as-code/bicep/modules/privateDnsZones/mc-privateDnsZones.parameters.example.json +++ b/infra-as-code/bicep/modules/privateDnsZones/mc-privateDnsZones.parameters.example.json @@ -43,6 +43,9 @@ "Environment": "POC" } }, + "parVirtualNetworkIdToLink": { + "value": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxxxxxxxxx/providers/Microsoft.Network/virtualNetworks/xxxxxxxxxxx" + }, "parTelemetryOptOut": { "value": false } diff --git a/infra-as-code/bicep/modules/privateDnsZones/privateDnsZones.bicep b/infra-as-code/bicep/modules/privateDnsZones/privateDnsZones.bicep index fb5d4409c..94f69f039 100644 --- a/infra-as-code/bicep/modules/privateDnsZones/privateDnsZones.bicep +++ b/infra-as-code/bicep/modules/privateDnsZones/privateDnsZones.bicep @@ -60,8 +60,8 @@ param parPrivateDnsZones array = [ @description('Tags you would like to be applied to all resources in this module. Default: empty array') param parTags object = {} -@description('Resource ID of Hub VNet for Private DNS Zone VNet Links') -param parHubVirtualNetworkId string +@description('Resource ID of VNet for Private DNS Zone VNet Links') +param parVirtualNetworkIdToLink string = '' @description('Set Parameter to true to Opt-out of deployment telemetry') param parTelemetryOptOut bool = false @@ -75,13 +75,13 @@ resource resPrivateDnsZones 'Microsoft.Network/privateDnsZones@2020-06-01' = [fo tags: parTags }] -resource resVirtualNetworkLink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = [for privateDnsZoneName in parPrivateDnsZones: { +resource resVirtualNetworkLink 'Microsoft.Network/privateDnsZones/virtualNetworkLinks@2020-06-01' = [for privateDnsZoneName in parPrivateDnsZones: if (!empty(parVirtualNetworkIdToLink)) { name: '${privateDnsZoneName}/${privateDnsZoneName}' location: 'global' properties: { registrationEnabled: false virtualNetwork: { - id: parHubVirtualNetworkId + id: parVirtualNetworkIdToLink } } dependsOn: resPrivateDnsZones diff --git a/infra-as-code/bicep/modules/privateDnsZones/privateDnsZones.parameters.example.json b/infra-as-code/bicep/modules/privateDnsZones/privateDnsZones.parameters.example.json index 89d6adbc1..8d3da1691 100644 --- a/infra-as-code/bicep/modules/privateDnsZones/privateDnsZones.parameters.example.json +++ b/infra-as-code/bicep/modules/privateDnsZones/privateDnsZones.parameters.example.json @@ -1,70 +1,73 @@ { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "parLocation": { - "value": "eastus" - }, - "parPrivateDnsZones": { - "value": [ - "privatelink.azure-automation.net", - "privatelink.database.windows.net", - "privatelink.sql.azuresynapse.net", - "privatelink.dev.azuresynapse.net", - "privatelink.azuresynapse.net", - "privatelink.blob.core.windows.net", - "privatelink.table.core.windows.net", - "privatelink.queue.core.windows.net", - "privatelink.file.core.windows.net", - "privatelink.web.core.windows.net", - "privatelink.dfs.core.windows.net", - "privatelink.documents.azure.com", - "privatelink.mongo.cosmos.azure.com", - "privatelink.cassandra.cosmos.azure.com", - "privatelink.gremlin.cosmos.azure.com", - "privatelink.table.cosmos.azure.com", - "privatelink.postgres.database.azure.com", - "privatelink.mysql.database.azure.com", - "privatelink.mariadb.database.azure.com", - "privatelink.vaultcore.azure.net", - "privatelink.managedhsm.azure.net", - "privatelink.siterecovery.windowsazure.com", - "privatelink.servicebus.windows.net", - "privatelink.azure-devices.net", - "privatelink.eventgrid.azure.net", - "privatelink.azurewebsites.net", - "privatelink.api.azureml.ms", - "privatelink.notebooks.azure.net", - "privatelink.service.signalr.net", - "privatelink.monitor.azure.com", - "privatelink.oms.opinsights.azure.com", - "privatelink.ods.opinsights.azure.com", - "privatelink.agentsvc.azure-automation.net", - "privatelink.afs.azure.net", - "privatelink.datafactory.azure.net", - "privatelink.adf.azure.com", - "privatelink.redis.cache.windows.net", - "privatelink.redisenterprise.cache.azure.net", - "privatelink.purview.azure.com", - "privatelink.purviewstudio.azure.com", - "privatelink.digitaltwins.azure.net", - "privatelink.azconfig.io", - "privatelink.cognitiveservices.azure.com", - "privatelink.azurecr.io", - "privatelink.search.windows.net", - "privatelink.azurehdinsight.net", - "privatelink.media.azure.net", - "privatelink.his.arc.azure.com", - "privatelink.guestconfiguration.azure.com" - ] - }, - "parTags": { - "value": { - "Environment": "POC" - } - }, - "parTelemetryOptOut": { - "value": false + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "parLocation": { + "value": "eastus" + }, + "parPrivateDnsZones": { + "value": [ + "privatelink.azure-automation.net", + "privatelink.database.windows.net", + "privatelink.sql.azuresynapse.net", + "privatelink.dev.azuresynapse.net", + "privatelink.azuresynapse.net", + "privatelink.blob.core.windows.net", + "privatelink.table.core.windows.net", + "privatelink.queue.core.windows.net", + "privatelink.file.core.windows.net", + "privatelink.web.core.windows.net", + "privatelink.dfs.core.windows.net", + "privatelink.documents.azure.com", + "privatelink.mongo.cosmos.azure.com", + "privatelink.cassandra.cosmos.azure.com", + "privatelink.gremlin.cosmos.azure.com", + "privatelink.table.cosmos.azure.com", + "privatelink.postgres.database.azure.com", + "privatelink.mysql.database.azure.com", + "privatelink.mariadb.database.azure.com", + "privatelink.vaultcore.azure.net", + "privatelink.managedhsm.azure.net", + "privatelink.siterecovery.windowsazure.com", + "privatelink.servicebus.windows.net", + "privatelink.azure-devices.net", + "privatelink.eventgrid.azure.net", + "privatelink.azurewebsites.net", + "privatelink.api.azureml.ms", + "privatelink.notebooks.azure.net", + "privatelink.service.signalr.net", + "privatelink.monitor.azure.com", + "privatelink.oms.opinsights.azure.com", + "privatelink.ods.opinsights.azure.com", + "privatelink.agentsvc.azure-automation.net", + "privatelink.afs.azure.net", + "privatelink.datafactory.azure.net", + "privatelink.adf.azure.com", + "privatelink.redis.cache.windows.net", + "privatelink.redisenterprise.cache.azure.net", + "privatelink.purview.azure.com", + "privatelink.purviewstudio.azure.com", + "privatelink.digitaltwins.azure.net", + "privatelink.azconfig.io", + "privatelink.cognitiveservices.azure.com", + "privatelink.azurecr.io", + "privatelink.search.windows.net", + "privatelink.azurehdinsight.net", + "privatelink.media.azure.net", + "privatelink.his.arc.azure.com", + "privatelink.guestconfiguration.azure.com" + ] + }, + "parTags": { + "value": { + "Environment": "POC" } + }, + "parVirtualNetworkIdToLink": { + "value": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxxxxxxxxx/providers/Microsoft.Network/virtualNetworks/xxxxxxxxxxx" + }, + "parTelemetryOptOut": { + "value": false } - } \ No newline at end of file + } +} \ No newline at end of file diff --git a/infra-as-code/bicep/modules/publicIp/README.md b/infra-as-code/bicep/modules/publicIp/README.md index 705142d00..529ad2309 100644 --- a/infra-as-code/bicep/modules/publicIp/README.md +++ b/infra-as-code/bicep/modules/publicIp/README.md @@ -10,14 +10,15 @@ Module deploys the following resources: The module requires the following inputs: - | Parameter | Type | Default | Description | Requirement | Example | - | --------------------- | ------ | ------------------------ | -------------------------------------------------------- | ------------------ | ------------------------------- | - | parPublicIPName | string | none | Name associated with the Public IP to be created | 1-80 char | alz-bastion-PublicIP | - | parPublicIPSku | object | none | SKU of IP to deploy to Azure | Standard or Basic | Standard | - | parPublicIPProperties | object | none | N/A | - | parLocation | string | resourceGroup().location | Location where Public IP address will be deployed | Valid Azure Region | `eastus2` | - | parTags | object | none | Tags to be appended to resource after it is created | none | {"Environment" : "Development"} | - | parTelemetryOptOut | bool | `false` | Set Parameter to true to Opt-out of deployment telemetry | none | `false` | + | Parameter | Type | Default | Description | Requirement | Example | + | --------------------- | ------ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ------------------------------------ | + | parPublicIPName | string | none | Name associated with the Public IP to be created | 1-80 char | alz-bastion-PublicIP | + | parPublicIPSku | object | none | SKU of IP to deploy to Azure | Standard or Basic | Standard | + | parPublicIPProperties | object | none | N/A | + | parLocation | string | resourceGroup().location | Location where Public IP address will be deployed | Valid Azure Region | `eastus2` | + | parAvailabilityZones | array | Empty Array `[]` | Availability Zones to deploy the Public IP across. Region must support Availability Zones to use. If it does not then leave empty. | none | `[]` or `['1']` or `['1' ,'2', '3']` | + | parTags | object | none | Tags to be appended to resource after it is created | none | {"Environment" : "Development"} | + | parTelemetryOptOut | bool | `false` | Set Parameter to true to Opt-out of deployment telemetry | none | `false` | ## Outputs diff --git a/infra-as-code/bicep/modules/publicIp/publicIp.bicep b/infra-as-code/bicep/modules/publicIp/publicIp.bicep index 401cd75f5..7eb81ef28 100644 --- a/infra-as-code/bicep/modules/publicIp/publicIp.bicep +++ b/infra-as-code/bicep/modules/publicIp/publicIp.bicep @@ -10,6 +10,14 @@ param parPublicIPProperties object @description('Azure Region to deploy Public IP Address to. Default: Current Resource Group') param parLocation string = resourceGroup().location +@allowed([ + '1' + '2' + '3' +]) +@description('Availability Zones to deploy the Public IP across. Region must support Availability Zones to use. If it does not then leave empty.') +param parAvailabilityZones array = [] + @description('Tags to be applied to resource when deployed. Default: None') param parTags object @@ -19,10 +27,11 @@ param parTelemetryOptOut bool = false // Customer Usage Attribution Id var varCuaid = '3f85b84c-6bad-4c42-86bf-11c233241c22' -resource resPublicIP 'Microsoft.Network/publicIPAddresses@2021-02-01' ={ +resource resPublicIP 'Microsoft.Network/publicIPAddresses@2021-05-01' ={ name: parPublicIPName tags: parTags location: parLocation + zones: parAvailabilityZones sku: parPublicIPSku properties: parPublicIPProperties } diff --git a/infra-as-code/bicep/modules/vwanConnectivity/README.md b/infra-as-code/bicep/modules/vwanConnectivity/README.md index 2f4d95030..4083bb957 100644 --- a/infra-as-code/bicep/modules/vwanConnectivity/README.md +++ b/infra-as-code/bicep/modules/vwanConnectivity/README.md @@ -8,54 +8,64 @@ Module deploys the following resources which can be configured by parameters: - Virtual Hub. The virtual hub is a prerequisite to connect to either a VPN Gateway, an ExpressRoute Gateway or an Azure Firewall to the virtual WAN - VPN Gateway - ExpressRoute Gateway -- Public IP is deployed only if Azure Firewall is enabled - Azure Firewall - Azure Firewall policy +- DDoS Standard Plan +- Private DNS Zones - Details of all the Azure Private DNS zones can be found here --> [https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-dns#azure-services-dns-zone-configuration](https://docs.microsoft.com/en-us/azure/private-link/private-endpoint-dns#azure-services-dns-zone-configuration) ## Parameters The module requires the following inputs: - | Parameter | Type | Default | Description | Requirement | Example | - | ---------------------------- | ------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | ---------------------------- | - | parVirtualHubEnabled | bool | true | Switch to enable deployment of Virtual Hub | None | true | - | parVPNGatewayEnabled | bool | true | Switch to enable deployment of VPN Gateway service | Virtual Hub | true | - | parERGatewayEnabled | bool | true | Switch to enable deployment of ExpressRoute Gateway | Virtual Hub | true | - | parAzureFirewallEnabled | bool | true | Switch to enable deployment of Azure Firewall | Virtual Hub | true | - | parNetworkDNSEnableProxy | bool | true | Switch to enable DNS proxy for Azure Firewall policies | Azure Firewall | true | - | parCompanyPrefix | string | alz | Prefix value which will be pre-appended to all resource names | 1-10 char | alz | - | parPublicIPSku | string | Standard | SKU or Tier of Public IP to deploy | Standard or Basic | Standard | - | parTags | object | Empty Array [] | List of tags (Key Value Pairs) to be applied to resources | None | environment: 'POC' | - | parVhubAddressPrefix | string | 10.100.0.0/23 | CIDR range for the Virtual WAN's Virtual Hub Network | CIDR Notation | 10.100.0.0/23 | - | parAzureFirewallTier | string | Standard | Tier associated with the Firewall to be deployed. | Standard or Premium | Standard | - | parVWanName | string | ${parCompanyPrefix}-vwan-${resourceGroup().location} | Name prefix for Virtual WAN. Prefix will be appended with the region. | 2-50 char | alz-vwan-eastus | - | parVHubName | string | ${parCompanyPrefix}-vhub-${resourceGroup().location} | Name prefix for Virtual Hub. Prefix will be appended with the region. | 2-50 char | alz-vhub-eastus | - | parVPNGwName | string | ${parCompanyPrefix}-vpngw-${resourceGroup().location} | Name prefix for VPN Gateway. Prefix will be appended with the region. | 2-50 char | alz-vpngw-eastus | - | parERGwName | string | ${parCompanyPrefix}-ergw-${resourceGroup().location} | Name prefix for ExpressRoute Gateway. Prefix will be appended with the region. | 2-50 char | alz-ergw-eastus | - | parAzureFirewallName | string | ${parCompanyPrefix}-fw-${resourceGroup().location} | Name associated with Azure Firewall | 1-80 char | alz-fw-eastus | - | parFirewallPoliciesName | string | ${parCompanyPrefix}-azfwpolicy-${resourceGroup().location} | Name associated with Azure Firewall | 1-80 char | alz-azfwpolicy-eastus | - | parLocation | string | `resourceGroup().location` | The Azure Region to deploy the resources into | None | `eastus` | - | parVPNGwScaleUnit | int | 1 | The scale unit for the VPN Gateway | None | 1 | - | parERGwScaleUnit | int | 1 | The scale unit for the ExpressRoute Gateway | None | 1 | - | parTelemetryOptOut | bool | false | Set Parameter to true to Opt-out of deployment telemetry | None | false | + | Parameter | Type | Default | Description | Requirement | Example | + | --------------------------------- | ------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | + | parVirtualHubEnabled | bool | true | Switch to enable deployment of Virtual Hub | None | true | + | parVPNGatewayEnabled | bool | true | Switch to enable deployment of VPN Gateway service | Virtual Hub | true | + | parERGatewayEnabled | bool | true | Switch to enable deployment of ExpressRoute Gateway | Virtual Hub | true | + | parAzureFirewallEnabled | bool | true | Switch to enable deployment of Azure Firewall | Virtual Hub | true | + | parNetworkDNSEnableProxy | bool | true | Switch to enable DNS proxy for Azure Firewall policies | Azure Firewall | true | + | parDdosEnabled | bool | true | Switch to enable deployment of distributed denial of service attacks service | None | true | + | parPrivateDnsZonesEnabled | bool | true | Switch to enable deployment of Azure Private DNS Zones | None | true | + | parPrivateDnsZonesResourceGroup | string | `resourceGroup().name` | Target Resource Group Name for Azure Private DNS Zones | 1-90 char | `Hub_PrivateDNS_POC` - Must already be present | + | parPrivateDnsZones | array | See example parameters file [`vwanConnectivity.parameters.example.json`](vwanConnectivity.parameters.example.json) | Array of DNS Zones to provision in Hub Virtual Network. Default: All known Azure Private DNS Zones except for: `privatelink.batch.azure.com`, `privatelink.azmk8s.io` and `privatelink.siterecovery.windowsazure.com` as these are region specific and `privatelink.{dnsPrefix}.database.windows.net` as the DNS Prefix is individual, which you can add to the parameters file with the required region and DNS Prefix in the zone name that you wish to deploy for. For more details on private DNS Zones please refer to the above link. | None | See Default | + | parVirtualNetworkIdToLink | string | Empty String `''` | Resource ID of VNet for Private DNS Zone VNet Links | None or Valid Resource ID of the Virtual Network | `/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/xxxxxxxxxxx/providers/Microsoft.Network/virtualNetworks/xxxxxxxxxxx` | + | parCompanyPrefix | string | alz | Prefix value which will be pre-appended to all resource names | 1-10 char | alz | + | parTags | object | Empty Array [] | List of tags (Key Value Pairs) to be applied to resources | None | environment: 'POC' | + | parVhubAddressPrefix | string | 10.100.0.0/23 | CIDR range for the Virtual WAN's Virtual Hub Network | CIDR Notation | 10.100.0.0/23 | + | parAzureFirewallTier | string | Standard | Tier associated with the Firewall to be deployed. | Standard or Premium | Standard | + | parVWanName | string | ${parCompanyPrefix}-vwan-${resourceGroup().location} | Name prefix for Virtual WAN. Prefix will be appended with the region. | 2-50 char | alz-vwan-eastus | + | parVHubName | string | ${parCompanyPrefix}-vhub-${resourceGroup().location} | Name prefix for Virtual Hub. Prefix will be appended with the region. | 2-50 char | alz-vhub-eastus | + | parVPNGwName | string | ${parCompanyPrefix}-vpngw-${resourceGroup().location} | Name prefix for VPN Gateway. Prefix will be appended with the region. | 2-50 char | alz-vpngw-eastus | + | parERGwName | string | ${parCompanyPrefix}-ergw-${resourceGroup().location} | Name prefix for ExpressRoute Gateway. Prefix will be appended with the region. | 2-50 char | alz-ergw-eastus | + | parAzureFirewallName | string | ${parCompanyPrefix}-fw-${resourceGroup().location} | Name associated with Azure Firewall | 1-80 char | alz-fw-eastus | + | parFirewallPoliciesName | string | ${parCompanyPrefix}-azfwpolicy-${resourceGroup().location} | Name associated with Azure Firewall Policy | 1-80 char | alz-azfwpolicy-eastus | + | parAzureFirewallAvailabilityZones | array | Empty Array [] | Availability Zones to deploy the Azure Firewall across. Region must support Availability Zones to use. If it does not then leave empty. | None | `['1']` or `['1' ,'2', '3']` | + | parDdosPlanName | string | ${parCompanyPrefix}-ddos-plan | Name which will be associated with distributed denial of service protection plan | 1-80 char | alz-ddos-plan | + | parLocation | string | `resourceGroup().location` | The Azure Region to deploy the resources into | None | `eastus` | + | parVPNGwScaleUnit | int | 1 | The scale unit for the VPN Gateway | None | 1 | + | parERGwScaleUnit | int | 1 | The scale unit for the ExpressRoute Gateway | None | 1 | + | parTelemetryOptOut | bool | false | Set Parameter to true to Opt-out of deployment telemetry | None | false | ## Outputs The module will generate the following outputs: -| Output | Type | Example | -| ------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| outVirtualWANName | string | alz-vwan-eastus | -| outVirtualWANID | string | /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/alz-vwan-eastus/providers/Microsoft.Network/virtualWans/alz-vwan-eastus | -| outVirtualHubName | string | alz-vhub-eastus | -| outVirtualHubID | string | /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/alz-vwan-eastus/providers/Microsoft.Network/virtualHubs/alz-vhub-eastus | +| Output | Type | Example | +| --------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| outVirtualWANName | string | alz-vwan-eastus | +| outVirtualWANID | string | /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/alz-vwan-eastus/providers/Microsoft.Network/virtualWans/alz-vwan-eastus | +| outVirtualHubName | string | alz-vhub-eastus | +| outVirtualHubID | string | /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/alz-vwan-eastus/providers/Microsoft.Network/virtualHubs/alz-vhub-eastus | +| outDdosPlanResourceId | string | /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/alz-vwan-eastus/providers/Microsoft.Network/ddosProtectionPlans/alz-ddos-plan | +| outPrivateDnsZones | array | `["name": "privatelink.azurecr.io", "id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/net-lz-spk-eastus-rg/providers/Microsoft.Network/privateDnsZones/privatelink.azurecr.io"]` | ## Deployment In this example, the resources required for Virtual WAN connectivity will be deployed to the resource group specified. According to the Azure Landing Zone Conceptual Architecture, the Virtual WAN resources should be deployed into the Platform connectivity subscription. During the deployment step, we will take parameters provided in the example parameters file. - | Azure Cloud | Bicep template | Input parameters file | - | -------------- | ------------------- | ---------------------------------------- | - | All regions | vwanConnectivity.bicep | vwanConnectivity.bicep.parameters.example.json | + | Azure Cloud | Bicep template | Input parameters file | + | -------------- | ---------------------- | ------------------------------------------------- | + | Global regions | vwanConnectivity.bicep | vwanConnectivity.bicep.parameters.example.json | + | China regions | vwanConnectivity.bicep | mc-vwanConnectivity.bicep.parameters.example.json | > For the examples below we assume you have downloaded or cloned the Git repo as-is and are in the root of the repository as your selected directory in your terminal of choice. @@ -63,7 +73,7 @@ In this example, the resources required for Virtual WAN connectivity will be dep ```bash # For Azure global regions # Set Platform connectivity subscription ID as the the current subscription -ConnectivitySubscriptionId="[your platform management subscription ID]" +ConnectivitySubscriptionId="[your platform connectivity subscription ID]" az account set --subscription $ConnectivitySubscriptionId az group create --location eastus \ @@ -78,7 +88,7 @@ OR ```bash # For Azure China regions # Set Platform connectivity subscription ID as the the current subscription -ConnectivitySubscriptionId="[your platform management subscription ID]" +ConnectivitySubscriptionId="[your platform connectivity subscription ID]" az account set --subscription $ConnectivitySubscriptionId az group create --location chinaeast2 \ @@ -87,7 +97,7 @@ az group create --location chinaeast2 \ az deployment group create \ --resource-group alz-vwan-chinaeast2 \ --template-file infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.bicep \ - --parameters @infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.parameters.example.json + --parameters @infra-as-code/bicep/modules/vwanConnectivity/mc-vwanConnectivity.parameters.example.json ``` ### PowerShell @@ -95,7 +105,7 @@ az deployment group create \ ```powershell # For Azure global regions # Set Platform connectivity subscription ID as the the current subscription -$ConnectivitySubscriptionId = "[your platform management subscription ID]" +$ConnectivitySubscriptionId = "[your platform connectivity subscription ID]" Select-AzSubscription -SubscriptionId $ConnectivitySubscriptionId @@ -111,7 +121,7 @@ OR ```powershell # For Azure China regions # Set Platform connectivity subscription ID as the the current subscription -$ConnectivitySubscriptionId = "[your platform management subscription ID]" +$ConnectivitySubscriptionId = "[your platform connectivity subscription ID]" Select-AzSubscription -SubscriptionId $ConnectivitySubscriptionId @@ -120,7 +130,7 @@ New-AzResourceGroup -Name 'alz-vwan-chinaeast2' ` New-AzResourceGroupDeployment ` -TemplateFile infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.bicep ` - -TemplateParameterFile infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.parameters.example.json ` + -TemplateParameterFile infra-as-code/bicep/modules/vwanConnectivity/mc-vwanConnectivity.parameters.example.json ` -ResourceGroupName 'alz-vwan-chinaeast2' ``` ## Example Output in Azure global regions diff --git a/infra-as-code/bicep/modules/vwanConnectivity/bicepconfig.json b/infra-as-code/bicep/modules/vwanConnectivity/bicepconfig.json index 2c0ef2c34..a33498c39 100644 --- a/infra-as-code/bicep/modules/vwanConnectivity/bicepconfig.json +++ b/infra-as-code/bicep/modules/vwanConnectivity/bicepconfig.json @@ -8,7 +8,33 @@ "level": "error" }, "no-hardcoded-env-urls": { - "level": "error" + "level": "error", + "disallowedhosts": [ + "management.core.windows.net", + "gallery.azure.com", + "management.core.windows.net", + "management.azure.com", + "login.microsoftonline.com", + "graph.windows.net", + "trafficmanager.net", + "vault.azure.net", + "datalake.azure.net", + "azuredatalakestore.net", + "azuredatalakeanalytics.net", + "vault.azure.net", + "api.loganalytics.io", + "api.loganalytics.iov1", + "asazure.windows.net", + "region.asazure.windows.net", + "api.loganalytics.iov1", + "api.loganalytics.io", + "asazure.windows.net", + "region.asazure.windows.net", + "batch.core.windows.net" + ], + "excludedhosts": [ + "schema.management.azure.com" + ] }, "no-unnecessary-dependson": { "level": "error" diff --git a/infra-as-code/bicep/modules/vwanConnectivity/mc-vwanConnectivity.parameters.example.json b/infra-as-code/bicep/modules/vwanConnectivity/mc-vwanConnectivity.parameters.example.json new file mode 100644 index 000000000..29ae9e78c --- /dev/null +++ b/infra-as-code/bicep/modules/vwanConnectivity/mc-vwanConnectivity.parameters.example.json @@ -0,0 +1,81 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "parVirtualHubEnabled": { + "value": true + }, + "parVPNGatewayEnabled": { + "value": true + }, + "parERGatewayEnabled": { + "value": true + }, + "parAzureFirewallEnabled": { + "value": true + }, + "parNetworkDNSEnableProxy": { + "value": true + }, + "parDdosEnabled": { + "value": false + }, + "parDdosPlanName": { + "value": "alz-ddos-plan" + }, + "parCompanyPrefix": { + "value": "alz" + }, + "parPublicIPSku": { + "value": "Standard" + }, + "parVhubAddressPrefix": { + "value": "10.100.0.0/23" + }, + "parAzureFirewallTier": { + "value": "Standard" + }, + "parAzureFirewallAvailabilityZones": { + "value": [] + }, + "parPrivateDnsZonesEnabled": { + "value": true + }, + "parPrivateDnsZones": { + "value": [ + "privatelink.azure-automation.cn", + "privatelink.database.chinacloudapi.cn", + "privatelink.blob.core.chinacloudapi.cn", + "privatelink.table.core.chinacloudapi.cn", + "privatelink.queue.core.chinacloudapi.cn", + "privatelink.file.core.chinacloudapi.cn", + "privatelink.web.core.chinacloudapi.cn", + "privatelink.dfs.core.chinacloudapi.cn", + "privatelink.documents.azure.cn", + "privatelink.mongo.cosmos.azure.cn", + "privatelink.cassandra.cosmos.azure.cn", + "privatelink.gremlin.cosmos.azure.cn", + "privatelink.table.cosmos.azure.cn", + "privatelink.postgres.database.chinacloudapi.cn", + "privatelink.mysql.database.chinacloudapi.cn", + "privatelink.mariadb.database.chinacloudapi.cn", + "privatelink.vaultcore.azure.cn", + "privatelink.servicebus.chinacloudapi.cn", + "privatelink.azure-devices.cn", + "privatelink.eventgrid.azure.cn", + "privatelink.chinacloudsites.cn", + "privatelink.api.ml.azure.cn", + "privatelink.notebooks.chinacloudapi.cn", + "privatelink.signalr.azure.cn", + "privatelink.azurehdinsight.cn", + "privatelink.afs.azure.cn", + "privatelink.datafactory.azure.cn", + "privatelink.adf.azure.cn", + "privatelink.redis.cache.chinacloudapi.cn" + ] + }, + "parTelemetryOptOut": { + "value": false + } + } +} \ No newline at end of file diff --git a/infra-as-code/bicep/modules/vwanConnectivity/media/vwanConnectivityBicepVisualizer.png b/infra-as-code/bicep/modules/vwanConnectivity/media/vwanConnectivityBicepVisualizer.png index 1f9785bb1..a8d0b0e8a 100755 Binary files a/infra-as-code/bicep/modules/vwanConnectivity/media/vwanConnectivityBicepVisualizer.png and b/infra-as-code/bicep/modules/vwanConnectivity/media/vwanConnectivityBicepVisualizer.png differ diff --git a/infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.bicep b/infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.bicep index d1e19542f..bceddd1c6 100644 --- a/infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.bicep +++ b/infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.bicep @@ -11,13 +11,6 @@ param parVhubAddressPrefix string = '10.100.0.0/23' ]) param parAzureFirewallTier string = 'Standard' -@description('Public IP Address SKU. Default: Standard') -@allowed([ - 'Basic' - 'Standard' -]) -param parPublicIPSku string = 'Standard' - @description('Tags you would like to be applied to all resources in this module. Default: empty array') param parTags object = {} @@ -51,6 +44,14 @@ param parERGwName string = '${parCompanyPrefix}-ergw-${parLocation}' @description('Azure Firewall Name. Default: {parCompanyPrefix}-fw-{parLocation}') param parAzureFirewallName string = '${parCompanyPrefix}-fw-${parLocation}' +@allowed([ + '1' + '2' + '3' +]) +@description('Availability Zones to deploy the Azure Firewall across. Region must support Availability Zones to use. If it does not then leave empty.') +param parAzureFirewallAvailabilityZones array = [] + @description('Azure Firewall Policies Name. Default: {parCompanyPrefix}-fwpol-{parLocation}') param parFirewallPoliciesName string = '${parCompanyPrefix}-azfwpolicy-${parLocation}' @@ -63,6 +64,77 @@ param parVPNGwScaleUnit int = 1 @description('The scale unit for this ExpressRoute Gateway: Default: 1') param parERGwScaleUnit int = 1 +@description('Switch which allows DDOS deployment to be disabled. Default: true') +param parDdosEnabled bool = true + +@description('DDOS Plan Name. Default: {parCompanyPrefix}-ddos-plan') +param parDdosPlanName string = '${parCompanyPrefix}-ddos-plan' + +@description('Switch which allows and deploys Private DNS Zones. Default: true') +param parPrivateDnsZonesEnabled bool = true + +@description('Resource Group Name for Private DNS Zones. Default: same resource group') +param parPrivateDnsZonesResourceGroup string = resourceGroup().name + +@description('Array of DNS Zones to provision in Hub Virtual Network. Default: All known Azure Private DNS Zones') +param parPrivateDnsZones array = [ + 'privatelink.azure-automation.net' + 'privatelink.database.windows.net' + 'privatelink.sql.azuresynapse.net' + 'privatelink.dev.azuresynapse.net' + 'privatelink.azuresynapse.net' + 'privatelink.blob.core.windows.net' + 'privatelink.table.core.windows.net' + 'privatelink.queue.core.windows.net' + 'privatelink.file.core.windows.net' + 'privatelink.web.core.windows.net' + 'privatelink.dfs.core.windows.net' + 'privatelink.documents.azure.com' + 'privatelink.mongo.cosmos.azure.com' + 'privatelink.cassandra.cosmos.azure.com' + 'privatelink.gremlin.cosmos.azure.com' + 'privatelink.table.cosmos.azure.com' + 'privatelink.${parLocation}.batch.azure.com' + 'privatelink.postgres.database.azure.com' + 'privatelink.mysql.database.azure.com' + 'privatelink.mariadb.database.azure.com' + 'privatelink.vaultcore.azure.net' + 'privatelink.managedhsm.azure.net' + 'privatelink.${parLocation}.azmk8s.io' + 'privatelink.${parLocation}.backup.windowsazure.com' + 'privatelink.siterecovery.windowsazure.com' + 'privatelink.servicebus.windows.net' + 'privatelink.azure-devices.net' + 'privatelink.eventgrid.azure.net' + 'privatelink.azurewebsites.net' + 'privatelink.api.azureml.ms' + 'privatelink.notebooks.azure.net' + 'privatelink.service.signalr.net' + 'privatelink.monitor.azure.com' + 'privatelink.oms.opinsights.azure.com' + 'privatelink.ods.opinsights.azure.com' + 'privatelink.agentsvc.azure-automation.net' + 'privatelink.afs.azure.net' + 'privatelink.datafactory.azure.net' + 'privatelink.adf.azure.com' + 'privatelink.redis.cache.windows.net' + 'privatelink.redisenterprise.cache.azure.net' + 'privatelink.purview.azure.com' + 'privatelink.purviewstudio.azure.com' + 'privatelink.digitaltwins.azure.net' + 'privatelink.azconfig.io' + 'privatelink.cognitiveservices.azure.com' + 'privatelink.azurecr.io' + 'privatelink.search.windows.net' + 'privatelink.azurehdinsight.net' + 'privatelink.media.azure.net' + 'privatelink.his.arc.azure.com' + 'privatelink.guestconfiguration.azure.com' +] + +@description('Resource ID of VNet for Private DNS Zone VNet Links') +param parVirtualNetworkIdToLink string = '' + @description('Set Parameter to true to Opt-out of deployment telemetry') param parTelemetryOptOut bool = false @@ -82,7 +154,7 @@ resource resVWAN 'Microsoft.Network/virtualWans@2021-05-01' = { } } -resource resVHub 'Microsoft.Network/virtualHubs@2021-05-01' = if(parVirtualHubEnabled && !empty(parVhubAddressPrefix)) { +resource resVHub 'Microsoft.Network/virtualHubs@2021-05-01' = if (parVirtualHubEnabled && !empty(parVhubAddressPrefix)) { name: parVHubName location: parLocation tags: parTags @@ -95,7 +167,28 @@ resource resVHub 'Microsoft.Network/virtualHubs@2021-05-01' = if(parVirtualHubEn } } -resource resVPNGateway 'Microsoft.Network/vpnGateways@2021-05-01' = if(parVirtualHubEnabled && parVPNGatewayEnabled) { +resource resVHubRouteTable 'Microsoft.Network/virtualHubs/hubRouteTables@2021-05-01' = if (parVirtualHubEnabled && parAzureFirewallEnabled) { + parent: resVHub + name: 'defaultRouteTable' + properties: { + labels: [ + 'default' + ] + routes: [ + { + name: 'default-to-azfw' + destinations: [ + '0.0.0.0/0' + ] + destinationType: 'CIDR' + nextHop: (parVirtualHubEnabled && parAzureFirewallEnabled) ? resAzureFirewall.id : '' + nextHopType: 'ResourceID' + } + ] + } +} + +resource resVPNGateway 'Microsoft.Network/vpnGateways@2021-05-01' = if (parVirtualHubEnabled && parVPNGatewayEnabled) { name: parVPNGwName location: parLocation tags: parTags @@ -105,7 +198,7 @@ resource resVPNGateway 'Microsoft.Network/vpnGateways@2021-05-01' = if(parVirtua bgpPeeringAddress: '' peerWeight: 5 } - virtualHub:{ + virtualHub: { id: resVHub.id } vpnGatewayScaleUnit: parVPNGwScaleUnit @@ -117,7 +210,7 @@ resource resERGateway 'Microsoft.Network/expressRouteGateways@2021-05-01' = if ( location: parLocation tags: parTags properties: { - virtualHub:{ + virtualHub: { id: resVHub.id } autoScaleConfiguration: { @@ -146,17 +239,13 @@ resource resAzureFirewall 'Microsoft.Network/azureFirewalls@2021-02-01' = if (pa name: parAzureFirewallName location: parLocation tags: parTags - properties:{ + zones: (!empty(parAzureFirewallAvailabilityZones) ? parAzureFirewallAvailabilityZones : json('null')) + properties: { hubIPAddresses: { publicIPs: { - addresses: [ - { - address: (parVirtualHubEnabled && parAzureFirewallEnabled) ? modAzureFirewallPublicIP.outputs.outPublicIPID : '' - } - ] count: 1 } - } + } sku: { name: 'AZFW_Hub' tier: parAzureFirewallTier @@ -164,7 +253,7 @@ resource resAzureFirewall 'Microsoft.Network/azureFirewalls@2021-02-01' = if (pa virtualHub: { id: parVirtualHubEnabled ? resVHub.id : '' } - additionalProperties: { + additionalProperties: { 'Network.DNS.EnableProxy': '${parNetworkDNSEnableProxy}' } firewallPolicy: { @@ -173,19 +262,22 @@ resource resAzureFirewall 'Microsoft.Network/azureFirewalls@2021-02-01' = if (pa } } -module modAzureFirewallPublicIP '../publicIp/publicIp.bicep' = if (parVirtualHubEnabled && parAzureFirewallEnabled) { - name: 'deploy-Firewall-Public-IP' +// DDoS plan is deployed even though not supported to attach to Virtual WAN today as per https://docs.microsoft.com/azure/firewall-manager/overview#known-issues - However, it can still be linked via policy to spoke VNets etc. +resource resDdosProtectionPlan 'Microsoft.Network/ddosProtectionPlans@2021-02-01' = if (parDdosEnabled) { + name: parDdosPlanName + location: parLocation + tags: parTags +} + +// Private DNS Zones cannot be linked to the Virtual WAN Hub today however, they can be linked to spokes as they are normal VNets as per https://docs.microsoft.com/azure/virtual-wan/howto-private-link +module modPrivateDnsZones '../privateDnsZones/privateDnsZones.bicep' = if (parPrivateDnsZonesEnabled) { + name: 'deploy-Private-DNS-Zones' + scope: resourceGroup(parPrivateDnsZonesResourceGroup) params: { - parPublicIPName: '${parAzureFirewallName}-PublicIP' parLocation: parLocation - parPublicIPProperties: { - publicIPAddressVersion: 'IPv4' - publicIPAllocationMethod: 'Static' - } - parPublicIPSku: { - name: parPublicIPSku - } parTags: parTags + parVirtualNetworkIdToLink: parVirtualNetworkIdToLink + parPrivateDnsZones: parPrivateDnsZones } } @@ -202,3 +294,9 @@ output outVirtualWANID string = resVWAN.id // Output Virtual Hub name and ID output outVirtualHubName string = resVHub.name output outVirtualHubID string = resVHub.id + +// Output DDoS Plan ID +output outDdosPlanResourceID string = resDdosProtectionPlan.id + +// Output Private DNS Zones +output outPrivateDnsZones array = (parPrivateDnsZonesEnabled ? modPrivateDnsZones.outputs.outPrivateDnsZones : []) diff --git a/infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.parameters.example.json b/infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.parameters.example.json index 495f4ce69..0a66f1d92 100644 --- a/infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.parameters.example.json +++ b/infra-as-code/bicep/modules/vwanConnectivity/vwanConnectivity.parameters.example.json @@ -1,36 +1,98 @@ { - "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", - "contentVersion": "1.0.0.0", - "parameters": { - "parVirtualHubEnabled": { - "value": true - }, - "parVPNGatewayEnabled":{ - "value": true - }, - "parERGatewayEnabled":{ - "value": true - }, - "parAzureFirewallEnabled": { - "value": true - }, - "parNetworkDNSEnableProxy": { - "value": true - }, - "parCompanyPrefix":{ - "value": "alz" - }, - "parPublicIPSku":{ - "value":"Standard" - }, - "parVhubAddressPrefix" : { - "value": "10.100.0.0/23" - }, - "parAzureFirewallTier": { - "value": "Standard" - }, - "parTelemetryOptOut": { - "value": false - } + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "parVirtualHubEnabled": { + "value": true + }, + "parVPNGatewayEnabled": { + "value": true + }, + "parERGatewayEnabled": { + "value": true + }, + "parAzureFirewallEnabled": { + "value": true + }, + "parNetworkDNSEnableProxy": { + "value": true + }, + "parDdosEnabled": { + "value": true + }, + "parDdosPlanName": { + "value": "alz-ddos-plan" + }, + "parCompanyPrefix": { + "value": "alz" + }, + "parVhubAddressPrefix": { + "value": "10.100.0.0/23" + }, + "parAzureFirewallTier": { + "value": "Standard" + }, + "parAzureFirewallAvailabilityZones": { + "value": [] + }, + "parPrivateDnsZonesEnabled": { + "value": true + }, + "parPrivateDnsZones": { + "value": [ + "privatelink.azure-automation.net", + "privatelink.database.windows.net", + "privatelink.sql.azuresynapse.net", + "privatelink.dev.azuresynapse.net", + "privatelink.azuresynapse.net", + "privatelink.blob.core.windows.net", + "privatelink.table.core.windows.net", + "privatelink.queue.core.windows.net", + "privatelink.file.core.windows.net", + "privatelink.web.core.windows.net", + "privatelink.dfs.core.windows.net", + "privatelink.documents.azure.com", + "privatelink.mongo.cosmos.azure.com", + "privatelink.cassandra.cosmos.azure.com", + "privatelink.gremlin.cosmos.azure.com", + "privatelink.table.cosmos.azure.com", + "privatelink.postgres.database.azure.com", + "privatelink.mysql.database.azure.com", + "privatelink.mariadb.database.azure.com", + "privatelink.vaultcore.azure.net", + "privatelink.managedhsm.azure.net", + "privatelink.siterecovery.windowsazure.com", + "privatelink.servicebus.windows.net", + "privatelink.azure-devices.net", + "privatelink.eventgrid.azure.net", + "privatelink.azurewebsites.net", + "privatelink.api.azureml.ms", + "privatelink.notebooks.azure.net", + "privatelink.service.signalr.net", + "privatelink.monitor.azure.com", + "privatelink.oms.opinsights.azure.com", + "privatelink.ods.opinsights.azure.com", + "privatelink.agentsvc.azure-automation.net", + "privatelink.afs.azure.net", + "privatelink.datafactory.azure.net", + "privatelink.adf.azure.com", + "privatelink.redis.cache.windows.net", + "privatelink.redisenterprise.cache.azure.net", + "privatelink.purview.azure.com", + "privatelink.purviewstudio.azure.com", + "privatelink.digitaltwins.azure.net", + "privatelink.azconfig.io", + "privatelink.cognitiveservices.azure.com", + "privatelink.azurecr.io", + "privatelink.search.windows.net", + "privatelink.azurehdinsight.net", + "privatelink.media.azure.net", + "privatelink.his.arc.azure.com", + "privatelink.guestconfiguration.azure.com" + ] + }, + "parTelemetryOptOut": { + "value": false } - } \ No newline at end of file + } +} \ No newline at end of file