a task in ansible 2.10.8:
I would like to merge two different lists of dicts to get one complemented with missing items, but not add a dict to the first list.
List of dicts one:
user_users:
- username: 'foo'
primarygid: 42
- username: 'bar'
List of dicts two:
user_users_skel:
- username: foo
uid: 600
primarygid: 600
shell: '/bin/bash'
ssh_login: false
- username: bar
uid: 602
primarygid: 602
shell: '/bin/bash'
ssh_login: true
- username: blupp
uid: 1000
primarygid: 1000
shell: '/bin/bash'
ssh_login: true
default_groups: 'admin'
initial_password_hash: '$2349887rhfewklrjn'
Expected Output (also a list of dicts):
- username: foo
uid: 600
primarygid: 42
shell: '/bin/bash'
ssh_login: false
- username: bar
uid: 602
primarygid: 602
shell: '/bin/bash'
ssh_login: true
I used different approaches, like
- set_fact:
eff_users: "{{ user_users | ansible.builtin.combine(user_users_skel) }}"
- ansible.builtin.debug:
var: eff_users
with bogus output.
users_all: "{{ [user_users, user_users_skel] |
community.general.lists_mergeby('username') }}"
gives
users_all:
- primarygid: 602
shell: /bin/bash
ssh_login: true
uid: 602
username: bar
- default_groups: admin
initial_password_hash: $2349887rhfewklrjn
primarygid: 1000
shell: /bin/bash
ssh_login: true
uid: 1000
username: blupp
- primarygid: 600
shell: /bin/bash
ssh_login: false
uid: 600
username: foo
usernames: "{{ user_users | map(attribute='username') }}"
gives
usernames:
- foo
- bar
eff_users: "{{ users_all | selectattr('username', 'in', usernames) }}"
gives what you want
eff_users:
- primarygid: 602
shell: /bin/bash
ssh_login: true
uid: 602
username: bar
- primarygid: 600
shell: /bin/bash
ssh_login: false
uid: 600
username: foo
Example of a complete playbook for testing
- hosts: all
vars:
user_users:
- username: foo
primarygid: 42
- username: bar
user_users_skel:
- username: foo
uid: 600
primarygid: 600
shell: /bin/bash
ssh_login: false
- username: bar
uid: 602
primarygid: 602
shell: /bin/bash
ssh_login: true
- username: blupp
uid: 1000
primarygid: 1000
shell: /bin/bash
ssh_login: true
default_groups: admin
initial_password_hash: $2349887rhfewklrjn
users_all: "{{ [user_users, user_users_skel] |
community.general.lists_mergeby('username') }}"
usernames: "{{ user_users | map(attribute='username') }}"
eff_users: "{{ users_all | selectattr('username', 'in', usernames) }}"
tasks:
- debug:
var: users_all
- debug:
var: usernames
- debug:
var: eff_users