Search code examples
terraformmonitoringnewrelic

How to create a resource for each combination of values using for_each loop in Terraform


I have the following variable:

locals {
  servers = [
    {
      "Environment": "UAT",
      "ServerName": "WebServer01",
      "Disks": [
        "C:",
        "D:"
      ],
    },
    {
      "Environment": "UAT",
      "ServerName": "WebServer02",
      "Disks": [
        "C:",
        "D:"
      ],
    }
  ]
}

Using a for_each loop, how can I create multiple resources based on a combination of ServerName and each Disk so I end up with 4 resources?

WebServer01 C: 
WebServer01 D: 
WebServer02 C: 
WebServer02 D:

I've started with the following to no avail.

resource "newrelic_alert_policy" "foo" {
  name = "foo"
}

resource "newrelic_nrql_alert_condition" "foo" {
  for_each = { for idx,val in var.servers : idx => val }
  policy_id                      = newrelic_alert_policy.foo.id
  type                           = "static"
  name                           = "foo"
  description                    = "Alert when transactions are taking too long"

  nrql {
    query = "SELECT average(host.disk.usedPercent) as 'Storage Usage' FROM Metric WHERE entity.name = '${each.value.ServerName}' and host.device = '${each.value.Disks}'"
  }

  critical {
    operator              = "above"
    threshold             = 90
    threshold_duration    = 600
    threshold_occurrences = "ALL"
  }

}

Solution

  • If the idea is to create one alert per disk on a server then you could use flattened intermediate local variable to use in the resources' for_each construct.

      locals {
    
      # This is a flattened projection of var.servers. It will contain one entry for each server and disk
      # { server_name = "WbeServer01"  , server_disk="C:" }
      # { server_name = "WbeServer01"  , server_disk="D:" }
        servers_and_disks = flatten([
          for x, server in var.servers : [
            for y, disk in server.Disks : {      
             id = "${server.ServerName}${disk}" 
             server_name = server.ServerName,
             server_disk = disk
            }
          ]
        ])
      }
    
      resource "newrelic_alert_policy" "foo" {
         name = "foo"
      }
    
      resource "newrelic_nrql_alert_condition" "foo" {   
        for_each = { for disk in local.servers_and_disks : disk.id => disk }   
        policy_id                      = newrelic_alert_policy.foo.id
        type                           = "static"
        name                           = "foo"
        description                    = "Alert when transactions are taking too long"
    
        nrql {
          query = "SELECT average(host.disk.usedPercent) as 'Storage Usage' FROM Metric WHERE entity.name = '${each.value.server_name}' and host.device = '${each.value.server_disk}'"
        }
    
        critical {
          operator              = "above"
          threshold             = 90
          threshold_duration    = 600
          threshold_occurrences = "ALL"
        }
    
    }