Search code examples
azureazure-resource-managerazure-eventhubazure-bicep

Azure Bicep Nested Loops


I'm trying to create an Azure Event Hub using json config and Bicep.

The Event Hub namespace deploys fine, but when I try to extend the code to namespaces/eventhubs and namespaces/eventhubs/authorizationRules then I encounter an issue as I have nested loops which from the looks of the error are not possible:

A nested resource cannot appear inside of a resource with a for-expression.bicep(BCP160)

My code:

    param eventHubs array
    
    resource eventHubNS 'Microsoft.EventHub/namespaces/eventhubs@2022-01-01-preview' = [for ns in eventHubs: {
  parent: eventHub
  name: ns.name
  properties: {
    messageRetentionInDays: ns.properties.messageRetentionInDays
    partitionCount: ns.properties.partitionCount
    status: ns.properties.status
  }
  resource eventHubAuthRules 'authorizationRules@2022-01-01-preview' = [for ar in ns.authorizationRulesRights: {
    name: ar.name
    properties: {
      rights: ar.rights
      }
    }]
}]

And the Json:

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "eventHubNameSpace": {
            "value": [{
                    "resourceGroup": "my-rg",
                    "name": "my-evhns",
                    "location": "uksouth",
                    "sku": {
                        "capacity": 1,
                        "name": "standard",
                        "tier": "standard"
                    },
                    "properties": {
                        "minimumTlsVersion": "1.2",
                        "publicNetworkAccess": "Enabled",
                        "disableLocalAuth": false,
                        "zoneRedundant": true,
                        "isAutoInflateEnabled": false,
                        "maximumThroughputUnits": 1,
                        "kafkaEnabled": true
                    },
                    "eventHubs": [
                        {
                            "name": "my-evh",
                            "properties": {
                                "messageRetentionInDays": 1,
                                "partitionCount": 1,
                                "status": "Active"
                            },
                            "authorizationRulesRights": [
                                {
                                    "name": "Rule1",
                                    "rights": ["Listen"]
                                },
                                {
                                    "name": "Rule2",
                                    "rights": ["Listen"]
                                }                               
                            ]
                        }
                    ]
                }
            ]
        }
    }
}

Solution

  • You could always create a module to create the authorization rules:

    // authorizationRules.bicep
    
    param eventHubNSName string
    param authorizationRulesRights array
    
    resource eventHubNS 'Microsoft.EventHub/namespaces/eventhubs@2022-01-01-preview' existing = {
      name: eventHubNSName
    }
    
    resource eventHubAuthRules 'Microsoft.EventHub/namespaces/eventhubs/authorizationRules@2022-01-01-preview' = [for ar in authorizationRulesRights: {
      parent: eventHubNS
      name: ar.name
      properties: {
        rights: ar.rights
      }
    }]
    
    

    And invoke it like that:

    ...
    param eventHubs array
    
    resource eventHubNS 'Microsoft.EventHub/namespaces/eventhubs@2022-01-01-preview' = [for ns in eventHubs: {
      parent: eventHub
      name: ns.name
      properties: {
        messageRetentionInDays: ns.properties.messageRetentionInDays
        partitionCount: ns.properties.partitionCount
        status: ns.properties.status
      }  
    }]
    
    module eventHubAuthRules 'authorizationRules.bicep' = [for (ns, i) in eventHubs: {
      name: 'authorizationRules-${ns.name}'
      params: {
        eventHubNSName: eventHubNS[i].name
        authorizationRulesRights: ns.authorizationRulesRights    
      }
    }]