Ability to treat a retrieved param value as param name
Suppose I'm using the network-security-group AVM module with the main.bicep
module someSNGResource '../module/network-security-group/main.bicep' = {
name: 'nsg-1'
params: {
name: 'nsg-webapp-subnet
location: westus2
securityRules: [for rule in rules: {
name: rule.name
properties: {
<omitted>
sourceApplicationSecurityGroupResourceIds: [
rule.sourceasg
]
destinationApplicationSecurityGroupResourceIds: [
rule.destinationasg
]
}
}
]
}
}
In my bicepparam file I would need to have the following
param rules = {
{
<ommited>
sourceasg: '/subscriptions/xxxx-xxxx-xx-xx-x-xxxx/resourceGroups/rg-vnet-uks/providers/Microsoft.Network/applicationSecurityGroups/asgweb1'
destinationasg: '/subscriptions/xxxx-xxxx-xx-xx-x-xxxx/resourceGroups/rg-vnet-uks/providers/Microsoft.Network/applicationSecurityGroups/asgweb2'
}
{
<ommited>
sourceasg: '/subscriptions/xxxx-xxxx-xx-xx-x-xxxx/resourceGroups/rg-vnet-uks/providers/Microsoft.Network/applicationSecurityGroups/asgweb2'
destinationasg: '/subscriptions/xxxx-xxxx-xx-xx-x-xxxx/resourceGroups/rg-vnet-uks/providers/Microsoft.Network/applicationSecurityGroups/asgweb3'
}
{
<ommited>
sourceasg: '/subscriptions/xxxx-xxxx-xx-xx-x-xxxx/resourceGroups/rg-vnet-uks/providers/Microsoft.Network/applicationSecurityGroups/asgweb3'
destinationasg: '/subscriptions/xxxx-xxxx-xx-xx-x-xxxx/resourceGroups/rg-vnet-uks/providers/Microsoft.Network/applicationSecurityGroups/asgweb1'
}
}
However this requires retrieving the application security group outside of bicep. What I would like to do is have a function that treats a string as a param. Lets call it asParam() for this example.
main.bicep
resource asg1 'Microsoft.Network/applicationSecurityGroups@2024-07-01' existing = {
name: 'asgweb1'
}
resource asg2 'Microsoft.Network/applicationSecurityGroups@2024-07-01' existing = {
name: 'asgweb2'
}
resource asg3 'Microsoft.Network/applicationSecurityGroups@2024-07-01' existing = {
name: 'asgweb3'
}
module someSNGResource '../module/network-security-group/main.bicep' = {
name: 'nsg-1'
params: {
name: 'nsg-webapp-subnet
location: westus2
securityRules: [for rule in rules: {
name: rule.name
properties: {
<omitted>
sourceApplicationSecurityGroupResourceIds: [
asParam(rule.sourceasg)
]
destinationApplicationSecurityGroupResourceIds: [
asParam(rule.destinationasg)
]
}
}
]
}
}
main.bicepparam
param rules = {
{
<ommited>
sourceasg: 'asg1.id'
destinationasg: 'asg2.id'
}
{
<ommited>
sourceasg: 'asg2.id'
destinationasg: 'asg3.id
}
{
<ommited>
sourceasg: 'asg3.id
destinationasg: 'asg1.id'
}
}
With this change existing resources could be referenced with their symbolic name inside the parameter file.
Unfortunately this is how we designed modules to work with Bicep and aren't planning on building direct support for this.
However, we are planning on working on the ability to pass a reference to a resource as an input or output for a module here: https://github.com/Azure/bicep/issues/2246
Would this help your use case?
I'm not sure if this is what you want, but here are two options that might do what you are looking for that works already today.
Option 1: Use variables in the bicepparam file.
This would look something like this:
main.bicep:
param rules object[]
module someSNGResource 'nsg.bicep' = {
params: {
securityRules: [for rule in rules: {
name: rule.name
properties: {
sourceApplicationSecurityGroupResourceIds: [
rule.sourceasg
]
destinationApplicationSecurityGroupResourceIds: [
rule.destinationasg
]
}
}
]
}
}
main.bicepparam
using 'main.bicep'
var asg1 = '/subscriptions/xxxx-xxxx-xx-xx-x-xxxx/resourceGroups/rg-vnet-uks/providers/Microsoft.Network/applicationSecurityGroups/asgweb1'
var asg2 = '/subscriptions/xxxx-xxxx-xx-xx-x-xxxx/resourceGroups/rg-vnet-uks/providers/Microsoft.Network/applicationSecurityGroups/asgweb2'
var asg3 = '/subscriptions/xxxx-xxxx-xx-xx-x-xxxx/resourceGroups/rg-vnet-uks/providers/Microsoft.Network/applicationSecurityGroups/asgweb3'
param rules = [
{
sourceasg: asg1
destinationasg: asg2
}
{
sourceasg: asg2
destinationasg: asg3
}
{
sourceasg: asg3
destinationasg: asg1
}
]
You would still have to define in the full resourceIds in the param file, but only once and you can then refer to them inside the rules parameter using just the variable names.
Option 2: Using the resourceId() function
If you are certain that all ASG's are in a specific resource group, another option could be to use the resourceId function inside your main.bicep, that could look something like this:
main.bicep
param rules object[]
param asgResourceGroup string = resourceGroup().name
module someSNGResource 'nsg.bicep' = {
params: {
securityRules: [for rule in rules: {
name: rule.name
properties: {
sourceApplicationSecurityGroupResourceIds: [
resourceId(asgResourceGroup, 'Microsoft.Network/applicationSecurityGroups', rule.sourceasg)
]
destinationApplicationSecurityGroupResourceIds: [
resourceId(asgResourceGroup, 'Microsoft.Network/applicationSecurityGroups', rule.destinationasg)
]
}
}
]
}
}
main.bicepparam
using 'main.bicep'
param asgResourceGroup = 'rg-vnet-uks'
param rules = [
{
sourceasg: 'asgweb1'
destinationasg: 'asgweb1'
}
{
sourceasg: 'asgweb1'
destinationasg: 'asgweb3'
}
{
sourceasg: 'asgweb3'
destinationasg: 'asgweb1'
}
]
This option comes with the benefit of just having to supply the name of each ASG in the parameter file. If the ASG resides in another resource group than you are deploying to, you also need to supply the name of that resource group as asgResourceGroup.
Option 2: Using the resourceId() function
If you are certain that all ASG's are in a specific resource group, another option could be to use the resourceId function inside your main.bicep, that could look something like this:
main.bicep
param rules object[] param asgResourceGroup string = resourceGroup().name
module someSNGResource 'nsg.bicep' = { params: { securityRules: [for rule in rules: { name: rule.name properties: { sourceApplicationSecurityGroupResourceIds: [ resourceId(asgResourceGroup, 'Microsoft.Network/applicationSecurityGroups', rule.sourceasg) ] destinationApplicationSecurityGroupResourceIds: [ resourceId(asgResourceGroup, 'Microsoft.Network/applicationSecurityGroups', rule.destinationasg) ] } } ] } }
main.bicepparam
using 'main.bicep'
param asgResourceGroup = 'rg-vnet-uks'
param rules = [ { sourceasg: 'asgweb1' destinationasg: 'asgweb1' } { sourceasg: 'asgweb1' destinationasg: 'asgweb3' } { sourceasg: 'asgweb3' destinationasg: 'asgweb1' } ] This option comes with the benefit of just having to supply the name of each ASG in the parameter file. If the ASG resides in another resource group than you are deploying to, you also need to supply the name of that resource group as asgResourceGroup.
This will do exactly what I want, thank you.