How to merge 2 list(map(string)) variables for use in a dynamic block

Hi folks,

I have 2 variables of this type list(map(string)) that I need to merge and then iterate through in a dynamic block. however I seem unable to do this whatever I try, how should i reconfigure this to produce the desired results please?

error

Error: Error in function call
│ 
│   on ../modules/db_parameter_group/main.tf line 6, in locals:
│    6:   merged_mysql_options = merge(var.mysql_standard_parameters,var.parameters...)
│     ├────────────────
│     │ var.mysql_standard_parameters is list of map of string with 15 elements
│     │ var.parameters is list of map of string with 2 elements
│ 
│ Call to function "merge" failed: arguments must be maps or objects, got "list of map of string".

snip of variables.tf

variable "parameters" {
  description = "A list of DB parameter maps to apply"
  type        = list(map(string))
  default     = []
}

variable "mysql_standard_parameters" {
  description = "A list of DB parameter maps to apply for MySQL instances"
  type        = list(map(string))
  default     = [
                   {
                      # The default value for max_connections can sometimes be too low for applications with connection pool configurations allowing a large number of connections or for shared DB instances.
                      name = "max_connections"
                      value = "1000"
                   },
                   {
                      # Increasing the redolog size from the default of 128MB for performance with a increse on crash recovery times as a result.
                      name = "innodb_log_file_size"
                      value = "600M"
                   }
         ]
}

snip of main.tf

  name        = var.use_name_prefix ? null : var.name
  name_prefix = var.use_name_prefix ? "${var.name}-" : null
  description = coalesce(var.description, format("%s parameter group", var.name))

  merged_mysql_options = merge(var.mysql_standard_parameters,var.parameters...)
  mysql_param = length(regexall(".*mysql*", var.family)) > 0

}

resource "aws_db_parameter_group" "mysql" {
  count = var.create && local.mysql_param ? 1 : 0

  name        = local.name
  name_prefix = local.name_prefix
  description = local.description
  family      = var.family

  dynamic "parameter" {
    # for_each = var.parameters
    for_each = local.merged_mysql_options
    content {
      name         = parameter.value.name
      value        = parameter.value.value
      apply_method = lookup(parameter.value, "apply_method", null)
    }
  }

  tags = merge(
    var.tags,
    {
      "Name" = var.name
    },
  )

  lifecycle {
    create_before_destroy = true
  }
}

Isn’t the concat() function, what you’re looking for (as long as the keys are uniq) ?

Changes to Outputs:
  + merged_mysql_options = [
      + {
          + "test" = "salad"
        },
      + {
          + "name"  = "max_connections"
          + "value" = "1000"
        },
      + {
          + "name"  = "innodb_log_file_size"
          + "value" = "600M"
        },
    ]


Hi @tbugfinder

Thanks for replying. Unfortunately there might be duplicate values in the combined list (but not within each list) and the nice thing about the merge function was that it was giving preference to the objects in the right hand side variable too which is what I wanted.

Steve

I wonder if I also combine with a distinct function and swap the variables round whether that might do :thinking: