Search code examples
azureazureservicebusazure-resource-managerazure-servicebus-queuesazure-bicep

Bicep - Pair arrays with loops


My case is that I have a list of companies, as well as a list of queues that I want to pair together in my bicep file. I want to use the result to add queues to an service bus namespace.

This is an example of the queue array:

`var queues = [
  'first-queue'
  'second-queue'
  'third-queue'
]``

And this is an example of the company array:

`var companies = [
  'apple'
  'intel'
  'blizzard'
]``

I would like to loop through the company list with bicep syntax and insert the company name before each queue. In this case i want to have a result like bwlow:

`var res = [ 
  'apple-first-queue'
  'apple-second-queue'
  'apple-third-queue'
  'intel-first-queue'
  'intel-second-queue'
  'intel-third-queue'
  'blizzard-first-queue'
  'blizzard-second-queue'
  'blizzard-third-queue'
]`

I've tried a few different ways but can't get it to work. This is my latest attempt below where I get an error message regarding the syntax of "queuesToCreate" in the form of* "Directly referencing a resource or module collection is not currently supported. Apply an array indexer to the expression"*.

Does anyone see what I'm doing wrong here and can point me in the right direction?

`// ## Service bus multiple companies module ## //
module queuesToCreate 'service-bus-loop.bicep' = [for company in companies: {
name: 'multipleQueues-${company}'
  params: {
    company: company
  }
}]
`

``// ## Service bus namespace ## //
resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-01-01-preview' = {
  name: serviceBusNamespaceName
  location: location
  sku: {
    name: skuName
  }
}

// ## Queues ## //
resource queues 'Microsoft.ServiceBus/namespaces/queues@2022-01-01-preview' = [for queueName in queuesToCreate: {
  parent: serviceBusNamespace
  name: queueName
  properties: {
    maxDeliveryCount: 1
    lockDuration: 'PT5M'
  }
}]`

This service-bus-loop.bicep file look like below and just returns an array as output

param company string
`// Create an array with the names of the queues
var queues = [
  '${company}-queue'
  '${company}-queue'
  '${company}-queue'
]

output res array = queues`

queuesToCreate variable has in above case an syntax error like "Directly referencing a resource or module collection is not currently supported. Apply an array indexer to the expression."


Solution

  • As suggested in the comment section, you could always use a module to create all the queues for a specific company.

    // service-bus-queues.bicep
    param serviceBusNamespaceName string
    param company string
    param queues array
    
    resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-01-01-preview' existing = {
      name: serviceBusNamespaceName
    }
    
    resource queuesToCreate 'Microsoft.ServiceBus/namespaces/queues@2022-01-01-preview' = [for queue in queues: {
      parent: serviceBusNamespace
      name: '${company}-${queue}'
      properties: {
        maxDeliveryCount: 1
        lockDuration: 'PT5M'
      }
    }]
    

    Then from you main, loop through companies.

    // main.bicep
    param serviceBusNamespaceName string
    param location string
    param skuName string
    
    var queues = [
      'first-queue'
      'second-queue'
      'third-queue'
    ]
    
    var companies = [
      'apple'
      'intel'
      'blizzard'
    ]
    
    resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-01-01-preview' = {
      name: serviceBusNamespaceName
      location: location
      sku: {
        name: skuName
      }
    }
    
    module queuesToCreate 'service-bus-queues.bicep' = [for company in companies: {
      name: 'multipleQueues-${company}'
      params: {
        serviceBusNamespaceName: serviceBusNamespace.name
        company: company
        queues: queues
      }
    }]