如何通过 PowerShell 或模板 link 到 Azure Web 应用程序的 Azure 混合连接?

How can I link an Azure Hybrid Connection to an Azure Web App via PowerShell or a template?

有没有办法以自动方式将混合连接添加到 Azure Web 应用程序? (通过 PowerShell 或资源模板,甚至是对 Azure 的 REST 调用 API?)

目前,我有一个使用资源管理器模板部署的 Azure Web 应用程序,并且一切都已正确配置,但是我无法弄清楚如何 link 将 Web 应用程序添加到现有的模板中的 BizTalk 混合连接或通过 PowerShell(某种自动化方式)。

可以找到用于管理 biztalk 服务的 REST API here 对更多开发者资源(包括 powershell)的引用 https://msdn.microsoft.com/en-us/library/azure/dn832182.aspx.

我没有 ARM 模板的示例,但也许模式可以帮助您 https://github.com/Azure/azure-resource-manager-schemas/blob/master/schemas/2014-04-01/Microsoft.BizTalkServices.json

Azure documentation 声明将 Azure Web 应用程序链接到现有混合连接只能通过门户手动完成:

NOTE: The Web Apps portion of the Hybrid Connections feature is available only in the Azure Portal.

您可以通过资源管理器 (https://resources.azure.com/) 通过 restful "Create" 调用在您向下钻取时手动执行此操作:

订阅 -> 资源组 -> 站点 -> -> 混合连接

我已经复制了资源管理器应用程序发出的调用并将其复制到 Powershell 中。

您需要:

  1. 找到您的订阅租户 ID(google)
  2. 向 AzureAD 注册应用程序
    • 获取该应用程序 ID 和机密
  3. 从资源管理器收集各种常量,例如 Biztalk Uri 和称为实体连接字符串的东西

该脚本使用这些详细信息获取身份验证令牌以从 powershell 调用其余部分 api。然后调用经典的 rest api 将现有的混合连接添加到网站。请注意,这仅适用于以前具有混合连接的网站,因此您无法在没有一些手动工作和从资源管理器记录详细信息的情况下启动全新的环境。

下面是这个脚本的副本,我从 Octopus deploy 调用它,所以所有 #{...} 变量都是从那里提供的。

此脚本将继续调用 api 端点到面向外部的网站,该网站通过混合连接调用内部系统。它将尝试 5 次等待 200 响应。

我在脚本中使用的 Hybrid.ConnectionRestUrl 变量是通过观察资源管理器的调用获得的。它是这样构造的:https://management.azure.com/subscriptions/#{SubscriptionId}/resourceGroups/#{resource-group-name}/providers/Microsoft.Web/sites/#{web-site-name}/hybridconnection/#{web-site-name}?api-version=2015-08-01

无法保证此脚本可以运行多长时间,因为它几乎不是受支持的方法。

    $authUri = "https://login.microsoftonline.com/#{tenant-domain}/oauth2/token"
    $authMethod = "POST"
    $authFormFields = @{resource='https://management.core.windows.net/';client_id='#{AzureAD.ApplicationId}';grant_type='client_credentials';client_secret='#{AzureAD.ApplicationSecret}'}
    $authResponse = Invoke-WebRequest -Uri $authUri -Method $authMethod -Body $authFormFields -ContentType "application/x-www-form-urlencoded" | ConvertFrom-Json

    $authorization = "Bearer " + $authResponse.access_token
    $headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
    $headers.Add("Authorization", $authorization)
    $headers.Add("Content-Type", "application/json")

    $URI = "#{Hybrid.ConnectionRestUrl}"
    $method = "PUT"
    $body = '{ "name" : "#{ExternalAzureService.WebApp}", "location" : "#{App.Location}", "type" : "Microsoft.Web/sites", "properties" : { "entityName" : "#{Hybrid.EntityName}", "entityConnectionString" : "#{Hybrid.EntityConnectionString}", "resourceType" : "", "resourceConnectionString" : "", "hostname" : "#{InternalService.Hostname.Raw}", "port" : 80, "biztalkUri" : "#{Hybrid.BiztalkUri}" } }'

    Write-Output $URI
    Write-Output $body

    Try
    {
        $result = Invoke-RestMethod -Uri $URI -Method $method -Headers $headers -Body $body
    }
    Catch
    {
        Write-Output "Error Occurred "
        $i = 1
        $pingUrl = "http://#{ExternalAzureService.WebApp.HostName}/api/callinternalsystem"
        Write-Output "Ping $i times this url: $pingUrl"
        Do
        {
             Write-Output "Starting Ping call $i"
             $response = Invoke-WebRequest $pingUrl
             If ($response.StatusCode -eq 200) {
                Write-Output "200 returned"
                Break
             }
             $i++
        } While ($i -le 5)
    }
    Write-Output " *********************************** SUCCESS ********************************** "
    Write-Output $result

现在可以使用 Microsoft.Web sites/hybridConnectionNamespaces/relays 模板参考在 Azure 资源管理器 (ARM) 模板中完成此操作。

这是一个简短的示例。

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2018-11-01",
      "resources": [
        {
          "apiVersion": "2019-08-01",
          "dependsOn": [
            "[resourceId('Microsoft.Web/sites', variables('appName'))]"
          ],
          "name": "[concat(variables('relayName'), '/', parameters('hybridConnectionName'))]",
          "properties": {
            "hostname": "[split(json(reference(variables('hybridConnectionResourceId'), '2017-04-01').userMetadata)[0].value, ':')[0]]",
            "port": "[split(json(reference(variables('hybridConnectionResourceId'), '2017-04-01').userMetadata)[0].value, ':')[1]]",
            "relayArmUri": "[variables('hybridConnectionResourceId')]",
            "relayName": "[parameters('hybridConnectionName')]",
            "sendKeyName": "[parameters('hybridConnectionSendKeyName')]",
            "sendKeyValue": "[listkeys(concat(variables('hybridConnectionResourceId'), '/authorizationRules/defaultSender'), '2017-04-01').primaryKey]",
            "serviceBusNamespace": "[variables('relayName')]"
          },
          "tags": {
            "displayName": "hc-some-name"
          },
          "type": "hybridConnectionNamespaces/relays"
        }
      ]
    }
  ]
}