How can I make a variable that has a filtered set of the volume group facts?

When I print ansible_facts.lvm.vgs, I get:

    vg_lago:
      free_g: '558.08'
      num_lvs: '5'
      num_pvs: '1'
      size_g: '1861.85'
    vg_mirror:
      free_g: '0'
      num_lvs: '1'
      num_pvs: '1'
      size_g: '9313.87'
    vg_picasso:
      free_g: '0'
      num_lvs: '4'
      num_pvs: '1'
      size_g: '39104.61'
    vg_vincent:
      free_g: '484.13'
      num_lvs: '10'
      num_pvs: '1'
      size_g: '926.38'

I want to create a new variable in the playbook that is the same as above, but with volume groups having free space equal to zero filtered out.

Thus, the desired result is to create a variable:

vars:    
    VolumeGroupsWithFreeSpace: []

That contains only:

    vg_lago:
      free_g: '558.08'
      num_lvs: '5'
      num_pvs: '1'
      size_g: '1861.85'
    vg_vincent:
      free_g: '484.13'
      num_lvs: '10'
      num_pvs: '1'
      size_g: '926.38'

I tried using:

"{{ ansible_facts.lvm.vgs | selectattr('free_g', 'equalto', '0') | list }}"

But this doesn’t seem to work, it complains that ‘free_g’ is an undefined property.

I’m not sure that selectattr can use a multi-dimensional property to filter on, and if it can, I can’t find the syntax for it.

Maybe it’s possible with a loop, so I started trying this:

- name: "Build a list of volume groups where free space is > 0."
      set_fact:
        VolumeGroupsWithFreeSpace: "{{ VolumeGroupsWithFreeSpace }} + [ '{{ item.free_g }}' ]"
      with_items: "{{ ansible_facts.lvm.vgs }}"

But this also complains:

'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'free_g'

How can I make a variable that has a filtered set of the volume group facts?

I think I’m close to an answer, but it’s not quite right:

---
- hosts: all
  become: true

  vars:    
    VolumeGroupsWithFreeSpace: []

  tasks:
    - name: "Print raw facts"
      debug:
        msg: "{{ ansible_facts.lvm.vgs }}"

    - name: Filter out full volume groups
      set_fact:        
        VolumeGroupsWithFreeSpace: "{{ VolumeGroupsWithFreeSpace }} + [ '{{ item }}' ]"
      when: "{{ (item.value.free_g | int) > 0 }}"
      loop: "{{ ansible_facts.lvm.vgs | dict2items }}"

    - name: Print VolumeGroupsWithFreeSpace.
      debug:
        msg: "{{ VolumeGroupsWithFreeSpace }}"

The output looks like:

msg: '[] + [ ''{''key'': ''vg_lago'', ''value'': {''size_g'': ''1861.85'', ''free_g'': ''558.08'', ''num_lvs'': ''5'', ''num_pvs'': ''1''}}'' ] + [ ''{''key'': ''vg_vincent'', ''value'': {''size_g'': ''926.38'', ''free_g'': ''484.13'', ''num_lvs'': ''10'', ''num_pvs'': ''1''}}'' ]'

So the filtering is working, it’s just storing it in a weird format. I think the issue is I don’t know how to add an element to an array.