Search code examples
listansiblenested

Ansible loop over nested and string loop


My goal is to have a task that runs in a loop over multiple objects in a list, one of those objects is a list itself. When i separate the list from the normal vars it works as expected, to save code i want to do them both in the same task.

The following playbook does not output my expected result, it prints all the objects of the list instead of iterating over them, how can i iterate over them essentially as a nested list? Ty very much :)

I have the following playbook:

- hosts: localhost
  connection: local
  gather_facts: false
  vars:
    test_var:
      - name: "ben"
      - name: "ben_test"
  tasks:
    - name: test print
      shell: "echo {{ item }}"
      loop:
        - "ben_str"
        - "ben_second_str"
        - "{{ test_var }}"

Also tried to have in the shell some if conditionals without success, would love to know so i can save some code instead of double printing.

In my case it's a more complex code, just for simplicity reasons using echo and shell :) Ty for the help.


Solution

  • I'm not entirely sure I get what you are trying to do exactly but I suspect both examples below should achieve what you expect. Meanwhile, I'd like to emphasize your data structure is absolutely not ideal (i.e. mix of string and list within the same list, mix of strings and objects in the same result flattened list....).

    Note: the list of options below is not exhaustive

    Option 1:

         - name: test print
           debug:
             var: item
           vars:
             my_list:
               - "ben_str"
               - "ben_second_str"
               - "{{ test_var | map(attribute='name') }}"
           loop: "{{ my_list | flatten }}"
    

    Option 2:

        - name: test print
          debug:
            var: item
          with_items:
            - "ben_str"
            - "ben_second_str"
            - "{{ test_var | map(attribute='name') }}"
    

    Option 3:

        - name: test print
          debug:
            var: item
          vars:
            my_other_list:
              - "ben_str"
              - "ben_second_str"
          loop: "{{ my_other_list + test_var | map(attribute='name') }}"
    

    which all give inserted in your above original play containing the test_var definition:

    TASK [test print] ************************************************************
    ok: [localhost] => (item=ben_str) => {
        "ansible_loop_var": "item",
        "item": "ben_str"
    }
    ok: [localhost] => (item=ben_second_str) => {
        "ansible_loop_var": "item",
        "item": "ben_second_str"
    }
    ok: [localhost] => (item=ben) => {
        "ansible_loop_var": "item",
        "item": "ben"
    }
    ok: [localhost] => (item=ben_test) => {
        "ansible_loop_var": "item",
        "item": "ben_test"
    }