I've been asked to code Bicep modules - coming from a Terraform background I have a pre-determined way I think they should work here - but so far have failed at the first hurdle.
I have a few Azure Event Hub Namespaces to create, and within each namespace there will be multiple actual Event Hubs underneath each
My original design therefore was to be as follows... main.bicep file, a modules/ehns.bicep (generic module to create a EH Namespace) modules/eh.bicep (generic module to create EH under a EH Namespace)
This way I had 2 modules and could just call them to create multiples of each other and then re-use those modules elsewhere
This singular bicep code works...
resource eventhubnamespace 'Microsoft.EventHub/namespaces@2022-01-01-preview' = {
name: 'evhns-stackoverflow-dev-uksouth-001'
location: 'uksouth'
sku: {
name: 'Standard'
tier: 'Standard'
}
properties: {
isAutoInflateEnabled: true
maximumThroughputUnits: 1
minimumTlsVersion: '1.2'
}
}
output eventhubnamespaceid string = eventhubnamespace.id
resource eventhub01 'Microsoft.EventHub/namespaces/eventhubs@2021-11-01' = {
name: 'eventhub-01'
parent: eventhubnamespace
properties: {
messageRetentionInDays: 7
partitionCount: 1
}
}
When creating modules...
modules/ehns.bicep file
param ehnsname string
param location string
param skuName string
param autoInflate bool
param maxThroughputUnits int
resource eventhubnamespace 'Microsoft.EventHub/namespaces@2022-01-01-preview' = {
name: ehnsname
location: location
sku: {
name: skuName
tier: skuName
}
properties: {
isAutoInflateEnabled: autoInflate
maximumThroughputUnits: maxThroughputUnits
minimumTlsVersion: '1.2'
}
}
output eventhubnamespaceid string = eventhubnamespace.id
modules/eh.bicep file
param ehname string
param ehnsparent string
param messageretentionindays int
param partitionCount int
resource eventhub01 'Microsoft.EventHub/namespaces/eventhubs@2021-11-01' = {
name: ehname
parent: ehnsparent
properties: {
messageRetentionInDays: messageretentionindays
partitionCount: partitionCount
}
}
main.bicep file to run both modules...
module eventhubnamespace 'modules/ehns.bicep' = {
name: 'deploy-eventHubnamespace'
params: {
ehnsname: 'evhns-stackoverflow-dev-uksouth-001'
location: 'uksouth'
skuName: 'Standard'
autoInflate: true
maxThroughputUnits: 1
}
}
module eventhub01 'modules/eh.bicep' = {
name: 'eventhub-01'
params: {
ehname: 'eventhub-01'
ehnsparent: eventhubnamespace.outputs.eventhubnamespaceid
messageretentionindays: 7
partitionCount: 1
}
}
This doesn't work because the module/eh.bicep doesn't like the way I am passing in the *parent *value from the ehns.bicep module.
The property "parent" expected a value of type "Microsoft.EventHub/namespaces" but the provided value is of type "string".bicep(BCP036)
There is no output from the ehns.bicep module that has the type Microsoft.EventHub/namespaces, it's only array/object/int/bool/string that are available
I take it this just isn't possible and I'm forced to create a single module for everything because the way the parent object needs to work?
The parent
syntax in bicep requires the resource to be defined in the template - it can be an existing resource. The simple version of this for your scenario is to just pass in the name of the parent, not the full resource id. So....
eh.bicep
param ehname string
param ehnsparentname string
param messageretentionindays int
param partitionCount int
resource ehnsparent 'Microsoft.EventHub/namespaces@2022-01-01-preview' existing = {
name: ehnsparentname
}
resource eventhub01 'Microsoft.EventHub/namespaces/eventhubs@2021-11-01' = {
name: ehname
parent: ehnsparent
properties: {
messageRetentionInDays: messageretentionindays
partitionCount: partitionCount
}
}
and then in main.bicep when you call the module
module eventhub01 'modules/eh.bicep' = {
name: 'eventhub-01'
dependsOn: eventhubnamespace // dependsOn is needed when not using an output
params: {
ehname: 'eventhub-01'
ehnsparentname: 'evhns-stackoverflow-dev-uksouth-001' // just the name, not the full id property
messageretentionindays: 7
partitionCount: 1
}
}
Whether you use an output or not is really a stylistic choice in the example you gave - you already know the name in main.bicep since you pass it into the other module... that said, if you don't use an output, you need to make sure there is an explicit dependsOn
defined between the parent and the child modules.