Início Rápido: criar um balanceador de carga público para balancear a carga de VMs usando um modelo do ARM

O balanceamento de carga fornece um nível mais alto de disponibilidade e escala com a distribuição das solicitações recebidas entre várias VMs (máquinas virtuais).

Este guia de início rápido mostra como implantar o Standard Load Balancer para balancear a carga de máquinas virtuais.

Diagrama de recursos implantados para um balanceador de carga público padrão.

O uso de um modelo do Resource Manager apresenta menos etapas comparado a outros métodos de implantação.

Um modelo do Azure Resource Manager é um arquivo JSON (JavaScript Object Notation) que define a infraestrutura e a configuração do seu projeto. O modelo usa a sintaxe declarativa. Você descreve a implantação pretendida sem escrever a sequência de comandos de programação para criar a implantação.

Se seu ambiente atender aos pré-requisitos e você estiver familiarizado com o uso de modelos ARM, selecione o botão Implantar no Azure. O modelo será aberto no portal do Azure.

Botão para implantar o modelo do Resource Manager no Azure.

Pré-requisitos

Se você não tiver uma assinatura do Azure, crie uma conta gratuita antes de começar.

Examinar o modelo

O modelo usado neste início rápido é proveniente dos Modelos de Início Rápido do Azure.

Os SKUs do balanceador de carga e do IP público precisam coincidir. Ao criar um Standard Load Balancer, você também precisa criar um endereço IP público padrão configurado como o front-end do Standard Load Balancer. Se você quiser criar um balanceador de carga básico, use este modelo. A Microsoft recomenda usar o SKU padrão para cargas de trabalho de produção.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "metadata": {
    "_generator": {
      "name": "bicep",
      "version": "0.26.54.24096",
      "templateHash": "14680538243429534307"
    }
  },
  "parameters": {
    "projectName": {
      "type": "string",
      "metadata": {
        "description": "Specifies a project name that is used for generating resource names."
      }
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "Specifies the location for all of the resources created by this template."
      }
    },
    "adminUsername": {
      "type": "string",
      "metadata": {
        "description": "Specifies the virtual machine administrator username."
      }
    },
    "adminPassword": {
      "type": "securestring",
      "metadata": {
        "description": "Specifies the virtual machine administrator password."
      }
    },
    "vmSize": {
      "type": "string",
      "defaultValue": "Standard_D2s_v3",
      "metadata": {
        "description": "Size of the virtual machine"
      }
    },
    "OSVersion": {
      "type": "string",
      "defaultValue": "2022-datacenter-azure-edition",
      "allowedValues": [
        "2016-datacenter-gensecond",
        "2016-datacenter-server-core-g2",
        "2016-datacenter-server-core-smalldisk-g2",
        "2016-datacenter-smalldisk-g2",
        "2016-datacenter-with-containers-g2",
        "2016-datacenter-zhcn-g2",
        "2019-datacenter-core-g2",
        "2019-datacenter-core-smalldisk-g2",
        "2019-datacenter-core-with-containers-g2",
        "2019-datacenter-core-with-containers-smalldisk-g2",
        "2019-datacenter-gensecond",
        "2019-datacenter-smalldisk-g2",
        "2019-datacenter-with-containers-g2",
        "2019-datacenter-with-containers-smalldisk-g2",
        "2019-datacenter-zhcn-g2",
        "2022-datacenter-azure-edition",
        "2022-datacenter-azure-edition-core",
        "2022-datacenter-azure-edition-core-smalldisk",
        "2022-datacenter-azure-edition-smalldisk",
        "2022-datacenter-core-g2",
        "2022-datacenter-core-smalldisk-g2",
        "2022-datacenter-g2",
        "2022-datacenter-smalldisk-g2"
      ],
      "metadata": {
        "description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version."
      }
    },
    "imageSku": {
      "type": "string",
      "defaultValue": "vs-2019-ent-latest-win11-n-gen2",
      "allowedValues": [
        "vs-2019-ent-latest-win11-n-gen2",
        "vs-2019-pro-general-win11-m365-gen2",
        "vs-2019-comm-latest-win11-n-gen2",
        "vs-2019-ent-general-win10-m365-gen2",
        "vs-2019-ent-general-win11-m365-gen2",
        "vs-2019-pro-general-win10-m365-gen2"
      ],
      "metadata": {
        "description": "Linux Sku"
      }
    },
    "securityType": {
      "type": "string",
      "defaultValue": "TrustedLaunch",
      "allowedValues": [
        "Standard",
        "TrustedLaunch"
      ],
      "metadata": {
        "description": "Security Type of the Virtual Machine."
      }
    }
  },
  "variables": {
    "securityProfileJson": {
      "uefiSettings": {
        "secureBootEnabled": true,
        "vTpmEnabled": true
      },
      "securityType": "[parameters('securityType')]"
    },
    "lbName": "[format('{0}-lb', parameters('projectName'))]",
    "lbSkuName": "Standard",
    "lbPublicIpAddressName": "[format('{0}-lbPublicIP', parameters('projectName'))]",
    "lbFrontEndName": "LoadBalancerFrontEnd",
    "lbBackendPoolName": "LoadBalancerBackEndPool",
    "lbProbeName": "loadBalancerHealthProbe",
    "nsgName": "[format('{0}-nsg', parameters('projectName'))]",
    "vNetName": "[format('{0}-vnet', parameters('projectName'))]",
    "vNetAddressPrefix": "10.0.0.0/16",
    "vNetSubnetName": "BackendSubnet",
    "vNetSubnetAddressPrefix": "10.0.0.0/24",
    "bastionName": "[format('{0}-bastion', parameters('projectName'))]",
    "bastionSubnetName": "AzureBastionSubnet",
    "vNetBastionSubnetAddressPrefix": "10.0.1.0/24",
    "bastionPublicIPAddressName": "[format('{0}-bastionPublicIP', parameters('projectName'))]",
    "vmStorageAccountType": "Premium_LRS",
    "extensionName": "GuestAttestation",
    "extensionPublisher": "Microsoft.Azure.Security.WindowsAttestation",
    "extensionVersion": "1.0",
    "maaTenantName": "GuestAttestation",
    "maaEndpoint": "[substring('emptyString', 0, 0)]",
    "ascReportingEndpoint": "[substring('emptystring', 0, 0)]",
    "natGatewayName": "[format('{0}-natgateway', parameters('projectName'))]",
    "natGatewayPublicIPAddressName": "[format('{0}-natPublicIP', parameters('projectName'))]"
  },
  "resources": [
    {
      "copy": {
        "name": "project_vm_1_networkInterface",
        "count": "[length(range(0, 3))]"
      },
      "type": "Microsoft.Network/networkInterfaces",
      "apiVersion": "2021-08-01",
      "name": "[format('{0}-vm{1}-networkInterface', parameters('projectName'), add(range(0, 3)[copyIndex()], 1))]",
      "location": "[parameters('location')]",
      "properties": {
        "ipConfigurations": [
          {
            "name": "ipconfig1",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('vNetSubnetName'))]"
              },
              "loadBalancerBackendAddressPools": [
                {
                  "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('lbBackendPoolName'))]"
                }
              ]
            }
          }
        ],
        "networkSecurityGroup": {
          "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/loadBalancers', variables('lbName'))]",
        "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]",
        "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('vNetSubnetName'))]"
      ]
    },
    {
      "copy": {
        "name": "project_vm_1_InstallWebServer",
        "count": "[length(range(0, 3))]"
      },
      "type": "Microsoft.Compute/virtualMachines/extensions",
      "apiVersion": "2021-11-01",
      "name": "[format('{0}-vm{1}/InstallWebServer', parameters('projectName'), add(range(0, 3)[copyIndex()], 1))]",
      "location": "[parameters('location')]",
      "properties": {
        "publisher": "Microsoft.Compute",
        "type": "CustomScriptExtension",
        "typeHandlerVersion": "1.10",
        "autoUpgradeMinorVersion": true,
        "settings": {
          "commandToExecute": "powershell.exe Install-WindowsFeature -name Web-Server -IncludeManagementTools && powershell.exe remove-item 'C:\\inetpub\\wwwroot\\iisstart.htm' && powershell.exe Add-Content -Path 'C:\\inetpub\\wwwroot\\iisstart.htm' -Value $('Hello World from ' + $env:computername)"
        }
      },
      "dependsOn": [
        "project_vm_1"
      ]
    },
    {
      "copy": {
        "name": "project_vm_1",
        "count": "[length(range(1, 3))]"
      },
      "type": "Microsoft.Compute/virtualMachines",
      "apiVersion": "2021-11-01",
      "name": "[format('{0}-vm{1}', parameters('projectName'), range(1, 3)[copyIndex()])]",
      "location": "[parameters('location')]",
      "zones": [
        "[string(range(1, 3)[copyIndex()])]"
      ],
      "properties": {
        "hardwareProfile": {
          "vmSize": "[parameters('vmSize')]"
        },
        "storageProfile": {
          "imageReference": {
            "publisher": "MicrosoftWindowsServer",
            "offer": "WindowsServer",
            "sku": "[parameters('OSVersion')]",
            "version": "latest"
          },
          "osDisk": {
            "createOption": "FromImage",
            "managedDisk": {
              "storageAccountType": "[variables('vmStorageAccountType')]"
            }
          }
        },
        "networkProfile": {
          "networkInterfaces": [
            {
              "id": "[resourceId('Microsoft.Network/networkInterfaces', format('{0}-vm{1}-networkInterface', parameters('projectName'), range(1, 3)[copyIndex()]))]"
            }
          ]
        },
        "osProfile": {
          "computerName": "[format('{0}-vm{1}', parameters('projectName'), range(1, 3)[copyIndex()])]",
          "adminUsername": "[parameters('adminUsername')]",
          "adminPassword": "[parameters('adminPassword')]",
          "windowsConfiguration": {
            "enableAutomaticUpdates": true,
            "provisionVMAgent": true
          }
        },
        "securityProfile": "[if(equals(parameters('securityType'), 'TrustedLaunch'), variables('securityProfileJson'), null())]"
      },
      "dependsOn": [
        "project_vm_1_networkInterface"
      ]
    },
    {
      "copy": {
        "name": "projectName_vm_1_3_GuestAttestation",
        "count": "[length(range(1, 3))]"
      },
      "condition": "[and(equals(parameters('securityType'), 'TrustedLaunch'), and(equals(variables('securityProfileJson').uefiSettings.secureBootEnabled, true()), equals(variables('securityProfileJson').uefiSettings.vTpmEnabled, true())))]",
      "type": "Microsoft.Compute/virtualMachines/extensions",
      "apiVersion": "2022-03-01",
      "name": "[format('{0}-vm{1}/GuestAttestation', parameters('projectName'), range(1, 3)[copyIndex()])]",
      "location": "[parameters('location')]",
      "properties": {
        "publisher": "[variables('extensionPublisher')]",
        "type": "[variables('extensionName')]",
        "typeHandlerVersion": "[variables('extensionVersion')]",
        "autoUpgradeMinorVersion": true,
        "enableAutomaticUpgrade": true,
        "settings": {
          "AttestationConfig": {
            "MaaSettings": {
              "maaEndpoint": "[variables('maaEndpoint')]",
              "maaTenantName": "[variables('maaTenantName')]"
            },
            "AscSettings": {
              "ascReportingEndpoint": "[variables('ascReportingEndpoint')]",
              "ascReportingFrequency": ""
            },
            "useCustomToken": "false",
            "disableAlerts": "false"
          }
        }
      },
      "dependsOn": [
        "project_vm_1"
      ]
    },
    {
      "type": "Microsoft.Network/natGateways",
      "apiVersion": "2021-05-01",
      "name": "[variables('natGatewayName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard"
      },
      "properties": {
        "idleTimeoutInMinutes": 4,
        "publicIpAddresses": [
          {
            "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('natGatewayPublicIPAddressName'))]"
          }
        ]
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses', variables('natGatewayPublicIPAddressName'))]"
      ]
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2021-05-01",
      "name": "[variables('natGatewayPublicIPAddressName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "Standard"
      },
      "properties": {
        "publicIPAddressVersion": "IPv4",
        "publicIPAllocationMethod": "Static",
        "idleTimeoutInMinutes": 4
      }
    },
    {
      "type": "Microsoft.Network/virtualNetworks/subnets",
      "apiVersion": "2021-08-01",
      "name": "[format('{0}/{1}', variables('vNetName'), variables('bastionSubnetName'))]",
      "properties": {
        "addressPrefix": "[variables('vNetBastionSubnetAddressPrefix')]"
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/virtualNetworks', variables('vNetName'))]",
        "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('vNetSubnetName'))]"
      ]
    },
    {
      "type": "Microsoft.Network/virtualNetworks/subnets",
      "apiVersion": "2021-08-01",
      "name": "[format('{0}/{1}', variables('vNetName'), variables('vNetSubnetName'))]",
      "properties": {
        "addressPrefix": "[variables('vNetSubnetAddressPrefix')]",
        "natGateway": {
          "id": "[resourceId('Microsoft.Network/natGateways', variables('natGatewayName'))]"
        }
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/natGateways', variables('natGatewayName'))]",
        "[resourceId('Microsoft.Network/virtualNetworks', variables('vNetName'))]"
      ]
    },
    {
      "type": "Microsoft.Network/bastionHosts",
      "apiVersion": "2021-08-01",
      "name": "[variables('bastionName')]",
      "location": "[parameters('location')]",
      "properties": {
        "ipConfigurations": [
          {
            "name": "IpConf",
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('bastionPublicIPAddressName'))]"
              },
              "subnet": {
                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('bastionSubnetName'))]"
              }
            }
          }
        ]
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses', variables('bastionPublicIPAddressName'))]",
        "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('vNetName'), variables('bastionSubnetName'))]"
      ]
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2021-08-01",
      "name": "[variables('bastionPublicIPAddressName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[variables('lbSkuName')]"
      },
      "properties": {
        "publicIPAddressVersion": "IPv4",
        "publicIPAllocationMethod": "Static"
      }
    },
    {
      "type": "Microsoft.Network/loadBalancers",
      "apiVersion": "2021-08-01",
      "name": "[variables('lbName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[variables('lbSkuName')]"
      },
      "properties": {
        "frontendIPConfigurations": [
          {
            "name": "[variables('lbFrontEndName')]",
            "properties": {
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses', variables('lbPublicIpAddressName'))]"
              }
            }
          }
        ],
        "backendAddressPools": [
          {
            "name": "[variables('lbBackendPoolName')]"
          }
        ],
        "loadBalancingRules": [
          {
            "name": "myHTTPRule",
            "properties": {
              "frontendIPConfiguration": {
                "id": "[resourceId('Microsoft.Network/loadBalancers/frontendIPConfigurations', variables('lbName'), variables('lbFrontEndName'))]"
              },
              "backendAddressPool": {
                "id": "[resourceId('Microsoft.Network/loadBalancers/backendAddressPools', variables('lbName'), variables('lbBackendPoolName'))]"
              },
              "frontendPort": 80,
              "backendPort": 80,
              "enableFloatingIP": false,
              "idleTimeoutInMinutes": 15,
              "protocol": "Tcp",
              "enableTcpReset": true,
              "loadDistribution": "Default",
              "disableOutboundSnat": true,
              "probe": {
                "id": "[resourceId('Microsoft.Network/loadBalancers/probes', variables('lbName'), variables('lbProbeName'))]"
              }
            }
          }
        ],
        "probes": [
          {
            "name": "[variables('lbProbeName')]",
            "properties": {
              "protocol": "Tcp",
              "port": 80,
              "intervalInSeconds": 5,
              "numberOfProbes": 2
            }
          }
        ],
        "outboundRules": []
      },
      "dependsOn": [
        "[resourceId('Microsoft.Network/publicIPAddresses', variables('lbPublicIpAddressName'))]"
      ]
    },
    {
      "type": "Microsoft.Network/publicIPAddresses",
      "apiVersion": "2021-08-01",
      "name": "[variables('lbPublicIpAddressName')]",
      "location": "[parameters('location')]",
      "sku": {
        "name": "[variables('lbSkuName')]"
      },
      "properties": {
        "publicIPAddressVersion": "IPv4",
        "publicIPAllocationMethod": "Static"
      }
    },
    {
      "type": "Microsoft.Network/networkSecurityGroups",
      "apiVersion": "2021-08-01",
      "name": "[variables('nsgName')]",
      "location": "[parameters('location')]",
      "properties": {
        "securityRules": [
          {
            "name": "AllowHTTPInbound",
            "properties": {
              "protocol": "*",
              "sourcePortRange": "*",
              "destinationPortRange": "80",
              "sourceAddressPrefix": "Internet",
              "destinationAddressPrefix": "*",
              "access": "Allow",
              "priority": 100,
              "direction": "Inbound"
            }
          }
        ]
      }
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "apiVersion": "2021-08-01",
      "name": "[variables('vNetName')]",
      "location": "[parameters('location')]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[variables('vNetAddressPrefix')]"
          ]
        }
      }
    }
  ],
  "outputs": {
    "location": {
      "type": "string",
      "value": "[parameters('location')]"
    },
    "name": {
      "type": "string",
      "value": "[variables('lbName')]"
    },
    "resourceGroupName": {
      "type": "string",
      "value": "[resourceGroup().name]"
    },
    "resourceId": {
      "type": "string",
      "value": "[resourceId('Microsoft.Network/loadBalancers', variables('lbName'))]"
    }
  }
}

Vários recursos do Azure foram definidos no modelo:

Importante

Os preços por hora começam a partir do momento em que o Bastion é implantado, independentemente do uso de dados de saída. Para saber mais, confira Preços e SKUs. Se estiver implantando o Bastion como parte de um tutorial ou teste, recomendamos que você exclua esse recurso após terminar de usá-lo.

Para encontrar mais modelos relacionados ao Azure Load Balancer, confira Modelos de Início Rápido do Azure.

Implantar o modelo

  1. Clique em Experimentar no bloco de código a seguir para abrir o Azure Cloud Shell e então acompanhe as instruções para entrar no Azure.

    $projectName = Read-Host -Prompt "Enter a project name with 12 or less letters or numbers that is used to generate Azure resource names"
    $location = Read-Host -Prompt "Enter the location (i.e. centralus)"
    $adminUserName = Read-Host -Prompt "Enter the virtual machine administrator account name"
    $adminPassword = Read-Host -Prompt "Enter the virtual machine administrator password" -AsSecureString
    
    $resourceGroupName = "${projectName}rg"
    $templateUri = "https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/quickstarts/microsoft.network/load-balancer-standard-create/azuredeploy.json"
    
    New-AzResourceGroup -Name $resourceGroupName -Location $location
    New-AzResourceGroupDeployment -ResourceGroupName $resourceGroupName -TemplateUri $templateUri -projectName $projectName -location $location -adminUsername $adminUsername -adminPassword $adminPassword
    
    Write-Host "Press [ENTER] to continue."
    

    Aguarde até ver o prompt do console.

  2. Selecione Copiar no bloco de códigos anterior para copiar o script do PowerShell.

  3. Clique com o botão direito do mouse no painel do console do shell e selecione Colar.

  4. Insira os valores.

    A implantação do modelo cria três zonas de disponibilidade. As zonas de disponibilidade têm suporte apenas em determinadas regiões. Use uma das regiões com suporte. Se você não tiver certeza, insira centralus.

    O nome do grupo de recursos é o nome do projeto com o acréscimo de rg. Você precisará do nome do grupo de recursos na seção a seguir.

A implantação do modelo leva cerca de 10 minutos. Quando tiver concluído, a saída deverá ser semelhante a:

Saída de implantação do PowerShell do modelo do Resource Manager do Azure Standard Load Balancer

O Azure PowerShell é usado para implantar o modelo. Use também o portal do Azure, a CLI do Azure e a API REST. Para saber mais sobre outros métodos de implantação, confira Implantar modelos.

Examinar os recursos implantados

  1. Entre no portal do Azure.

  2. Escolha Grupos de recursos no painel esquerdo.

  3. Selecione o grupo de recursos criado na seção anterior. O nome do grupo de recursos padrão é o nome do projeto com o acréscimo de -rg.

  4. Escolha o balanceador de carga. O nome padrão é o nome do projeto com o acréscimo de -lb.

  5. Copie apenas a parte do endereço IP do endereço IP público e cole-a na barra de endereço do seu navegador.

    IP público do modelo do Resource Manager do Azure Standard Load Balancer

    O navegador exibe a página padrão do servidor da Web dos Serviços de Informações da Internet (IIS).

    Servidor Web do IIS

Para ver o balanceador de carga distribuir o tráfego entre todas as três VMs, você poderá forçar a atualização de seu navegador da Web no computador cliente.

Limpar os recursos

Quando você não precisar mais deles, exclua os seguintes:

  • Resource group
  • Balanceador de carga
  • Recursos relacionados

Acesse o portal do Azure, selecione o grupo de recursos que contém o balanceador de carga e, em seguida, selecione Excluir o grupo de recursos.

Próximas etapas

Neste início rápido, você:

  • Criou uma rede virtual para o balanceador de carga e as máquinas virtuais.
  • Criou um host do Azure Bastion para gerenciamento.
  • Criou um Standard Load Balancer e anexou VMs a ele.
  • Configurou a investigação de integridade e a regra de tráfego do balanceador de carga.
  • Testou o balanceador de carga.

Para saber mais, continue com os tutoriais do Azure Load Balancer.