Nested multiple yaml values

hello

I have a yaml file I need to decode, I have the single values working but need help with the multiple values

here is my yaml file

---
rules:
- name: "test1234"
  priority: 1010
  direction: "Inbound"
  access: "Allow"
  protocol: "*"
  source_port_range:
    - "135"
    - "137"
    - "139"
  source_address_prefix:
    - "1.1.1.1"
  destination_port_range:
    - "*"
  destination_address_prefix:
    - "2.2.2.2"

- name: "test4567"
  priority: 1020
  direction: "Outbound"
  access: "Allow"
  protocol: "tcp"
  source_port_range: [ "25", "465", "587" ]
  source_address_prefix:
    - "2.2.2.2"
    - "2.3.2.3"
  destination_port_range:
    - "*"
  destination_address_prefix:
    - "*"

here is my terraform

resource "azurerm_network_security_rule" "nsr" {
  for_each = { for rule in local.rules : rule.name => rule }

    name                        = lower(each.value.name)
    priority                    = lower(each.value.priority)
    direction                   = lower(each.value.direction)
    access                      = lower(each.value.access)
    protocol                    = lower(each.value.protocol)
    source_port_range           = lower(each.value[*].source_port_range)
    destination_port_range      = "*"
    source_address_prefix       = "*"
    destination_address_prefix  = "*"
  
  
  resource_group_name         = azurerm_resource_group.rg.name
  network_security_group_name = azurerm_network_security_group.nsg.name
}

the problem is I dont know how to pick up multiple values like

 source_address_prefix:
    - "2.2.2.2"
    - "2.3.2.3"

I hope this makes sense, I know this wont work

 = lower(each.value[*].source_port_range)
length(lookup(each.value, "source_port_range", [])) == 0 ? null : each.value.source_port_range

any advice where i’m going wrong

thanks in advance

Hi @stravze!

I’m not familiar with this particular resource type, but after looking at its documentation I see that it has both a singular source_address_prefix argument and a plural source_address_prefixes argument.

Is your goal here to set source_address_prefix = "*" if the source_address_prefix list is empty or to set source_address_prefixes if it is non-empty?

If so, I’d try something like this:

  source_address_prefix   = length(each.value.source_address_prefix) == 0 ? "*" : null
  source_address_prefixes = length(each.value.source_address_prefix) != 0 ? each.value.source_address_prefix : null

The above exploits the fact that for resource arguments the value null is equivalent to not setting the argument at all, and so because these two conditions are exactly the opposite of one another the effect will be that only one of them can be set at a time, which should therefore create a valid configuration in all cases.

If I’ve misunderstood your intent here, it’d help if you could perhaps show some examples of what configuration you’d write if you were aiming to hard-code these values, rather than loading them from YAML, and then hopefully I or someone else can think about ways to achieve a similar result in a dynamic way.

Hi @apparentlymart

This worked a treat, many thanks

Hey can you please show me how you local.rules looks like? I’m trying to build something like that but I’m strungling with the yamldecode.

thanks a lot