Problem
I’m new to Azure Bicep (which in itself i pretty new) but have some experience with ARM templates.
I’m attempting to figure out how to connect an Azure Blog storage container to an Azure Event Grid subscription.
This isn’t working code. I’ve been following this instruction and am now attempting to use an EventGrid that isn’t discussed.
When I try to deploy my bicep-created template, I get the following error:
{
"error": {
"code": "InvalidRequest",
"message": "Invalid event subscription request: Supplied URL is invalid. It cannot be null or empty and should be a proper HTTPS URL like https://www.example.com."
}
}
This is what my event grid subscription looks like:
resource sub1 'Microsoft.EventGrid/systemTopics/eventSubscriptions@2020-04-01-preview' = {
name: '${eventgrid.name}${subscriptionName}'
properties: {
destination: {
properties: {
maxEventsPerBatch: 1
preferredBatchSizeInKilobytes: 64
}
endpointType: 'WebHook'
}
filter: {
subjectBeginsWith: '/blobServices/default/containers/mycontainer'
includedEventTypes: [
'Microsoft.Storage.BlobCreated'
]
}
labels: []
eventDeliverySchema: 'EventGridSchema'
retryPolicy: {
maxDeliveryAttempts: 30
eventTimeToLiveInMinutes: 1440
}
topicType: 'Microsoft.Storage.StorageAccounts'
}
}
I receive a different problem when I add an endpointUrl field to the event subscription:
{
"status": "Failed",
"error": {
"code": "ResourceDeploymentFailure",
"message": "The resource operation completed with terminal provisioning state 'Failed'.",
"details": [
{
"code": "Url validation",
"message": "Webhook validation handshake failed for https://foobarblee.blob.core.windows.net/results-nlp. Http POST request failed with response code Unknown. For troublehooting, visit https://aka.ms/esvalidation. Activity id:, timestamp: 9/22/2020 11:21:07 PM (UTC)."
}
]
}
}
The code in this section has been updated to look like this:
resource sub1 'Microsoft.EventGrid/systemTopics/eventSubscriptions@2020-04-01-preview' = {
name: '${eventgrid.name}${subscriptionName}'
properties: {
destination: {
properties: {
maxEventsPerBatch: 1
preferredBatchSizeInKilobytes: 64
endpointUrl: 'https://${storageAccount.name}.blob.core.windows.net/mycontainer'
}
endpointType: 'WebHook'
Unfortunately I can’t find any documentation on this particular issue.
This is how my full biceps file looks:
param location string = resourceGroup().location
param evgNamePrefix string = 'evg'
param subNamePrefix string = 'sub'
param stgNamePrefix string = 'stg'
param subOneName string = '/foo-local-debug'
param containerOneName string = '/mycontainer'
// param storageAccountName string = 'blee'
param globalRedundancy bool = true // defaults to true, but can be overridden
var storageAccountName = '${stgNamePrefix}${uniqueString(resourceGroup().id)}'
var eventGridName = '${evgNamePrefix}${uniqueString(resourceGroup().id)}'
var eventGridSubscriptionName = '${evgNamePrefix}${subNamePrefix}${uniqueString(resourceGroup().id)}${subOneName}'
resource evg 'Microsoft.EventGrid/systemTopics@2020-04-01-preview' = {
name: eventGridName
location: location
properties: {
source: stg.id
topicType: 'Microsoft.Storage.StorageAccounts'
}
}
resource sub1 'Microsoft.EventGrid/systemTopics/eventSubscriptions@2020-04-01-preview' = {
name: '${evg.name}${subOneName}'
properties: {
destination: {
properties: {
maxEventsPerBatch: 1
preferredBatchSizeInKilobytes: 64
endpointUrl: 'https://${stg.name}.blob.core.windows.net/mycontainer'
}
endpointType: 'WebHook'
}
filter: {
subjectBeginsWith: '/blobServices/default/containers/mycontainer'
includedEventTypes: [
'Microsoft.Storage.BlobCreated'
]
}
labels: []
eventDeliverySchema: 'EventGridSchema'
retryPolicy: {
maxDeliveryAttempts: 30
eventTimeToLiveInMinutes: 1440
}
topicType: 'Microsoft.Storage.StorageAccounts'
}
}
resource stg 'Microsoft.Storage/storageAccounts@2019-06-01' = {
name: storageAccountName
location: location
kind: 'StorageV2'
sku: {
name: globalRedundancy ? 'Standard_GRS' : 'Standard_LRS' // if true --> GRS, else --> LRS
}
properties: {
azureFilesIdentityBasedAuthentication: {
directoryServiceOptions: 'None'
}
largeFileSharesState: 'Disabled'
networkAcls: {
bypass: 'AzureServices'
virtualNetworkRules: []
ipRules: []
defaultAction: 'Allow'
}
supportsHttpsTrafficOnly: true
encryption: {
services: {
file: {
keyType: 'Account'
enabled: true
}
blob: {
keyType: 'Account'
enabled: true
}
}
keySource: 'Microsoft.Storage'
}
accessTier:'Hot'
}
}
resource bs 'Microsoft.Storage/storageAccounts/blobServices@2019-06-01' = {
name: '${stg.name}/default'
properties: {
cors: {
corsRules: []
}
deleteRetentionPolicy: {
enabled: true
days: 7
}
}
sku: {
name: globalRedundancy ? 'Standard_GRS' : 'Standard_LRS' // if true --> GRS, else --> LRS
tier: 'Standard'
}
}
resource c1 'Microsoft.Storage/storageAccounts/blobServices/containers@2019-06-01' = {
name: '${stg.name}/default${containerOneName}'
properties: {
defaultEncryptionScope:'$account-encryption-key'
denyEncryptionScopeOverride: false
publicAccess: 'None'
}
}
output storageId string = stg.id
output computedStorageName string = stg.name
output eventGridId string = evg.id
output eventGridsName string = evg.name
Asked by TrevorBrooks
Solution #1
The ARM JSON was created using the BICEP paper as a starting point. It works now that I set the Url to public webhook:
“endpointUrl”: “https://eval-mm.azurewebsites.net/api/Function1”
Subscription to EventGrid WebHook must be accessible to the public and does not accept URL arguments or headers. This irritates me greatly.
Enjoy BICEP; it’s a fantastic program:-)
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]"
},
"evgNamePrefix": {
"type": "string",
"defaultValue": "evg"
},
"subNamePrefix": {
"type": "string",
"defaultValue": "sub"
},
"stgNamePrefix": {
"type": "string",
"defaultValue": "stg"
},
"subOneName": {
"type": "string",
"defaultValue": "/foo-local-debug"
},
"containerOneName": {
"type": "string",
"defaultValue": "/mycontainer"
},
"globalRedundancy": {
"type": "bool",
"defaultValue": true
}
},
"functions": [],
"variables": {
"storageAccountName": "[format('{0}{1}', parameters('stgNamePrefix'), uniqueString(resourceGroup().id))]",
"eventGridName": "[format('{0}{1}', parameters('evgNamePrefix'), uniqueString(resourceGroup().id))]",
"eventGridSubscriptionName": "[format('{0}{1}{2}{3}', parameters('evgNamePrefix'), parameters('subNamePrefix'), uniqueString(resourceGroup().id), parameters('subOneName'))]"
},
"resources": [
{
"type": "Microsoft.EventGrid/systemTopics",
"apiVersion": "2020-04-01-preview",
"name": "[variables('eventGridName')]",
"location": "[parameters('location')]",
"properties": {
"source": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"topicType": "Microsoft.Storage.StorageAccounts"
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
]
},
{
"type": "Microsoft.EventGrid/systemTopics/eventSubscriptions",
"apiVersion": "2020-04-01-preview",
"name": "[format('{0}{1}', variables('eventGridName'), parameters('subOneName'))]",
"properties": {
"destination": {
"properties": {
"maxEventsPerBatch": 1,
"preferredBatchSizeInKilobytes": 64,
"endpointUrl": "https://eval-mm.azurewebsites.net/api/Function1"
},
"endpointType": "WebHook"
},
"filter": {
"subjectBeginsWith": "/blobServices/default/containers/mycontainer",
"includedEventTypes": [
"Microsoft.Storage.BlobCreated"
]
},
"labels": [],
"eventDeliverySchema": "EventGridSchema",
"retryPolicy": {
"maxDeliveryAttempts": 30,
"eventTimeToLiveInMinutes": 1440
},
"topicType": "Microsoft.Storage.StorageAccounts"
},
"dependsOn": [
"[resourceId('Microsoft.EventGrid/systemTopics', variables('eventGridName'))]",
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
]
},
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2019-06-01",
"name": "[variables('storageAccountName')]",
"location": "[parameters('location')]",
"kind": "StorageV2",
"sku": {
"name": "[if(parameters('globalRedundancy'), 'Standard_GRS', 'Standard_LRS')]"
},
"properties": {
"azureFilesIdentityBasedAuthentication": {
"directoryServiceOptions": "None"
},
"largeFileSharesState": "Disabled",
"networkAcls": {
"bypass": "AzureServices",
"virtualNetworkRules": [],
"ipRules": [],
"defaultAction": "Allow"
},
"supportsHttpsTrafficOnly": true,
"encryption": {
"services": {
"file": {
"keyType": "Account",
"enabled": true
},
"blob": {
"keyType": "Account",
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"accessTier": "Hot"
}
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices",
"apiVersion": "2019-06-01",
"name": "[format('{0}/default', variables('storageAccountName'))]",
"properties": {
"cors": {
"corsRules": []
},
"deleteRetentionPolicy": {
"enabled": true,
"days": 7
}
},
"sku": {
"name": "[if(parameters('globalRedundancy'), 'Standard_GRS', 'Standard_LRS')]",
"tier": "Standard"
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
]
},
{
"type": "Microsoft.Storage/storageAccounts/blobServices/containers",
"apiVersion": "2019-06-01",
"name": "[format('{0}/default{1}', variables('storageAccountName'), parameters('containerOneName'))]",
"properties": {
"defaultEncryptionScope": "$account-encryption-key",
"denyEncryptionScopeOverride": false,
"publicAccess": "None"
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
]
}
],
"outputs": {
"storageId": {
"type": "string",
"value": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
},
"computedStorageName": {
"type": "string",
"value": "[variables('storageAccountName')]"
},
"eventGridId": {
"type": "string",
"value": "[resourceId('Microsoft.EventGrid/systemTopics', variables('eventGridName'))]"
},
"eventGridsName": {
"type": "string",
"value": "[variables('eventGridName')]"
}
}
}
Answered by Markus Meyer
Post is based on https://stackoverflow.com/questions/64030748/webhook-url-for-azure-eventgrid-subscription-with-azure-bicep-fails