Generate a specific parameter multiple times within a single resource

Hi

I’m working with this F5 provider.

For_each seems to be out of the question, as that would create many datagroups.
I’ve been playing around with for but I’m not quite getting there…

The bigip_ltm_datagroup module expects any number of input parameter called “record”. I have a dns_a_record_set that resolves the hosts to IP.

variable "hosts" {
type = list(string)
  default = [
    "host1.com",
    "host2.com",
    "...."
  ]
}

data "dns_a_record_set" "host_ips" {
  for_each = toset(var.hosts)
  host = each.key
}


resource "bigip_ltm_datagroup" "datagroup" {
    name = "/Common/datagroup"
    type = "ip"
    // I need to iterate over dns_a_record_set to create multiple records,
    // within a single datagroup resource.
    record {
      name = <each ip>
      data = <each hostname>
    }

}

Any help is much appreciated

Terraform v1.0.8

Hi @steina1989,

You can generate multiple blocks of the same type using dynamic blocks:

resource "bigip_ltm_datagroup" "datagroup" {
  # ...

  dynamic "record" {
    for_each = data.dns_a_record_set.host_ips
    content {
      name = one(record.value.addrs)
      data = record.value.host
    }
  }
}

In the above I’ve assumed that you only have one IP address per hostname, and so it’s safe to take just the first element of .addrs using one. This will return an error if any of your hostnames have more than one IP address associated. If you need to support that case then you’ll need an intermediate step to flatten the data structure to include all of the hostname and IP address pairs:

locals {
  ip_host = toset(flatten([
    for rs in data.dns_a_record_set.host_ips : [
      for addr in o.addrs : {
        host = rs.host
        addr = addr
      }
    ]
  ]))
}

The result of this expression should be a flat set of all of the IP addresses and their associated hostnames, which you can then use instead of the data resource directly in your dynamic block:

  dynamic "record" {
    for_each = local.ip_host
    content {
      name = record.value.addr
      data = record.value.host
    }
  }
1 Like