How to create a Azure Function, Function Key when

2019-06-07 14:23发布

问题:

Summary: I'm authoring a function directly in Visual Studio which by design results in readonly function management in the portal. My question is how does one easily create a function key for said webhook?

Context: I'm trying to hook up a generic webhook to Event Grid. This process has led me down a path of needing to trigger a SubscriptionValidationEvent which in turn requires my webhook to provide a "code" on the URL which I'm assuming is a function key.

Also before I get down voted, I'm very well aware that there are multiple variants of this question asked and answered here already. I've tried them all and for one reason or another none of the solutions that involve writing PowerShell against a poorly documented Keys API using Kudu creds seem to work for me.

My hope is that someone knows of a way to solve this with the CLI or even easier, creating a functionName.json file by hand and dropping it in the secrets directory.

Lastly as tempting as it is for me to use the prerelease EventGrid binding, I'm currently unable to push pre-release code in my environment.

回答1:

Found this interesting article on how to manage azure functions keys from Powershell:

  • Manage Azure Functions Keys

Also official documentation (was hard to find this wiki):

  • Key management API

Here are the key points:

  1. Get the publishing credentials
  2. Generate the Kudu API Authorisation token
  3. Call Kudu /api/functions/admin/token to get a JWT that can be used with the Functions Key API
  4. Then you can do whatever you want

Here is my existing script

    Param(
    [string] [Parameter(Mandatory=$true)] $resourceGroupName,
    [string] [Parameter(Mandatory=$true)] $functionappName,
    [string] [Parameter(Mandatory=$true)] $keyname,
    [string] [Parameter()] $slot
)

if (![string]::IsNullOrWhiteSpace($slot)){
    $apiBaseUrl = "https://$functionappName-$slot.scm.azurewebsites.net/api"
    $siteBaseUrl = "https://$functionappName-$slot.azurewebsites.net"
    $resourceType = "Microsoft.Web/sites/slots/config"
    $resourceName = "$functionappName/$slot/publishingcredentials"
}
else {
    $apiBaseUrl = "https://$functionappName.scm.azurewebsites.net/api"
    $siteBaseUrl = "https://$functionappName.azurewebsites.net"
    $resourceType = "Microsoft.Web/sites/config"
    $resourceName = "$functionappName/publishingcredentials"
}

Write-Host "Get the publishing credentials"
$publishingCredentials = Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroupName -ResourceType $resourceType -ResourceName $resourceName -Action list -ApiVersion 2015-08-01 -Force

Write-Host "Generate the Kudu API Authorisation Token"
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $publishingCredentials.Properties.PublishingUserName, $publishingCredentials.Properties.PublishingPassword)))

Write-Host "Call Kudu /api/functions/admin/token to get a JWT that can be used with the Functions Key API"
$jwt = Invoke-RestMethod -Uri "$apiBaseUrl/functions/admin/token" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Method GET

Write-Host "Creates or updates an host key at the specified resource with an auto generated key"
$mynewkey = (Invoke-RestMethod -Uri "$siteBaseUrl/admin/host/keys/$keyname" -Headers @{Authorization=("Bearer {0}" -f $jwt)} -Method Post).value

EDIT

Newly created function apps use TLS 1.2 by default so you need to add this line at the top of the Powershell script:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12