Search code examples
ansiblejinja2

flatten ansible result using jinja2


I am getting a list of elements of the same structure using ansible, it looks a bit like the following:

results: [
  {
    "a": "foo",
    "b": "bar",
    "c": [
      {"c1": ...},
      {"c2": ...}
      {"c3": ...}]
  },
  {
    "a": "foo2",
    "b": "bar2",
    "c": [
      {"c4": ...},
      {"c5": ...}
      {"c6": ...}]
  }
]

I would need to iterate over all subelements of c - of all elements, so what I want is a list of the elements: c1, c2, c3, c4, c5, c6...

Normally I would use a nested loop, but since ansible is using jinja2s filters, I have no clue on how to accomplish that. I am totally new to this kind of data transformation.


To give some context, the actual code is:

- name: Find log files that are older than 1 day
  find:
    paths: "{{ item }}"
    age: 1d
    recurse: no
  register: oldLogs
  loop:
    - "/var/log"
    - "/home/user/log"

- name: print files
  debug:
    msg: "{{ oldLogs.results | <some filters here> }}\n"

Yes, I know I could pass a list of paths to find instead, but that's not the way I want to go, instead I would like to learn on how to use filters in such a situation.


Solution

  • For example,

    results_c: "{{ (results|
                    map(attribute='c')|
                    flatten|
                    combine).keys()|list }}"
    

    gives the list

    results_c: [c1, c2, c3, c4, c5, c6]
    

    Example of a complete playbook for testing

    - hosts: localhost
      vars:
        results:
          - a: foo
            b: bar
            c:
              - c1: val_1
              - c2: val_2
              - c3: val_3
          - a: foo2
            b: bar2
            c:
              - c4: val_4
              - c5: val_5
              - c6: val_6
        results_c: "{{ (results|
                        map(attribute='c')|
                        flatten|
                        combine).keys()|list }}"
      tasks:
        - debug:
            var: item
          loop: "{{ results_c }}"
    

    gives (abridged)

    TASK [debug] *********************************************************************************
    ok: [localhost] => (item=c1) => 
      ansible_loop_var: item
      item: c1
    ok: [localhost] => (item=c2) => 
      ansible_loop_var: item
      item: c2
    ok: [localhost] => (item=c3) => 
      ansible_loop_var: item
      item: c3
    ok: [localhost] => (item=c4) => 
      ansible_loop_var: item
      item: c4
    ok: [localhost] => (item=c5) => 
      ansible_loop_var: item
      item: c5
    ok: [localhost] => (item=c6) => 
      ansible_loop_var: item
      item: c6