As we all know, the Logic App endpoints are one of the Event Grid subscribers to handle the events from either System or Custom Event Grid Topics. In Consumption Logic App, we had an option to choose the Logic Apps from drop down or using the Webhook URL provided with endpoint URL but it isn't in in case single tenant Logic App at the time of writing this article. If you would like to use the single-tenant LogicApp workflow endpoints as Event Grid Subscribers, we need to explicit perform the subscription handshake validation. Let see what errors we see while creating subscription with Single-Tenant LogicApp endpoints and how to implement explicit subscription handshake validation as documented here below.
In short, when an endpoint (Subscriber) need to act like Event Grid Subscriber to handle the events, it must first validate the Subscription handshake (Validation) to agree that its accepting to receive the events. In this validation Event Grid sends a validation request to the endpoint (Subscriber) and subscriber needs to accept the invite and sends the acceptance back to the Event Grid Publisher. Then the Publisher/Topic will send the events to the endpoint.
In case of consumption Logic App, it has been implemented internally to accept the validations by default and doesn't need any explicit handshake validation as specified above. Where Single-Tenant Logic App must perform an explicit handshake validation. Please check details below on the same.
Standard Logic App Workflow endpoint URL as Event Grid Subscription:
- If you don't have the handshake implemented in single-tenant Logic App workflow and try to provisioning the Event Grid subscription with the webhook URL provided with workflow endpoint URL, you will get the below error.
Error: Deployment has failed with the following error: {"code":"Url validation","message":"Webhook validation handshake failed for https://lastandard.azurewebsites.net/api/EventGridTrigger/triggers/manual/invoke. Http POST request retuned 2XX response with response body . When a validation request is accepted without validation code in the response body, Http GET is expected on the validation url included in the validation event(within 10 minutes). For troubleshooting, visit https://aka.ms/esvalidation. Activity id:d0eb08b7-8b8f-4e69-8bbe-42644345a05e, timestamp: 6/5/2021 10:50:59 AM (UTC)."}
- Event Grid Topic (System/Custom) support events with different schema types (Event Grid, Cloud Event 1.0 and Custom Schema). Let's check below on how to implement handshake validation for both Event Grid Schema and Cloud Event Schema with Logic App standard workflow endpoint URL below.
Event Grid Schema:
- You will see the workflow receiving a request for the above failure which has the details of Subscription Validation Event.
[
{
"id": "fe464e0d-645b-4ad4-91b9-a69ab838bc5a",
"topic": "/subscriptions/{YourSubscriptionId}/resourceGroups/{ResourceGroupName}/providers/Microsoft.EventGrid/topics/LAStandardEventGridTopic",
"subject": "",
"data": {
"validationCode": "E2D26E49-82E1-432E3-EEE-ERTS",
},
"eventType": "Microsoft.EventGrid.SubscriptionValidationEvent",
"eventTime": "2021-06-05T10:50:58.4926037Z",
"metadataVersion": "1",
"dataVersion": "2"
}
]
- Explicit Handshake Validation: To perform explicit handshake validation, we need to edit the workflow which acts like subscriber to send the retrieved validation code in response as below.
- Further, you can implement conditional statement to differentiate whether its event validation request or actual event later on as both logics are in same workflow, you can define a conditional statement to validate whether it is handshake validation request or actual using based on event type as below.
"eventType"="Microsoft.EventGrid.SubscriptionValidationEvent")
[or]
existence of Validationcode (IsValidationCode present?)
Response action:
{
"validationResponse": @{triggerBody()[0]?['data']?['validationCode']}
}
Cloud Event Schema 1.0:
- You will see the workflow receiving a request for the above failure which has the details of Subscription Validation Event.
{
"headers": {
"Host": "standartlogicapp.azurewebsites.net",
"Max-Forwards": "10",
"WebHook-Request-Origin": "eventgrid.azure.net",
"WebHook-Request-Callback": https://rp-eastus.eventgrid.azure.net:553/eventsubscriptions/standartlogicappsubsdemo/validate?id=abcs&t=2022-03-21T09:29:34.8876876Z&apiVersion=2020-10-15-preview&token=abcd,
"X-ARR-LOG-ID": "b9ac0e95-d954-46af-849d-3714727fb024",
"CLIENT-IP": "52.149.248.2:31744",
"DISGUISED-HOST": "standartlogicapp.azurewebsites.net",
"X-SITE-DEPLOYMENT-ID": "Standartlogicapp",
"WAS-DEFAULT-HOSTNAME": "standartlogicapp.azurewebsites.net",
"X-Forwarded-Proto": "https",
"X-AppService-Proto": "https",
"X-ARR-SSL": "2048|256|CN=Microsoft RSA TLS CA 02, O=Microsoft Corporation, C=US|CN=*.azurewebsites.net",
"X-Forwarded-TlsVersion": "1.2",
"X-Forwarded-For": "52.149.248.2:31744",
"X-Original-URL": "/api/laworkflowdemo/triggers/manual/invoke?api-version=2020-05-01-preview&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=QEQczGVbFk7tf_8XYa7O34pXfRyTEo7JPIGfww2HdYA",
"X-WAWS-Unencoded-URL": "/api/laworkflowdemo/triggers/manual/invoke?api-version=2020-05-01-preview&sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=QEQczGVbFk7tf_8XYa7O34pXfRyTEo7JPIGfww2HdYA"
}
}
- Explicit Handshake Validation: To perform explicit handshake validation, we need to extract the 'webhook-request-callback' header field value in a validation request and make a GET request call to it along with request contains the same header filed.
"headers": {
"WebHook-Request-Origin": "@{triggerOutputs()['headers']?['WebHook-Request-Origin']}"
},
- Workflow definition looks like below:
{
"definition": {
"$schema": https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#,
"actions": {
"Is_Validation_Request": {
"actions": {
"Handshake_Validation_": {
"inputs": {
"headers": {
"WebHook-Request-Origin": "@{triggerOutputs()['headers']?['WebHook-Request-Origin']}"
},
"method": "GET",
"uri": "@{triggerOutputs()?['headers']?['WebHook-Request-Callback']}"
},
"runAfter": {},
"type": "Http"
}
},
"expression": {
"and": [
{
"not": {
"equals": [
"@triggerOutputs()?['headers']?['WebHook-Request-Callback']",
"@null"
]
}
}
]
},
"runAfter": {},
"type": "If"
}
},
"contentVersion": "1.0.0.0",
"outputs": {},
"triggers": {
"manual": {
"inputs": {},
"kind": "Http",
"type": "Request"
}
}
},
"kind": "Stateful"
}
Note:
Event Grid topics won't be able to deliver the events on private endpoints. Hence if you have Logic App enabled with Private Endpoint, you wouldn't be able to use the workflow endpoints as event grid subscriptions. Check more details https://docs.microsoft.com/en-us/azure/event-grid/consume-private-endpoints
Feel free to let me know if you have any issues or suggestions.