获取应用服务环境内部负载均衡IP

Obtain IP of Internal Load Balancer in App Service Environment

我正在开发 ARM 模板以部署配置有内部负载平衡器 (ILB ASE) 的应用服务环境 v2。有没有办法获取内部负载均衡器从它所连接的 vnet 获取的虚拟 IP (VIP) 地址作为输出?当我在配置后通过 PowerShell 查看 ASE 的属性时,我没有看到 IP 地址或负载平衡器的 属性。

您可以像这样使用输出:

"outputs": {
      "privateIp": {
        "type": "string",
          "value": "[reference(parameters('lbname')).frontendIPConfigurations[0].properties.privateIPAddress]"
      }
    }

这是我的模板,创建一个 Vnet 和一个内部负载均衡器:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "vnetName": {
      "type": "string",
      "defaultValue": "VNet1",
      "metadata": {
        "description": "VNet name"
      }
    },
    "vnetAddressPrefix": {
      "type": "string",
      "defaultValue": "10.0.0.0/16",
      "metadata": {
        "description": "Address prefix"
      }
    },
    "subnet1Prefix": {
      "type": "string",
      "defaultValue": "10.0.0.0/24",
      "metadata": {
        "description": "Subnet 1 Prefix"
      }
    },
    "subnet1Name": {
      "type": "string",
      "defaultValue": "Subnet1",
      "metadata": {
        "description": "Subnet 1 Name"
      }
    },
    "subnet2Prefix": {
      "type": "string",
      "defaultValue": "10.0.1.0/24",
      "metadata": {
        "description": "Subnet 2 Prefix"
      }
    },
    "subnet2Name": {
      "type": "string",
      "defaultValue": "Subnet2",
      "metadata": {
        "description": "Subnet 2 Name"
      }
    },
    "lbname": {
      "defaultValue": "jasonlbb",
      "type": "String"
    }
    },
"variables": {
    "virtualnetworkname" : "vnet1",
    "apiVersion": "2015-06-15",
    "vnetID": "[resourceId('Microsoft.Network/virtualNetworks',variables('virtualnetworkname'))]",
    "subnetRef": "[concat(variables('vnetID'),'/subnets/',parameters('subnet1Name'))]"
},
  "resources": [
    {
      "apiVersion": "2015-06-15",
      "type": "Microsoft.Network/virtualNetworks",
      "name": "[parameters('vnetName')]",
      "location": "[resourceGroup().location]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "[parameters('vnetAddressPrefix')]"
          ]
        },
        "subnets": [
          {
            "name": "[parameters('subnet1Name')]",
            "properties": {
              "addressPrefix": "[parameters('subnet1Prefix')]"
            }
          },
          {
            "name": "[parameters('subnet2Name')]",
            "properties": {
              "addressPrefix": "[parameters('subnet2Prefix')]"
            }
          }
        ]
      }
    },
    {
      "apiVersion": "2015-05-01-preview",
      "type": "Microsoft.Network/loadBalancers",
      "name": "[parameters('lbname')]",
      "location": "[resourceGroup().location]",
      "dependsOn": [
        "[variables('vnetID')]"
      ],
      "properties": {
        "frontendIPConfigurations": [
          {
            "properties": {
              "subnet": {
                "id": "[variables('subnetRef')]"
              },
              "privateIPAllocationMethod": "Dynamic"
            },
            "name": "LoadBalancerFrontend"
          }
        ],
        "backendAddressPools": [
          {
            "name": "BackendPool1"
          }
        ],
        "loadBalancingRules": [
          {
            "properties": {
              "frontendIPConfiguration": {
                "id": "[concat(resourceId('Microsoft.Network/loadBalancers', parameters('lbname')), '/frontendIpConfigurations/LoadBalancerFrontend')]"
              },
              "backendAddressPool": {
                "id": "[concat(resourceId('Microsoft.Network/loadBalancers', parameters('lbname')), '/backendAddressPools/BackendPool1')]"
              },
              "probe": {
                "id": "[concat(resourceId('Microsoft.Network/loadBalancers', parameters('lbname')), '/probes/lbprobe')]"
              },
              "protocol": "Tcp",
              "frontendPort": 80,
              "backendPort": 80,
              "idleTimeoutInMinutes": 15
            },
            "Name": "lbrule"
          }
        ],
        "probes": [
          {
            "properties": {
              "protocol": "Tcp",
              "port": 80,
              "intervalInSeconds": 15,
              "numberOfProbes": 2
            },
            "name": "lbprobe"
          }
        ]
      } 
    }
  ],
  "outputs": {
      "privateIp": {
        "type": "string",
          "value": "[reference(parameters('lbname')).frontendIPConfigurations[0].properties.privateIPAddress]"
      }
    }
}

这是关于结果的屏幕截图:

希望对您有所帮助。

经过大量研究和测试...目前无法将此作为 ARM 模板的输出来执行。以下是可以收集价值的方式:

  1. 通过 Resource Explorer...虽然这对于以编程方式执行此操作不是很有帮助,但它确实帮助我找出了其他两种方法

  2. 使用 PowerShell 查询 management.azure.com API 但您必须发布具有适当权限的应用程序并分配应用程序以在您正在尝试从

  3. 查询资源的订阅
  4. 使用 Azure CLI。这个方法原来是最简单的。

我需要这个值来完全自动化部署位于 ILB ASE 前面的 App Gateway。我使用 Terraform 进行部署自动化,并且我 运行 来自 Azure Cloud Shell 的 Terraform 配置。我使用 shell 脚本开始部署,在该脚本中我动态获取存储状态文件的存储帐户的存储帐户密钥。然后我查询 ILB ASE 以获取 IP 地址并将其设置为一个变量,然后我将其传递到 Terraform

下面是我使用的 shell 脚本的副本:

#!/bin/bash
set -eo pipefail

# The block below will grab the access key for the storage account that is used
# to store state files

subscription_name="<my_subscription_name>"
tfstate_storage_resource_group="terraform-state-rg"
tfstate_storage_account="<name_of_statefile_storage_account>"
subscription_id="my_subscription_id>"
ilbase_rg_name="<name_of_resourcegroup_where_ase_is_deployed>"
ilbase_name="<name_of_ase>"

az account set --subscription "$subscription_name"
tfstate_storage_access_key=$(
  az storage account keys list \
  --resource-group "$tfstate_storage_resource_group" \
  --account-name "$tfstate_storage_account" \
  --query '[0].value' -o tsv
)

echo ""
echo "Terraform state storage account access key:"
echo $tfstate_storage_access_key
echo ""

# The block below will get the Virtual IP of the ASE Internal Load Balancer
# which will be used to create the App GW

ilbase_virtual_ip=$(
  az resource show \
  --ids "/subscriptions/$subscription_id/resourceGroups/$ilbase_rg_name/providers/Microsoft.Web/hostingEnvironments/$ilbase_name/capacities/virtualip" \
  --query "additionalProperties.internalIpAddress"
)

echo ""
echo "ASE internal load balancer IP:"
echo $ilbase_virtual_ip
echo ""

terraform plan \
  -var "tfstate_access_key=$tfstate_storage_access_key" \
  -var "ilbase_virtual_ip=$ilbase_virtual_ip"

如果您使用的是 Terraform,下面是我如何让它工作的。必须使用 Terraform 中的外部数据源以及 Azure CLI 和 jq 来解决 Azure 和 Terraform 外部数据提供程序中的错误。

# As of writing, the ASE ARM deployment don’t return the IP address of the ILB
# ASE. This workaround querys Azure’s API to get the values we need for use
# elsewhere in the script.
# See this 
data “external” “app_service_environment_ilb_ase_ip_address” {
  # This calls the Azure CLI then passes the value to jq to return JSON as a single
  # string so that external provider can parse it properly. Otherwise you get an
  # error. See this bug https://github.com/terraform-providers/terraform-provider-external/issues/23
  program = [“bash”, “-c”, “az resource show --ids ${local.app_service_environment_id}/capacities/virtualip --query ‘{internalIpAddress: internalIpAddress}’ | jq -c”]

  # Explicit dependency on the ASE ARM deployment because this command will fail
  # if that resource isn’t built yet.
  depends_on = [azurerm_template_deployment.ase]
}