Datadog Specific - Iterating Over Object Maps

The makeup of a Datadog template_variable_preset:

### Nested template_variable_preset` blocks

Nested template_variable_preset blocks have the following structure:

  • name - (Required) The displayed name of the preset.
  • template_variable : (Required) Block describing the values that a template_variable within this preset should assume. Each referenced template_variable name must be defined on the dashboard, but not all template_variables must be included in a preset. One or more blocks can be defined per preset.
    • name : (Required) The name of the template_variable being referenced.
    • value : (Required) The value that the template_variable should assume.`

A developer can include a variable number of these in a terraform configuration for a dashboard. I have attempted all sorts of ways to deal with this object type, including:

variable "template_variable_presets" {
  type = map(object({
    names = set(string)
  }))
  default = {
    tvar1 = ["name", "value"]
    tvar2 = ["name", "value"]
  }
  description = "Nested block describing saved configurations of existing template variables. Multiple template_variable_preset blocks are allowed within a datadog_dashboard resource, and multiple template_variables can be described by each template_variable_preset."
}

and, locals…

 t_presets = flatten([
    for tpn, obj in var.template_variable_presets : [
      for  tvar in obj.names : {
        name = tpn
        value = tvar
      }
    ]
  ])

That produces this error:

Error: Invalid default value for variable

  on variables.tf line 32, in variable "template_variable_presets":
  32:   default = {
  33:     tvar1 = ["name", "value"],
  34:     tvar2 = ["name", "value"]
  35:   }

This default value is not compatible with the variable's type constraint:
element "tvar2": object required.

What is the proper way to go about this?

The type constraint you specified for that variable calls for the value to be a map of objects, but the default value you gave is a map of tuples. Therefore Terraform produces an error, because it can’t convert a tuple to an object.

To make this work, you can either change the type constraint or you can change the default value.

variable "template_variable_presets" {
  type = map(object({
    names = set(string)
  }))
  default = {
    tvar1 = {
      names = ["name", "value"]
    }
    tvar2 = {
      names = ["name", "value"]
    }
  }
}
variable "template_variable_presets" {
  type = map(set(string))
  default = {
    tvar1 = ["name", "value"]
    tvar2 = ["name", "value"]
  }
}

Given the way you wrote that t_presets expression I think the first example above is the one that you’ll want, because it will make the default value match the structure that the t_presets expression seems to be expecting.

I appreciate you. That answer nailed it, and frankly, I realized my blunder as I was reading your answer. Thank you.

It turns out that I have a headache - nothing seems to work. A “value is not expected here” and so on… So, understanding that the Datadog provider supplies the resource, can anyone tell me how to generate the following:

template_variable_preset {
    name = "preset_1"
    template_variable {
      name = "var_1"
      value = "host.dc"
    }
    template_variable {
      name = "var_2"
      value = "my_service"
    }
  }

There are two ‘name’ variables there. The one immediately under

template_variable_preset { 

is the name of the grouping. The

template_variable {
      name = ""
      value = ""
}

block can be specified one or more times by the developer so it seems a dynamic block is fitting here. Thoughts?