【问题标题】:Get Webhook url of a Function App in ARM to use for Event Grid Subscription获取 ARM 中函数应用程序的 Webhook url 以用于事件网格订阅
【发布时间】:2019-01-03 08:58:33
【问题描述】:

我正在尝试自动部署我们的环境 vir ARM 模板。我可以部署事件网格和函数应用,但现在我需要在部署函数应用后将函数应用订阅到事件网格。有没有办法获取函数应用的 webhook url

  1. 通过 ARM
  2. 发布管道中的其他一些组件 (Powershell)

一旦我们有了 webhook url,我们就可以通过 ARM 创建订阅 - 但要访问正确的 url 似乎是我们落伍的地方。

请帮忙

【问题讨论】:

  • 您可以使用 REST API 吗?看看下面的链接:stackoverflow.com/questions/50367435/…
  • 好的,谢谢。看过那篇文章 - 如何通过 VSTS 进行其余的通话是我现在卡住的地方。谢谢

标签: azure azure-functions azure-eventgrid


【解决方案1】:

在上面@Van 和@Barrie 的回答的帮助下,我设法完成了这项工作。

此脚本从 azure api 返回 masterkey 和 defaultkey,这使您能够从发布管道中的 functionApp/webApp 创建 eventgrid 订阅。

Van 的脚本(7 月 30 日)适用于 FA 版本 1,但不适用于 FunctionApps V2(api 中有所更改)。在 V2 中使用此脚本时,错误是:

运行时密钥存储在 blob 存储中。此 API 不支持此配置。请将环境变量 AzureWebJobsSecretStorageType 值更改为“文件”。

我修改了这个脚本,现在它适用于 V2:

#DEBUG: when debugging (running in powershell on local pc) you need to comment out the next line by starting the line with #
param($resourceGroupName, $webAppname)

function Get-PublishingProfileCredentials($resourceGroupName, $webAppName){
        $resourceType = "Microsoft.Web/sites/config"
        $resourceName = "$webAppName/publishingcredentials"
        $publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion 2015-08-01 -Force
        return $publishingCredentials
}

function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName){
        $publishingCredentials = Get-PublishingProfileCredentials $resourceGroupName $webAppName
        return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
}

function Get-MasterAPIKey($kuduApiAuthorisationToken, $webAppName ){    
        $bearerToken = Invoke-RestMethod -Uri https://$webAppName.scm.azurewebsites.net/api/functions/admin/token  -Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} 

        $masterkeyResponse = Invoke-RestMethod -Method GET -Headers @{Authorization=("Bearer {0}" -f $bearerToken)} -Uri "https://$webAppName.azurewebsites.net/admin/host/systemkeys/_master" 
        $masterKeyValue = $masterkeyResponse.value
        return $masterKeyValue
}

function Get-HostAPIKeys($kuduApiAuthorisationToken, $webAppName, $masterKey ){
        $apiUrl = "https://$webAppName.azurewebsites.net/admin/host/keys?code=$masterKey"
        $result = Invoke-WebRequest $apiUrl
        return $result
}

#DEBUG: when debugging this in powershell on my local pc I use this to authenticate (remove # to uncomment the next line):
#Login-AzureRmAccount -SubscriptionName "Insert_Subscription_Name_Here"


#DEBUG: when debugging you need to set these parameters:
# $resourceGroupName = "Insert_ResourceGroup_Name_Here"
# $webAppname = "Insert_FunctionApp_Name_Here"


#Auth Header
$kuduToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppName

#MasterKey
$masterKey = Get-MasterAPIKey $kuduToken $webAppName
Write-Host "masterKey = " $masterKey

#Default Key
$result = Get-HostAPIKeys $kuduToken $webAppName $masterkey
$keysCode =  $result.Content | ConvertFrom-Json
Write-Host "default Key = " $keysCode.Keys[0].Value

#Set Return Values:
$faMasterKey = $masterkey
$faDefaultKey = $keysCode.Keys[0].Value

Write-Output ("##vso[task.setvariable variable=fa_MasterKey;]$faMasterKey")
Write-Output ("##vso[task.setvariable variable=fa_DefaultKey;]$faDefaultKey")

这个剧本和范的剧本只有一点点不同。主要区别在于此脚本将在 Azure CLI Functions V2 上运行。更多信息:https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-event-grid

【讨论】:

  • 对于 eventgrid 函数需要更新函数,以便它从“https://$webAppName.azurewebsites.net/admin/host/systemkeys/eventgrid_extension”请求主密钥
  • @NathanHart,这将检索系统密钥,而不是主密钥,不是吗?
【解决方案2】:

您应该能够像这样输出 webhook URL:

"outputs": {       
    "Url": {
        "type": "string",
        "value": "[listsecrets(resourceId('Microsoft.Web/sites/functions', parameters('yourFunctionAppName'), parameters('yourFunctionName')),'2015-08-01').trigger_url]"
    }        
}

这是一个相关的answer

【讨论】:

  • 不,不是这个。我可以找到 trigger_url 但它不能用作 EventGrid webhook 订阅。我们要查找的 URL 是:https://{functionApp}.azurewebsites.net/runtime/webhooks/EventGridExtensionConfig?functionName={function}&code={masterKey}。 masterKey 是我们正在努力解决的问题 - 我遇到了其他关于如何调用 rest api 来获取密钥的帖子。但这在 VSTS 中也不是那么容易实现的
  • 好的,但是如果您将.trigger_url 更改为.key 并自己填充URL,您应该能够获得密钥。然后在 VSTS 中,您可以使用 arm-output 扩展来检索密钥并使用它:marketplace.visualstudio.com/…
  • 不幸的是,这个键不适用于 EventGrid 订阅 - 我只是仔细检查了它,但它不起作用。更糟糕的是 - 如果您在门户中查看功能键(主键或默认键),它与“listsecrets”命令中给出的键不同。在门户中看到的键确实有效。我很沮丧。我在这上面浪费了这么多时间——这方面的文档还不够好。
  • 我认为目前不可能。请在此处打开一个问题github.com/Azure/azure-functions-host/issues
【解决方案3】:

我终于设法让它工作了。最后,我创建了一个提取主密钥(和默认密钥)的 powershell 任务,现在我可以创建我的 eventgrid 订阅。

感谢

这是我使用的 powershell 脚本:

param($resourceGroupName, $webAppname)

function Get-PublishingProfileCredentials($resourceGroupName, $webAppName){

$resourceType = "Microsoft.Web/sites/config"
$resourceName = "$webAppName/publishingcredentials"
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName 
$resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action 
list -ApiVersion 2015-08-01 -Force
return $publishingCredentials   
}

function Get-KuduApiAuthorisationHeaderValue($resourceGroupName, $webAppName){

$publishingCredentials = Get-PublishingProfileCredentials $resourceGroupName $webAppName
return ("Basic {0}" -f [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword))))
}

function Get-MasterAPIKey($kuduApiAuthorisationToken, $webAppName ){

$apiUrl = "https://$webAppName.scm.azurewebsites.net/api/functions/admin/masterkey"

$result = Invoke-RestMethod -Uri $apiUrl -Headers @{"Authorization"=$kuduApiAuthorisationToken;"If-Match"="*"} 

return $result`
}

function Get-HostAPIKeys($kuduApiAuthorisationToken, $webAppName, $masterKey ){

$apiUrl = "https://$webAppName.azurewebsites.net/admin/host/keys?code=$masterKey"

$result = Invoke-WebRequest $apiUrl

return $result`
}

$accessToken = Get-KuduApiAuthorisationHeaderValue $resourceGroupName $webAppname

$adminCode = Get-MasterAPIKey $accessToken $webAppname

Write-Host "masterKey = " $adminCode.Masterkey

$result = Get-HostAPIKeys $accessToken $webAppname $adminCode.Masterkey

$keysCode =  $result.Content | ConvertFrom-Json

Write-Host "default Key = " $keysCode.Keys[0].Value

$faMasterKey = $adminCode.Masterkey
$faDefaultKey = $keysCode.Keys[0].Value

Write-Output ("##vso[task.setvariable variable=fa_MasterKey;]$faMasterKey")
Write-Output ("##vso[task.setvariable variable=fa_DefaultKey;]$faDefaultKey")

这将输出:

  • “fa_MasterKey”变量中的主密钥
  • “fa_DefaultKey”变量中的 defaultKey

(我将尝试创建一个 VSTS 任务并将其发布到市场 - 稍后将详细介绍)

​​>

【讨论】:

  • 这对我们有用,直到 MS 发布了 FA 版本 ~2。功能应用程序现在将密钥存储在 blob 中 - 这导致 Kudu 无法访问密钥,因为它不再存储在 Kudu 中。根据我们相应的机智 MS 有一个临时解决方法来切换密钥存储文件 - 但它只是暂时的。没有关于永久解决方案的消息或继续使用 ~1 版本
【解决方案4】:

我和你在同一条船上,最终得到了这个工作,但花了很多时间来确定正确的端点等。我试图做的是为我的一个资源组创建一个事件订阅,使用az eventgrid event-subscription create。主要问题是--endpoint 参数,因为它上面有一个code 查询字符串参数。通过这样做,我可以很容易地在 Azure 门户中找到它:

  1. 转到我的函数应用
  2. 转到我要添加为事件订阅处理程序的函数
  3. 点击“添加事件网格订阅”
  4. 复制“订阅者端点”值

但是,我想以编程方式完成这一切,但事实证明这很困难。最后,我使用的 bash 脚本是这样的:

#!/bin/bash

appName="myfunctionappname"
resourceGroup="myresourcegroupname"

# First do a KUDU login so we can get a JWT bearer token
user=$(az webapp deployment list-publishing-profiles -n $appName -g $resourceGroup --query "[?publishMethod=='MSDeploy'].userName" -o tsv)
pass=$(az webapp deployment list-publishing-profiles -n $appName -g $resourceGroup --query "[?publishMethod=='MSDeploy'].userPWD" -o tsv)
bearerToken=$(curl -s -u $user:$pass https://$appName.scm.azurewebsites.net/api/functions/admin/token | tr -d '"')

# Creating event grid subscription linked against the endpoint is an admin function so requires a master key
masterKeyResponse=$(curl -s -H "Authorization: Bearer $bearerToken" "https://$appName.azurewebsites.net/admin/host/systemkeys/_master")
masterKey=$(echo $masterKeyResponse | jq '.value' | tr -d '"')

functionName="MyFunctionName"
az eventgrid event-subscription create -g $resourceGroup --name "test-event-subscription" --endpoint "https://$appName.azurewebsites.net/runtime/webhooks/EventGridExtensionConfig?functionName=$functionName&code=$masterKey"

【讨论】:

    【解决方案5】:

    对于 V 2.0 和 3.0 Function Apps,您必须将 AzureWebJobsSecretStorageType 设置为文件:

      "properties": {
        "name": "[variables('functionsName')]",
        "siteConfig": {
          "appSettings": [
            {
              "name": "FUNCTIONS_EXTENSION_VERSION",
              "value": "~3"
            },
            {
              "name": "AzureWebJobsSecretStorageType",
              "value": "files"
            },
    

    然后您可以使用以下方法获取 url 或密钥和 url:

      "outputs": {
        "mValidateConfigurationUrl": {
          "type": "string",
          "value": "[listsecrets(resourceId('Microsoft.Web/sites/functions', variables('functionsName'), 'mValidateConfiguration'),'2015-08-01').trigger_url]"
        },
        "mValidateConfigurationUrlObj": {
          "type": "object",
          "value": "[listsecrets(resourceId('Microsoft.Web/sites/functions', variables('functionsName'), 'mValidateConfiguration'),'2015-08-01')]"
        }
    

    【讨论】:

      猜你喜欢
      • 2019-12-13
      • 1970-01-01
      • 2018-03-18
      • 2021-02-22
      • 1970-01-01
      • 2019-07-16
      • 2020-07-18
      • 1970-01-01
      • 2018-10-10
      相关资源
      最近更新 更多