Dynamic block name

Can a dynamic block name itself be a variable?

Am trying to create a resource that has a logging_configuration block, which has a inner set of blocks that when declared will create log groups.

resource "aws_resource" "example" {
 arg1 = var.arg1
 ...
 logging_config {
    agent_log {
        name_prefix = "dr_ag"
    }
    error_log {
        name_prefix = "dr_err"
    }
 }
}

The inner blocks are like 6 different categories. Currently am declaring like above and the resource spins off log groups when it finds an inner block.

So was checking out if the inner block can be dynamically created off of a map(string), like so:

variable "logs_configs" {
  type = map(string)
  default = {
    "agent_log" = "dr_ag"
    "error_log" = "dr_err"
  }
}

resource "aws_resource" "example" {
  arg1 = var.arg1
  ...
  dynamic "logging_config" {
    for_each = var.logs_configs
    dynamic logging_config.key {   <== Can this be from a variable!!
      content {
        name_prefix = logging_config.value.value
        enabled     = true
      }
    }
  }
}

Obviously the above code doesn’t compile, but is there an alternative way to achieve something like above. Any thoughts. Thanks.

Hi @codecorrect,

The block type name and the attributes inside the content block are both checked by Terraform statically during the validation phase and so cannot be dynamic.

To achieve this effect in a way that Terraform can statically verify against the provider schema you will need to write out one dynamic block per possible block type, like this:

  dynamic "agent_log" {
    for_each = {
      for k, v in var.logs_configs : k => v
      if k == "agent_log"
    }
    content {
      name_prefix = logging_config.value
      enabled      = true
    }
  }

The for expression here filters out all of the elements that don’t have a matching map key. In this case that means you will only have zero or one blocks of this type, because it’s impossible for there to be two elements of the map which have the key "agent_log".

If you write out a block like the above for each of the possible block types then that should get the result you described, but note that if the caller specifies any map keys that aren’t expected this approach will silently ignore them. To avoid that and give better feedback, I’d suggest adding a validation rule to the variable block which raises an error if there are any unexpected keys in the map, so the caller will get better feedback about the mistake.