# Merging dictionaries for "environment" parameter

**URL:** <https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827>\
**Category:** Ansible Project\
**Created:** [July 31, 2014, 11:15pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827 "2014-07-31T23:15:34Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Steven\_Ringo](https://avatars.discourse-cdn.com/v4/letter/s/bc79bd/32.png) [@Steven\_Ringo](https://forum.ansible.com/u/Steven_Ringo)\
**Post date:** [July 31, 2014, 11:15pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/1 "2014-07-31T23:15:34Z")

</div>

Hi,

I am wanting to use the `environment` task parameter with dictionaries taken from two roles, e.g.

in `roles/ruby/vars/main.yml`:

```auto
ruby_environment:
    GEM_HOME: "/home/deploy/.gem/ruby/2.1.2"
    PATH: "/home/deploy/.gem/ruby/2.1.2/bin:/opt/rubies/ruby-2.1.2/lib/ruby/gems/2.1.0/bin:/opt/rubies/ruby-2.1.2/bin"

```

in `roles/rails/tasks/main.yml`, I am wanting to do something like this:

```auto
- name: execute bundler
  command: bundle install --deployment
  environment:
    "{{ ruby_environment }}" merged with "RAILS_ENV: production"

```

Is this possible?

Thanks,

Steve

---

<div class="post-metadata">

**Author:** ![Steven\_Ringo](https://avatars.discourse-cdn.com/v4/letter/s/bc79bd/32.png) [@Steven\_Ringo](https://forum.ansible.com/u/Steven_Ringo)\
**Post date:** [July 31, 2014, 11:24pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/2 "2014-07-31T23:24:40Z")

</div>

To add: would prefer not to use hash\_behaviour = merge if possible.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [July 31, 2014, 11:56pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/3 "2014-07-31T23:56:36Z")

</div>

I think this might be proposing something like a jinja2 filter that merges one hash with another and returns it.

I’m not aware of this, but some other folks go deeper than me.

I’m not opposed to a filter plugin function being added that does this being added if that makes sense.

---

<div class="post-metadata">

**Author:** ![Steven\_Ringo](https://avatars.discourse-cdn.com/v4/letter/s/bc79bd/32.png) [@Steven\_Ringo](https://forum.ansible.com/u/Steven_Ringo)\
**Post date:** [August 1, 2014, 12:00am UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/4 "2014-08-01T00:00:32Z")

</div>

I thought it might be possible to loop over each hash respectively and then create a new one with all of those.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 1, 2014, 12:06am UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/5 "2014-08-01T00:06:08Z")

</div>

That in particular, I’d think no.

What I’d really like might look something like

environment: “{{ dict1 | update(dict2) }}”

Anybody done anything like that with stock Jinja2-voodoo magic? If not, it’s about a two liner in filter\_plugins/core.py to expose the native hash update function.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [August 1, 2014, 12:53pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/6 "2014-08-01T12:53:30Z")

</div>

dict1 + dict2

I also have an update to ‘set theory’ that will allow you to do dict1|union(dict2)  
​

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [August 1, 2014, 1:14pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/7 "2014-08-01T13:14:08Z")

</div>

So that’s a thing already with {{ dict1 + dict2 }}?

Nice.

---

<div class="post-metadata">

**Author:** ![Evgeny\_Goldin](https://avatars.discourse-cdn.com/v4/letter/e/848f3c/32.png) [@Evgeny\_Goldin](https://forum.ansible.com/u/Evgeny_Goldin)\
**Post date:** [October 24, 2014, 10:08pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/8 "2014-10-24T22:08:40Z")

</div>

Not really. Python doesn’t allow to merge two hashes using “{{ env1 + env2 }}”. Here’s what worked for me:

playbooks/filter\_plugins/filters.py:

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [October 25, 2014, 12:09am UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/9 "2014-10-25T00:09:18Z")

</div>

I think your filter plugin could be more easily written:

hash\_a.update(hash\_b)

perhaps?

If you send in a pull request, this seems reasonable to have as a core filter.

I’d probably call it ‘update’ if I’m correct on the above, which I think I am. If not, perhaps “merge”.

---

<div class="post-metadata">

**Author:** ![Brian\_Coca1](https://avatars.discourse-cdn.com/v4/letter/b/278dde/32.png) [@Brian\_Coca1](https://forum.ansible.com/u/Brian_Coca1)\
**Post date:** [October 29, 2014, 3:36am UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/10 "2014-10-29T03:36:15Z")

</div>

I could swear I had patched the union filter to use update when dicts were passed in, let me try this again.

Brian Coca

---

<div class="post-metadata">

**Author:** ![kesten\_broughton1](https://avatars.discourse-cdn.com/v4/letter/k/dc4da7/32.png) [@kesten\_broughton1](https://forum.ansible.com/u/kesten_broughton1)\
**Post date:** [November 26, 2014, 2:57pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/11 "2014-11-26T14:57:59Z")

</div>

It would be nicer to have a filter for jinja2, but this works:

defaults.yml  
d1:  
k1: 1

d2:  
k1: 2  
k2: 3

tasks/main.yml

- name: dbg  
debug: msg=“{{d1}} {{d2}}”

- set\_fact:  
d1: “{% do d1.update(d2) %}{{d1}}”

- debug: msg=“{{d1[‘k1’]}}”

OUTPUT

TASK: [gnf\_data | dbg] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
 ESTABLISH CONNECTION FOR USER: ubuntu  
ok: [deploy-test-1] =\> {  
“msg”: “{‘k1’: 1} {‘k2’: 3, ‘k1’: 2}”  
}

TASK: [gnf\_data | set\_fact] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
 ESTABLISH CONNECTION FOR USER: ubuntu  
ok: [deploy-test-1] =\> {“ansible\_facts”: {“d1”: {“k1”: 2, “k2”: 3}}}

TASK: [gnf\_data | debug msg=“{{d1[‘k1’]}}”] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
 ESTABLISH CONNECTION FOR USER: ubuntu  
ok: [deploy-test-1] =\> {  
“msg”: “2”  
}

---

<div class="post-metadata">

**Author:** ![T.N\_T](https://avatars.discourse-cdn.com/v4/letter/t/dbc845/32.png) [@T.N\_T](https://forum.ansible.com/u/T.N_T)\
**Post date:** [March 16, 2015, 2:39pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/12 "2015-03-16T14:39:07Z")

</div>

I had exactly the same idea. Did anybody do a PR for this? I don’t see it in 1.9 nor in devel.

If nobody else has time for it I could do it. I think this is really a gap. Anyway this way is definitely more what they call _pythonic_ than tweaking the union filter.

My code is simply:

`

`  
def update(dic, odic):  
dic.update(odic)  
return dic

class FilterModule(object):

def filters(self):  
return {

‘update’: update,  
‘update\_dict’: update,  
‘merge\_dict’: update  
}

`

`

---

<div class="post-metadata">

**Author:** ![Brian\_Coca](https://avatars.discourse-cdn.com/v4/letter/b/6de8d8/32.png) [@Brian\_Coca](https://forum.ansible.com/u/Brian_Coca)\
**Post date:** [March 16, 2015, 4:01pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/13 "2015-03-16T16:01:25Z")

</div>

there is a hash\_merge PR pending but it won't make it into 1.9.

---

<div class="post-metadata">

**Author:** ![T.N\_T](https://avatars.discourse-cdn.com/v4/letter/t/dbc845/32.png) [@T.N\_T](https://forum.ansible.com/u/T.N_T)\
**Post date:** [March 16, 2015, 5:09pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/14 "2015-03-16T17:09:16Z")

</div>

Looks nice. And nice to know. Thank you!

---

<div class="post-metadata">

**Author:** ![kevin](https://avatars.discourse-cdn.com/v4/letter/k/2acd7d/32.png) [@kevin](https://forum.ansible.com/u/kevin)\
**Post date:** [August 21, 2015, 6:15pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/15 "2015-08-21T18:15:31Z")

</div>

Looks like update doesn’t do a recursive hash merge. This might be the solution, [https://www.xormedia.com/recursively-merge-dictionaries-in-python/](https://www.xormedia.com/recursively-merge-dictionaries-in-python/)  
Is the best practice be to add this as a jinja filter?

---

<div class="post-metadata">

**Author:** ![vadyochik](https://avatars.discourse-cdn.com/v4/letter/v/a6a055/32.png) [@vadyochik](https://forum.ansible.com/u/vadyochik)\
**Post date:** [August 26, 2016, 4:35pm UTC](https://forum.ansible.com/t/merging-dictionaries-for-environment-parameter/15827/16 "2016-08-26T16:35:43Z")

</div>

For version 2.0+ check this please:

[http://docs.ansible.com/ansible/playbooks\_filters.html#combining-hashes-dictionaries](http://docs.ansible.com/ansible/playbooks_filters.html#combining-hashes-dictionaries)

"
