ansibleansible-filter

Ansible getent module's loop output results parsing


I am trying to check if a number of users are present or not in the managed node using getent module and create a list of users who are not present. The piece of code is:

- getent:
    database: passwd
    key: "{{ item }}"
    fail_key: no
  register: x
  loop:
    - "user1"
    - "user2"

- debug: var=x.results

- set_fact:
    fail_list: "{{ x.results | }}"

I am stuck at this point.
Is there any way I can save the users who are not present to the variable fail_list as a list?
In the above example, user1 is not present and user2 is present in the managed node.
The ansible version I am using is 2.9 and the debug output is a list of dicts as below:

    "x.results": [
        {
            "ansible_facts": {
                "getent_passwd": {
                    "user1": null
                }
            },
            "ansible_loop_var": "item",
            "changed": false,
            "failed": false,
            "invocation": {
                "module_args": {
                    "database": "passwd",
                    "fail_key": false,
                    "key": "user1",
                    "service": null,
                    "split": null
                }
            },
            "item": "user1",
            "msg": "One or more supplied key could not be found in the database."
        },
        {
            "ansible_facts": {
                "discovered_interpreter_python": "/usr/bin/python",
                "getent_passwd": {
                    "user2": [
                        "x",
                        "0",
                        "0",
                        "user2",
                        "/home/user2",
                        "/bin/bash"
                    ]
                }
            },
            "ansible_loop_var": "item",
            "changed": false,
            "failed": false,
            "invocation": {
                "module_args": {
                    "database": "passwd",
                    "fail_key": false,
                    "key": "user2",
                    "service": null,
                    "split": null
                }
            },
            "item": "user2"
        },

Solution

  • Run getent once and search the list of users. For example

    - hosts: localhost
      tasks:
        - getent:
            database: passwd
        - debug:
            msg: User {{ item }} exists.
          loop:
            - root
            - user1
            - user2
          when: item in my_users
          vars:
            my_users: "{{ getent_passwd.keys()|list }}"
    

    gives

    ok: [localhost] => (item=root) => {
        "msg": "User root exists."
    }
    skipping: [localhost] => (item=user1) 
    skipping: [localhost] => (item=user2)