Skip to content

Single Optional Block

GlennChia edited this page Jul 7, 2021 · 1 revision

This patten covers the following phrase in the Terraform Registry:

(Optional) A <name of block> block as defined below.

Example:

(Optional) A filter block as defined below.

Simple use case

In the configuration.tfvars file:

filter = {
  dimensions = {
    explicit_name = {
      name = "ResourceGroupName"
      values = [
        "example",
      ]
    }
  }
}

In the resource file:

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

  content {
    dynamic "dimension" {
      for_each = var.settings.filter.dimensions

      content {
        name   = dimension.value.name
        values = dimension.value.values
      }
    }
  }
}
  • The for_each here includes a null check that determines the value of a feature flag. This for_each syntax ensures that the block remains optional and will not error if there is no filter block specified.

Advanced use case to conditionally handle certain keys

Example:

A not block supports the following:

dimension - (Optional) One dimension block as defined below to filter the budget on. Conflicts with tag.

In the configuration.tfvars file:

not = {
  dimension = {
    resource_group_key = {
      name = "resource_group_key"
      values = [
        "test",
      ]
    }
  }
}

In the resource file:

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

  content {
    dynamic "dimension" {
      for_each = {
        for key, value in try(var.settings.filter.not.dimension, {}) : 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.not.dimension, {}) : 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 not block is a single optional block and uses the feature flag pattern
  • The dimension block is also a single 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.
Clone this wiki locally