Search code examples
ansiblejmespathjson-query

How to filter element of list with a list in ansible with a json_query or other


I created an ansible playbook. And I want a task executed only if a json_query returns element.

The json query have to returned an array searching if in an element from array of array exists in an element of another array.

I already tried using json_query (jmespath) with simplified queries I read the jmespath doc and try with the website tutorial. Read the ansible documentation and try to find example.

I think the good solution is to use contains built-in functions and map functions. But example with map and the documentation is not clear for me.

Example :

array_of_array_to_check : [
{
    hosts : ["host1", "host2"],
    name : "name1"
},
{
    hosts : [ "host3", "host1"],
    name : "name2"
},
{
    hosts : ["host4", "host5"],
    name : "name3"
}
]

array_parameters: ["host1", "host18"]

Expected :

result: [
{
    hosts: ["host1", "host2"],
    name: "name1"
},
{
    hosts: ["host3", "host1"],
    name: "name2"
}
]

Solution

  • here is a way to do it:

    ---
    - hosts: localhost
      gather_facts: false
      vars:
        array_of_array_to_check:
        - hosts:
          - host1
          - host2
          name: name1
        - hosts:
          - host3
          - host1
          name: name2
        - hosts:
          - host4
          - host5
          name: name3
        array_parameters: 
        - host1
        - host18
    
      tasks:
      - name: parse array and add to results
        set_fact: 
          results_array: "{{ results_array | default([]) + [item] }}"
        when: item.hosts | intersect(array_parameters) | length > 0
        with_items:
        - "{{ array_of_array_to_check }}"
    
      - debug:
          var: results_array
    

    basically you parse the array_of_array_to_check list, and if you find common elements in its elements' hosts list with the array_parameters, then you add the whole "item" to the results_array

    intersect filter gets the "unique list of all items in both" , so if length is more than 0, then there are matches found.

    hope it helps.