Подключите веб-приложение Azure к виртуальной сети, используя шаблон ARM

Я пытаюсь создать сценарий настройки группы ресурсов в Azure, в рамках этого мне нужно веб-приложение для связи со службой, работающей на виртуальной машине, через виртуальную сеть.

Я создал шаблон, который, кажется, делает все необходимое для создания соединения, но по какой-то причине соединение не установлено. Просмотр портала показывает, что сайт подключен к виртуальной сети и что сертификаты синхронизированы, но в конфигурации точка-сайт на шлюзе виртуальной сети нет активных подключений.

Однако если я отключаю веб-приложение от виртуальной сети, а затем использую кнопку настройки на портале Azure для повторного подключения к той же виртуальной сети, все работает отлично.

Должно быть что-то, чего мне не хватает в моем шаблоне, но потратив последние несколько часов на поиск, я не могу понять, что

Вот мой ARM шаблон

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
  },
  "variables": {

  },
  "resources": [
    {
      "type": "Microsoft.Network/networkSecurityGroups",
      "name": "[variables('nsgName')]",
      "apiVersion": "2016-03-30",
      "location": "[parameters('location')]",
      "properties": {
        "securityRules": []
      },
      "resources": [ ],
      "dependsOn": [ ]
    },
    {
      "type": "Microsoft.Network/networkSecurityGroups",
      "name": "[variables('infrastructureNsgName')]",
      "apiVersion": "2016-03-30",
      "location": "[parameters('location')]",
      "properties": {
        "securityRules": []
      },
      "resources": [ ],
      "dependsOn": [ ]
    },
    {
      "type": "Microsoft.Network/virtualNetworks",
      "name": "[variables('vnetName')]",
      "apiVersion": "2016-03-30",
      "location": "[parameters('location')]",
      "properties": {
        "addressSpace": {
          "addressPrefixes": [
            "10.1.0.0/16"
          ]
        },
        "subnets": [
          {
            "name": "default",
            "properties": {
              "addressPrefix": "10.1.0.0/17",
              "networkSecurityGroup": {
                "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]"
              }
            }
          },
          {
            "name": "infrastructure",
            "properties": {
              "addressPrefix": "10.1.254.0/24",
              "networkSecurityGroup": {
                "id": "[resourceId('Microsoft.Network/networkSecurityGroups', variables('infrastructureNsgName'))]"
              }
            }
          },
          {
            "name": "GatewaySubnet",
            "properties": {
              "addressPrefix": "10.1.128.0/24"
            }
          }
        ]
      },
      "resources": [ ],
      "dependsOn": [
        "[resourceId('Microsoft.Network/networkSecurityGroups', variables('nsgName'))]",
        "[resourceId('Microsoft.Network/networkSecurityGroups', variables('infrastructureNsgName'))]"
      ]
    },
    {
      "type": "Microsoft.Web/sites",
      "kind": "api",
      "name": "[variables('gatewaySiteName')]",
      "apiVersion": "2015-08-01",
      "location": "[parameters('location')]",
      "properties": {
        "name": "[variables('gatewaySiteName')]",
        "hostNames": [
          "[concat(variables('gatewaySiteName'),'.azurewebsites.net')]"
        ],
        "enabledHostNames": [
          "[concat(variables('gatewaySiteName'),'.azurewebsites.net')]",
          "[concat(variables('gatewaySiteName'),'.scm.azurewebsites.net')]"
        ],
        "hostNameSslStates": [
          {
            "name": "[concat(variables('gatewaySiteName'),'.azurewebsites.net')]",
            "sslState": 0,
            "thumbprint": null,
            "ipBasedSslState": 0
          },
          {
            "name": "[concat(variables('gatewaySiteName'),'.scm.azurewebsites.net')]",
            "sslState": 0,
            "thumbprint": null,
            "ipBasedSslState": 0
          }
        ],
        "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', variables('gatewayServerFarmName'))]"
      },
      "resources": [],
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms', variables('gatewayServerFarmName'))]",
        "[concat('Microsoft.Network/virtualNetworks/', variables('vnetName'))]"
      ]
    },
    {
      "type": "Microsoft.Web/serverfarms",
      "sku": {
        "name": "S1",
        "tier": "Standard",
        "size": "S1",
        "family": "S",
        "capacity": 1
      },
      "kind": "",
      "name": "[variables('gatewayServerFarmName')]",
      "apiVersion": "2015-08-01",
      "location": "[parameters('location')]",
      "properties": {
        "name": "[variables('gatewayServerFarmName')]",
        "numberOfWorkers": 1
      },
      "resources": [ ],
      "dependsOn": [ ]
    },
    {
      "name": "[variables('vnetGatewayIpName')]",
      "type": "Microsoft.Network/publicIPAddresses",
      "location": "[parameters('location')]",
      "apiVersion": "2015-06-15",
      "properties": {
        "publicIPAllocationMethod": "Dynamic"
      }
    },
    {
      "name": "[variables('vnetGatewayName')]",
      "type": "Microsoft.Network/virtualNetworkGateways",
      "location": "[parameters('location')]",
      "apiVersion": "2015-06-15",
      "dependsOn": [
        "[concat('Microsoft.Network/publicIPAddresses/', variables('vnetGatewayIpName'))]",
        "[concat('Microsoft.Network/virtualNetworks/', variables('vnetName'))]"
      ],
      "properties": {
        "ipConfigurations": [
          {
            "properties": {
              "privateIPAllocationMethod": "Dynamic",
              "subnet": {
                "id": "[resourceId('Microsoft.Network/virtualNetworks/subnets',variables('vnetName'),'GatewaySubnet')]"
              },
              "publicIPAddress": {
                "id": "[resourceId('Microsoft.Network/publicIPAddresses',variables('vnetGatewayIpName'))]"
              }
            },
            "name": "vnetGatewayConfig"
          }
        ],
        "gatewayType": "Vpn",
        "vpnType": "RouteBased",
        "enableBgp": false,
        "vpnClientConfiguration": {
          "vpnClientAddressPool": {
            "addressPrefixes": [
              "172.16.201.0/24"
            ]
          },
          "vpnClientRootCertificates": [
            {
              "name": "AppServiceCertificate.cer",
              "properties": {
                "PublicCertData": "[reference(concat('Microsoft.Web/sites/', variables('gatewaySiteName'), '/virtualNetworkConnections/virtualNetworkConnections')).certBlob]"
              }
            }
          ]
        }
      }
    },
    {
      "name": "[variables('gatewayVnetConnectionName')]",
      "type": "Microsoft.Web/sites/virtualNetworkConnections",
      "location": "[parameters('location')]",
      "apiVersion": "2015-08-01",
      "dependsOn": [
        "[concat('Microsoft.Web/sites/', variables('gatewaySiteName'))]",
        "[concat('Microsoft.Network/virtualNetworks/', variables('vnetName'))]"
      ],
      "properties": {
        "vnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks', variables('vnetName'))]"
      }
    }
  ]
}

2 ответа

Я никогда не смог бы сделать это с помощью одного только шаблона ARM. Однако, если вы можете провести еще одну команду PowerShell после создания, она прекрасно работает:

# Set VNET Integration for Web App

$ResourceGroup = "WeMadeThatInWestEuropeDidntWe"
$WebApp = "LearningMomentsInProduction"
$PropertiesObject = @{
       vnetName = "JimAreYouSureThisIsTheStagingVNET";
}

Set-AzureRmResource -PropertyObject $PropertiesObject `
                    -ResourceGroupName $ResourceGroup `
                    -ResourceType Microsoft.Web/sites/config `
                    -ResourceName $WebApp/web `
                    -ApiVersion 2015-08-01 -Force -Verbose |
                        Select -expand Properties |
                        Select VnetName

# Expected output:
#
#  VnetName                                   
#  --------                                   
#  JimAreYouSureThisIsTheStagingVNET
#
# At this point your Web App is hooked up to the VNET

РЕДАКТИРОВАТЬ:

Это не делает то, что я думал, что делает.

Чтобы повторно синхронизировать сертификаты "точка-сайт":

$ResourceGroup = "WeMadeThatInWestEuropeDidntWe"
# VNET Name or Gateway name, try with gateway name!
$vnetName = "JimAreYouSureThisIsTheStagingVNET";

$PropertiesObject = @{
  resyncRequired = "true"
}

Set-AzureRmResource -PropertyObject $PropertiesObject -ResourceGroupName $ResourceGroup `
                    -ResourceType Microsoft.Web/sites/virtualNetworkConnections `
                    -ResourceName $VnetName
                    -ApiVersion 2015-08-01 `
                    -Force -Verbose

Хороший способ найти правильные настройки после того, как вы настроили их правильно на портале Azure, - это заглянуть под капот. Это можно сделать, просмотрев https://resources.azure.com/ или проводник ресурсов на портале Azure.

Здесь вы найдете json в том состоянии, в котором он работает, и сравните их с вашим шаблоном ARM. Настройки не могут быть скопированы 1 на 1, но это близко. Удачи в поиске разницы.

Вы помещаете его как вложенный ресурс на сайте:

(Предполагается, что все находится в одной подписке и группе ресурсов, иначе вам нужно будет изменить параметры для resourceId())

"properties":[],
"resources": [
                {
                    "name": "[concat(variables('webappSiteName'), '/', variables('webappSiteName'), '-vnetIntegration')]",
                    "type": "Microsoft.Web/sites/virtualNetworkConnections",
                    "apiVersion": "2018-02-01",
                    "properties": {
                        "vnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks', 'vnetname')]"
                    },
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('webappSiteName'))]"
                    ]
                }
]

Как минимум это то, что требуется, однако Microsoft.Web/sites/virtualNetworkConnections ресурс должен иметь предоставленные данные сертификата клиента (которые должны быть настроены в P2S-соединении в вашем шлюзе vnet), что является свойством certBlob что согласно документации:

Большой двоичный объект файла сертификата (.cer), содержащий открытый ключ закрытого ключа, используемый для аутентификации VPN-соединения типа "точка-сеть".

Если этот подузел работал у меня, если вы не укажете информацию о сертификате, ваше веб-приложение (-а) покажет ошибку, говоря, что сертификаты не синхронизированы.

Обратитесь к virtualNetworkConnections документация онлайн

Надеюсь это поможет.

Другие вопросы по тегам