Loop through object attributes in a single resource?

I’m currently doing some work with the New Relic provider and need to provide a list of “Synthetic check” resources within a single “alert condition” resource block.

To build out the Synthetic check resources I’d created a for_each loop in the resource that reads from a list variable

The resource:

resource "newrelic_synthetics_monitor" "additional_monitors" {
  for_each = var.additional_uris
  
  name      = each.key
  type      = "SIMPLE"
  frequency = "1"
  status    = "DISABLED"
  locations = var.monitoring_locations
  
  uri = each.value
}

This is creating the resources just fine, but the issue is when I try to do this for my alert condition, it creates multiple resources for each item added, rather than populating the list in the single resource:

resource "newrelic_synthetics_multilocation_alert_condition" "frontend" {
  for_each = var.additional_uris
  policy_id = newrelic_alert_policy.synthetics_checks.id

  name                         = "Frontend"
  enabled                      = "true"
  violation_time_limit_seconds = 3600

  entities = [
    newrelic_synthetics_monitor.category.id,
    newrelic_synthetics_monitor.homepage.id,
    newrelic_synthetics_monitor.product.id,
    newrelic_synthetics_monitor.additional_monitors[each.key].id
  ]
....

I’ve tried reading and experimenting on dynamic blocks and flatten… though struggling to come up with a solution.

Hi @harleymckenzie,

If I’m understanding correctly your requirement, it sounds like you need to have an additional entry in your entities argument for each of the instances of newrelic_synthetics_monitor.additional_monitors.

I think you could get that result using the setunion function in addition to a for expression to systematically take the id attribute from each object:

entities = setunion(
  [
    newrelic_synthetics_monitor.category.id,
    newrelic_synthetics_monitor.homepage.id,
    newrelic_synthetics_monitor.product.id,
  ],
  [for m in newrelic_synthetics_monitor.additional_monitors : m.id],
)

The important part here is that for expression:

[for m in newrelic_synthetics_monitor.additional_monitors : m.id]

It constructs a list by taking the id attribute from each element of the map newrelic_synthetics_monitor.additional_monitors. We can then use that list as a set, along with the other statically-defined set, and combine the two together with setunion to get a single value for that argument.

1 Like

That did it :slightly_smiling_face:

Thanks for the simple solution! Spent almost entire day banging my head against this