Home > Enterprise >  Terraform conditional option_settings in a dynamic option block
Terraform conditional option_settings in a dynamic option block

Time:12-27

When using RDS option_groups, there are some options that require option_settings and some that don't. Terraform throws an error if the option_settings block is included with an option that doesn't use option settings, and terraform apply fails. I have a module that accepts a map of objects for RDS instances, including their option groups/options/option_settings. Within this is a resource that has an option that requires the option settings to be omitted (S3_INTEGRATION option). Below is the option_group resource block code being used:

resource "aws_db_option_group" "main" {
  for_each = {
    for name, rds in var.main : name => rds
    if rds.option_group_name != ""
  }
  name                     = each.value["option_group_name"]
  option_group_description = "Terraform Option Group"
  engine_name              = each.value["engine"]
  major_engine_version     = each.value["major_engine_version"]

  dynamic "option" {
    for_each = each.value["options"]
    content {
      option_name = option.key

      option_settings {
        name  = option.value["option_name"]
        value = option.value["option_value"]
      }
    }
  }
}

Is there a way to make the option_settings block creation in an option conditional to circumvent this?

CodePudding user response:

Terraform supports nested dynamic blocks too, which in my understanding is something that you are looking for.

Hashicorp documentation on Nested Dynamic Blocks: https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks#multi-level-nested-block-structures

You can modify your aws_db_option_group module with the below code and make your option_settings optional for the module. It will work only when the values are supplied(but it also depends on the typing of the variable if its flexible).

If you are already using Terraform version >= 1.3 then you also can use optional object type attributes already.

Hashicorp documentations : https://www.hashicorp.com/blog/terraform-1-3-improves-extensibility-and-maintainability-of-terraform-modules

resource "aws_db_option_group" "main" {
  for_each = {
    for name, rds in var.main : name => rds
    if rds.option_group_name != ""
  }
  name                     = each.value["option_group_name"]
  option_group_description = "Terraform Option Group"
  engine_name              = each.value["engine"]
  major_engine_version     = each.value["major_engine_version"]

  dynamic "option" {
    for_each = each.value["options"]
    content {
      option_name = option.key

      dynamic "option_settings" {
        for_each = option.value["option_settings"]

        content {
          name  = option_settings.key
          value = option_settings.value
        }
        ## Uncomment if you find this better and remove the above content block.
        # content {
        #   name  = option_settings.value["name"]
        #   value = option_settings.value["value"]
        # }
      }
    }
  }
}

Hope it helps.

  • Related