combining dicts in a list

Hello,

I have a list of dicts, and I would like to add a (key, value) pair to each dict (ie. to each element of the list).

Typically, I have this list:

  • port: 2000
    release: trusty
  • port: 2001
    release: xenial

And I would like to create this one

  • port: 2000
    release: trusty
    name: trusty-2000
  • port: 2001
    release: xenial
    name: xenial-2001

Is it possible? I tried using the “map(‘combine’)” filter (see below) but do see how to compute a different value for each element.
This is probably something obvious that I’m missing.

Thank you!

$ cat list.yaml

  • hosts: localhost
    vars:
  • containers:
  • port: 2000
    release: trusty
  • port: 2001
    release: xenial
  • containers_with_name: “{{ containers | map(‘combine’, {‘name’: ‘TODO:release-port’ }) | list }}”
    tasks:
  • debug:
    msg: “containers_with_name: {{ containers_with_name }}”

$ ansible-playbook list.yaml
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [localhost] ***************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [debug] *******************************************************************
ok: [localhost] => {
“msg”: “containers_with_name: [{u’release’: u’trusty’, u’port’: 2000, ‘name’: ‘TODO:release-port’}, {u’release’: u’xenial’, u’port’: 2001, ‘name’: ‘TODO:release-port’}]”
}
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0

Try this. Its not exactly pretty, but it seems to do what you need.

$ cat listtest-playbook.yml

Hello,

thank you for your answer, and sorry for my late one.

Try this. Its not exactly pretty,

indeed :frowning:
I’m growing increasingly frustrated by the many quirks and lack of expressibility of ansible’s dialect .

This would have been peanuts to write in python. I probably investigate how to write python module/filters in order to avoid jinja-ed yaml.

but it seems to do what you need.

Yes, thank you.
For my real use-case, I ended-up using with_subelements (see below), but I’ll recall how you use set_fact.

$ cat hosts
[jenkins_masters]
ald-1545-de
[jenkins_slaves_holders]
ald-1545-de
ald-1469-de
[jenkins_slaves_holders:vars]
jenkins_slaves=[{‘release’: ‘trusty’, ‘ssh_port’: 2000},{‘release’: ‘xenial’, ‘ssh_port’: 2001}]

$ cat main.yaml

let ansible know about each created container

add_host “bypasses the play host loop”: it will only be called from one host.

Let this host be “localhost”, for symmetry.

  • hosts: localhost
    tasks:
  • add_host:
    hostname: “{{ item.0.inventory_hostname_short }}-build-{{ item.1.release }}”
    container_holder_inventory_hostname_short: “{{ item.0.inventory_hostname_short }}”
    ansible_port: “{{ item.1.ssh_port }}”
    ansible_host: “{{ item.0.ansible_host }}”
    ansible_user: ‘root’
    jenkins_master: “{{ groups[‘jenkins_masters’] | first | mandatory }}”
    groups: ‘build,jenkinsslaves’
    with_subelements:
  • “{{ groups[‘jenkins_slaves_holders’] | map(‘extract’, hostvars) | list }}”
  • jenkins_slaves

Thank you again!