Search code examples
azureservicebusazure-servicebus-topicsazure-bicep

Creating too many topics in Azure Service bus via BICEP file


I have a list of 100+ topics that I pass into a bicep file below.

param serviceBusName string
param topics array
param location string = resourceGroup().location

resource serviceBus_resource  'Microsoft.ServiceBus/namespaces@2021-11-01' = {
  name: serviceBusName
  location: location
  sku: {
    name: 'Premium'
    tier: 'Premium'
    capacity: 1
  }
}

resource serviceBus_topics 'Microsoft.ServiceBus/namespaces/topics@2021-11-01' = [for item in topics: {
  name: '${serviceBusName}/${item.n}'
  dependsOn: [
    serviceBus_resource
  ]
}]

When I tried to add another topic, I get the following error on my Azure Devops pipeline:

This results in an error "##[warning]Environment variable 'TOPICSTOCREATE' exceeds the maximum supported length. Environment variable length: 32770 , Maximum supported length: 32766"

I have tried to break down the for loop

e.g.

param topicsCount = length(topics)
[for i in range(0, itemCount): {
                        param subsetTopics = take(skip(topics, i), 10)
                        resource serviceBus_topics 'Microsoft.ServiceBus/namespaces/topics@2021-11-01' = [for item in subsetTopics: {
                          name: '${serviceBusName}/${item.n}'
                        }]
                        i = i + 10
}]

and similar things, but it looks like nested loops are not possible in bicep? Is there a way around this?


Solution

  • In sounds like you just want to batch the resource creation, in which case you can just use the batchSize decorator on the resource.

    @batchSize(10)
    resource serviceBus_topics 'Microsoft.ServiceBus/namespaces/topics@2021-11-01' = [for item in topics: {
      name: '${serviceBusName}/${item.n}'
      dependsOn: [
        serviceBus_resource
      ]
    }]
    

    An alternate approach if you simply wanted to limit the creation;

    You could decorate the topics parameter to limit the array length;

    @maxLength(500)
    param topics array
    

    This would cause a deployment validation failure if you provided too many.

    For a softer approach you could have another parameter for the max, verify by leveraging the ternary operator and then use a loop index;

    param serviceBusName string
    param topics array
    param location string = resourceGroup().location
    param maxTopics int = 3
    
    resource serviceBus_resource  'Microsoft.ServiceBus/namespaces@2021-11-01' = {
      name: serviceBusName
      location: location
      sku: {
        name: 'Premium'
        tier: 'Premium'
        capacity: 1
      }
    }
    
    var topicsToCreate = length(topics) > maxTopics ? maxTopics : length(topics)
    
    resource serviceBus_topics 'Microsoft.ServiceBus/namespaces/topics@2021-11-01' = [for i in range(0, topicsToCreate): {
      name: topics[i]
      parent: serviceBus_resource
    }]