# Merging multiple (more than 2) dicts, the correct way

**URL:** <https://forum.ansible.com/t/merging-multiple-more-than-2-dicts-the-correct-way/8592>\
**Category:** Get Help\
**Tags:** windows, variables\
**Created:** [September 18, 2024, 12:37pm UTC](https://forum.ansible.com/t/merging-multiple-more-than-2-dicts-the-correct-way/8592 "2024-09-18T12:37:24Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![erichymowitz](https://avatars.discourse-cdn.com/v4/letter/e/9d8465/32.png) [@erichymowitz](https://forum.ansible.com/u/erichymowitz)\
**Post date:** [September 18, 2024, 12:37pm UTC](https://forum.ansible.com/t/merging-multiple-more-than-2-dicts-the-correct-way/8592/1 "2024-09-18T12:37:24Z")

</div>

So I know that we’re doing this incorrectly. The question is, how can I do this the correct way?

I have a `windows.yml` group variable file that contains a dict that lists the basic software that machines will need:

```auto
default_baseline_includes:
  7zip: true
  bigfix: true
  checkmk: true
  chrome: true
  d4voip: false
  firefox: true
  git: true

```

Then I have other group var files, such as `windows_admin.yml` `windows_32bit.yml` `windows_itps.yml` etc, that might have changes:

```auto
override_baseline_includes:
  bigfix: false
  checkmk: false

```

Then I put them together like this:

```auto
baseline_includes: "{{ default_baseline_includes|combine(override_baseline_includes) }}"

```

I’m under the impression that this definition is evaluated at run-time – that is, not at the moment it’s defined, but whenever the `baseline_incluces` variable is actually called/referenced, it uses whatever happens to be in `override_baseline_includes` at that time. (Maybe I’m wrong?)

The problem is that, if a machine is in several groups, it might have several options to define (and thus replace) the `override_baseline_includes` dict. If this were perl, I could just say

```auto
  $baseline{bigfix} = false;

```

and it wouldn’t affect the rest of the dict. But in ansible (as far as I can tell), creating `override_baseline_includes` will completely remove and replace a pre-existing `override_baseline_includes`

So the question is …

How can I, correctly, have several different dicts similar to my `override_baseline_includes` , that will all be merged together with my `default_baseline_includes` …

(bonus question) merged in the correct order? (I’m not sure what the correct order **is** yet, other than “host-based should override group-based, and group-based should override the default”

I hope this makes sense. Thanks in advance.

---

<div class="post-metadata">

**Author:** ![erichymowitz](https://avatars.discourse-cdn.com/v4/letter/e/9d8465/32.png) [@erichymowitz](https://forum.ansible.com/u/erichymowitz)\
**Post date:** [September 18, 2024, 4:55pm UTC](https://forum.ansible.com/t/merging-multiple-more-than-2-dicts-the-correct-way/8592/2 "2024-09-18T16:55:21Z")

</div>

So I don’t know if it’s acceptable to answer your own question.

My boss referred me to this web page

> **[Ansible Pattern: Cumulative Inventory Variables](https://witchychant.com/ansible-cumulative-inventory-variables/)**
>
> This is something I’ve never actually used, but has come up multiple times in #ansible, e.g. “I want to add on to a list variable in N places, but writing foo: "{{ foo1 + (foo2 | default(\[\])) + (fooN | default(\[\])) }}" is horrible and clunky and I...

specifically, the final example.

The plan is that each individual group’s `override_baseline_includes` will be renamed `override_baseline_includes_##` and assigned a number from 00 to 98, and each individual host’s `override_baseline_includes` will become `override_baseline_includes_99`

Then we will set

```auto
override_baseline_includes: "{{ q('vars', *q('varnames', '^override_baseline_includes_')) | flatten }}"

baseline_includes: "{{ default_baseline_includes|combine(override_baseline_includes) }}"

```

The first line should grab all of the various `override_baseline_includes_##` files in lexical (numerical) order into a single `override_baseline_includes` , which will then be merged into the `default_baseline_includes` .

I suppose we could have saved a few steps by giving the `default_baseline_includes` a name like `override_baseline_includes_00`, but so far, our testing has worked correctly, and using the word “override” seemed wrong for the defaults.

Anyway, I think this has solved our problem.
