Search code examples
azure-cliazure-eventgridazure-bicep

BadRequest by InvalidTemplate when deploying a bicep file containing an eventgridSubscription with a servicebus destination endpoint


What I would like to achieve is to be able to generate eventgridsubscriptions very easy using bicep. Because manually it costs a lot of time. I have to create like a over a dozen each day. I have the following bicep file called main.bicep

param eventSubscriptionName string = 'eventSubName'
param storageAccountName string ='storeAccountName'
param deadLetterAccountName string = 'deadlttrstore'
param serviceBusQueueName string = 'queue.name.enter'
param onrampName string = 'storagecontainername'

resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = {
  name: storageAccountName
}

resource deadLetterAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = {
  name: deadLetterAccountName
}

resource serviceBusQueue 'Microsoft.ServiceBus/namespaces/queues@2021-11-01' existing = {
  name: serviceBusQueueName
}

resource eventgridsubscription 'Microsoft.EventGrid/eventSubscriptions@2021-12-01' = {
  name: eventSubscriptionName
  scope: storageAccount
  properties: {
    deadLetterDestination: {
      endpointType: 'StorageBlob'
      properties: {
        blobContainerName: 'storage-deadletters'
        resourceId: deadLetterAccount.id
      }
    }
    destination: {
      endpointType: 'ServiceBusQueue'
      properties: {
        deliveryAttributeMappings: [
          {
            name: serviceBusQueueName
            type: 'Static'
            properties: {
              isSecret: false
              value: ''
            }
          }
        ]
        resourceId: serviceBusQueue.id
      }
    }
    eventDeliverySchema: 'EventGridSchema'
    filter: {
      enableAdvancedFilteringOnArrays: false
      includedEventTypes: [
        'Microsoft.Storage.BlobCreated'
      ]
      isSubjectCaseSensitive: false
      subjectBeginsWith: '/blobServices/default/containers/${onrampName}'
      subjectEndsWith: '.json'
    }
    retryPolicy: {
      eventTimeToLiveInMinutes: 1440
      maxDeliveryAttempts: 5
    }
  }
}

When I want create the event subscription using az cli with:

az deployment group create -f main.bicep -g <resource-group>

I get the following error:

{
    "status": "Failed",
    "error":
    {
        "code": "DeploymentFailed",
        "message": "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.",
        "details":
        [
            {
                "code": "BadRequest",
                "message": "{\r\n  \"error\":
                {\r\n    \"code\": \"InvalidTemplate\",\r\n    \"message\": \"Unable to process template language expressions for resource '/subscriptions/x1234456-f9cc-44e5-bc40-5f02d962f2d7/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>/providers/Microsoft.EventGrid/eventSubscriptions/eventSubName' at line '34' and column '5'. 'The language expression property array index '1' is out of bounds.'\",\r\n    \"additionalInfo\":
                [\r\n      {\r\n        \"type\": \"TemplateViolation\",\r\n        \"info\": {\r\n          \"lineNumber\": 34,\r\n          \"linePosition\": 5,\r\n          \"path\": \"\"\r\n        }\r\n      }\r\n    ]\r\n  }\r\n}"
            }
        ]
    }
}

I am working according to the template documented at MS here:

https://learn.microsoft.com/en-us/azure/templates/microsoft.eventgrid/eventsubscriptions?tabs=bicep


Solution

  • Eventually the solution was quite simple the servicebus resource was missing its parent resource namely the servicebus namespace. Once that was added it worked.

    resource serviceBus 'Microsoft.ServiceBus/namespaces@2021-11-01' existing = {
      name: serviceBusName
    }
    

    and

    resource serviceBusQueue 'Microsoft.ServiceBus/namespaces/queues@2021-11-01' existing = {
      parent: serviceBus
      name: serviceBusQueueName
    }
    

    to

    param eventSubscriptionName string = 'eventSubName'
    param storageAccountName string ='storeAccountName'
    param deadLetterAccountName string = 'deadlttrstore'
    param serviceBusQueueName string = 'queue.name.enter'
    param onrampName string = 'storagecontainername'
    
    resource storageAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = {
      name: storageAccountName
    }
    
    resource deadLetterAccount 'Microsoft.Storage/storageAccounts@2021-09-01' existing = {
      name: deadLetterAccountName
    }
    
    resource serviceBus 'Microsoft.ServiceBus/namespaces@2021-11-01' existing = {
      name: serviceBusName
    }
    
    resource serviceBusQueue 'Microsoft.ServiceBus/namespaces/queues@2021-11-01' existing = {
      parent: serviceBus
      name: serviceBusQueueName
    }
    
    resource eventgridsubscription 'Microsoft.EventGrid/eventSubscriptions@2021-12-01' = {
      name: eventSubscriptionName
      scope: storageAccount
      properties: {
        deadLetterDestination: {
          endpointType: 'StorageBlob'
          properties: {
            blobContainerName: 'storage-deadletters'
            resourceId: deadLetterAccount.id
          }
        }
        destination: {
          endpointType: 'ServiceBusQueue'
          properties: {
            deliveryAttributeMappings: [
              {
                name: serviceBusQueueName
                type: 'Static'
                properties: {
                  isSecret: false
                  value: 'some-value'
                }
              }
            ]
            resourceId: serviceBusQueue.id
          }
        }
        eventDeliverySchema: 'EventGridSchema'
        filter: {
          enableAdvancedFilteringOnArrays: false
          includedEventTypes: [
            'Microsoft.Storage.BlobCreated'
          ]
          isSubjectCaseSensitive: false
          subjectBeginsWith: '/blobServices/default/containers/${onrampName}'
          subjectEndsWith: '.json'
        }
        retryPolicy: {
          eventTimeToLiveInMinutes: 1440
          maxDeliveryAttempts: 5
        }
      }
    }