Search code examples
ansiblejmespath

Ansible Filter with_items list


I am using Ansible 2.10.7 and I need to filter a specific item in the with_items list.

Before using with_items msg looks like this:

"ansible_facts": {
    "cvp_info": {
        "version": "2020.2.3"
    },
    "devices": [
        {
            "architecture": "",
            "bootupTimeStamp": 1615810038.137913,
            "bootupTimestamp": 1615810038.137913,
            "complianceCode": "",

Playbook:

---
- name: Playbook to demonstrate cv_container module.
  hosts: cvp_servers
  connection: local
  gather_facts: no
  collections:
    - arista.cvp
  vars:
  vars_files:
            - vars.yml
  tasks:
    - name: "collecting facts from CVP {{inventory_hostname}}"
      arista.cvp.cv_facts:
        facts:
          devices
    - name: "Print out facts from CVP"
      debug:
        msg: "{{item.name}}"
      with_items: "{{devices}}"

After using the with_items: "{{devices}}", I see it is filtering the big list and then I get this output which I want to filter:

ok: [hq] => (item={'hostname': 'rd-sw055', 'danzEnabled': False, 'mlagEnabled': False, 'streamingStatus': 'active', 'status': 'Registered','bootupTimeStamp': 1605618537.210405, 'internalBuildId': '8c8dfbf2-a4d1-420a-9c9c-59f6aa67a14e', 'taskIdList': [], 'tempAction': None, 'memTotal': 0, 'memFree': 0, 'sslConfigAvailable': False, 'sslEnabledByCVP': False, 'lastSyncUp': 0, 'type': 'netelement', 'dcaKey': None, 'containerName': 'HQ', 
  'name': 'rd-sw055','deviceSpecificConfiglets': ['rd-sw055'], 'imageBundle': ''}) => {
  "msg": "rd-sw055"
      
ok: [hq] => (item={'hostname': 'rd-sw01', 'danzEnabled': False, 'mlagEnabled': False, 'streamingStatus': 'active', 'status': 'Registered','bootupTimeStamp': 1605618537.210405, 'internalBuildId': '8c8dfbf2-a4d1-420a-9c9c-59f6aa67a14e', 'taskIdList': [], 'tempAction': None, 'memTotal': 0, 'memFree': 0, 'sslConfigAvailable': False, 'sslEnabledByCVP': False, 'lastSyncUp': 0, 'type': 'netelement', 'dcaKey': None, 'containerName': 'HQ',
  'name': 'rd-sw01','deviceSpecificConfiglets': ['rd-sw01'], 'imageBundle': ''}) => {
  "msg": "rd-sw01"

I want it to show only the item with the 'name': 'rd-sw01' how can I do it?

I have tried using

loop_control:
   label: '{{ item.name }}'

At the end of the playbook but this will only show name value and not the whole item values.

End result wanted:

ok: [hq] => (item={'hostname': 'rd-sw01', 'danzEnabled': False, 'mlagEnabled': False, 'streamingStatus': 'active', 'status': 'Registered','bootupTimeStamp': 1605618537.210405, 'internalBuildId': '8c8dfbf2-a4d1-420a-9c9c-59f6aa67a14e', 'taskIdList': [], 'tempAction': None, 'memTotal': 0, 'memFree': 0, 'sslConfigAvailable': False, 'sslEnabledByCVP': False, 'lastSyncUp': 0, 'type': 'netelement', 'dcaKey': None, 'containerName': 'HQ',
  'name': 'rd-sw01','deviceSpecificConfiglets': ['rd-sw01'], 'imageBundle': ''}) => {
  "msg": "rd-sw01"

Solution

  • You do want a when condition here:

    - debug:
        var: item
      loop: "{{ devices }}"
      when: item.name == 'rd-sw01'
      loop_control:
        label: "{{ item.name }}"
    

    Or even, simpler, skip the loop:

    - debug:
        var: devices | selectattr("name", "eq", "rd-sw01")