listansibleelement

Ansible - remove empty elements from the list


I have an ansible output from which I want to remove all empty (none) elements for a specific attribute. Here is the example list:

"resources": [
    {
        "id": "9c40900909",
        "name": "some_name1"
    },
    {
        "id": "pc4b09090"
    },
    {
        "id": "8lknkkn45"
    },
    {
        "id": "9df40900909",
        "name": "some_name2"
    }
]

Here is how I reduced the list to be just "resources" with attribute "name":

- set_fact:
    resources_names: "{{ output.resources | map(attribute='name') }}"

Problem with that is that I get the elements that does not have any value for the name. These are "AnsibleUndefined" in the following output:

- debug:
    msg: resources_names list is "{{ resources_names }}"
ok: [localhost] => {
   "msg": "resources_names list is \"['some_name1', AnsibleUndefined, AnsibleUndefined, 'some_name2']\""
}

I tried to remove it with reject and regexp but that's not working.

- set_fact:
    list2: "{{ resources_names | reject('match', '^$') | list }}"

Same with this one:

- set_fact:
    resources_names: "{{ output.resources | map(attribute='name') | rejectattr('name', 'none') }}"

Any idea?

Thanks.


Solution

  • In a nutshell:

    ---
    - hosts: localhost
      gather_facts: false
    
      vars:
        resources: [
            {
                "id": "9c40900909",
                "name": "some_name1"
            },
            {
                "id": "pc4b09090"
            },
            {
                "id": "8lknkkn45"
            },
            {
                "id": "9df40900909",
                "name": "some_name2"
            }
        ]
    
      tasks:
        - debug:
            msg: "{{ resources | selectattr('name', 'defined') | map(attribute='name') }}"
    

    which gives:

    $ ansible-playbook /tmp/play.yml 
    [WARNING]: No inventory was parsed, only implicit localhost is available
    
    PLAY [localhost] *******************************************************************************************************************************************************************************
    
    TASK [debug] ***********************************************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": [
            "some_name1",
            "some_name2"
        ]
    }
    
    PLAY RECAP *************************************************************************************************************************************************************************************
    localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0