Dyego Eugenio/Interesting way to use dynamic blocks on terraform

Created Wed, 03 Aug 2022 10:23:00 +0300 Modified Thu, 03 Aug 2023 15:46:24 +0000

This post will describe a interesting way to create conditional blocks in Terraform.

I faced the need to create blocks only if they are specified in the config variable. I found a way using dynamic blocks and checking if the key matches with the block names. Another interesting point here are the nested dynamic blocks and the ability to give a name for the nested loop variables. This makes the life easier to identify where the data is coming from.

Here is the Terraform code block using dynamic blocks.

resource "elasticstack_elasticsearch_index_lifecycle" "this" {
  for_each = var.ilm_config
  name     = replace(each.key, "_", "-")

  dynamic "delete" {
    for_each = { for k, v in each.value : k => v if k == "delete" }
    iterator = d1

    content {
      min_age = lookup(d1.value, "min_age", "6d")

      dynamic "delete" {
        for_each = { for k, v in d1.value : k => v if k == "delete" }
        iterator = d2

        content {
          delete_searchable_snapshot = lookup(d2.value, "delete_searchable_snapshot", true)
        }
      }
    }
  }

  dynamic "hot" {
    for_each = { for k, v in each.value : k => v if k == "hot" }

    content {
      min_age = lookup(hot.value, "min_age", "0ms")

      dynamic "rollover" {
        for_each = { for k, v in hot.value : k => v if k == "rollover" }

        content {
          max_age                = lookup(rollover.value, "max_age", "1d")
          max_docs               = lookup(rollover.value, "max_docs", 0)
          max_primary_shard_size = lookup(rollover.value, "max_primary_shard_size", "25gb")
        }
      }

      dynamic "set_priority" {
        for_each = { for k, v in hot.value : k => v if k == "set_priority" }

        content {
          priority = lookup(set_priority.value, "priority", 100)
        }
      }
    }
  }
}

And the way that you can specify the configs for the module looks like this

module "elasticstack" {
  source = "modules/elasticstack/"
  ilm_config = {
    logs_test = {
      delete = {
        min_age = "1d"
      }
    }
    another_ilm = {
      delete = {}
      hot    = { rollover = {} }
    }
  }
}