Ansible - Filter a dict with a list of keys

17,376

Here you go:

- name: Manage users Authorized Keys
  authorized_key:
    user: "{{ item.key }}"
    key: "{{ item.value.authorized_keys | map('extract',pub_keys) | list | join('\n') }}"
    exclusive: yes
  with_dict: "{{ users }}"

See extract filter usage.

Also when you use map you should almost always typecast it to list to prevent generator object value.

Share:
17,376
xenlo
Author by

xenlo

Linux/Unix Systems Engineer & Open Source enthusiast

Updated on June 15, 2022

Comments

  • xenlo
    xenlo almost 2 years

    I have a list which is actually a list of keys of a dict. And I want to get a concatenated string with the dict filtered on this list of keys and use it in a module option.

    My use case here is users that have a list of public keys's name to generate an authorized_keys file.

     1 ---
     2 - hosts: localhost
     3   become: false
     4   vars:
     5     pub_keys:
     6       key01: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ[…]5/ someuser@somehost
     7       key02: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ[…]ea otheruser@somewher
     8       key03: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ[…]dN anyser@anyhost
     9     users:
    10       root:
    11         home: /root
    12         shell: /bin/bash
    13         authorized_keys:
    14           - key01
    15       mgmtusr:
    16         home: /home/mgmtusr
    17         shell: /bin/bash
    18         authorized_keys:
    19           - key01
    20           - key02
    21           - key03
    22
    23   tasks:
    24     - name: Debug Authorized Keys
    25       debug:
    26         msg: "USER:{{ item.key }} AUTHKEYSLIST:{{ pub_keys|selectattr(item.authorized_keys) }}"
    27       with_dict: "{{ users }}"
    28
    29     - name: Manage users Authorized Keys
    30       authorized_key:
    31         user: "{{ item.key }}"
    32         key: "{{ pub_keys|selectattr(item.authorized_keys) }}"
    33         exclusive: yes
    34       with_dict: "{{ users }}"
    35
    

    As you can see here, I give it a try with dict|selectattr(list) but it fails.

    Getting <generator object select_or_reject at 0x…> in the debug module and of course an invalid key specified in the authorized_key module.

    TASK [Debug Authorized Keys] **************************************************************************************************************************************************************************************************************************************************
    ok: [localhost] => (item={'key': u'mgmtusr', 'value': {u'home': u'/home/mgmtusr', u'shell': u'/bin/bash', u'authorized_keys': [u'key01', u'key02', u'key03']}}) => {
        "item": {
            "key": "mgmtusr",
            "value": {
                "authorized_keys": [
                    "key01",
                    "key02",
                    "key03"
                ],
                "home": "/home/mgmtusr",
                "shell": "/bin/bash"
            }
        },
        "msg": "USER:mgmtusr AUTHKEYSLIST:"
    }
    ok: [localhost] => (item={'key': u'root', 'value': {u'home': u'/root', u'shell': u'/bin/bash', u'authorized_keys': [u'key01']}}) => {
        "item": {
            "key": "root",
            "value": {
                "authorized_keys": [
                    "key01"
                ],
                "home": "/root",
                "shell": "/bin/bash"
            }
        },
        "msg": "USER:root AUTHKEYSLIST:"
    }
    
    TASK [Manage users Authorized Keys] *******************************************************************************************************************************************************************************************************************************************
    failed: [localhost] (item={'key': u'mgmtusr', 'value': {u'home': u'/home/mgmtusr', u'shell': u'/bin/bash', u'authorized_keys': [u'key01', u'key02', u'key03']}}) => {"changed": false, "failed": true, "item": {"key": "mgmtusr", "value": {"authorized_keys": ["key01", "key02", "key03"], "home": "/home/mgmtusr", "shell": "/bin/bash"}}, "msg": "Failed to lookup user mgmtusr: 'getpwnam(): name not found: mgmtusr'"}
    failed: [localhost] (item={'key': u'root', 'value': {u'home': u'/root', u'shell': u'/bin/bash', u'authorized_keys': [u'key01']}}) => {"changed": false, "failed": true, "item": {"key": "root", "value": {"authorized_keys": ["key01"], "home": "/root", "shell": "/bin/bash"}}, "msg": "invalid key specified: "}
    

    Like other tries (with_subelements, lookup('template', …) selectattr does not seems the solution. Any proposition?

  • xenlo
    xenlo over 6 years
    Thanks for that answer! I read a bit on map when searching but didn't get it yet. So definitively now, I have to learn more about that one.