I'm trying to work out how to loop over a list of dicts and extract the name of each entry to merge with another variable.
jinja2 pseudo code which should give the desired result:
---
docker_applications:
- name: foo
zfs_opts:
quota: 4G
compression: false
- name: bar
zfs_filesystems:
- name: rust/ftp
- name: ssd/one
quota: 1T
- name: ssd/two
{% for i in docker_applications %}
- name: "docker/{{ i.name }}"
{% for k, v in i.zfs_opts %}
{{ k }}: {{ v }}
{% endfor %}
{% endfor %}
Which would give:
---
zfs_filesystems:
- name: rust/ftp
- name: ssd/one
quota: 1T
- name: ssd/two
- name: docker/foo
quota: 4G
compression: false
- name: docker/bar
I know you can't use jinja2 templates in a variable files, so I am trying to do the merge in the inventory file but I'm at a loss on how I could achieve this.
- name: nas
hosts: nas
become: true
become_user: root
roles:
- docker
- zfs
vars:
zfs_filesystems: zfs_filesystems|do_something
Put the declaration into the vars
docker_fs: "{{ docker_applications|
json_query('[].[{name: join(`/`, [`docker`, name])}, zfs_opts]')|
map('combine')|list }}"
gives
docker_fs:
- compression: false
name: docker/foo
quota: 4G
- name: docker/bar
Then, concatenate the lists
- set_fact:
zfs_filesystems: "{{ zfs_filesystems + docker_fs }}"
gives
zfs_filesystems:
- name: rust/ftp
- name: ssd/one
quota: 1T
- name: ssd/two
- compression: false
name: docker/foo
quota: 4G
- name: docker/bar
Example of a complete playbook for testing
- hosts: localhost
vars:
docker_applications:
- name: foo
zfs_opts:
quota: 4G
compression: false
- name: bar
zfs_filesystems:
- name: rust/ftp
- name: ssd/one
quota: 1T
- name: ssd/two
docker_fs: "{{ docker_applications|
json_query('[].[{name: join(`/`, [`docker`, name])}, zfs_opts]')|
map('combine')|list }}"
tasks:
- debug:
var: docker_fs
- set_fact:
zfs_filesystems: "{{ zfs_filesystems + docker_fs }}"
- debug:
var: zfs_filesystems
The above solution puts the full value of the attribute zfs_opts into the dictionary. Optionally, select the attributes quota and compression. The declaration below
docker_fs: "{{ docker_applications|
json_query('[].{name: join(`/`, [`docker`, name]),
quota: zfs_opts.quota,
compression: zfs_opts.compression}') }}"
gives
docker_fs:
- compression: false
name: docker/foo
quota: 4G
- compression: null
name: docker/bar
quota: null
Optionally, get rid of the null values
docker_fs: "{{ docker_applications|
json_query('[].{name: join(`/`, [`docker`, name]),
quota: zfs_opts.quota,
compression: zfs_opts.compression}')|
map('dict2items')|
map('rejectattr', 'value', 'eq', None)|
map('items2dict')|
list }}"
gives
docker_fs:
- compression: false
name: docker/foo
quota: 4G
- name: docker/bar