Lance Lyons
Lance Lyons

Reputation: 51

Bicep module reference as a parent in another resource

I am trying to reference and existing bicep module as a parent of another resource.

module vnethub 'modules/vnet/vnet.bicep' = {
  scope: resourceGroup(rg.name)
  name: 'hub-VNet'
  params: {
    vnetAddressSpace: {
        addressPrefixes: hubVNETaddPrefixes
    }
    vnetNamePrefix: 'hub'
    subnets: [
      hubVNETdefaultSubnet
      hubVNETfirewalSubnet
      hubVNETVMSubnet
      hubVNETBastionSubnet
    ]
  }
  dependsOn: [
    rg
  ]
}


.
.
.

resource subnetfw 'Microsoft.Network/virtualNetworks/subnets@2020-11-01' existing = {
  scope: resourceGroup(rg.name)
  name: '${vnethub.name}/AzureFirewallSubnet'
  parent: vnethub
}

when I do this I get an error on execution

Error BCP036: The property "parent" expected a value of type "Microsoft.Network/virtualNetworks" but the provided value is of type "module"

what am I doing wrong?

Upvotes: 5

Views: 11559

Answers (3)

FreemanRU
FreemanRU

Reputation: 349

You no need to provide parent if you use full path of the child resource. But to build full path you must know the resource name. First, add to your module something like this ():

// you existing code
resource vnetResoruce 'Microsoft.Network/virtualNetworks@2020-11-01' = {
// your code still here
}

// add this at the end
output vnetName string = vnetResoruce.name

Change your code in the main bicep to:

module vnethub 'vnet.bicep' = {
  scope: resourceGroup(rg.name)
  name: 'hub-VNet'
  params: { ... }
}

resource subnetfw 'Microsoft.Network/virtualNetworks/subnets@2020-11-01' existing = {
  scope: resourceGroup(rg.name)
  name: '${vnethub.outputs.vnetName}/AzureFirewallSubnet'
}

More info about full name: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/child-resource-name-type#full-resource-name-outside-parent

and about outputs: https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/outputs?tabs=azure-powershell

Upvotes: 1

bmoore-msft
bmoore-msft

Reputation: 8737

There are 2 ways you can do this one is below. Essentially you would put both the vnet and subnet into modules and use the output of the vnet module as input to the subnet module. Here's what main.bicep would look like. Note that the vnethub module needs to have an output of the vnet name, you already know the rg.

module vnethub 'vnet.bicep' = {
  scope: resourceGroup(rg.name)
  name: 'hub-VNet'
  params: { ... }
}

module subnetfw 'subnet.bicep' = {
  scope: resourceGroup(rg.name)
  name: 'subnetfw'
  params: {
    rg: rg
    vnetName: vnethub.outputs.vnetName
  }
}

The subnet.bicep module would be:

param rg object
param vnetName string

resource vnet 'Microsoft.Network/virtualNetworks@2021-05-01' existing = {
  scope: resourceGroup(rg.name)
  name: vnetName
}

resource subnetfw 'Microsoft.Network/virtualNetworks/subnets@2020-11-01' existing = {
  parent: vnet
  name: 'AzureFirewallSubnet'
}

That's one way - the reason you need that in your original example is that (it looks like) you don't have the name of the vnet in main.bicep. If you do know the name of the vnet, then you don't need to add the subnet module, you can just add the existing resource reference to main.bicep.

Does that help?

Upvotes: 8

Rob Reagan
Rob Reagan

Reputation: 7696

The "module" keyword in Bicep says that you want to call another file and process its contents. In this case, you're calling the Bicep template declared in the files modules/vnet/vnet.bicep.

This module file modules/vnet/vnet.bicep may define many different resources.

Then, you're trying to set the parent resource of subnetfw to the module name.

Also, you do not need to set a dependency (dependsOn) on a resource group.

I recommend pulling your vnet definition out of the file modules/vnet/vnet.bicep and getting at least a simple case working within a single Bicep file before attempting to factor out modules.

Upvotes: 0

Related Questions