Q:

Dynamic Nested Blocks for modules

I would like to create a module for the Azure Application Gateway.
I want to disable some rule groups with the inline block disabled_rule_group, but how can I make this configurable in the module? This should be a optional variable.
I found the for_each for the nested blocks.
Example:
variable "disabled_rule_groups" {
  default     = [
    {
      rule_group_name = "REQUEST-931-APPLICATION-ATTACK-RFI"
      rules           = [
        931100,
        931130]
    },
    {
      rule_group_name = "REQUEST-942-APPLICATION-ATTACK-SQLI"
      rules           = [
        942100
      ]
    }
  ]
}

resource "azurerm_application_gateway" "AppGateway" {
  dynamic "disabled_rule_group" {
    for_each = [var.disabled_rule_groups]
    content {
      rule_group_name = disabled_rule_group.value.rule_group_name
      rules           = disabled_rule_group.value.rules
    }
  }
}

This is not working however.
Does anybody have an idea how to fix the syntax?
Additionally, the variable disabled_rule_groups should be optional. So if no disabled_rule_groups is set the block should be disabled.
How can i achieve this? Do i need a second boolean variable and a if in the for each?

A:

Yes, the syntax you have there is incorrect. You apparently mean this:
resource "azurerm_application_gateway" "AppGateway" {
  dynamic "disabled_rule_group" {
    for_each = var.disabled_rule_groups // Removed [ ] from this line.
    content {
      rule_group_name = disabled_rule_group.value.rule_group_name
      rules           = disabled_rule_group.value.rules
    }
  }
}

Additionally, the variable disabled_rule_groups should be optional. So if no disabled_rule_groups is set the block should be disabled. How can i achieve this? Do i need a second boolean variable and a if in the for each?

The best way to make the parameter optional is to allow it to default to an empty list. But the way you've written it, it already is optional, but when not specified, will default to the default you have written out.
Probably, what you want is this:
variable "disabled_rule_groups" {
  default = []
}

Then, you don't need any conditional logic, because if you loop over an empty list (i.e. for_each = []) then none of those dynamic nested blocks will be generated, and that appears to be what you want.

