Loop场景下Bicep模块如何处理父资源引用及订阅创建依赖
问题
通过循环创建Azure Service Bus的Topic和Subscription时,偶尔会执行失败,报错显示在Topic未创建完成的情况下就尝试创建Subscription,重新运行管道则可正常执行。报错信息如下:
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
推测问题源于未正确设置资源依赖关系,希望明确如何让特定Subscription仅在对应Topic创建完成后再启动创建流程,不确定是否需要将循环从for topic in topicsAndSubscriptions改为for (topic, i) in topicsAndSubscriptions来添加dependsOn[i]。
相关代码
Main.bicepparam
using './main.biceicep' 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' ] } ]
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 } } ]
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: {} } ]
解决方案
1. 为Subscription模块添加对应Topic的强依赖
在main.bicep中,将模块循环改为带索引的形式,明确指定每个Subscription模块依赖于对应索引的Topic资源,确保Topic创建完成后再启动Subscription的创建:
修改后的main.bicep模块部分:
module subs 'modules/subscription.bicep' = [ for (topic, i) in topicsAndSubscriptions: { name: '${topic.name}-subs' params: { servicebusNamespaceName: serviceBusNamespaceName topicName: topic.name subscriptions: topic.subscriptions } // 绑定对应索引的Topic资源作为依赖 dependsOn: [ serviceBusTopic[i] ] } ]
2. 优化Subscription模块的资源定义(可选但推荐)
在subscription.bicep中,避免手动拼接资源全名,改用parent属性关联对应Topic,让Bicep自动识别资源层级关系,同时提升代码可读性:
修改后的subscription.bicep:
param serviceBusNamespaceName string param topicName string param subscriptions array = ['asubscription', 'anotherone'] // 引用已创建的Topic作为父资源 resource targetTopic 'Microsoft.ServiceBus/namespaces/topics@2022-10-01-preview' existing = { parent: resource('Microsoft.ServiceBus/namespaces@2022-01-01-preview', serviceBusNamespaceName) name: topicName } resource sub 'Microsoft.ServiceBus/namespaces/topics/subscriptions@2022-10-01-preview' = [ for subName in subscriptions: { parent: targetTopic name: subName properties: {} } ]
此优化无需修改main.bicep的参数传递,仅需保留第一步的dependsOn配置即可。
内容的提问来源于stack exchange,提问作者h00jraq
相关产品推荐
相关产品推荐

