{ "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "metadata": { "_generator": { "name": "bicep", "version": "0.11.1.770", "templateHash": "13320210290143748634" } }, "parameters": { "location": { "type": "string", "defaultValue": "[resourceGroup().location]", "minLength": 6, "metadata": { "description": "The location of this regional hub. All resources, including spoke resources, will be deployed to this region. This region must support availability zones." } }, "deployVpnGateway": { "type": "bool", "defaultValue": false, "metadata": { "description": "Set to true to include a basic VPN Gateway deployment into the hub. Set to false to leave network space for a VPN Gateway, but do not deploy one. Default is false. Note deploying VPN gateways can take significant time." } }, "deployVirtualMachines": { "type": "bool", "defaultValue": false, "metadata": { "description": "Set to true to include one Windows and one Linux virtual machine for you to experience peering, gateway transit, and bastion access. Default is false." } }, "adminUsername": { "type": "string", "defaultValue": "azureadmin", "metadata": { "description": "Username for both the Linux and Windows VM. Must only contain letters, numbers, hyphens, and underscores and may not start with a hyphen or number. Only needed when providing deployVirtualMachines=true." }, "maxLength": 20, "minLength": 4 }, "adminPassword": { "type": "secureString", "metadata": { "description": "Password for both the Linux and Windows VM. Password must have 3 of the following: 1 lower case character, 1 upper case character, 1 number, and 1 special character. Must be at least 12 characters. Only needed when providing deployVirtualMachines=true." }, "maxLength": 70 } }, "variables": { "suffix": "[uniqueString(subscription().subscriptionId, resourceGroup().id)]", "numFirewallIpAddressesToAssign": 3 }, "resources": [ { "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', format('vnet-{0}-hub', parameters('location')), format('to_{0}', format('vnet-{0}-spoke-one', parameters('location'))))]", "properties": { "allowForwardedTraffic": false, "allowGatewayTransit": false, "allowVirtualNetworkAccess": true, "useRemoteGateways": false, "remoteVirtualNetwork": { "id": "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-one', parameters('location')))]" } }, "dependsOn": [ "[resourceId('Microsoft.Network/virtualNetworks/virtualNetworkPeerings', format('vnet-{0}-spoke-one', parameters('location')), format('to_{0}', format('vnet-{0}-hub', parameters('location'))))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-one', parameters('location')))]" ] }, { "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', format('vnet-{0}-hub', parameters('location')), format('to_{0}', format('vnet-{0}-spoke-two', parameters('location'))))]", "properties": { "allowForwardedTraffic": false, "allowGatewayTransit": false, "allowVirtualNetworkAccess": true, "useRemoteGateways": false, "remoteVirtualNetwork": { "id": "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-two', parameters('location')))]" } }, "dependsOn": [ "[resourceId('Microsoft.Network/virtualNetworks/virtualNetworkPeerings', format('vnet-{0}-spoke-two', parameters('location')), format('to_{0}', format('vnet-{0}-hub', parameters('location'))))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-two', parameters('location')))]" ] }, { "type": "Microsoft.Network/firewallPolicies/ruleCollectionGroups", "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', format('fw-policies-{0}', parameters('location')), 'DefaultNetworkRuleCollectionGroup')]", "properties": { "priority": 200, "ruleCollections": [ { "ruleCollectionType": "FirewallPolicyFilterRuleCollection", "name": "org-wide-allowed", "priority": 100, "action": { "type": "Allow" }, "rules": [ { "ruleType": "NetworkRule", "name": "DNS", "description": "Allow DNS outbound (for simplicity, adjust as needed)", "ipProtocols": [ "UDP" ], "sourceAddresses": [ "*" ], "sourceIpGroups": [], "destinationAddresses": [ "*" ], "destinationIpGroups": [], "destinationFqdns": [], "destinationPorts": [ "53" ] } ] } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/firewallPolicies', format('fw-policies-{0}', parameters('location')))]" ] }, { "type": "Microsoft.Network/firewallPolicies/ruleCollectionGroups", "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', format('fw-policies-{0}', parameters('location')), 'DefaultApplicationRuleCollectionGroup')]", "properties": { "priority": 300, "ruleCollections": [ { "ruleCollectionType": "FirewallPolicyFilterRuleCollection", "name": "org-wide-allowed", "priority": 100, "action": { "type": "Allow" }, "rules": "[if(parameters('deployVirtualMachines'), createArray(createObject('ruleType', 'ApplicationRule', 'name', 'WindowsVirtualMachineHealth', 'description', 'Supports Windows Updates and Windows Diagnostics', 'fqdnTags', createArray('WindowsDiagnostics', 'WindowsUpdate'), 'protocols', createArray(createObject('protocolType', 'Https', 'port', 443)), 'sourceAddresses', createArray('10.200.0.0/24'))), createArray())]" } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/firewallPolicies/ruleCollectionGroups', format('fw-policies-{0}', parameters('location')), 'DefaultNetworkRuleCollectionGroup')]", "[resourceId('Microsoft.Network/firewallPolicies', format('fw-policies-{0}', parameters('location')))]" ] }, { "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', format('vnet-{0}-spoke-one', parameters('location')), format('to_{0}', format('vnet-{0}-hub', parameters('location'))))]", "properties": { "allowForwardedTraffic": false, "allowGatewayTransit": false, "allowVirtualNetworkAccess": true, "useRemoteGateways": false, "remoteVirtualNetwork": { "id": "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]" } }, "dependsOn": [ "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-one', parameters('location')))]" ] }, { "type": "Microsoft.Network/virtualNetworks/virtualNetworkPeerings", "apiVersion": "2023-04-01", "name": "[format('{0}/{1}', format('vnet-{0}-spoke-two', parameters('location')), format('to_{0}', format('vnet-{0}-hub', parameters('location'))))]", "properties": { "allowForwardedTraffic": false, "allowGatewayTransit": false, "allowVirtualNetworkAccess": true, "useRemoteGateways": false, "remoteVirtualNetwork": { "id": "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]" } }, "dependsOn": [ "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-two', parameters('location')))]" ] }, { "type": "Microsoft.OperationalInsights/workspaces", "apiVersion": "2022-10-01", "name": "[format('la-hub-{0}-{1}', parameters('location'), variables('suffix'))]", "location": "[parameters('location')]", "properties": { "sku": { "name": "PerGB2018" }, "retentionInDays": 90, "forceCmkForQuery": false, "publicNetworkAccessForIngestion": "Enabled", "publicNetworkAccessForQuery": "Enabled", "features": { "disableLocalAuth": false, "enableLogAccessUsingOnlyResourcePermissions": true }, "workspaceCapping": { "dailyQuotaGb": -1 } }, "metadata": { "description": "This Log Analyics Workspace stores logs from the regional hub network, its spokes, and other related resources. Workspaces are regional resource, as such there would be one workspace per hub (region)" } }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.OperationalInsights/workspaces/{0}', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ], "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]" ] }, { "type": "Microsoft.Network/networkSecurityGroups", "apiVersion": "2023-04-01", "name": "[format('nsg-{0}-bastion', parameters('location'))]", "location": "[parameters('location')]", "properties": { "securityRules": [ { "name": "AllowWebExperienceInbound", "properties": { "description": "Allow our users in. Update this to be as restrictive as possible.", "protocol": "Tcp", "sourcePortRange": "*", "destinationPortRange": "443", "sourceAddressPrefix": "Internet", "destinationAddressPrefix": "*", "access": "Allow", "priority": 100, "direction": "Inbound" } }, { "name": "AllowControlPlaneInbound", "properties": { "description": "Service Requirement. Allow control plane access. Regional Tag not yet supported.", "protocol": "Tcp", "sourcePortRange": "*", "destinationPortRange": "443", "sourceAddressPrefix": "GatewayManager", "destinationAddressPrefix": "*", "access": "Allow", "priority": 110, "direction": "Inbound" } }, { "name": "AllowHealthProbesInbound", "properties": { "description": "Service Requirement. Allow Health Probes.", "protocol": "Tcp", "sourcePortRange": "*", "destinationPortRange": "443", "sourceAddressPrefix": "AzureLoadBalancer", "destinationAddressPrefix": "*", "access": "Allow", "priority": 120, "direction": "Inbound" } }, { "name": "AllowBastionHostToHostInbound", "properties": { "description": "Service Requirement. Allow Required Host to Host Communication.", "protocol": "*", "sourcePortRange": "*", "destinationPortRanges": [ "8080", "5701" ], "sourceAddressPrefix": "VirtualNetwork", "destinationAddressPrefix": "VirtualNetwork", "access": "Allow", "priority": 130, "direction": "Inbound" } }, { "name": "DenyAllInbound", "properties": { "description": "No further inbound traffic allowed.", "protocol": "*", "sourcePortRange": "*", "destinationPortRange": "*", "sourceAddressPrefix": "*", "destinationAddressPrefix": "*", "access": "Deny", "priority": 1000, "direction": "Inbound" } }, { "name": "AllowSshToVnetOutbound", "properties": { "description": "Allow SSH out to the virtual network", "protocol": "Tcp", "sourcePortRange": "*", "sourceAddressPrefix": "*", "destinationPortRange": "22", "destinationAddressPrefix": "VirtualNetwork", "access": "Allow", "priority": 100, "direction": "Outbound" } }, { "name": "AllowRdpToVnetOutbound", "properties": { "description": "Allow RDP out to the virtual network", "protocol": "Tcp", "sourcePortRange": "*", "sourceAddressPrefix": "*", "destinationPortRange": "3389", "destinationAddressPrefix": "VirtualNetwork", "access": "Allow", "priority": 110, "direction": "Outbound" } }, { "name": "AllowControlPlaneOutbound", "properties": { "description": "Required for control plane outbound. Regional prefix not yet supported", "protocol": "Tcp", "sourcePortRange": "*", "sourceAddressPrefix": "*", "destinationPortRange": "443", "destinationAddressPrefix": "AzureCloud", "access": "Allow", "priority": 120, "direction": "Outbound" } }, { "name": "AllowBastionHostToHostOutbound", "properties": { "description": "Service Requirement. Allow Required Host to Host Communication.", "protocol": "*", "sourcePortRange": "*", "sourceAddressPrefix": "VirtualNetwork", "destinationPortRanges": [ "8080", "5701" ], "destinationAddressPrefix": "VirtualNetwork", "access": "Allow", "priority": 130, "direction": "Outbound" } }, { "name": "AllowBastionCertificateValidationOutbound", "properties": { "description": "Service Requirement. Allow Required Session and Certificate Validation.", "protocol": "*", "sourcePortRange": "*", "sourceAddressPrefix": "*", "destinationPortRange": "80", "destinationAddressPrefix": "Internet", "access": "Allow", "priority": 140, "direction": "Outbound" } }, { "name": "DenyAllOutbound", "properties": { "description": "No further outbound traffic allowed.", "protocol": "*", "sourcePortRange": "*", "destinationPortRange": "*", "sourceAddressPrefix": "*", "destinationAddressPrefix": "*", "access": "Deny", "priority": 1000, "direction": "Outbound" } } ] }, "metadata": { "description": "The NSG around the Azure Bastion subnet. Source: https://learn.microsoft.com/azure/bastion/bastion-nsg" } }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/networkSecurityGroups/{0}', format('nsg-{0}-bastion', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/networkSecurityGroups', format('nsg-{0}-bastion', parameters('location')))]" ] }, { "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2023-04-01", "name": "[format('vnet-{0}-hub', parameters('location'))]", "location": "[parameters('location')]", "properties": { "addressSpace": { "addressPrefixes": [ "10.0.0.0/22" ] }, "subnets": [ { "name": "AzureBastionSubnet", "properties": { "addressPrefix": "10.0.1.0/26", "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', format('nsg-{0}-bastion', parameters('location')))]" } } }, { "name": "GatewaySubnet", "properties": { "addressPrefix": "10.0.2.0/27" } }, { "name": "AzureFirewallSubnet", "properties": { "addressPrefix": "10.0.3.0/26" } } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/networkSecurityGroups', format('nsg-{0}-bastion', parameters('location')))]" ], "metadata": { "description": "The regional hub network." } }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/virtualNetworks/{0}', format('vnet-{0}-hub', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]" ] }, { "copy": { "name": "pipsAzureFirewall", "count": "[length(range(0, variables('numFirewallIpAddressesToAssign')))]" }, "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2023-04-01", "name": "[format('pip-fw-{0}-{1}', parameters('location'), padLeft(range(0, variables('numFirewallIpAddressesToAssign'))[copyIndex()], 2, '0'))]", "location": "[parameters('location')]", "sku": { "name": "Standard" }, "zones": [ "1", "2", "3" ], "properties": { "publicIPAllocationMethod": "Static", "idleTimeoutInMinutes": 4, "publicIPAddressVersion": "IPv4" } }, { "copy": { "name": "pipsAzureFirewall_diagnosticSetting", "count": "[length(range(0, variables('numFirewallIpAddressesToAssign')))]" }, "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', format('pip-fw-{0}-{1}', parameters('location'), padLeft(range(0, variables('numFirewallIpAddressesToAssign'))[range(0, variables('numFirewallIpAddressesToAssign'))[copyIndex()]], 2, '0')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ], "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/publicIPAddresses', format('pip-fw-{0}-{1}', parameters('location'), padLeft(range(0, variables('numFirewallIpAddressesToAssign'))[range(0, variables('numFirewallIpAddressesToAssign'))[copyIndex()]], 2, '0')))]" ] }, { "type": "Microsoft.Network/firewallPolicies", "apiVersion": "2023-04-01", "name": "[format('fw-policies-{0}', parameters('location'))]", "location": "[parameters('location')]", "properties": { "sku": { "tier": "Standard" }, "threatIntelMode": "Deny", "insights": { "isEnabled": true, "retentionDays": 30, "logAnalyticsResources": { "defaultWorkspaceId": { "id": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]" } } }, "threatIntelWhitelist": { "fqdns": [], "ipAddresses": [] }, "intrusionDetection": null, "dnsSettings": { "servers": [], "enableProxy": true } }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]" ], "metadata": { "description": "Azure Firewall Policy" } }, { "type": "Microsoft.Network/azureFirewalls", "apiVersion": "2023-04-01", "name": "[format('fw-{0}', parameters('location'))]", "location": "[parameters('location')]", "zones": [ "1", "2", "3" ], "properties": { "copy": [ { "name": "ipConfigurations", "count": "[length(range(0, variables('numFirewallIpAddressesToAssign')))]", "input": { "name": "[format('pip-fw-{0}-{1}', parameters('location'), padLeft(range(0, variables('numFirewallIpAddressesToAssign'))[range(0, variables('numFirewallIpAddressesToAssign'))[copyIndex('ipConfigurations')]], 2, '0'))]", "properties": { "subnet": "[if(equals(0, range(0, variables('numFirewallIpAddressesToAssign'))[copyIndex('ipConfigurations')]), createObject('id', resourceId('Microsoft.Network/virtualNetworks/subnets', format('vnet-{0}-hub', parameters('location')), 'AzureFirewallSubnet')), null())]", "publicIPAddress": { "id": "[resourceId('Microsoft.Network/publicIPAddresses', format('pip-fw-{0}-{1}', parameters('location'), padLeft(range(0, variables('numFirewallIpAddressesToAssign'))[range(0, variables('numFirewallIpAddressesToAssign'))[copyIndex('ipConfigurations')]], 2, '0')))]" } } } } ], "sku": { "name": "AZFW_VNet", "tier": "Standard" }, "firewallPolicy": { "id": "[resourceId('Microsoft.Network/firewallPolicies', format('fw-policies-{0}', parameters('location')))]" } }, "dependsOn": [ "[resourceId('Microsoft.Network/firewallPolicies/ruleCollectionGroups', format('fw-policies-{0}', parameters('location')), 'DefaultApplicationRuleCollectionGroup')]", "[resourceId('Microsoft.Network/firewallPolicies/ruleCollectionGroups', format('fw-policies-{0}', parameters('location')), 'DefaultNetworkRuleCollectionGroup')]", "[resourceId('Microsoft.Network/firewallPolicies', format('fw-policies-{0}', parameters('location')))]", "pipsAzureFirewall", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]" ], "metadata": { "description": "This is the regional Azure Firewall that all regional spoke networks can egress through." } }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/azureFirewalls/{0}', format('fw-{0}', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ], "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/azureFirewalls', format('fw-{0}', parameters('location')))]", "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]" ] }, { "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2023-04-01", "name": "[format('pip-ab-{0}', parameters('location'))]", "location": "[parameters('location')]", "sku": { "name": "Standard" }, "zones": [ "1", "2", "3" ], "properties": { "publicIPAllocationMethod": "Static", "idleTimeoutInMinutes": 4, "publicIPAddressVersion": "IPv4" }, "metadata": { "description": "The public IP for the regional hub's Azure Bastion service." } }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', format('pip-ab-{0}', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ], "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/publicIPAddresses', format('pip-ab-{0}', parameters('location')))]" ] }, { "type": "Microsoft.Network/bastionHosts", "apiVersion": "2023-04-01", "name": "[format('ab-{0}-{1}', parameters('location'), variables('suffix'))]", "location": "[parameters('location')]", "sku": { "name": "Basic" }, "properties": { "ipConfigurations": [ { "name": "hub-subnet", "properties": { "privateIPAllocationMethod": "Dynamic", "subnet": { "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', format('vnet-{0}-hub', parameters('location')), 'AzureBastionSubnet')]" }, "publicIPAddress": { "id": "[resourceId('Microsoft.Network/publicIPAddresses', format('pip-ab-{0}', parameters('location')))]" } } } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/publicIPAddresses', format('pip-ab-{0}', parameters('location')))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]" ], "metadata": { "description": "This regional hub's Azure Bastion service. NSGs are configured to allow Bastion to reach any resource subnet in peered spokes." } }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/bastionHosts/{0}', format('ab-{0}-{1}', parameters('location'), variables('suffix')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ], "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/bastionHosts', format('ab-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]" ] }, { "condition": "[parameters('deployVpnGateway')]", "type": "Microsoft.Network/publicIPAddresses", "apiVersion": "2023-04-01", "name": "[format('pip-vgw-{0}', parameters('location'))]", "location": "[parameters('location')]", "sku": { "name": "Standard" }, "zones": [ "1", "2", "3" ], "properties": { "publicIPAllocationMethod": "Static", "idleTimeoutInMinutes": 4, "publicIPAddressVersion": "IPv4" }, "metadata": { "description": "The public IPs for the regional VPN gateway. Only deployed if requested." } }, { "condition": "[parameters('deployVpnGateway')]", "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/publicIPAddresses/{0}', format('pip-vgw-{0}', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ], "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/publicIPAddresses', format('pip-vgw-{0}', parameters('location')))]" ] }, { "condition": "[parameters('deployVpnGateway')]", "type": "Microsoft.Network/virtualNetworkGateways", "apiVersion": "2023-04-01", "name": "[format('vgw-{0}-hub', parameters('location'))]", "location": "[parameters('location')]", "properties": { "sku": { "name": "VpnGw2AZ", "tier": "VpnGw2AZ" }, "gatewayType": "Vpn", "vpnType": "RouteBased", "vpnGatewayGeneration": "Generation2", "ipConfigurations": [ { "name": "default", "properties": { "privateIPAllocationMethod": "Dynamic", "publicIPAddress": { "id": "[resourceId('Microsoft.Network/publicIPAddresses', format('pip-vgw-{0}', parameters('location')))]" }, "subnet": { "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', format('vnet-{0}-hub', parameters('location')), 'GatewaySubnet')]" } } } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/publicIPAddresses', format('pip-vgw-{0}', parameters('location')))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]" ], "metadata": { "description": "The is the regional VPN gateway, configured with basic settings. Only deployed if requested." } }, { "condition": "[parameters('deployVpnGateway')]", "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/virtualNetworkGateways/{0}', format('vgw-{0}-hub', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ], "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/virtualNetworkGateways', format('vgw-{0}-hub', parameters('location')))]" ] }, { "type": "Microsoft.Network/routeTables", "apiVersion": "2023-04-01", "name": "[format('route-to-{0}-hub-fw', parameters('location'))]", "location": "[parameters('location')]", "properties": { "routes": [ { "name": "r-nexthop-to-fw", "properties": { "nextHopType": "VirtualAppliance", "addressPrefix": "0.0.0.0/0", "nextHopIpAddress": "[reference(resourceId('Microsoft.Network/azureFirewalls', format('fw-{0}', parameters('location')))).ipConfigurations[0].properties.privateIPAddress]" } } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/azureFirewalls', format('fw-{0}', parameters('location')))]" ], "metadata": { "description": "Next hop to the regional hub's Azure Firewall" } }, { "type": "Microsoft.Network/networkSecurityGroups", "apiVersion": "2023-04-01", "name": "nsg-spoke-resources", "location": "[parameters('location')]", "properties": { "securityRules": [ { "name": "AllowBastionRdpFromHub", "properties": { "protocol": "Tcp", "sourcePortRange": "*", "sourceAddressPrefix": "[reference(resourceId('Microsoft.Network/virtualNetworks/subnets', format('vnet-{0}-hub', parameters('location')), 'AzureBastionSubnet'), '2022-01-01').addressPrefix]", "destinationPortRanges": [ "3389" ], "destinationAddressPrefix": "VirtualNetwork", "access": "Allow", "priority": 100, "direction": "Inbound" } }, { "name": "AllowBastionSshFromHub", "properties": { "protocol": "Tcp", "sourcePortRange": "*", "sourceAddressPrefix": "[reference(resourceId('Microsoft.Network/virtualNetworks/subnets', format('vnet-{0}-hub', parameters('location')), 'AzureBastionSubnet'), '2022-01-01').addressPrefix]", "destinationPortRanges": [ "22" ], "destinationAddressPrefix": "VirtualNetwork", "access": "Allow", "priority": 110, "direction": "Inbound" } }, { "name": "DenyAllInBound", "properties": { "protocol": "*", "sourcePortRange": "*", "sourceAddressPrefix": "*", "destinationPortRange": "*", "destinationAddressPrefix": "*", "access": "Deny", "priority": 1000, "direction": "Inbound" } } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-hub', parameters('location')))]" ], "metadata": { "description": "NSG on the resource subnet (just using a common one for all as an example, but usually would be based on the specific needs of the spoke)." } }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/networkSecurityGroups/{0}', 'nsg-spoke-resources')]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-resources')]" ] }, { "type": "Microsoft.Network/networkSecurityGroups", "apiVersion": "2023-04-01", "name": "nsg-spoke-privatelinkendpoints", "location": "[parameters('location')]", "properties": { "securityRules": [ { "name": "AllowAll443InFromVnet", "properties": { "protocol": "Tcp", "sourcePortRange": "*", "sourceAddressPrefix": "VirtualNetwork", "destinationPortRange": "443", "destinationAddressPrefix": "VirtualNetwork", "access": "Allow", "priority": 100, "direction": "Inbound" } }, { "name": "DenyAllInbound", "properties": { "protocol": "*", "sourcePortRange": "*", "sourceAddressPrefix": "*", "destinationPortRange": "*", "destinationAddressPrefix": "*", "access": "Deny", "priority": 1000, "direction": "Inbound" } }, { "name": "DenyAllOutbound", "properties": { "protocol": "*", "sourcePortRange": "*", "sourceAddressPrefix": "*", "destinationPortRange": "*", "destinationAddressPrefix": "*", "access": "Deny", "priority": 1000, "direction": "Outbound" } } ] }, "metadata": { "description": "NSG on the Private Link subnet (just using a common one for all as an example, but usually would be based on the specific needs of the spoke)." } }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/networkSecurityGroups/{0}', 'nsg-spoke-privatelinkendpoints')]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "logs": [ { "categoryGroup": "allLogs", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-privatelinkendpoints')]" ] }, { "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2023-04-01", "name": "[format('vnet-{0}-spoke-one', parameters('location'))]", "location": "[parameters('location')]", "properties": { "addressSpace": { "addressPrefixes": [ "10.100.0.0/22" ] }, "subnets": [ { "name": "snet-resources", "properties": { "addressPrefix": "10.100.0.0/24", "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-resources')]" }, "privateEndpointNetworkPolicies": "Disabled", "privateLinkServiceNetworkPolicies": "Disabled", "routeTable": { "id": "[resourceId('Microsoft.Network/routeTables', format('route-to-{0}-hub-fw', parameters('location')))]" } } }, { "name": "snet-privatelinkendpoints", "properties": { "addressPrefix": "10.100.1.0/26", "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-privatelinkendpoints')]" }, "privateEndpointNetworkPolicies": "Enabled", "privateLinkServiceNetworkPolicies": "Enabled", "routeTable": { "id": "[resourceId('Microsoft.Network/routeTables', format('route-to-{0}-hub-fw', parameters('location')))]" } } } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-privatelinkendpoints')]", "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-resources')]", "[resourceId('Microsoft.Network/routeTables', format('route-to-{0}-hub-fw', parameters('location')))]" ] }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/virtualNetworks/{0}', format('vnet-{0}-spoke-one', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-one', parameters('location')))]" ] }, { "condition": "[parameters('deployVirtualMachines')]", "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2023-04-01", "name": "[format('nic-vm-{0}-spoke-one-linux', parameters('location'))]", "location": "[parameters('location')]", "properties": { "ipConfigurations": [ { "name": "default", "properties": { "subnet": { "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', format('vnet-{0}-spoke-one', parameters('location')), 'snet-resources')]" }, "privateIPAllocationMethod": "Dynamic" } } ], "enableAcceleratedNetworking": true }, "dependsOn": [ "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-one', parameters('location')))]" ], "metadata": { "description": "The private Network Interface Card for the linux VM in spoke one." } }, { "condition": "[parameters('deployVirtualMachines')]", "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/networkInterfaces/{0}', format('nic-vm-{0}-spoke-one-linux', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/networkInterfaces', format('nic-vm-{0}-spoke-one-linux', parameters('location')))]" ] }, { "condition": "[parameters('deployVirtualMachines')]", "type": "Microsoft.Compute/virtualMachines", "apiVersion": "2023-03-01", "name": "[format('vm-{0}-spoke-one-linux', parameters('location'))]", "location": "[parameters('location')]", "properties": { "hardwareProfile": { "vmSize": "Standard_D2ds_v4" }, "storageProfile": { "osDisk": { "createOption": "FromImage", "managedDisk": { "storageAccountType": "Standard_LRS" }, "caching": "ReadOnly", "diffDiskSettings": { "option": "Local", "placement": "CacheDisk" }, "deleteOption": "Delete" }, "imageReference": { "publisher": "Canonical", "offer": "0001-com-ubuntu-server-focal", "sku": "20_04-lts-gen2", "version": "latest" }, "dataDisks": [] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, "storageUri": null } }, "networkProfile": { "networkInterfaces": [ { "id": "[resourceId('Microsoft.Network/networkInterfaces', format('nic-vm-{0}-spoke-one-linux', parameters('location')))]", "properties": { "deleteOption": "Delete", "primary": true } } ] }, "osProfile": { "computerName": "examplevm", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPassword')]", "linuxConfiguration": { "disablePasswordAuthentication": false, "patchSettings": { "patchMode": "ImageDefault", "assessmentMode": "ImageDefault" } } }, "priority": "Regular" }, "dependsOn": [ "[resourceId('Microsoft.Network/networkInterfaces', format('nic-vm-{0}-spoke-one-linux', parameters('location')))]" ], "metadata": { "description": "A basic Linux virtual machine that will be attached to spoke one." } }, { "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2023-04-01", "name": "[format('vnet-{0}-spoke-two', parameters('location'))]", "location": "[parameters('location')]", "properties": { "addressSpace": { "addressPrefixes": [ "10.200.0.0/22" ] }, "subnets": [ { "name": "snet-resources", "properties": { "addressPrefix": "10.200.0.0/24", "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-resources')]" }, "privateEndpointNetworkPolicies": "Disabled", "privateLinkServiceNetworkPolicies": "Disabled", "routeTable": { "id": "[resourceId('Microsoft.Network/routeTables', format('route-to-{0}-hub-fw', parameters('location')))]" } } }, { "name": "snet-privatelinkendpoints", "properties": { "addressPrefix": "10.200.1.0/26", "networkSecurityGroup": { "id": "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-privatelinkendpoints')]" }, "privateEndpointNetworkPolicies": "Enabled", "privateLinkServiceNetworkPolicies": "Enabled", "routeTable": { "id": "[resourceId('Microsoft.Network/routeTables', format('route-to-{0}-hub-fw', parameters('location')))]" } } } ] }, "dependsOn": [ "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-privatelinkendpoints')]", "[resourceId('Microsoft.Network/networkSecurityGroups', 'nsg-spoke-resources')]", "[resourceId('Microsoft.Network/routeTables', format('route-to-{0}-hub-fw', parameters('location')))]" ] }, { "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/virtualNetworks/{0}', format('vnet-{0}-spoke-two', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-two', parameters('location')))]" ] }, { "condition": "[parameters('deployVirtualMachines')]", "type": "Microsoft.Network/networkInterfaces", "apiVersion": "2023-04-01", "name": "[format('nic-vm-{0}-spoke-two-windows', parameters('location'))]", "location": "[parameters('location')]", "properties": { "ipConfigurations": [ { "name": "default", "properties": { "subnet": { "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', format('vnet-{0}-spoke-two', parameters('location')), 'snet-resources')]" }, "privateIPAllocationMethod": "Dynamic" } } ], "enableAcceleratedNetworking": true }, "dependsOn": [ "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}-spoke-two', parameters('location')))]" ], "metadata": { "description": "The private Network Interface Card for the Windows VM in spoke two." } }, { "condition": "[parameters('deployVirtualMachines')]", "type": "Microsoft.Insights/diagnosticSettings", "apiVersion": "2021-05-01-preview", "scope": "[format('Microsoft.Network/networkInterfaces/{0}', format('nic-vm-{0}-spoke-two-windows', parameters('location')))]", "name": "to-hub-la", "properties": { "workspaceId": "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "metrics": [ { "category": "AllMetrics", "enabled": true } ] }, "dependsOn": [ "[resourceId('Microsoft.OperationalInsights/workspaces', format('la-hub-{0}-{1}', parameters('location'), variables('suffix')))]", "[resourceId('Microsoft.Network/networkInterfaces', format('nic-vm-{0}-spoke-two-windows', parameters('location')))]" ] }, { "condition": "[parameters('deployVirtualMachines')]", "type": "Microsoft.Compute/virtualMachines", "apiVersion": "2023-03-01", "name": "[format('vm-{0}-spoke-two-windows', parameters('location'))]", "location": "[parameters('location')]", "properties": { "hardwareProfile": { "vmSize": "Standard_D2s_v3" }, "storageProfile": { "osDisk": { "createOption": "FromImage", "caching": "ReadWrite", "managedDisk": { "storageAccountType": "Premium_LRS" }, "deleteOption": "Delete" }, "imageReference": { "publisher": "MicrosoftWindowsServer", "offer": "WindowsServer", "sku": "2022-datacenter-azure-edition", "version": "latest" }, "dataDisks": [] }, "diagnosticsProfile": { "bootDiagnostics": { "enabled": true, "storageUri": null } }, "networkProfile": { "networkInterfaces": [ { "id": "[resourceId('Microsoft.Network/networkInterfaces', format('nic-vm-{0}-spoke-two-windows', parameters('location')))]", "properties": { "deleteOption": "Delete", "primary": true } } ] }, "osProfile": { "computerName": "examplevm", "adminUsername": "[parameters('adminUsername')]", "adminPassword": "[parameters('adminPassword')]", "windowsConfiguration": { "enableAutomaticUpdates": true, "provisionVMAgent": true, "patchSettings": { "patchMode": "AutomaticByOS", "assessmentMode": "ImageDefault" } } }, "priority": "Regular" }, "dependsOn": [ "[resourceId('Microsoft.Network/networkInterfaces', format('nic-vm-{0}-spoke-two-windows', parameters('location')))]" ], "metadata": { "description": "A basic Windows virtual machine that will be attached to spoke two." } } ] }