Dynamic inline blocks

Hello, I have been unable to find a way to create dynamic inline blocks.
I have a specific example.

resource "google_monitoring_uptime_check_config" "uptime_check" {
  display_name     = var.display_name
  timeout          = var.timeout
  period           = var.period
  selected_regions = var.selected_regions

  monitored_resource {
    type = var.type

    labels = {
      project_id  = var.project_id
      host        = var.host
      instance_id = var.instance_id
      zone        = var.zone
      module_id   = var.module_id
      version_id  = var.version_id
    }
  }
}

The issue is, different resource types have different labels which are required.

uptime_url
project_id: The identifier of the GCP project associated with this resource
host: The hostname or IP address of the check

gce_instance
project_id: The identifier of the GCP project associated with this resource
instance_id: The numeric VM instance identifier assigned by Compute Engine
zone: The Compute Engine zone in which the VM is running

gae_app
project_id: The identifier of the GCP project associated with this resource
module_id: The service/module name
version_id: The version name
zone: The GAE zone where the application is running

How do I make the labels block dynamic so I can pass it any of the three examples above?

Hi @mwohlin,

Because of the equals sign after labels it seems like this is an argument expecting a map value, rather than a nested block. That means we can use any Terraform expression to construct a suitable map value to pass to it.

One way to get this done would be to build a local data structure that describes all of the possible shapes and then select the one that’s appropriate for the current var.type, like this:

locals {
  monitored_resource_labels = {
    uptime_url = {
      project_id = var.project_id
      host       = var.host
    }
    gce_instance = {
      project_id  = var.project_id
      instance_id = var.instance_id
      zone        = var.zone
    }
    gae_app = {
      project_id = var.project_id
      module_id  = var.module_id
      version_id = var.version_id
      zone       = var.zone
    }
  }
}

resource "google_monitoring_uptime_check_config" "uptime_check" {
  # ...

  monitored_resource {
    type = var.type
    labels = local.monitored_resource_labels[var.type]
  }
}

This will also have the side-effect of producing an error if var.type is set to a string that doesn’t appear as a key in local.monitored_resource_labels, which may be an advantage or a disadvantage depending on how flexible you want this module to be.

Hi @apparentlymart ,

Thank you! That is exactly what I was looking for!
I really appreciate your time and help.
Best wishes…