skip to Main Content

So I’m trying to write something that will allow me to create topics and subscriptions in a loop and while I think I’ve achieved that thanks to code founded here, I’m facing some problems and I’n not sure how to resolve them.
It looks like sometimes bicep fails because it try to create subscription when topics creation is not yet finished. When I re-run my pipeline, it works just fine. I guess this is the reason:

https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/linter-rule-use-parent-property

The error I get is:
The incoming request is not recognized as a namespace policy put request. ttps://aka.ms/sbResourceMgrExceptions. TrackingId:e1d2c50d-fe92-43d8-abfe-8eb2c1917a70_G5, SystemTracker:ihdev-nonprod-servicebus.servicebus.windows.net:dev-sb-topic-test/subscriptions/dev-sb-sub-test, Timestamp:2024-04-08T13:33:29 (Code: MessagingGatewayNotFoundStatusCode

I’m not sure how to avoid this error.
Is there a way to create particular subscription only if corresponding topic was created? I guess I cannot simply add dependsOn[i] as I would have to change from for topic in topicsAndSubscriptions to something like for (topic, i) in topicsAndSubscriptions but maybe I’m wrong?

Main.bicepparam:

using './main.bicep'

param serviceBusNamespaceName = '#{SBUS_NAMESPACE_NAME}#'
param topicsAndSubscriptions = [
  {
    name: 'dev-sb-top-failure'
    subscriptions: [
      'dev-sb-sub-failure'
    ]
  }
  {
    name: 'xrm-dev-sb-report-completion'
    subscriptions: [
      'dev-sb-sub-report-completion'
    ]
  }
  {
    name: 'dev-sb-top-completion'
    subscriptions: [
      'dev-sb-sub-completion'
    ]
  }
  {
    name: 'dev-sb-top-discharge'
    subscriptions: [
      'dev-sb-sub-discharge'
    ]
  }
]

Here is the code for main.bicep

@description('Name of the Service Bus namespace')
param serviceBusNamespaceName string

@description('Location for all resources.')
param location string = resourceGroup().location
param topicsAndSubscriptions array

resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-01-01-preview' = {
  name: serviceBusNamespaceName
  location: location
  sku: {
    name: 'Premium'
  }
  properties: {}
}

resource serviceBusTopic 'Microsoft.ServiceBus/namespaces/topics@2022-10-01-preview' = [
  for topic in topicsAndSubscriptions: {
    parent: serviceBusNamespace
    name: topic.name
    properties: {}
  }
]

module subs 'modules/subscription.bicep' = [
  for topic in topicsAndSubscriptions: {
    name: '${topic.name}-subs'
    params: {
      servicebusNamespaceName: serviceBusNamespaceName
      topicName: topic.name
      subscriptions: topic.subscriptions
    }
  }
]

module file:

param servicebusNamespaceName string
param topicName string
param subscriptions array = ['asubscription', 'anotherone']

resource sub 'Microsoft.ServiceBus/namespaces/topics/subscriptions@2022-10-01-preview' = [
  for i in subscriptions: {
    name: '${servicebusNamespaceName}/${topicName}/${i}'
    properties: {}
  }
]

2

Answers


  1. In Bicep, the dependsOn property is used to explicitly declare that one resource should only be created after another has been successfully provisioned.

    To solve your problem, you should adjust your Bicep templates to ensure that subscriptions are only created after their respective topics have been successfully created as the following:

    resource serviceBusTopics 'Microsoft.ServiceBus/namespaces/topics@2022-10-01-preview' = [
      for (topic, i) in topicsAndSubscriptions: {
        name: topic.name
        parent: serviceBusNamespace
        properties: {}
      }
    ]
    
    module subs 'modules/subscription.bicep' = [
      for (topic, i) in topicsAndSubscriptions: {
        name: '${topic.name}-subs'
        params: {
          servicebusNamespaceName: serviceBusNamespaceName
          topicName: topic.name
          subscriptions: topic.subscriptions
        }
        dependsOn: [
          serviceBusTopics[i] // This ensures each subscription module waits for its corresponding topic to be created
        ]
      }
    ]
    
    Login or Signup to reply.
  2. Implicit dependency is recommended in your circumstance

    main.bicep

    @description('Name of the Service Bus namespace')
    param serviceBusNamespaceName string
    
    @description('Location for all resources.')
    param location string = resourceGroup().location
    param topicsAndSubscriptions array
    
    resource serviceBusNamespace 'Microsoft.ServiceBus/namespaces@2022-01-01-preview' = {
      name: serviceBusNamespaceName
      location: location
      sku: {
        name: 'Premium'
      }
      properties: {}
    }
    
    resource serviceBusTopic 'Microsoft.ServiceBus/namespaces/topics@2022-10-01-preview' = [ for topic in topicsAndSubscriptions: {
        parent: serviceBusNamespace
        name: topic.name
        properties: {}
      }
    ]
    
    module subs 'modules/subscription.bicep' = [ for (topic, i) in topicsAndSubscriptions: {
        name: '${topic.name}-subs'
        params: {
          servicebusNamespaceName: serviceBusNamespaceName
          topicName: serviceBusTopic[i].name
          subscriptions: topic.subscriptions
        }
      }
    ]
    
    

    subscription.bicep

    param servicebusNamespaceName string
    param topicName string
    param subscriptions array = ['asubscription', 'anotherone']
    
    resource sub 'Microsoft.ServiceBus/namespaces/topics/subscriptions@2022-10-01-preview' = [ for i in subscriptions: {
        name: '${servicebusNamespaceName}/${topicName}/${i}'
        properties: {}
      }
    ]
    
    

    main.bicepparam

    using './main.bicep'
    
    param serviceBusNamespaceName = '#{SBUS_NAMESPACE_NAME}#'
    param topicsAndSubscriptions = [
      {
        name: 'dev-sb-top-failure'
        subscriptions: [
          'dev-sb-sub-failure'
        ]
      }
      {
        name: 'xrm-dev-sb-report-completion'
        subscriptions: [
          'dev-sb-sub-report-completion'
        ]
      }
      {
        name: 'dev-sb-top-completion'
        subscriptions: [
          'dev-sb-sub-completion'
        ]
      }
      {
        name: 'dev-sb-top-discharge'
        subscriptions: [
          'dev-sb-sub-discharge'
        ]
      }
    ]
    

    topicName: serviceBusTopic[i].name here will allow topic deployment before
    corresponding subscription. I have test it, works well.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search