Skip to content

Multiple Optional Blocks

GlennChia edited this page Jul 7, 2021 · 1 revision

This patten covers the following phrase in the Terraform Registry:

(Optional) One or more <name of block> blocks as defined below to filter the budget on.

Example:

(Optional) One or more dimension blocks as defined below to filter the budget on.

Use case with condition on the name attribute

In the configuration.tfvars file:

filter = {
  dimensions = {
    explicit_name = {
      name = "ResourceGroupName"
      values = [
        "example",
      ]
    },
    resource_group_key = {
      # lz_key = "examples"
      name = "resource_group_key"
      values = [
        "test",
      ]
    }
  }
}
  • Defines 2 dimension blocks. One has the name that is within the list of allowed names. The second has the name resource_group_key that will be used to look up the resource groups and retrieve the id that will then be mapped to ResourceId in the resource file below.

In the resource file:

dynamic "filter" {
  for_each = try(var.settings.filter, null) == null ? [] : [1]

  content {
    dynamic "dimension" {
      for_each = {
        for key, value in try(var.settings.filter.dimensions, {}) : key => value
        if lower(value.name) != "resource_group_key"
      }

      content {
        name   = dimension.value.name
        values = dimension.value.values
      }
    }

    dynamic "dimension" {
      for_each = {
        for key, value in try(var.settings.filter.dimensions, {}) : key => value
        if lower(value.name) == "resource_group_key"
      }

      content {
        name = "ResourceId"
        values = try(flatten([
          for key, value in var.resource_groups[try(dimension.value.lz_key, var.client_config.landingzone_key)] : value.id
          if contains(dimension.value.values, key)
        ]), [])
      }
    }
  }
}
  • The for_each here includes a null check that determines the value of a feature flag. This for_each syntax ensures that the filer block remains optional and will not error if there is no filter block specified.
  • The dimension block is also a multiple optional block. However, we want to conditionally use some logic depending on the key used. In this case, destructure the object in the for_each to get the value.name and then use a conditional to detect if the value.name matches a certain string. This pattern is very similar to the single optional block pattern that also involves the resource_group_key
Clone this wiki locally