The process of finding a specific item within an array of objects should be straightforward in any programming language. It was, however, difficult to perform this operation in Bicep until recently. Although the language provided many array functions, the majority of them were fairly simple or dealt with primitive types such as strings and integers.
A common use case is to have a virtual network Bicep module that creates a virtual network with required subnets and outputs an array of objects which contain subnet details, name, and resourceId:
output subnets array = [for (subnet, i) in subnets: {
name: virtualNetwork.properties.subnets[i].name
id: virtualNetwork.properties.subnets[i].id
}]
In order to obtain the resourceId of a specific subnet from a virtual network output array, we need to use its name. To accomplish this, we can use the newly introduced filter() lambda functions in bicep. This function takes an array as a parameter with an expression (a.k.a. predicate) to which items in the array should satisfy. The result is a new array that has been “filtered”.
outputArray filter(inputArray, lambda expression)
The array of subnet objects needs to be filtered based on the name of the required subnet. The resulting array should contain only one item, which we can access using first(). In the end, the code looks like this:
module aks 'aks.bicep' = {
name: 'aks'
scope: rg
params:{
location: location
clusterSubnetId: first(filter(network.outputs.subnets, x => x.name == 'ClusterSubnet')).id
}
}