diff --git a/.azuredevops/modulePipelines/ms.network.loadbalancers.yml b/.azuredevops/modulePipelines/ms.network.loadbalancers.yml index bc5150aee2..27403cb51f 100644 --- a/.azuredevops/modulePipelines/ms.network.loadbalancers.yml +++ b/.azuredevops/modulePipelines/ms.network.loadbalancers.yml @@ -44,6 +44,7 @@ stages: deploymentBlocks: - path: $(modulePath)/.parameters/parameters.json - path: $(modulePath)/.parameters/min.parameters.json + - path: $(modulePath)/.parameters/internal.parameters.json - stage: Publishing displayName: Publish module diff --git a/.azuredevops/platformPipelines/platform.dependencies.yml b/.azuredevops/platformPipelines/platform.dependencies.yml index 88bd93488c..bb09bf9cc7 100644 --- a/.azuredevops/platformPipelines/platform.dependencies.yml +++ b/.azuredevops/platformPipelines/platform.dependencies.yml @@ -884,3 +884,18 @@ stages: - path: $(dependencyPath)/$(resourceType)/parameters/parameters.json templateFilePath: $(templateFilePath) displayName: Default Virtual Machine + + - stage: deploy_lb + displayName: Deploy load balancers + dependsOn: + - deploy_vnet + variables: + resourceType: 'Microsoft.Network/loadBalancers' + templateFilePath: $(modulesPath)/$(resourceType)/deploy.bicep + jobs: + - template: /.azuredevops/pipelineTemplates/jobs.validateModuleDeployment.yml + parameters: + deploymentBlocks: + - path: $(dependencyPath)/$(resourceType)/parameters/internal.parameters.json + templateFilePath: $(templateFilePath) + displayName: Deploy module diff --git a/.github/workflows/ms.network.loadbalancers.yml b/.github/workflows/ms.network.loadbalancers.yml index 15abbd0f24..9ecfb85d10 100644 --- a/.github/workflows/ms.network.loadbalancers.yml +++ b/.github/workflows/ms.network.loadbalancers.yml @@ -81,7 +81,7 @@ jobs: strategy: fail-fast: false matrix: - parameterFilePaths: ['min.parameters.json', 'parameters.json'] + parameterFilePaths: ['min.parameters.json', 'parameters.json', 'internal.parameters.json'] steps: - name: 'Checkout' uses: actions/checkout@v2 diff --git a/.github/workflows/platform.dependencies.yml b/.github/workflows/platform.dependencies.yml index 0654d5e798..fc34d7c707 100644 --- a/.github/workflows/platform.dependencies.yml +++ b/.github/workflows/platform.dependencies.yml @@ -1265,3 +1265,30 @@ jobs: subscriptionId: '${{ secrets.ARM_SUBSCRIPTION_ID }}' managementGroupId: '${{ secrets.ARM_MGMTGROUP_ID }}' removeDeployment: '${{ env.removeDeployment }}' + + job_deploy_lb: + runs-on: ubuntu-20.04 + name: 'Deploy load balancers' + env: + namespace: 'Microsoft.Network\loadBalancers' + needs: + - job_deploy_vnet + strategy: + fail-fast: false + matrix: + parameterFilePaths: ['internal.parameters.json'] + steps: + - name: 'Checkout' + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: 'Deploy module' + uses: ./.github/actions/templates/validateModuleDeployment + with: + templateFilePath: 'arm/${{ env.namespace }}/deploy.bicep' + parameterFilePath: '${{ env.dependencyPath }}/${{ env.namespace }}/parameters/${{ matrix.parameterFilePaths }}' + location: '${{ env.defaultLocation }}' + resourceGroupName: '${{ env.defaultResourceGroupName }}' + subscriptionId: '${{ secrets.ARM_SUBSCRIPTION_ID }}' + managementGroupId: '${{ secrets.ARM_MGMTGROUP_ID }}' + removeDeployment: '${{ env.removeDeployment }}' diff --git a/arm/Microsoft.Network/loadBalancers/.parameters/internal.parameters.json b/arm/Microsoft.Network/loadBalancers/.parameters/internal.parameters.json new file mode 100644 index 0000000000..4c3ffb022f --- /dev/null +++ b/arm/Microsoft.Network/loadBalancers/.parameters/internal.parameters.json @@ -0,0 +1,101 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "value": "<>-az-lb-internal-001" + }, + "loadBalancerSku": { + "value": "Standard" + }, + "frontendIPConfigurations": { + "value": [ + { + "name": "privateIPConfig1", + "subnetId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<>-az-vnet-x-001/subnets/<>-az-subnet-x-001" + } + ] + }, + "backendAddressPools": { + "value": [ + { + "name": "servers" + } + ] + }, + "probes": { + "value": [ + { + "name": "probe1", + "protocol": "Tcp", + "port": "62000", + "intervalInSeconds": 5, + "numberOfProbes": 2 + } + ] + }, + "loadBalancingRules": { + "value": [ + { + "name": "privateIPLBRule1", + "frontendIPConfigurationName": "privateIPConfig1", + "frontendPort": 0, + "backendPort": 0, + "enableFloatingIP": true, + "idleTimeoutInMinutes": 4, + "protocol": "All", + "loadDistribution": "Default", + "probeName": "probe1", + "disableOutboundSnat": true, + "enableTcpReset": false, + "backendAddressPoolName": "servers" + } + ] + }, + "inboundNatRules": { + "value": [ + { + "name": "inboundNatRule1", + "frontendIPConfigurationName": "privateIPConfig1", + "frontendPort": 443, + "backendPort": 443, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 4, + "protocol": "Tcp", + "enableTcpReset": false + }, + { + "name": "inboundNatRule2", + "frontendIPConfigurationName": "privateIPConfig1", + "frontendPort": 3389, + "backendPort": 3389 + } + ] + }, + "roleAssignments": { + "value": [ + { + "roleDefinitionIdOrName": "Reader", + "principalIds": [ + "<>" + ] + } + ] + }, + "diagnosticLogsRetentionInDays": { + "value": 7 + }, + "diagnosticStorageAccountId": { + "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Storage/storageAccounts/adp<>azsax001" + }, + "diagnosticWorkspaceId": { + "value": "/subscriptions/<>/resourcegroups/validation-rg/providers/microsoft.operationalinsights/workspaces/adp-<>-az-law-x-001" + }, + "diagnosticEventHubAuthorizationRuleId": { + "value": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.EventHub/namespaces/adp-<>-az-evhns-x-001/AuthorizationRules/RootManageSharedAccessKey" + }, + "diagnosticEventHubName": { + "value": "adp-<>-az-evh-x-001" + } + } +} diff --git a/arm/Microsoft.Network/loadBalancers/.parameters/min.parameters.json b/arm/Microsoft.Network/loadBalancers/.parameters/min.parameters.json index dac87cc927..695027dc9f 100644 --- a/arm/Microsoft.Network/loadBalancers/.parameters/min.parameters.json +++ b/arm/Microsoft.Network/loadBalancers/.parameters/min.parameters.json @@ -9,9 +9,7 @@ "value": [ { "name": "publicIPConfig1", - "publicIPAddressId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/publicIPAddresses/adp-<>-az-pip-min-lb", - "subnetId": "", - "privateIPAddress": "" + "publicIPAddressId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/publicIPAddresses/adp-<>-az-pip-min-lb" } ] } diff --git a/arm/Microsoft.Network/loadBalancers/.parameters/parameters.json b/arm/Microsoft.Network/loadBalancers/.parameters/parameters.json index 1dd8655e73..8ed7862388 100644 --- a/arm/Microsoft.Network/loadBalancers/.parameters/parameters.json +++ b/arm/Microsoft.Network/loadBalancers/.parameters/parameters.json @@ -9,9 +9,7 @@ "value": [ { "name": "publicIPConfig1", - "publicIPAddressId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/publicIPAddresses/adp-<>-az-pip-x-lb", - "subnetId": "", - "privateIPAddress": "" + "publicIPAddressId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/publicIPAddresses/adp-<>-az-pip-x-lb" } ] }, diff --git a/arm/Microsoft.Network/loadBalancers/deploy.bicep b/arm/Microsoft.Network/loadBalancers/deploy.bicep index fce86c4573..940d9e9e61 100644 --- a/arm/Microsoft.Network/loadBalancers/deploy.bicep +++ b/arm/Microsoft.Network/loadBalancers/deploy.bicep @@ -64,24 +64,24 @@ param inboundNatRules array = [] @description('Optional. The outbound rules.') param outboundRules array = [] -var frontendsSubnets = [for item in frontendIPConfigurations: { - id: item.subnetId -}] -var frontendsPublicIPAddresses = [for item in frontendIPConfigurations: { - id: item.publicIPAddressId -}] -var frontendsObj = { - subnets: frontendsSubnets - publicIPAddresses: frontendsPublicIPAddresses -} - var frontendIPConfigurations_var = [for (frontendIPConfiguration, index) in frontendIPConfigurations: { name: frontendIPConfiguration.name properties: { - subnet: !empty(frontendIPConfiguration.subnetId) ? frontendsObj.subnets[index] : null - publicIPAddress: !empty(frontendIPConfiguration.publicIPAddressId) ? frontendsObj.publicIPAddresses[index] : null - privateIPAddress: !empty(frontendIPConfiguration.privateIPAddress) ? frontendIPConfiguration.privateIPAddress : null - privateIPAllocationMethod: !empty(frontendIPConfiguration.subnetId) ? (empty(frontendIPConfiguration.privateIPAddress) ? 'Dynamic' : 'Static') : null + subnet: contains(frontendIPConfiguration, 'subnetId') && !empty(frontendIPConfiguration.subnetId) ? { + id: frontendIPConfiguration.subnetId + } : null + publicIPAddress: contains(frontendIPConfiguration, 'publicIPAddressId') && !empty(frontendIPConfiguration.publicIPAddressId) ? { + id: frontendIPConfiguration.publicIPAddressId + } : null + privateIPAddress: contains(frontendIPConfiguration, 'privateIPAddress') && !empty(frontendIPConfiguration.privateIPAddress) ? frontendIPConfiguration.privateIPAddress : null + privateIPAddressVersion: contains(frontendIPConfiguration, 'privateIPAddressVersion') ? frontendIPConfiguration.privateIPAddressVersion : 'IPv4' + privateIPAllocationMethod: contains(frontendIPConfiguration, 'subnetId') && !empty(frontendIPConfiguration.subnetId) ? (contains(frontendIPConfiguration, 'privateIPAddress') ? 'Static' : 'Dynamic') : null + gatewayLoadBalancer: contains(frontendIPConfiguration, 'gatewayLoadBalancer') && !empty(frontendIPConfiguration.gatewayLoadBalancer) ? { + id: frontendIPConfiguration.gatewayLoadBalancer + } : null + publicIPPrefix: contains(frontendIPConfiguration, 'publicIPPrefix') && !empty(frontendIPConfiguration.publicIPPrefix) ? { + id: frontendIPConfiguration.publicIPPrefix + } : null } }] @@ -130,13 +130,17 @@ var probes_var = [for probe in probes: { name: probe.name properties: { protocol: contains(probe, 'protocol') ? probe.protocol : 'Tcp' - requestPath: (contains(probe, 'protocol') && toLower(probe.protocol) == 'tcp') ? null : probe.requestPath + requestPath: toLower(probe.protocol) != 'tcp' ? probe.requestPath : null port: contains(probe, 'port') ? probe.port : 80 intervalInSeconds: contains(probe, 'intervalInSeconds') ? probe.intervalInSeconds : 5 numberOfProbes: contains(probe, 'numberOfProbes') ? probe.numberOfProbes : 2 } }] +var backendAddressPoolNames = [for backendAddressPool in backendAddressPools: { + name: backendAddressPool.name +}] + @description('Optional. The name of metrics that will be streamed.') @allowed([ 'AllMetrics' @@ -169,20 +173,20 @@ resource loadBalancer 'Microsoft.Network/loadBalancers@2021-05-01' = { } properties: { frontendIPConfigurations: frontendIPConfigurations_var - backendAddressPools: backendAddressPools loadBalancingRules: loadBalancingRules_var + backendAddressPools: backendAddressPoolNames outboundRules: outboundRules_var probes: probes_var } } module loadBalancer_backendAddressPools 'backendAddressPools/deploy.bicep' = [for (backendAddressPool, index) in backendAddressPools: { - name: '${uniqueString(deployment().name, location)}-LoadBalancer-backendAddressPools-${index}' + name: '${uniqueString(deployment().name, location)}-loadBalancer-backendAddressPools-${index}' params: { loadBalancerName: loadBalancer.name name: backendAddressPool.name - loadBalancerBackendAddresses: contains(backendAddressPool, 'loadBalancerBackendAddresses') ? backendAddressPool.loadBalancerBackendAddresses : [] - tunnelInterfaces: contains(backendAddressPool, 'tunnelInterfaces') ? backendAddressPool.tunnelInterfaces : [] + tunnelInterfaces: contains(backendAddressPool, 'tunnelInterfaces') && !empty(backendAddressPool.tunnelInterfaces) ? backendAddressPool.tunnelInterfaces : [] + loadBalancerBackendAddresses: contains(backendAddressPool, 'loadBalancerBackendAddresses') && !empty(backendAddressPool.loadBalancerBackendAddresses) ? backendAddressPool.loadBalancerBackendAddresses : [] } }] @@ -245,3 +249,6 @@ output resourceId string = loadBalancer.id @description('The resource group the load balancer was deployed into') output resourceGroupName string = resourceGroup().name + +@description('The backend address pools available in the load balancer.') +output backendpools array = loadBalancer.properties.backendAddressPools diff --git a/arm/Microsoft.Network/loadBalancers/readme.md b/arm/Microsoft.Network/loadBalancers/readme.md index 462bf1d2dc..5261b6180b 100644 --- a/arm/Microsoft.Network/loadBalancers/readme.md +++ b/arm/Microsoft.Network/loadBalancers/readme.md @@ -210,6 +210,7 @@ Tag names and tag values can be provided as needed. A tag can be left without a | Output Name | Type | Description | | :-- | :-- | :-- | +| `backendpools` | array | The backend address pools available in the load balancer. | | `name` | string | The name of the load balancer | | `resourceGroupName` | string | The resource group the load balancer was deployed into | | `resourceId` | string | The resource ID of the load balancer | diff --git a/utilities/pipelines/dependencies/Microsoft.Network/loadBalancers/parameters/internal.parameters.json b/utilities/pipelines/dependencies/Microsoft.Network/loadBalancers/parameters/internal.parameters.json new file mode 100644 index 0000000000..341c6db81b --- /dev/null +++ b/utilities/pipelines/dependencies/Microsoft.Network/loadBalancers/parameters/internal.parameters.json @@ -0,0 +1,76 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "value": "adp-<>-az-lb-internal-001" + }, + "loadBalancerSku": { + "value": "Standard" + }, + "frontendIPConfigurations": { + "value": [ + { + "name": "privateIPConfig1", + "subnetId": "/subscriptions/<>/resourceGroups/validation-rg/providers/Microsoft.Network/virtualNetworks/adp-<>-az-vnet-x-001/subnets/<>-az-subnet-x-001" + } + ] + }, + "backendAddressPools": { + "value": [ + { + "name": "servers" + } + ] + }, + "probes": { + "value": [ + { + "name": "probe1", + "protocol": "Tcp", + "port": "62000", + "intervalInSeconds": 5, + "numberOfProbes": 2 + } + ] + }, + "loadBalancingRules": { + "value": [ + { + "name": "privateIPLBRule1", + "frontendIPConfigurationName": "privateIPConfig1", + "frontendPort": 0, + "backendPort": 0, + "enableFloatingIP": true, + "idleTimeoutInMinutes": 4, + "protocol": "All", + "loadDistribution": "Default", + "probeName": "probe1", + "disableOutboundSnat": true, + "enableTcpReset": false, + "backendAddressPoolName": "servers" + } + ] + }, + "inboundNatRules": { + "value": [ + { + "name": "inboundNatRule1", + "frontendIPConfigurationName": "privateIPConfig1", + "frontendPort": 443, + "backendPort": 443, + "enableFloatingIP": false, + "idleTimeoutInMinutes": 4, + "protocol": "Tcp", + "enableTcpReset": false + }, + { + "name": "inboundNatRule2", + "frontendIPConfigurationName": "privateIPConfig1", + "frontendPort": 3389, + "backendPort": 3389 + } + ] + } + } +}