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
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:
Implicit dependency is recommended in your circumstance
main.bicep
subscription.bicep
main.bicepparam
topicName: serviceBusTopic[i].name here will allow topic deployment before
corresponding subscription. I have test it, works well.