Coder Perfect

How to use Bicep to refer to an object in an array of objects

Problem

In a module that builds a virtual network with four subnets, I’m trying to output the referenceId of each subnet. I can retrieve the first one, [0], but when I try to output the other three, [1], [2], and [3], the deployment fails and throws the following error:

The property array index “1” of the language expression is out of limits.

The code for creating the virtualNetwork and subnets is as follows:

resource virtualNetwork 'Microsoft.Network/virtualNetworks@2018-11-01' = {
  name: vNetName
  location: location
  tags: tags
  properties: {
    addressSpace: {
      addressPrefixes: [
        addressPrefix
      ]
    }
    subnets: subnets
  }
}

subnets is an array variable of type:

var subnets = [
  {
    name: mgmtSubnetName
    properties: {
      addressPrefix: mgmtSubnetAddressPrefix
    }
  }
  {
    name: intSubnetName
    properties: {
      addressPrefix: intSubnetAddressPrefix
    }
  }
  {
    name: extSubnetName
    properties: {
      addressPrefix: extSubnetAddressPrefix
    }
  }
  {
    name: vdmsSubnetName
    properties: {
      addressPrefix: vdmsSubnetAddressPrefix
    }
  }
]

When I use the output line below, an array of four objects is returned…one for each subnet created:

output subnets array = virtualNetwork.properties.subnets

The following is the format for each object:

{
    "name":"<value>",
    "id":"<value>",
    "etag":"<value>",
    "properties":{
        "provisioningState":"Succeeded",
        "addressPrefix":"<value>",
        "ipConfigurations":[
            {
                "id":"<value>"
            }
        ],
        "delegations":[]
    },
    "type":"Microsoft.Network/virtualNetworks/subnets"
}

The first object in the subnets array is returned when I use the output line below:

virtualNetwork.properties output subnet1 object .subnets[0]

The resourceId of the first subnet is returned when I use the output line below:

output subnet1 string = virtualNetwork.properties.subnets[0].id

Using indexes 1, 2, or 3, I am unable to obtain the other objects in the array.

I have also tried the resourceId function (example below) but the behavior is exactly the same for indexes 1, 2, or 3:

resourceId(‘Microsoft.Network/VirtualNetworks/subnets’, name, subnets[0].name) output subnet1Id string = resourceId(‘Microsoft.Network/VirtualNetworks/subnets’, name, subnets[0].name)

Asked by phydeauxman

Solution #1

You may deploy the vnet and subnets using the bicep template below, which outputs the subnets and subnet ids as follows:

var subnets = [
  {
    name: 'vm-subnet'
    properties: {
      addressPrefix:'10.0.0.0/24'
    }
  }
  {
    name: 'webapp-subnet'
    properties: {
      addressPrefix:'10.0.1.0/24'
    }
  }
  {
    name: 'appgw-subnet'
    properties: {
      addressPrefix:'10.0.2.0/24'
    }
  }
  {
    name: 'bastion-subnet'
    properties: {
      addressPrefix:'10.0.3.0/24'
    }
  }
]
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2018-11-01' = {
  name: 'ansuman-vnet'
  location: 'east us'
  properties: {
    addressSpace: {
      addressPrefixes: [
        '10.0.0.0/16'
      ]
    }
    subnets: subnets
  }
}

output subnets array = [for (name, i) in subnets :{
  subnets : virtualNetwork.properties.subnets[i]
}]

output subnetids array = [for (name, i) in subnets :{
  subnets : virtualNetwork.properties.subnets[i].id
}]

output subnetappgw string = virtualNetwork.properties.subnets[2].id

output webappsubnet object = virtualNetwork.properties.subnets[1]

Outputs:

Note: I am using the latest Bicep version i.e. Bicep CLI version 0.4.1124

Answered by AnsumanBal-MT

Post is based on https://stackoverflow.com/questions/70815460/how-to-reference-an-object-in-an-array-of-objects-using-bicep