1

I'm trying to add entries to the labels and metadata sub-blocks on the google_monitoring_metric_descriptor resource. I'm having a tough time making for_each loop over my map of structures for each metric descriptor, as well as the inner collections for labels and metadata. It doesn't appear to accept an inner for_each inside the block, and trying to assign to it with = also seems not to work.


locals {
  metrics = {
    gsuite_user_count = {
      name = "projects/my-gcp-project-123/metricDescriptors/custom.googleapis.com/gsuite_user_count",
      labels = [
        {
          key = "gsuite_domain"
        },
        {
          key         = "opencensus_task",
          description = "Opencensus task identifier"
        }
      ],
      metricKind  = "GAUGE",
      valueType   = "INT64",
      unit        = "1",
      description = "Number of users in GSuite Directory.",
      displayName = "custom.googleapis.com/gsuite_user_count",
      type        = "custom.googleapis.com/gsuite_user_count"
    }
  }
}

resource "google_monitoring_metric_descriptor" "basic" {
  provider     = google-beta
  for_each     = local.metrics
  description  = lookup(each.value, "description")
  display_name = each.value.displayName

  # How do I do this?
  labels = [for label in each.value.labels : {
    key   = label.key
    value = label.value
  }]

  //  launch_stage = each.value.launchStage
  //  metadata     = each.value.metadata
  metric_kind = each.value.metricKind
  type        = each.value.type
  unit        = each.value.unit
  value_type  = each.value.valueType
  project     = var.project_id
}

This gives this error on terraform apply:

Error: Unsupported argument

  on /Users/jaycarlton/repos/workbench/ops/terraform/modules/workbench/modules/monitoring/modules/metrics/main.tf line 32, in resource "google_monitoring_metric_descriptor" "basic":
  32:   labels = [for label in each.value.labels : {

An argument named "labels" is not expected here. Did you mean to define a
block of type "labels"?
Jay Carlton
  • 1,118
  • 1
  • 11
  • 27

1 Answers1

2

The label could be set iteratively using dynamic blocks. It could be something along these lines:

  dynamic "labels" {
    for_each = each.value.labels
    content {
      key   = labels.key
      value = labels.value
    }
  }
Marcin
  • 215,873
  • 14
  • 235
  • 294
  • That makes sense. Is there only ever one `each` at a time? – Jay Carlton Oct 27 '20 at 01:35
  • 1
    @JayCarlton Not sure what do you mean? – Marcin Oct 27 '20 at 04:27
  • I sense this follow-up question is about the iterator variable inside the `dynamic` block. The name `each` is always the iterator for the main resource `for_each`; each dynamic block has its own iterator variable which is (by default) named after the block type, which is why `labels.key` and `labels.value` are relevant inside the block. – Martin Atkins Oct 28 '20 at 22:39
  • @MartinAtkins well put. It does seem like a smell that the iterator is always named `each` except when it ain't. This would likely have been more natural if I'd learned the basics before diving in too deep here. – Jay Carlton Nov 14 '20 at 23:38