Reputation: 1309
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 ?
Upvotes: 2
Views: 9837
Reputation: 1106
There are various ways to do this including using this deepmerge provider:
https://registry.terraform.io/modules/cloudposse/config/yaml/0.5.0/submodules/deepmerge
Here is a way that assumes only that /usr/bin/jq exists. I am not saying it is pretty, but it does work and ensures that you get the same semantics as a jq * operator.
locals {
left = {...}
right = {...}
merged = {
for k, v in data.external.merge.result : k => jsondecode(v)
}
}
data "external" "merge" {
program = [
"/usr/bin/jq",
"((.left|fromjson) * (.right|fromjson))|with_entries(.value|=tojson)"
]
query = {
left = jsonencode(local.left)
right = jsonencode(local.right)
}
}
Upvotes: 2
Reputation: 4176
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.
Upvotes: 5