How to merge two level nested maps in terraform?

Viewed 843

I know there is an open feature request for deepmerge but I just wanted to see if there is any work around for my use case. lets consider the following local variables:

locals {
  default = {
    class = "class1"
    options = {
       option1 = "1"
       option2 = "2"
    }
  }
  configs = {
    configA = {
        name = "A"
        max = 10
        min = 5
        enabled  = true
        options = {
            option3 = "3"
        }
    }
    configB = {
        name = "B"
        max  = 20
        min     = 10
        enabled  = false
    }
  }
}

so I can merge the configs with default like this:

for key, config in local.configs : key => merge(local.default, config)

and the result will be:

configs = {
    configA = {
        name = "A"
        class = "class1"
        max = 10
        min = 5
        enabled  = true
        options = {
            option3 = "3"
        }
    }
    configB = {
        name = "B"
        class = "class1"
        max  = 20
        min     = 10
        enabled  = false
        options = {
            option1 = "1"
            option2 = "2"
        }
    }
  }

The problem is the nested map (options property) gets completely replaced by configA since merge cannot handle nested merge. Is there any work around for it in terraform 1.1.3 ?

1 Answers

If you know the structure of the map, you can merge the included elements separately as you wish.

In this case this should work:

merged = {
  for key, config in local.configs : key =>
  merge(
    local.default,
    config,
    { options = merge(local.default.options, lookup(config, "options", {})) }
  )
}

So first merge the top-level elements, and then handle the options separately.

Related