The problem I am trying to solve is I need to identify one of the Azure subnets in a virtual network by part of it's name. This is so I can then later retrieve it's CIDR. I only know part beforehand such as "mgmt-1" or "egress-1". The actual name of the subnet is much longer but will end in something like that. This was my process:
I have the vnet name so I pull all subnets:
data "azurerm_virtual_network" "this" {
name = local.vnet
resource_group_name = "myrg"
}
Now what I wish I could do is this:
locals {
mgmt_index = index(data.azurerm_virtual_network.this.subnets, "*mgmt-1")
mgmt_subnet = data.azurerm_virtual_network.this.subnets[local.mgmt_index]
}
However index wants an exact match, not a regex. Is this possible to do? Perhaps a better way?
Thank you,
It is not possible to directly look up a list item using a regex match, but you can use for
expressions to apply arbitrary filters to a collection when constructing a new collection:
locals {
mgmt_subnets = toset([
for s in data.azurerm_virtual_network.this.subnets : s
if can(regex(".*?mgmt-1", s.name))
])
}
In principle an expression like the above could match more than one object, so I wrote this to produce a set of objects that match.
If you expect that there will never be more than one object whose name matches the pattern then you can use Terraform's one
function to assert that and then Terraform will check to confirm that there's no more than one element (returning an error if not) and then return that one value.
locals {
mgmt_subnet = one([
for s in data.azurerm_virtual_network.this.subnets : s
if can(regex(".*?mgmt-1", s.name))
])
}
If the condition doesn't match any of the subnet objects then in the first case you'll have an empty set and in the second case you'll have the value null
.