diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index cd68d6e437..788f7d6bcf 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -110,7 +110,7 @@ /avm/res/network/virtual-network/ @Azure/avm-res-network-virtualnetwork-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/network/virtual-network-gateway/ @Azure/avm-res-network-virtualnetworkgateway-module-owners-bicep @Azure/avm-core-team-technical-bicep #/avm/res/network/virtual-wan/ @Azure/avm-res-network-virtualwan-module-owners-bicep @Azure/avm-core-team-technical-bicep -#/avm/res/network/vpn-gateway/ @Azure/avm-res-network-vpngateway-module-owners-bicep @Azure/avm-core-team-technical-bicep +/avm/res/network/vpn-gateway/ @Azure/avm-res-network-vpngateway-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/network/vpn-site/ @Azure/avm-res-network-vpnsite-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/operational-insights/workspace/ @Azure/avm-res-operationalinsights-workspace-module-owners-bicep @Azure/avm-core-team-technical-bicep /avm/res/operations-management/solution/ @Azure/avm-res-operationsmanagement-solution-module-owners-bicep @Azure/avm-core-team-technical-bicep diff --git a/.github/workflows/avm.res.network.vpn-gateway.yml b/.github/workflows/avm.res.network.vpn-gateway.yml new file mode 100644 index 0000000000..b3e8214753 --- /dev/null +++ b/.github/workflows/avm.res.network.vpn-gateway.yml @@ -0,0 +1,83 @@ +name: "avm.res.network.vpn-gateway" + +on: + schedule: + - cron: "0 12 1/15 * *" # Bi-Weekly Test (on 1st & 15th of month) + workflow_dispatch: + inputs: + staticValidation: + type: boolean + description: "Execute static validation" + required: false + default: true + deploymentValidation: + type: boolean + description: "Execute deployment validation" + required: false + default: true + removeDeployment: + type: boolean + description: "Remove deployed module" + required: false + default: true + + push: + branches: + - main + paths: + - ".github/actions/templates/avm-**" + - ".github/workflows/avm.template.module.yml" + - ".github/workflows/avm.res.network.vpn-gateway.yml" + - "avm/res/network/vpn-gateway/**" + - "avm/utilities/pipelines/**" + - "!*/**/README.md" + +env: + modulePath: "avm/res/network/vpn-gateway" + workflowPath: ".github/workflows/avm.res.network.vpn-gateway.yml" + +concurrency: + group: ${{ github.workflow }} + +jobs: + ########################### + # Initialize pipeline # + ########################### + job_initialize_pipeline: + runs-on: ubuntu-20.04 + name: "Initialize pipeline" + steps: + - name: "Checkout" + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: "Set input parameters to output variables" + id: get-workflow-param + uses: ./.github/actions/templates/avm-getWorkflowInput + with: + workflowPath: "${{ env.workflowPath}}" + - name: "Get module test file paths" + id: get-module-test-file-paths + uses: ./.github/actions/templates/avm-getModuleTestFiles + with: + modulePath: "${{ env.modulePath }}" + outputs: + workflowInput: ${{ steps.get-workflow-param.outputs.workflowInput }} + moduleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.moduleTestFilePaths }} + psRuleModuleTestFilePaths: ${{ steps.get-module-test-file-paths.outputs.psRuleModuleTestFilePaths }} + modulePath: "${{ env.modulePath }}" + + ############################## + # Call reusable workflow # + ############################## + call-workflow-passing-data: + name: "Run" + needs: + - job_initialize_pipeline + uses: ./.github/workflows/avm.template.module.yml + with: + workflowInput: "${{ needs.job_initialize_pipeline.outputs.workflowInput }}" + moduleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.moduleTestFilePaths }}" + psRuleModuleTestFilePaths: "${{ needs.job_initialize_pipeline.outputs.psRuleModuleTestFilePaths }}" + modulePath: "${{ needs.job_initialize_pipeline.outputs.modulePath}}" + secrets: inherit diff --git a/avm/res/network/vpn-gateway/README.md b/avm/res/network/vpn-gateway/README.md new file mode 100644 index 0000000000..c137256a33 --- /dev/null +++ b/avm/res/network/vpn-gateway/README.md @@ -0,0 +1,624 @@ +# VPN Gateways `[Microsoft.Network/vpnGateways]` + +This module deploys a VPN Gateway. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Usage examples](#Usage-examples) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Notes](#Notes) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Authorization/locks` | [2020-05-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Authorization/2020-05-01/locks) | +| `Microsoft.Network/vpnGateways` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/vpnGateways) | +| `Microsoft.Network/vpnGateways/natRules` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/vpnGateways/natRules) | +| `Microsoft.Network/vpnGateways/vpnConnections` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/vpnGateways/vpnConnections) | + +## Usage examples + +The following section provides usage examples for the module, which were used to validate and deploy the module successfully. For a full reference, please review the module's test folder in its repository. + +>**Note**: Each example lists all the required parameters first, followed by the rest - each in alphabetical order. + +>**Note**: To reference the module, please use the following syntax `br/public:avm/res/network/vpn-gateway:`. + +- [Using only defaults](#example-1-using-only-defaults) +- [Using large parameter set](#example-2-using-large-parameter-set) +- [WAF-aligned](#example-3-waf-aligned) + +### Example 1: _Using only defaults_ + +This instance deploys the module with the minimum set of required parameters. + + +
+ +via Bicep module + +```bicep +module vpnGateway 'br/public:avm/res/network/vpn-gateway:' = { + name: '${uniqueString(deployment().name, location)}-test-vpngmin' + params: { + // Required parameters + name: 'vpngmin001' + virtualHubResourceId: '' + // Non-required parameters + location: '' + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "vpngmin001" + }, + "virtualHubResourceId": { + "value": "" + }, + // Non-required parameters + "location": { + "value": "" + } + } +} +``` + +
+

+ +### Example 2: _Using large parameter set_ + +This instance deploys the module with most of its features enabled. + + +

+ +via Bicep module + +```bicep +module vpnGateway 'br/public:avm/res/network/vpn-gateway:' = { + name: '${uniqueString(deployment().name, location)}-test-vpngmax' + params: { + // Required parameters + name: 'vpngmax001' + virtualHubResourceId: '' + // Non-required parameters + bgpSettings: { + asn: 65515 + peerWeight: 0 + } + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + natRules: [ + { + externalMappings: [ + { + addressSpace: '192.168.21.0/24' + } + ] + internalMappings: [ + { + addressSpace: '10.4.0.0/24' + } + ] + mode: 'EgressSnat' + name: 'natRule1' + type: 'Static' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + vpnConnections: [ + { + connectionBandwidth: 100 + enableBgp: false + enableInternetSecurity: true + enableRateLimiting: false + name: '' + remoteVpnSiteResourceId: '' + routingWeight: 0 + useLocalAzureIpAddress: false + usePolicyBasedTrafficSelectors: false + vpnConnectionProtocolType: 'IKEv2' + } + ] + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "vpngmax001" + }, + "virtualHubResourceId": { + "value": "" + }, + // Non-required parameters + "bgpSettings": { + "value": { + "asn": 65515, + "peerWeight": 0 + } + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "natRules": { + "value": [ + { + "externalMappings": [ + { + "addressSpace": "192.168.21.0/24" + } + ], + "internalMappings": [ + { + "addressSpace": "10.4.0.0/24" + } + ], + "mode": "EgressSnat", + "name": "natRule1", + "type": "Static" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "vpnConnections": { + "value": [ + { + "connectionBandwidth": 100, + "enableBgp": false, + "enableInternetSecurity": true, + "enableRateLimiting": false, + "name": "", + "remoteVpnSiteResourceId": "", + "routingWeight": 0, + "useLocalAzureIpAddress": false, + "usePolicyBasedTrafficSelectors": false, + "vpnConnectionProtocolType": "IKEv2" + } + ] + } + } +} +``` + +
+

+ +### Example 3: _WAF-aligned_ + +This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework. + + +

+ +via Bicep module + +```bicep +module vpnGateway 'br/public:avm/res/network/vpn-gateway:' = { + name: '${uniqueString(deployment().name, location)}-test-vpngwaf' + params: { + // Required parameters + name: 'vpngwaf001' + virtualHubResourceId: '' + // Non-required parameters + bgpSettings: { + asn: 65515 + peerWeight: 0 + } + location: '' + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + natRules: [ + { + externalMappings: [ + { + addressSpace: '192.168.21.0/24' + } + ] + internalMappings: [ + { + addressSpace: '10.4.0.0/24' + } + ] + mode: 'EgressSnat' + name: 'natRule1' + type: 'Static' + } + ] + tags: { + Environment: 'Non-Prod' + 'hidden-title': 'This is visible in the resource name' + Role: 'DeploymentValidation' + } + vpnConnections: [ + { + connectionBandwidth: 100 + enableBgp: false + enableInternetSecurity: true + enableRateLimiting: false + name: '' + remoteVpnSiteResourceId: '' + routingWeight: 0 + useLocalAzureIpAddress: false + usePolicyBasedTrafficSelectors: false + vpnConnectionProtocolType: 'IKEv2' + } + ] + } +} +``` + +
+

+ +

+ +via JSON Parameter file + +```json +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + // Required parameters + "name": { + "value": "vpngwaf001" + }, + "virtualHubResourceId": { + "value": "" + }, + // Non-required parameters + "bgpSettings": { + "value": { + "asn": 65515, + "peerWeight": 0 + } + }, + "location": { + "value": "" + }, + "lock": { + "value": { + "kind": "CanNotDelete", + "name": "myCustomLockName" + } + }, + "natRules": { + "value": [ + { + "externalMappings": [ + { + "addressSpace": "192.168.21.0/24" + } + ], + "internalMappings": [ + { + "addressSpace": "10.4.0.0/24" + } + ], + "mode": "EgressSnat", + "name": "natRule1", + "type": "Static" + } + ] + }, + "tags": { + "value": { + "Environment": "Non-Prod", + "hidden-title": "This is visible in the resource name", + "Role": "DeploymentValidation" + } + }, + "vpnConnections": { + "value": [ + { + "connectionBandwidth": 100, + "enableBgp": false, + "enableInternetSecurity": true, + "enableRateLimiting": false, + "name": "", + "remoteVpnSiteResourceId": "", + "routingWeight": 0, + "useLocalAzureIpAddress": false, + "usePolicyBasedTrafficSelectors": false, + "vpnConnectionProtocolType": "IKEv2" + } + ] + } + } +} +``` + +
+

+ + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | Name of the VPN gateway. | +| [`virtualHubResourceId`](#parameter-virtualhubresourceid) | string | The resource ID of a virtual Hub to connect to. Note: The virtual Hub and Gateway must be deployed into the same location. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`bgpSettings`](#parameter-bgpsettings) | object | BGP settings details. | +| [`enableBgpRouteTranslationForNat`](#parameter-enablebgproutetranslationfornat) | bool | Enable BGP routes translation for NAT on this VPN gateway. | +| [`enableTelemetry`](#parameter-enabletelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | +| [`isRoutingPreferenceInternet`](#parameter-isroutingpreferenceinternet) | bool | Enable routing preference property for the public IP interface of the VPN gateway. | +| [`location`](#parameter-location) | string | Location where all resources will be created. | +| [`lock`](#parameter-lock) | object | The lock settings of the service. | +| [`natRules`](#parameter-natrules) | array | List of all the NAT Rules to associate with the gateway. | +| [`tags`](#parameter-tags) | object | Tags of the resource. | +| [`vpnConnections`](#parameter-vpnconnections) | array | The VPN connections to create in the VPN gateway. | +| [`vpnGatewayScaleUnit`](#parameter-vpngatewayscaleunit) | int | The scale unit for this VPN gateway. | + +### Parameter: `name` + +Name of the VPN gateway. + +- Required: Yes +- Type: string + +### Parameter: `virtualHubResourceId` + +The resource ID of a virtual Hub to connect to. Note: The virtual Hub and Gateway must be deployed into the same location. + +- Required: Yes +- Type: string + +### Parameter: `bgpSettings` + +BGP settings details. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `enableBgpRouteTranslationForNat` + +Enable BGP routes translation for NAT on this VPN gateway. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `enableTelemetry` + +Enable telemetry via a Globally Unique Identifier (GUID). + +- Required: No +- Type: bool +- Default: `True` + +### Parameter: `isRoutingPreferenceInternet` + +Enable routing preference property for the public IP interface of the VPN gateway. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `location` + +Location where all resources will be created. + +- Required: No +- Type: string +- Default: `[resourceGroup().location]` + +### Parameter: `lock` + +The lock settings of the service. + +- Required: No +- Type: object + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`kind`](#parameter-lockkind) | string | Specify the type of lock. | +| [`name`](#parameter-lockname) | string | Specify the name of lock. | + +### Parameter: `lock.kind` + +Specify the type of lock. + +- Required: No +- Type: string +- Allowed: + ```Bicep + [ + 'CanNotDelete' + 'None' + 'ReadOnly' + ] + ``` + +### Parameter: `lock.name` + +Specify the name of lock. + +- Required: No +- Type: string + +### Parameter: `natRules` + +List of all the NAT Rules to associate with the gateway. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `tags` + +Tags of the resource. + +- Required: No +- Type: object + +### Parameter: `vpnConnections` + +The VPN connections to create in the VPN gateway. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `vpnGatewayScaleUnit` + +The scale unit for this VPN gateway. + +- Required: No +- Type: int +- Default: `2` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `location` | string | The location the resource was deployed into. | +| `name` | string | The name of the VPN gateway. | +| `resourceGroupName` | string | The name of the resource group the VPN gateway was deployed into. | +| `resourceId` | string | The resource ID of the VPN gateway. | + +## Cross-referenced modules + +_None_ + +## Notes + +### Parameter Usage: `bgpSettings` + +

+ +Parameter JSON format + +```json +"bgpSettings": { + "asn": 65515, + "peerWeight": 0, + "bgpPeeringAddresses": [ + { + "ipconfigurationId": "Instance0", + "defaultBgpIpAddresses": [ + "10.0.0.12" + ], + "customBgpIpAddresses": [], + "tunnelIpAddresses": [ + "20.84.35.53", + "10.0.0.4" + ] + }, + { + "ipconfigurationId": "Instance1", + "defaultBgpIpAddresses": [ + "10.0.0.13" + ], + "customBgpIpAddresses": [], + "tunnelIpAddresses": [ + "20.84.34.225", + "10.0.0.5" + ] + } + ] +} +``` + +
+ +
+ +Bicep format + +```bicep +bgpSettings: { + asn: 65515 + peerWeight: 0 + bgpPeeringAddresses: [ + { + ipconfigurationId: 'Instance0' + defaultBgpIpAddresses: [ + '10.0.0.12' + ] + customBgpIpAddresses: [] + tunnelIpAddresses: [ + '20.84.35.53' + '10.0.0.4' + ] + } + { + ipconfigurationId: 'Instance1' + defaultBgpIpAddresses: [ + '10.0.0.13' + ] + customBgpIpAddresses: [] + tunnelIpAddresses: [ + '20.84.34.225' + '10.0.0.5' + ] + } + ] +} +``` + +
+

diff --git a/avm/res/network/vpn-gateway/main.bicep b/avm/res/network/vpn-gateway/main.bicep new file mode 100644 index 0000000000..1b7b5f8f4d --- /dev/null +++ b/avm/res/network/vpn-gateway/main.bicep @@ -0,0 +1,160 @@ +metadata name = 'VPN Gateways' +metadata description = 'This module deploys a VPN Gateway.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. Name of the VPN gateway.') +param name string + +@description('Optional. Location where all resources will be created.') +param location string = resourceGroup().location + +@description('Optional. The VPN connections to create in the VPN gateway.') +param vpnConnections array = [] + +@description('Optional. List of all the NAT Rules to associate with the gateway.') +param natRules array = [] + +@description('Required. The resource ID of a virtual Hub to connect to. Note: The virtual Hub and Gateway must be deployed into the same location.') +param virtualHubResourceId string + +@description('Optional. BGP settings details.') +param bgpSettings object = {} + +@description('Optional. Enable BGP routes translation for NAT on this VPN gateway.') +param enableBgpRouteTranslationForNat bool = false + +@description('Optional. Enable routing preference property for the public IP interface of the VPN gateway.') +param isRoutingPreferenceInternet bool = false + +@description('Optional. The scale unit for this VPN gateway.') +param vpnGatewayScaleUnit int = 2 + +@description('Optional. Tags of the resource.') +param tags object? + +@description('Optional. The lock settings of the service.') +param lock lockType + +@description('Optional. Enable telemetry via a Globally Unique Identifier (GUID).') +param enableTelemetry bool = true + +resource avmTelemetry 'Microsoft.Resources/deployments@2023-07-01' = if (enableTelemetry) { + name: take('46d3xbcp.res.network-vpngateway.${replace('-..--..-', '.', '-')}.${substring(uniqueString(deployment().name, location), 0, 4)}', 64) + properties: { + mode: 'Incremental' + template: { + '$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#' + contentVersion: '1.0.0.0' + resources: [] + outputs: { + telemetry: { + type: 'String' + value: 'For more information, see https://aka.ms/avm/TelemetryInfo' + } + } + } + } +} + +resource vpnGateway 'Microsoft.Network/vpnGateways@2023-04-01' = { + name: name + location: location + tags: tags + properties: { + bgpSettings: bgpSettings + enableBgpRouteTranslationForNat: enableBgpRouteTranslationForNat + isRoutingPreferenceInternet: isRoutingPreferenceInternet + vpnGatewayScaleUnit: vpnGatewayScaleUnit + connections: [for (connection, index) in vpnConnections: { + name: connection.name + properties: { + connectionBandwidth: connection.?connectionBandwidth + enableBgp: connection.?enableBgp + enableInternetSecurity: connection.?enableInternetSecurity + remoteVpnSite: contains(connection, 'remoteVpnSiteResourceId') ? { + id: connection.remoteVpnSiteResourceId + } : null + enableRateLimiting: connection.?enableRateLimiting + routingConfiguration: connection.?routingConfiguration + routingWeight: connection.?routingWeight + sharedKey: connection.?sharedKey + useLocalAzureIpAddress: connection.?useLocalAzureIpAddress + usePolicyBasedTrafficSelectors: connection.?usePolicyBasedTrafficSelectors + vpnConnectionProtocolType: connection.?vpnConnectionProtocolType + ipsecPolicies: connection.?ipsecPolicies + trafficSelectorPolicies: connection.?trafficSelectorPolicies + vpnLinkConnections: connection.?vpnLinkConnections + } + }] + virtualHub: { + id: virtualHubResourceId + } + } +} + +resource vpnGateway_lock 'Microsoft.Authorization/locks@2020-05-01' = if (!empty(lock ?? {}) && lock.?kind != 'None') { + name: lock.?name ?? 'lock-${name}' + properties: { + level: lock.?kind ?? '' + notes: lock.?kind == 'CanNotDelete' ? 'Cannot delete resource or child resources.' : 'Cannot delete or modify the resource or child resources.' + } + scope: vpnGateway +} + +module vpnGateway_natRules 'nat-rule/main.bicep' = [for (natRule, index) in natRules: { + name: '${deployment().name}-NATRule-${index}' + params: { + name: natRule.name + vpnGatewayName: vpnGateway.name + externalMappings: contains(natRule, 'externalMappings') ? natRule.externalMappings : [] + internalMappings: contains(natRule, 'internalMappings') ? natRule.internalMappings : [] + ipConfigurationId: contains(natRule, 'ipConfigurationId') ? natRule.ipConfigurationId : '' + mode: contains(natRule, 'mode') ? natRule.mode : '' + type: contains(natRule, 'type') ? natRule.type : '' + } +}] + +module vpnGateway_vpnConnections 'vpn-connection/main.bicep' = [for (connection, index) in vpnConnections: { + name: '${deployment().name}-Connection-${index}' + params: { + name: connection.name + vpnGatewayName: vpnGateway.name + connectionBandwidth: connection.?connectionBandwidth + enableBgp: connection.?enableBgp + enableInternetSecurity: connection.?enableInternetSecurity + remoteVpnSiteResourceId: connection.?remoteVpnSiteResourceId + enableRateLimiting: connection.?enableRateLimiting + routingConfiguration: connection.?routingConfiguration + routingWeight: connection.?routingWeight + sharedKey: connection.?sharedKey + useLocalAzureIpAddress: connection.?useLocalAzureIpAddress + usePolicyBasedTrafficSelectors: connection.?usePolicyBasedTrafficSelectors + vpnConnectionProtocolType: connection.?vpnConnectionProtocolType + trafficSelectorPolicies: connection.?trafficSelectorPolicies + vpnLinkConnections: connection.?vpnLinkConnections + } +}] + +@description('The name of the VPN gateway.') +output name string = vpnGateway.name + +@description('The resource ID of the VPN gateway.') +output resourceId string = vpnGateway.id + +@description('The name of the resource group the VPN gateway was deployed into.') +output resourceGroupName string = resourceGroup().name + +@description('The location the resource was deployed into.') +output location string = vpnGateway.location + +// =============== // +// Definitions // +// =============== // + +type lockType = { + @description('Optional. Specify the name of lock.') + name: string? + + @description('Optional. Specify the type of lock.') + kind: ('CanNotDelete' | 'ReadOnly' | 'None')? +}? diff --git a/avm/res/network/vpn-gateway/main.json b/avm/res/network/vpn-gateway/main.json new file mode 100644 index 0000000000..8482c23f93 --- /dev/null +++ b/avm/res/network/vpn-gateway/main.json @@ -0,0 +1,614 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "languageVersion": "2.0", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "7269875381422514128" + }, + "name": "VPN Gateways", + "description": "This module deploys a VPN Gateway.", + "owner": "Azure/module-maintainers" + }, + "definitions": { + "lockType": { + "type": "object", + "properties": { + "name": { + "type": "string", + "nullable": true, + "metadata": { + "description": "Optional. Specify the name of lock." + } + }, + "kind": { + "type": "string", + "allowedValues": [ + "CanNotDelete", + "None", + "ReadOnly" + ], + "nullable": true, + "metadata": { + "description": "Optional. Specify the type of lock." + } + } + }, + "nullable": true + } + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. Name of the VPN gateway." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Optional. Location where all resources will be created." + } + }, + "vpnConnections": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The VPN connections to create in the VPN gateway." + } + }, + "natRules": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of all the NAT Rules to associate with the gateway." + } + }, + "virtualHubResourceId": { + "type": "string", + "metadata": { + "description": "Required. The resource ID of a virtual Hub to connect to. Note: The virtual Hub and Gateway must be deployed into the same location." + } + }, + "bgpSettings": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. BGP settings details." + } + }, + "enableBgpRouteTranslationForNat": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable BGP routes translation for NAT on this VPN gateway." + } + }, + "isRoutingPreferenceInternet": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable routing preference property for the public IP interface of the VPN gateway." + } + }, + "vpnGatewayScaleUnit": { + "type": "int", + "defaultValue": 2, + "metadata": { + "description": "Optional. The scale unit for this VPN gateway." + } + }, + "tags": { + "type": "object", + "nullable": true, + "metadata": { + "description": "Optional. Tags of the resource." + } + }, + "lock": { + "$ref": "#/definitions/lockType", + "metadata": { + "description": "Optional. The lock settings of the service." + } + }, + "enableTelemetry": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Optional. Enable telemetry via a Globally Unique Identifier (GUID)." + } + } + }, + "resources": { + "avmTelemetry": { + "condition": "[parameters('enableTelemetry')]", + "type": "Microsoft.Resources/deployments", + "apiVersion": "2023-07-01", + "name": "[take(format('46d3xbcp.res.network-vpngateway.{0}.{1}', replace('-..--..-', '.', '-'), substring(uniqueString(deployment().name, parameters('location')), 0, 4)), 64)]", + "properties": { + "mode": "Incremental", + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "resources": [], + "outputs": { + "telemetry": { + "type": "String", + "value": "For more information, see https://aka.ms/avm/TelemetryInfo" + } + } + } + } + }, + "vpnGateway": { + "type": "Microsoft.Network/vpnGateways", + "apiVersion": "2023-04-01", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "tags": "[parameters('tags')]", + "properties": { + "copy": [ + { + "name": "connections", + "count": "[length(parameters('vpnConnections'))]", + "input": { + "name": "[parameters('vpnConnections')[copyIndex('connections')].name]", + "properties": { + "connectionBandwidth": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'connectionBandwidth')]", + "enableBgp": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'enableBgp')]", + "enableInternetSecurity": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'enableInternetSecurity')]", + "remoteVpnSite": "[if(contains(parameters('vpnConnections')[copyIndex('connections')], 'remoteVpnSiteResourceId'), createObject('id', parameters('vpnConnections')[copyIndex('connections')].remoteVpnSiteResourceId), null())]", + "enableRateLimiting": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'enableRateLimiting')]", + "routingConfiguration": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'routingConfiguration')]", + "routingWeight": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'routingWeight')]", + "sharedKey": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'sharedKey')]", + "useLocalAzureIpAddress": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'useLocalAzureIpAddress')]", + "usePolicyBasedTrafficSelectors": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'usePolicyBasedTrafficSelectors')]", + "vpnConnectionProtocolType": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'vpnConnectionProtocolType')]", + "ipsecPolicies": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'ipsecPolicies')]", + "trafficSelectorPolicies": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'trafficSelectorPolicies')]", + "vpnLinkConnections": "[tryGet(parameters('vpnConnections')[copyIndex('connections')], 'vpnLinkConnections')]" + } + } + } + ], + "bgpSettings": "[parameters('bgpSettings')]", + "enableBgpRouteTranslationForNat": "[parameters('enableBgpRouteTranslationForNat')]", + "isRoutingPreferenceInternet": "[parameters('isRoutingPreferenceInternet')]", + "vpnGatewayScaleUnit": "[parameters('vpnGatewayScaleUnit')]", + "virtualHub": { + "id": "[parameters('virtualHubResourceId')]" + } + } + }, + "vpnGateway_lock": { + "condition": "[and(not(empty(coalesce(parameters('lock'), createObject()))), not(equals(tryGet(parameters('lock'), 'kind'), 'None')))]", + "type": "Microsoft.Authorization/locks", + "apiVersion": "2020-05-01", + "scope": "[format('Microsoft.Network/vpnGateways/{0}', parameters('name'))]", + "name": "[coalesce(tryGet(parameters('lock'), 'name'), format('lock-{0}', parameters('name')))]", + "properties": { + "level": "[coalesce(tryGet(parameters('lock'), 'kind'), '')]", + "notes": "[if(equals(tryGet(parameters('lock'), 'kind'), 'CanNotDelete'), 'Cannot delete resource or child resources.', 'Cannot delete or modify the resource or child resources.')]" + }, + "dependsOn": [ + "vpnGateway" + ] + }, + "vpnGateway_natRules": { + "copy": { + "name": "vpnGateway_natRules", + "count": "[length(parameters('natRules'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-NATRule-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('natRules')[copyIndex()].name]" + }, + "vpnGatewayName": { + "value": "[parameters('name')]" + }, + "externalMappings": "[if(contains(parameters('natRules')[copyIndex()], 'externalMappings'), createObject('value', parameters('natRules')[copyIndex()].externalMappings), createObject('value', createArray()))]", + "internalMappings": "[if(contains(parameters('natRules')[copyIndex()], 'internalMappings'), createObject('value', parameters('natRules')[copyIndex()].internalMappings), createObject('value', createArray()))]", + "ipConfigurationId": "[if(contains(parameters('natRules')[copyIndex()], 'ipConfigurationId'), createObject('value', parameters('natRules')[copyIndex()].ipConfigurationId), createObject('value', ''))]", + "mode": "[if(contains(parameters('natRules')[copyIndex()], 'mode'), createObject('value', parameters('natRules')[copyIndex()].mode), createObject('value', ''))]", + "type": "[if(contains(parameters('natRules')[copyIndex()], 'type'), createObject('value', parameters('natRules')[copyIndex()].type), createObject('value', ''))]" + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "6015512722948676501" + }, + "name": "VPN Gateway NAT Rules", + "description": "This module deploys a VPN Gateway NAT Rule.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the NAT rule." + } + }, + "vpnGatewayName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent VPN gateway this NAT rule is associated with. Required if the template is used in a standalone deployment." + } + }, + "externalMappings": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An address prefix range of destination IPs on the outside network that source IPs will be mapped to. In other words, your post-NAT address prefix range." + } + }, + "internalMappings": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An address prefix range of source IPs on the inside network that will be mapped to a set of external IPs. In other words, your pre-NAT address prefix range." + } + }, + "ipConfigurationId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. A NAT rule must be configured to a specific VPN Gateway instance. This is applicable to Dynamic NAT only. Static NAT rules are automatically applied to both VPN Gateway instances." + } + }, + "mode": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "EgressSnat", + "IngressSnat" + ], + "metadata": { + "description": "Optional. The type of NAT rule for VPN NAT. IngressSnat mode (also known as Ingress Source NAT) is applicable to traffic entering the Azure hub's site-to-site VPN gateway. EgressSnat mode (also known as Egress Source NAT) is applicable to traffic leaving the Azure hub's Site-to-site VPN gateway." + } + }, + "type": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "Dynamic", + "Static" + ], + "metadata": { + "description": "Optional. The type of NAT rule for VPN NAT. Static one-to-one NAT establishes a one-to-one relationship between an internal address and an external address while Dynamic NAT assigns an IP and port based on availability." + } + } + }, + "resources": [ + { + "type": "Microsoft.Network/vpnGateways/natRules", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('vpnGatewayName'), parameters('name'))]", + "properties": { + "externalMappings": "[parameters('externalMappings')]", + "internalMappings": "[parameters('internalMappings')]", + "ipConfigurationId": "[if(not(empty(parameters('ipConfigurationId'))), parameters('ipConfigurationId'), null())]", + "mode": "[if(not(empty(parameters('mode'))), parameters('mode'), null())]", + "type": "[if(not(empty(parameters('type'))), parameters('type'), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the NAT rule." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the NAT rule." + }, + "value": "[resourceId('Microsoft.Network/vpnGateways/natRules', parameters('vpnGatewayName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the NAT rule was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "vpnGateway" + ] + }, + "vpnGateway_vpnConnections": { + "copy": { + "name": "vpnGateway_vpnConnections", + "count": "[length(parameters('vpnConnections'))]" + }, + "type": "Microsoft.Resources/deployments", + "apiVersion": "2022-09-01", + "name": "[format('{0}-Connection-{1}', deployment().name, copyIndex())]", + "properties": { + "expressionEvaluationOptions": { + "scope": "inner" + }, + "mode": "Incremental", + "parameters": { + "name": { + "value": "[parameters('vpnConnections')[copyIndex()].name]" + }, + "vpnGatewayName": { + "value": "[parameters('name')]" + }, + "connectionBandwidth": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'connectionBandwidth')]" + }, + "enableBgp": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'enableBgp')]" + }, + "enableInternetSecurity": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'enableInternetSecurity')]" + }, + "remoteVpnSiteResourceId": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'remoteVpnSiteResourceId')]" + }, + "enableRateLimiting": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'enableRateLimiting')]" + }, + "routingConfiguration": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'routingConfiguration')]" + }, + "routingWeight": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'routingWeight')]" + }, + "sharedKey": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'sharedKey')]" + }, + "useLocalAzureIpAddress": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'useLocalAzureIpAddress')]" + }, + "usePolicyBasedTrafficSelectors": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'usePolicyBasedTrafficSelectors')]" + }, + "vpnConnectionProtocolType": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'vpnConnectionProtocolType')]" + }, + "trafficSelectorPolicies": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'trafficSelectorPolicies')]" + }, + "vpnLinkConnections": { + "value": "[tryGet(parameters('vpnConnections')[copyIndex()], 'vpnLinkConnections')]" + } + }, + "template": { + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "12494321080277868905" + }, + "name": "VPN Gateway VPN Connections", + "description": "This module deploys a VPN Gateway VPN Connection.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the VPN connection." + } + }, + "vpnGatewayName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent VPN gateway this VPN connection is associated with. Required if the template is used in a standalone deployment." + } + }, + "ipsecPolicies": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The IPSec policies to be considered by this connection." + } + }, + "trafficSelectorPolicies": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The traffic selector policies to be considered by this connection." + } + }, + "vpnLinkConnections": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of all VPN site link connections to the gateway." + } + }, + "routingConfiguration": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Routing configuration indicating the associated and propagated route tables for this connection." + } + }, + "usePolicyBasedTrafficSelectors": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable policy-based traffic selectors." + } + }, + "useLocalAzureIpAddress": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Use local Azure IP to initiate connection." + } + }, + "enableRateLimiting": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable rate limiting." + } + }, + "enableInternetSecurity": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable internet security." + } + }, + "enableBgp": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable BGP flag." + } + }, + "routingWeight": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. Routing weight for VPN connection." + } + }, + "connectionBandwidth": { + "type": "int", + "defaultValue": 10, + "metadata": { + "description": "Optional. Expected bandwidth in MBPS." + } + }, + "vpnConnectionProtocolType": { + "type": "string", + "defaultValue": "IKEv2", + "allowedValues": [ + "IKEv1", + "IKEv2" + ], + "metadata": { + "description": "Optional. Gateway connection protocol." + } + }, + "sharedKey": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "Optional. SharedKey for the VPN connection." + } + }, + "remoteVpnSiteResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Reference to a VPN site to link to." + } + } + }, + "resources": [ + { + "type": "Microsoft.Network/vpnGateways/vpnConnections", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('vpnGatewayName'), parameters('name'))]", + "properties": { + "connectionBandwidth": "[parameters('connectionBandwidth')]", + "enableBgp": "[parameters('enableBgp')]", + "enableInternetSecurity": "[parameters('enableInternetSecurity')]", + "enableRateLimiting": "[parameters('enableRateLimiting')]", + "ipsecPolicies": "[parameters('ipsecPolicies')]", + "remoteVpnSite": "[if(not(empty(parameters('remoteVpnSiteResourceId'))), createObject('id', parameters('remoteVpnSiteResourceId')), null())]", + "routingConfiguration": "[parameters('routingConfiguration')]", + "routingWeight": "[parameters('routingWeight')]", + "sharedKey": "[parameters('sharedKey')]", + "trafficSelectorPolicies": "[parameters('trafficSelectorPolicies')]", + "useLocalAzureIpAddress": "[parameters('useLocalAzureIpAddress')]", + "usePolicyBasedTrafficSelectors": "[parameters('usePolicyBasedTrafficSelectors')]", + "vpnConnectionProtocolType": "[parameters('vpnConnectionProtocolType')]", + "vpnLinkConnections": "[parameters('vpnLinkConnections')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the VPN connection." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the VPN connection." + }, + "value": "[resourceId('Microsoft.Network/vpnGateways/vpnConnections', parameters('vpnGatewayName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the VPN connection was deployed into." + }, + "value": "[resourceGroup().name]" + } + } + } + }, + "dependsOn": [ + "vpnGateway" + ] + } + }, + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the VPN gateway." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the VPN gateway." + }, + "value": "[resourceId('Microsoft.Network/vpnGateways', parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the VPN gateway was deployed into." + }, + "value": "[resourceGroup().name]" + }, + "location": { + "type": "string", + "metadata": { + "description": "The location the resource was deployed into." + }, + "value": "[reference('vpnGateway', '2023-04-01', 'full').location]" + } + } +} \ No newline at end of file diff --git a/avm/res/network/vpn-gateway/nat-rule/README.md b/avm/res/network/vpn-gateway/nat-rule/README.md new file mode 100644 index 0000000000..8c38b734ed --- /dev/null +++ b/avm/res/network/vpn-gateway/nat-rule/README.md @@ -0,0 +1,123 @@ +# VPN Gateway NAT Rules `[Microsoft.Network/vpnGateways/natRules]` + +This module deploys a VPN Gateway NAT Rule. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/vpnGateways/natRules` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/vpnGateways/natRules) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the NAT rule. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`vpnGatewayName`](#parameter-vpngatewayname) | string | The name of the parent VPN gateway this NAT rule is associated with. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`externalMappings`](#parameter-externalmappings) | array | An address prefix range of destination IPs on the outside network that source IPs will be mapped to. In other words, your post-NAT address prefix range. | +| [`internalMappings`](#parameter-internalmappings) | array | An address prefix range of source IPs on the inside network that will be mapped to a set of external IPs. In other words, your pre-NAT address prefix range. | +| [`ipConfigurationId`](#parameter-ipconfigurationid) | string | A NAT rule must be configured to a specific VPN Gateway instance. This is applicable to Dynamic NAT only. Static NAT rules are automatically applied to both VPN Gateway instances. | +| [`mode`](#parameter-mode) | string | The type of NAT rule for VPN NAT. IngressSnat mode (also known as Ingress Source NAT) is applicable to traffic entering the Azure hub's site-to-site VPN gateway. EgressSnat mode (also known as Egress Source NAT) is applicable to traffic leaving the Azure hub's Site-to-site VPN gateway. | +| [`type`](#parameter-type) | string | The type of NAT rule for VPN NAT. Static one-to-one NAT establishes a one-to-one relationship between an internal address and an external address while Dynamic NAT assigns an IP and port based on availability. | + +### Parameter: `name` + +The name of the NAT rule. + +- Required: Yes +- Type: string + +### Parameter: `vpnGatewayName` + +The name of the parent VPN gateway this NAT rule is associated with. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `externalMappings` + +An address prefix range of destination IPs on the outside network that source IPs will be mapped to. In other words, your post-NAT address prefix range. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `internalMappings` + +An address prefix range of source IPs on the inside network that will be mapped to a set of external IPs. In other words, your pre-NAT address prefix range. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `ipConfigurationId` + +A NAT rule must be configured to a specific VPN Gateway instance. This is applicable to Dynamic NAT only. Static NAT rules are automatically applied to both VPN Gateway instances. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `mode` + +The type of NAT rule for VPN NAT. IngressSnat mode (also known as Ingress Source NAT) is applicable to traffic entering the Azure hub's site-to-site VPN gateway. EgressSnat mode (also known as Egress Source NAT) is applicable to traffic leaving the Azure hub's Site-to-site VPN gateway. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'EgressSnat' + 'IngressSnat' + ] + ``` + +### Parameter: `type` + +The type of NAT rule for VPN NAT. Static one-to-one NAT establishes a one-to-one relationship between an internal address and an external address while Dynamic NAT assigns an IP and port based on availability. + +- Required: No +- Type: string +- Default: `''` +- Allowed: + ```Bicep + [ + '' + 'Dynamic' + 'Static' + ] + ``` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the NAT rule. | +| `resourceGroupName` | string | The name of the resource group the NAT rule was deployed into. | +| `resourceId` | string | The resource ID of the NAT rule. | + +## Cross-referenced modules + +_None_ diff --git a/avm/res/network/vpn-gateway/nat-rule/main.bicep b/avm/res/network/vpn-gateway/nat-rule/main.bicep new file mode 100644 index 0000000000..cf5b272641 --- /dev/null +++ b/avm/res/network/vpn-gateway/nat-rule/main.bicep @@ -0,0 +1,59 @@ +metadata name = 'VPN Gateway NAT Rules' +metadata description = 'This module deploys a VPN Gateway NAT Rule.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The name of the NAT rule.') +param name string + +@description('Conditional. The name of the parent VPN gateway this NAT rule is associated with. Required if the template is used in a standalone deployment.') +param vpnGatewayName string + +@description('Optional. An address prefix range of destination IPs on the outside network that source IPs will be mapped to. In other words, your post-NAT address prefix range.') +param externalMappings array = [] + +@description('Optional. An address prefix range of source IPs on the inside network that will be mapped to a set of external IPs. In other words, your pre-NAT address prefix range.') +param internalMappings array = [] + +@description('Optional. A NAT rule must be configured to a specific VPN Gateway instance. This is applicable to Dynamic NAT only. Static NAT rules are automatically applied to both VPN Gateway instances.') +param ipConfigurationId string = '' + +@description('Optional. The type of NAT rule for VPN NAT. IngressSnat mode (also known as Ingress Source NAT) is applicable to traffic entering the Azure hub\'s site-to-site VPN gateway. EgressSnat mode (also known as Egress Source NAT) is applicable to traffic leaving the Azure hub\'s Site-to-site VPN gateway.') +@allowed([ + '' + 'EgressSnat' + 'IngressSnat' +]) +param mode string = '' + +@description('Optional. The type of NAT rule for VPN NAT. Static one-to-one NAT establishes a one-to-one relationship between an internal address and an external address while Dynamic NAT assigns an IP and port based on availability.') +@allowed([ + '' + 'Dynamic' + 'Static' +]) +param type string = '' + +resource vpnGateway 'Microsoft.Network/vpnGateways@2023-04-01' existing = { + name: vpnGatewayName +} + +resource natRule 'Microsoft.Network/vpnGateways/natRules@2023-04-01' = { + name: name + parent: vpnGateway + properties: { + externalMappings: externalMappings + internalMappings: internalMappings + ipConfigurationId: !empty(ipConfigurationId) ? ipConfigurationId : null + mode: !empty(mode) ? any(mode) : null + type: !empty(type) ? any(type) : null + } +} + +@description('The name of the NAT rule.') +output name string = natRule.name + +@description('The resource ID of the NAT rule.') +output resourceId string = natRule.id + +@description('The name of the resource group the NAT rule was deployed into.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/vpn-gateway/nat-rule/main.json b/avm/res/network/vpn-gateway/nat-rule/main.json new file mode 100644 index 0000000000..077e369959 --- /dev/null +++ b/avm/res/network/vpn-gateway/nat-rule/main.json @@ -0,0 +1,110 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "6015512722948676501" + }, + "name": "VPN Gateway NAT Rules", + "description": "This module deploys a VPN Gateway NAT Rule.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the NAT rule." + } + }, + "vpnGatewayName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent VPN gateway this NAT rule is associated with. Required if the template is used in a standalone deployment." + } + }, + "externalMappings": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An address prefix range of destination IPs on the outside network that source IPs will be mapped to. In other words, your post-NAT address prefix range." + } + }, + "internalMappings": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. An address prefix range of source IPs on the inside network that will be mapped to a set of external IPs. In other words, your pre-NAT address prefix range." + } + }, + "ipConfigurationId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. A NAT rule must be configured to a specific VPN Gateway instance. This is applicable to Dynamic NAT only. Static NAT rules are automatically applied to both VPN Gateway instances." + } + }, + "mode": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "EgressSnat", + "IngressSnat" + ], + "metadata": { + "description": "Optional. The type of NAT rule for VPN NAT. IngressSnat mode (also known as Ingress Source NAT) is applicable to traffic entering the Azure hub's site-to-site VPN gateway. EgressSnat mode (also known as Egress Source NAT) is applicable to traffic leaving the Azure hub's Site-to-site VPN gateway." + } + }, + "type": { + "type": "string", + "defaultValue": "", + "allowedValues": [ + "", + "Dynamic", + "Static" + ], + "metadata": { + "description": "Optional. The type of NAT rule for VPN NAT. Static one-to-one NAT establishes a one-to-one relationship between an internal address and an external address while Dynamic NAT assigns an IP and port based on availability." + } + } + }, + "resources": [ + { + "type": "Microsoft.Network/vpnGateways/natRules", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('vpnGatewayName'), parameters('name'))]", + "properties": { + "externalMappings": "[parameters('externalMappings')]", + "internalMappings": "[parameters('internalMappings')]", + "ipConfigurationId": "[if(not(empty(parameters('ipConfigurationId'))), parameters('ipConfigurationId'), null())]", + "mode": "[if(not(empty(parameters('mode'))), parameters('mode'), null())]", + "type": "[if(not(empty(parameters('type'))), parameters('type'), null())]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the NAT rule." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the NAT rule." + }, + "value": "[resourceId('Microsoft.Network/vpnGateways/natRules', parameters('vpnGatewayName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the NAT rule was deployed into." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file diff --git a/avm/res/network/vpn-gateway/tests/e2e/defaults/dependencies.bicep b/avm/res/network/vpn-gateway/tests/e2e/defaults/dependencies.bicep new file mode 100644 index 0000000000..3b2439f31c --- /dev/null +++ b/avm/res/network/vpn-gateway/tests/e2e/defaults/dependencies.bicep @@ -0,0 +1,27 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Optional. The name of the Virtual Hub to create.') +param virtualHubName string + +@description('Required. The name of the virtual WAN to create.') +param virtualWANName string + +resource virtualWan 'Microsoft.Network/virtualWans@2023-04-01' = { + name: virtualWANName + location: location +} + +resource virtualHub 'Microsoft.Network/virtualHubs@2022-01-01' = { + name: virtualHubName + location: location + properties: { + virtualWan: { + id: virtualWan.id + } + addressPrefix: '10.1.0.0/16' + } +} + +@description('The resource ID of the created Virtual Hub.') +output virtualHubResourceId string = virtualHub.id diff --git a/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep b/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep new file mode 100644 index 0000000000..6f4e6a45f1 --- /dev/null +++ b/avm/res/network/vpn-gateway/tests/e2e/defaults/main.test.bicep @@ -0,0 +1,59 @@ +targetScope = 'subscription' + +metadata name = 'Using only defaults' +metadata description = 'This instance deploys the module with the minimum set of required parameters.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.vpngateways-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'vpngmin' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + location:location + virtualHubName: 'dep-${namePrefix}-vh-${serviceShort}' + virtualWANName: 'dep-${namePrefix}-vw-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // + +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + location: location + name: '${namePrefix}${serviceShort}001' + virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId + } +}] + + diff --git a/avm/res/network/vpn-gateway/tests/e2e/max/dependencies.bicep b/avm/res/network/vpn-gateway/tests/e2e/max/dependencies.bicep new file mode 100644 index 0000000000..a15b268388 --- /dev/null +++ b/avm/res/network/vpn-gateway/tests/e2e/max/dependencies.bicep @@ -0,0 +1,49 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Optional. The name of the Virtual Hub to create.') +param virtualHubName string + +@description('Optional. The name of the VPN Site to create.') +param vpnSiteName string + +@description('Required. The name of the virtual WAN to create.') +param virtualWANName string + +resource virtualWan 'Microsoft.Network/virtualWans@2023-04-01' = { + name: virtualWANName + location: location +} + +resource virtualHub 'Microsoft.Network/virtualHubs@2022-01-01' = { + name: virtualHubName + location: location + properties: { + virtualWan: { + id: virtualWan.id + } + addressPrefix: '10.0.0.0/24' + } +} + +resource vpnSite 'Microsoft.Network/vpnSites@2023-04-01' = { + name: vpnSiteName + location: location + properties: { + virtualWan: { + id: virtualWan.id + } + addressSpace: { + addressPrefixes: [ + '10.1.0.0/16' + ] + } + ipAddress: '10.1.0.0' + } +} + +@description('The resource ID of the created Virtual Hub.') +output virtualHubResourceId string = virtualHub.id + +@description('The resource ID of the created VPN site.') +output vpnSiteResourceId string = vpnSite.id diff --git a/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep b/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep new file mode 100644 index 0000000000..1b146064ef --- /dev/null +++ b/avm/res/network/vpn-gateway/tests/e2e/max/main.test.bicep @@ -0,0 +1,103 @@ +targetScope = 'subscription' + +metadata name = 'Using large parameter set' +metadata description = 'This instance deploys the module with most of its features enabled.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.vpngateways-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'vpngmax' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + location:location + virtualHubName: 'dep-${namePrefix}-vh-${serviceShort}' + virtualWANName: 'dep-${namePrefix}-vw-${serviceShort}' + vpnSiteName: 'dep-${namePrefix}-vs-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + location: location + name: '${namePrefix}${serviceShort}001' + virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId + bgpSettings: { + asn: 65515 + peerWeight: 0 + } + vpnConnections: [ + { + connectionBandwidth: 100 + enableBgp: false + name: 'Connection-${last(split(nestedDependencies.outputs.vpnSiteResourceId, '/'))}' + remoteVpnSiteResourceId: nestedDependencies.outputs.vpnSiteResourceId + enableInternetSecurity: true + vpnConnectionProtocolType: 'IKEv2' + enableRateLimiting: false + useLocalAzureIpAddress: false + usePolicyBasedTrafficSelectors: false + routingWeight: 0 + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + natRules: [ + { + externalMappings: [ + { + addressSpace: '192.168.21.0/24' + } + ] + internalMappings: [ + { + addressSpace: '10.4.0.0/24' + } + ] + mode: 'EgressSnat' + name: 'natRule1' + type: 'Static' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] + + diff --git a/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/dependencies.bicep b/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/dependencies.bicep new file mode 100644 index 0000000000..a15b268388 --- /dev/null +++ b/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/dependencies.bicep @@ -0,0 +1,49 @@ +@description('Optional. The location to deploy resources to.') +param location string = resourceGroup().location + +@description('Optional. The name of the Virtual Hub to create.') +param virtualHubName string + +@description('Optional. The name of the VPN Site to create.') +param vpnSiteName string + +@description('Required. The name of the virtual WAN to create.') +param virtualWANName string + +resource virtualWan 'Microsoft.Network/virtualWans@2023-04-01' = { + name: virtualWANName + location: location +} + +resource virtualHub 'Microsoft.Network/virtualHubs@2022-01-01' = { + name: virtualHubName + location: location + properties: { + virtualWan: { + id: virtualWan.id + } + addressPrefix: '10.0.0.0/24' + } +} + +resource vpnSite 'Microsoft.Network/vpnSites@2023-04-01' = { + name: vpnSiteName + location: location + properties: { + virtualWan: { + id: virtualWan.id + } + addressSpace: { + addressPrefixes: [ + '10.1.0.0/16' + ] + } + ipAddress: '10.1.0.0' + } +} + +@description('The resource ID of the created Virtual Hub.') +output virtualHubResourceId string = virtualHub.id + +@description('The resource ID of the created VPN site.') +output vpnSiteResourceId string = vpnSite.id diff --git a/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep b/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep new file mode 100644 index 0000000000..0353359af5 --- /dev/null +++ b/avm/res/network/vpn-gateway/tests/e2e/waf-aligned/main.test.bicep @@ -0,0 +1,103 @@ +targetScope = 'subscription' + +metadata name = 'WAF-aligned' +metadata description = 'This instance deploys the module in alignment with the best-practices of the Azure Well-Architected Framework.' + +// ========== // +// Parameters // +// ========== // + +@description('Optional. The name of the resource group to deploy for testing purposes.') +@maxLength(90) +param resourceGroupName string = 'dep-${namePrefix}-network.vpngateways-${serviceShort}-rg' + +@description('Optional. The location to deploy resources to.') +param location string = deployment().location + +@description('Optional. A short identifier for the kind of deployment. Should be kept short to not run into resource-name length-constraints.') +param serviceShort string = 'vpngwaf' + +@description('Optional. A token to inject into the name of each resource.') +param namePrefix string = '#_namePrefix_#' + +// ============ // +// Dependencies // +// ============ // + +// General resources +// ================= +resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = { + name: resourceGroupName + location: location +} + +module nestedDependencies 'dependencies.bicep' = { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-nestedDependencies' + params: { + location:location + virtualHubName: 'dep-${namePrefix}-vh-${serviceShort}' + virtualWANName: 'dep-${namePrefix}-vw-${serviceShort}' + vpnSiteName: 'dep-${namePrefix}-vs-${serviceShort}' + } +} + +// ============== // +// Test Execution // +// ============== // +@batchSize(1) +module testDeployment '../../../main.bicep' = [for iteration in [ 'init', 'idem' ]: { + scope: resourceGroup + name: '${uniqueString(deployment().name, location)}-test-${serviceShort}-${iteration}' + params: { + location: location + name: '${namePrefix}${serviceShort}001' + virtualHubResourceId: nestedDependencies.outputs.virtualHubResourceId + bgpSettings: { + asn: 65515 + peerWeight: 0 + } + vpnConnections: [ + { + connectionBandwidth: 100 + enableBgp: false + name: 'Connection-${last(split(nestedDependencies.outputs.vpnSiteResourceId, '/'))}' + remoteVpnSiteResourceId: nestedDependencies.outputs.vpnSiteResourceId + enableInternetSecurity: true + vpnConnectionProtocolType: 'IKEv2' + enableRateLimiting: false + useLocalAzureIpAddress: false + usePolicyBasedTrafficSelectors: false + routingWeight: 0 + } + ] + lock: { + kind: 'CanNotDelete' + name: 'myCustomLockName' + } + natRules: [ + { + externalMappings: [ + { + addressSpace: '192.168.21.0/24' + } + ] + internalMappings: [ + { + addressSpace: '10.4.0.0/24' + } + ] + mode: 'EgressSnat' + name: 'natRule1' + type: 'Static' + } + ] + tags: { + 'hidden-title': 'This is visible in the resource name' + Environment: 'Non-Prod' + Role: 'DeploymentValidation' + } + } +}] + + diff --git a/avm/res/network/vpn-gateway/version.json b/avm/res/network/vpn-gateway/version.json new file mode 100644 index 0000000000..8def869ede --- /dev/null +++ b/avm/res/network/vpn-gateway/version.json @@ -0,0 +1,7 @@ +{ + "$schema": "https://aka.ms/bicep-registry-module-version-file-schema#", + "version": "0.1", + "pathFilters": [ + "./main.json" + ] +} diff --git a/avm/res/network/vpn-gateway/vpn-connection/README.md b/avm/res/network/vpn-gateway/vpn-connection/README.md new file mode 100644 index 0000000000..520447f305 --- /dev/null +++ b/avm/res/network/vpn-gateway/vpn-connection/README.md @@ -0,0 +1,255 @@ +# VPN Gateway VPN Connections `[Microsoft.Network/vpnGateways/vpnConnections]` + +This module deploys a VPN Gateway VPN Connection. + +## Navigation + +- [Resource Types](#Resource-Types) +- [Parameters](#Parameters) +- [Outputs](#Outputs) +- [Cross-referenced modules](#Cross-referenced-modules) +- [Notes](#Notes) + +## Resource Types + +| Resource Type | API Version | +| :-- | :-- | +| `Microsoft.Network/vpnGateways/vpnConnections` | [2023-04-01](https://learn.microsoft.com/en-us/azure/templates/Microsoft.Network/2023-04-01/vpnGateways/vpnConnections) | + +## Parameters + +**Required parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`name`](#parameter-name) | string | The name of the VPN connection. | + +**Conditional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`vpnGatewayName`](#parameter-vpngatewayname) | string | The name of the parent VPN gateway this VPN connection is associated with. Required if the template is used in a standalone deployment. | + +**Optional parameters** + +| Parameter | Type | Description | +| :-- | :-- | :-- | +| [`connectionBandwidth`](#parameter-connectionbandwidth) | int | Expected bandwidth in MBPS. | +| [`enableBgp`](#parameter-enablebgp) | bool | Enable BGP flag. | +| [`enableInternetSecurity`](#parameter-enableinternetsecurity) | bool | Enable internet security. | +| [`enableRateLimiting`](#parameter-enableratelimiting) | bool | Enable rate limiting. | +| [`ipsecPolicies`](#parameter-ipsecpolicies) | array | The IPSec policies to be considered by this connection. | +| [`remoteVpnSiteResourceId`](#parameter-remotevpnsiteresourceid) | string | Reference to a VPN site to link to. | +| [`routingConfiguration`](#parameter-routingconfiguration) | object | Routing configuration indicating the associated and propagated route tables for this connection. | +| [`routingWeight`](#parameter-routingweight) | int | Routing weight for VPN connection. | +| [`sharedKey`](#parameter-sharedkey) | securestring | SharedKey for the VPN connection. | +| [`trafficSelectorPolicies`](#parameter-trafficselectorpolicies) | array | The traffic selector policies to be considered by this connection. | +| [`useLocalAzureIpAddress`](#parameter-uselocalazureipaddress) | bool | Use local Azure IP to initiate connection. | +| [`usePolicyBasedTrafficSelectors`](#parameter-usepolicybasedtrafficselectors) | bool | Enable policy-based traffic selectors. | +| [`vpnConnectionProtocolType`](#parameter-vpnconnectionprotocoltype) | string | Gateway connection protocol. | +| [`vpnLinkConnections`](#parameter-vpnlinkconnections) | array | List of all VPN site link connections to the gateway. | + +### Parameter: `name` + +The name of the VPN connection. + +- Required: Yes +- Type: string + +### Parameter: `vpnGatewayName` + +The name of the parent VPN gateway this VPN connection is associated with. Required if the template is used in a standalone deployment. + +- Required: Yes +- Type: string + +### Parameter: `connectionBandwidth` + +Expected bandwidth in MBPS. + +- Required: No +- Type: int +- Default: `10` + +### Parameter: `enableBgp` + +Enable BGP flag. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `enableInternetSecurity` + +Enable internet security. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `enableRateLimiting` + +Enable rate limiting. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `ipsecPolicies` + +The IPSec policies to be considered by this connection. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `remoteVpnSiteResourceId` + +Reference to a VPN site to link to. + +- Required: No +- Type: string +- Default: `''` + +### Parameter: `routingConfiguration` + +Routing configuration indicating the associated and propagated route tables for this connection. + +- Required: No +- Type: object +- Default: `{}` + +### Parameter: `routingWeight` + +Routing weight for VPN connection. + +- Required: No +- Type: int +- Default: `0` + +### Parameter: `sharedKey` + +SharedKey for the VPN connection. + +- Required: No +- Type: securestring +- Default: `''` + +### Parameter: `trafficSelectorPolicies` + +The traffic selector policies to be considered by this connection. + +- Required: No +- Type: array +- Default: `[]` + +### Parameter: `useLocalAzureIpAddress` + +Use local Azure IP to initiate connection. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `usePolicyBasedTrafficSelectors` + +Enable policy-based traffic selectors. + +- Required: No +- Type: bool +- Default: `False` + +### Parameter: `vpnConnectionProtocolType` + +Gateway connection protocol. + +- Required: No +- Type: string +- Default: `'IKEv2'` +- Allowed: + ```Bicep + [ + 'IKEv1' + 'IKEv2' + ] + ``` + +### Parameter: `vpnLinkConnections` + +List of all VPN site link connections to the gateway. + +- Required: No +- Type: array +- Default: `[]` + + +## Outputs + +| Output | Type | Description | +| :-- | :-- | :-- | +| `name` | string | The name of the VPN connection. | +| `resourceGroupName` | string | The name of the resource group the VPN connection was deployed into. | +| `resourceId` | string | The resource ID of the VPN connection. | + +## Cross-referenced modules + +_None_ + +## Notes + +### Parameter Usage: `routingConfiguration` + +

+ +Parameter JSON format + +```json +"routingConfiguration": { + "associatedRouteTable": { + "id": "/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/virtualHubs/SampleVirtualHub/hubRouteTables/defaultRouteTable" + }, + "propagatedRouteTables": { + "labels": [ + "default" + ], + "ids": [ + { + "id": "/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/virtualHubs/SampleVirtualHub/hubRouteTables/defaultRouteTable" + } + ] + }, + "vnetRoutes": { + "staticRoutes": [] + } +} +``` + +
+ +
+ +Bicep format + +```bicep +routingConfiguration: { + associatedRouteTable: { + id: '/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/virtualHubs/SampleVirtualHub/hubRouteTables/defaultRouteTable' + } + propagatedRouteTables: { + labels: [ + 'default' + ] + ids: [ + { + id: '/subscriptions/[[subscriptionId]]/resourceGroups/validation-rg/providers/Microsoft.Network/virtualHubs/SampleVirtualHub/hubRouteTables/defaultRouteTable' + } + ] + } + vnetRoutes: { + staticRoutes: [] + } +} +``` + +
+

diff --git a/avm/res/network/vpn-gateway/vpn-connection/main.bicep b/avm/res/network/vpn-gateway/vpn-connection/main.bicep new file mode 100644 index 0000000000..f189154ce4 --- /dev/null +++ b/avm/res/network/vpn-gateway/vpn-connection/main.bicep @@ -0,0 +1,92 @@ +metadata name = 'VPN Gateway VPN Connections' +metadata description = 'This module deploys a VPN Gateway VPN Connection.' +metadata owner = 'Azure/module-maintainers' + +@description('Required. The name of the VPN connection.') +param name string + +@description('Conditional. The name of the parent VPN gateway this VPN connection is associated with. Required if the template is used in a standalone deployment.') +param vpnGatewayName string + +@description('Optional. The IPSec policies to be considered by this connection.') +param ipsecPolicies array = [] + +@description('Optional. The traffic selector policies to be considered by this connection.') +param trafficSelectorPolicies array = [] + +@description('Optional. List of all VPN site link connections to the gateway.') +param vpnLinkConnections array = [] + +@description('Optional. Routing configuration indicating the associated and propagated route tables for this connection.') +param routingConfiguration object = {} + +@description('Optional. Enable policy-based traffic selectors.') +param usePolicyBasedTrafficSelectors bool = false + +@description('Optional. Use local Azure IP to initiate connection.') +param useLocalAzureIpAddress bool = false + +@description('Optional. Enable rate limiting.') +param enableRateLimiting bool = false + +@description('Optional. Enable internet security.') +param enableInternetSecurity bool = false + +@description('Optional. Enable BGP flag.') +param enableBgp bool = false + +@description('Optional. Routing weight for VPN connection.') +param routingWeight int = 0 + +@description('Optional. Expected bandwidth in MBPS.') +param connectionBandwidth int = 10 + +@description('Optional. Gateway connection protocol.') +@allowed([ + 'IKEv1' + 'IKEv2' +]) +param vpnConnectionProtocolType string = 'IKEv2' + +@description('Optional. SharedKey for the VPN connection.') +@secure() +param sharedKey string = '' + +@description('Optional. Reference to a VPN site to link to.') +param remoteVpnSiteResourceId string = '' + +resource vpnGateway 'Microsoft.Network/vpnGateways@2023-04-01' existing = { + name: vpnGatewayName +} + +resource vpnConnection 'Microsoft.Network/vpnGateways/vpnConnections@2023-04-01' = { + name: name + parent: vpnGateway + properties: { + connectionBandwidth: connectionBandwidth + enableBgp: enableBgp + enableInternetSecurity: enableInternetSecurity + enableRateLimiting: enableRateLimiting + ipsecPolicies: ipsecPolicies + remoteVpnSite: !empty(remoteVpnSiteResourceId) ? { + id: remoteVpnSiteResourceId + } : null + routingConfiguration: routingConfiguration + routingWeight: routingWeight + sharedKey: sharedKey + trafficSelectorPolicies: trafficSelectorPolicies + useLocalAzureIpAddress: useLocalAzureIpAddress + usePolicyBasedTrafficSelectors: usePolicyBasedTrafficSelectors + vpnConnectionProtocolType: vpnConnectionProtocolType + vpnLinkConnections: vpnLinkConnections + } +} + +@description('The name of the VPN connection.') +output name string = vpnConnection.name + +@description('The resource ID of the VPN connection.') +output resourceId string = vpnConnection.id + +@description('The name of the resource group the VPN connection was deployed into.') +output resourceGroupName string = resourceGroup().name diff --git a/avm/res/network/vpn-gateway/vpn-connection/main.json b/avm/res/network/vpn-gateway/vpn-connection/main.json new file mode 100644 index 0000000000..c47ab3e50d --- /dev/null +++ b/avm/res/network/vpn-gateway/vpn-connection/main.json @@ -0,0 +1,176 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "metadata": { + "_generator": { + "name": "bicep", + "version": "0.23.1.45101", + "templateHash": "12494321080277868905" + }, + "name": "VPN Gateway VPN Connections", + "description": "This module deploys a VPN Gateway VPN Connection.", + "owner": "Azure/module-maintainers" + }, + "parameters": { + "name": { + "type": "string", + "metadata": { + "description": "Required. The name of the VPN connection." + } + }, + "vpnGatewayName": { + "type": "string", + "metadata": { + "description": "Conditional. The name of the parent VPN gateway this VPN connection is associated with. Required if the template is used in a standalone deployment." + } + }, + "ipsecPolicies": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The IPSec policies to be considered by this connection." + } + }, + "trafficSelectorPolicies": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. The traffic selector policies to be considered by this connection." + } + }, + "vpnLinkConnections": { + "type": "array", + "defaultValue": [], + "metadata": { + "description": "Optional. List of all VPN site link connections to the gateway." + } + }, + "routingConfiguration": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Optional. Routing configuration indicating the associated and propagated route tables for this connection." + } + }, + "usePolicyBasedTrafficSelectors": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable policy-based traffic selectors." + } + }, + "useLocalAzureIpAddress": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Use local Azure IP to initiate connection." + } + }, + "enableRateLimiting": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable rate limiting." + } + }, + "enableInternetSecurity": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable internet security." + } + }, + "enableBgp": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Enable BGP flag." + } + }, + "routingWeight": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Optional. Routing weight for VPN connection." + } + }, + "connectionBandwidth": { + "type": "int", + "defaultValue": 10, + "metadata": { + "description": "Optional. Expected bandwidth in MBPS." + } + }, + "vpnConnectionProtocolType": { + "type": "string", + "defaultValue": "IKEv2", + "allowedValues": [ + "IKEv1", + "IKEv2" + ], + "metadata": { + "description": "Optional. Gateway connection protocol." + } + }, + "sharedKey": { + "type": "securestring", + "defaultValue": "", + "metadata": { + "description": "Optional. SharedKey for the VPN connection." + } + }, + "remoteVpnSiteResourceId": { + "type": "string", + "defaultValue": "", + "metadata": { + "description": "Optional. Reference to a VPN site to link to." + } + } + }, + "resources": [ + { + "type": "Microsoft.Network/vpnGateways/vpnConnections", + "apiVersion": "2023-04-01", + "name": "[format('{0}/{1}', parameters('vpnGatewayName'), parameters('name'))]", + "properties": { + "connectionBandwidth": "[parameters('connectionBandwidth')]", + "enableBgp": "[parameters('enableBgp')]", + "enableInternetSecurity": "[parameters('enableInternetSecurity')]", + "enableRateLimiting": "[parameters('enableRateLimiting')]", + "ipsecPolicies": "[parameters('ipsecPolicies')]", + "remoteVpnSite": "[if(not(empty(parameters('remoteVpnSiteResourceId'))), createObject('id', parameters('remoteVpnSiteResourceId')), null())]", + "routingConfiguration": "[parameters('routingConfiguration')]", + "routingWeight": "[parameters('routingWeight')]", + "sharedKey": "[parameters('sharedKey')]", + "trafficSelectorPolicies": "[parameters('trafficSelectorPolicies')]", + "useLocalAzureIpAddress": "[parameters('useLocalAzureIpAddress')]", + "usePolicyBasedTrafficSelectors": "[parameters('usePolicyBasedTrafficSelectors')]", + "vpnConnectionProtocolType": "[parameters('vpnConnectionProtocolType')]", + "vpnLinkConnections": "[parameters('vpnLinkConnections')]" + } + } + ], + "outputs": { + "name": { + "type": "string", + "metadata": { + "description": "The name of the VPN connection." + }, + "value": "[parameters('name')]" + }, + "resourceId": { + "type": "string", + "metadata": { + "description": "The resource ID of the VPN connection." + }, + "value": "[resourceId('Microsoft.Network/vpnGateways/vpnConnections', parameters('vpnGatewayName'), parameters('name'))]" + }, + "resourceGroupName": { + "type": "string", + "metadata": { + "description": "The name of the resource group the VPN connection was deployed into." + }, + "value": "[resourceGroup().name]" + } + } +} \ No newline at end of file