Create an Event Grid Subscription to an Azure Function V2

Last weeks I was developing an Azure Function with an Event Grid Trigger using the new V2 Runtime (in .Net Core) and because the changes from V1 some things where not working anymore as expected.

In this post I will show you how to create an Event Grid subscription to an Azure Function with an Event Grid Trigger in the V2 Runtime.

Nuget

One of the changes in the V2 runtime is that now the functions bindings (HTTP, Storage Queue, Timer, Event Grid etc..) are now provided in separate Nuget packages, called “binding extensions”.

For an Event Grid Trigger we need the Microsoft.Azure.WebJobs.Extensions.EventGrid Nuget package (at least version 2.0.0 or higher). If you create an Azure Function with an Event Grid trigger from the Portal the UI will alert you that you need this extension and it will be installed for you behind the scenes.

egextensionnotinstalled

It’s important to install the package because it has to be present in the bin directory of the function app otherwise the following steps will not work.

If you are using a precompiled C# function after installing the Nuget package you have to publish the Function in Azure.

SystemKey

To create an Event Grid Subscription to the function we need a SystemKey, the endpoints to get this keys are changed in V2, unfortunately at the moment of writing the documentation has not been updated. I have created an issue for this and Microsoft is working to update the docs.

The right endpoint to get the SystemKey is:

http://{functionappname}.azurewebsites.net/admin/host/systemkeys/eventgrid_extension?code={masterkey}

Where the MasterKey is the “_master” key of your function app.

App Setting

Before we can do the call to get the SystemKey we need to set/add the AzureWebJobsSecretStorageType app setting to ‘files‘, because this issue due to changes in the Azure Function V2 Runtime.

Deployment

After all the previous steps are done we can now generate the SystemKey and use it to create an Event Grid Subscription to the function endpoint.

I have created a Gist with a PowerShell script to do all the work needed:


#
#.SYNOPSIS
# Creates Event Grid Subscription.
#.DESCRIPTION
# Creates an Event Grid Subscription (Topic type: Azure Subscription) to a Function App V2
#.OUTPUTS
# Progress messages
#
Param(
[string]$ResourceGroupName,
[string]$FunctionAppName,
[string]$FunctionName,
[string]$EventGridSubscriptionName,
[string]$FunctionUrl="azurewebsites.net"
)
Function Get-AppServicePublishingCredentials($resourceGroupName, $functionAppName)
{
$resourceType = "Microsoft.Web/sites/config"
$resourceName = "$functionAppName/publishingcredentials"
$publishingCredentials = Invoke-AzureRmResourceAction ResourceGroupName $resourceGroupName ResourceType $resourceType ResourceName $resourceName Action list ApiVersion 20150801 Force
return $publishingCredentials
}
function Get-EncodedCredentials($resourceGroupName, $functionAppName)
{
$publishingCredentials = Get-AppServicePublishingCredentials $resourceGroupName $functionAppName
$pair = "$($publishingCredentials.Properties.PublishingUserName):$($publishingCredentials.Properties.PublishingPassword)"
$encodedCreds = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($pair))
return $encodedCreds
}
function Get-MasterAPIKey($encodedCreds, $functionAppName)
{
$result = Invoke-RestMethod Uri "https://$functionAppName.scm.$FunctionUrl/api/functions/admin/masterkey" Headers @{Authorization=("Basic {0}" -f $encodedCreds)}
return $result.masterKey
}
function Get-EventGridExtensionSystemKey($functionAppName, $masterKey)
{
$result = Invoke-RestMethod ("https://$functionAppName.$FunctionUrl/admin/host/systemkeys/eventgrid_extension?code=" + $masterKey)
return $result.value
}
function Create-EventGridSubscription($functionAppName, $functionName, $systemKey, $eventGridSubscriptionName)
{
$functionEndpointURL = "https://" + $functionAppName + ".$FunctionUrl/runtime/webhooks/eventgrid?functionName=" + $functionName + "&code=" + $systemkey +""
$subscriptionID=(Get-AzureRmContext).Subscription.Id
New-AzureRmDeployment `
Name egdeployment `
Location westeurope `
TemplateUri https://raw.githubusercontent.com/Azure/azurequickstarttemplates/master/101eventgridresourceeventstowebhook/azuredeploy.json `
eventSubName $eventGridSubscriptionName `
endpoint $functionEndpointURL
}
# Get the Encoded Publish Credentials, so we can call Kudu API to get master key
$encodedCreds = Get-EncodedCredentials $ResourceGroupName $FunctionAppName
Write-Output "This is the encodedCreds: $encodedCreds"
# Get master key to call Event Grid Extension API
$masterKey = Get-MasterAPIKey $encodedCreds $FunctionAppName
Write-Output "This is the masterKey: $masterkey"
# Get Event Grid SystemKey, so we can create the Event Grid Webhook
$systemKey = Get-EventGridExtensionSystemKey $FunctionAppName $masterkey
Write-Output "This is the SystemKey: $systemKey"
Write-Output "Creating the Event Grid Subscription:"
CreateEventGridSubscription $FunctionAppName $FunctionName $systemKey $EventGridSubscriptionName

In the PowerShell script I use an ARM Template (from the Azure Quickstart Gallery) to create the Event Grid Subscription at Azure Subscription level (sorry for the confusing subscription words).

If you want to create the Event Grid Subscription at Resource Group level use the New-AzureRmResourceGroupDeployment cmdlet instead (at line 49), providing the Resource Group name you want to link.

4 thoughts on “Create an Event Grid Subscription to an Azure Function V2

Add yours

  1. Hey Marco,

    I believe that the end point in Get-EventGridExtensionSystemKey should be “http” and not “https” – you can also remove the access token parameter from that function since it is also not used.

    Hope this helps!

    Like

  2. Hello Macro,
    Thank you for this…I am having issues replicating what you have done here and was wondering if you can help out.
    I first had issues with the parameters and then had to hard code the masterkey and systemkey. Despite doing this I got the following error message.

    ################################################################################
    the deployment ‘egdeployment’ failed with error(s). Showing 1 out of 1 error(s). Status Message: The resource operation completed with
    | terminal provisioning state ‘Failed’. (Code: ResourceDeploymentFailure) – Webhook validation handshake failed for
    | https://azltrialfuncapp.alipfunctionapp.azurewebsites.net/runtime/webhooks/EventGrid. Http POST request failed with response code Unknown. For
    | troublehooting, visit https://aka.ms/esvalidation. Activity id:07cbd4ac-324d-4656-a239-77aac33e51f2, timestamp: 6/12/2020 4:25:26 PM (UTC). (Code:Url
    | validation) CorrelationId: 27ee89bf-526a-4116-b8ce-c4cbc44574d7

    #################################################################################

    Please any idea what I might be doing wrong

    Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Blog at WordPress.com.

Up ↑

%d bloggers like this: