Filter loop result by string list?

I run an action via a loop list of multiple times:

Action (1):

    - name: My action loop
        ...
      register: fruit_result
      loop:
        - apple
        - banana
        - orange
        - kiwi
        ...

However I have a list of fruit for which I *don’t want to run the loop. This list is the result from a command action:

Action (0):

    - name: Get the list for which to do nothing
      ansible.builtin.command:
        cmd: ...
      register: fruit_to_avoid

fruit_to_avoid might contain

"""orange
apple
"""

So now, in this example for orange and apple I do not want to run the loop (1).

Given that I run (0) beforehand, how can I run the loop only for fruit not in the fruit_to_avoid?

Firsly, split the command output to a list and then you can use difference filter, like so:

    - name: My action loop
        ...
      register: fruit_result
      loop: "{{ fruits | difference(fruit_to_avoid.stdout | trim | split('\n')) }}"
      vars:
        fruits:
          - apple
          - banana
          - orange
          - kiwi
2 Likes

Test an item is not in the text

    - name: My action loop
      when: item not in fruit_to_avoid.stdout
      register: fruit_result
        ...
      loop: [apple, banana, orange, kiwi]

Alternatively, put the list into a variable

    fruits: [apple, banana, orange, kiwi]

and reject items

    - name: My action loop
      register: fruit_result
         ...
      loop: "{{ fruits | reject('in', fruit_to_avoid.stdout) }}"

Example of a complete playbook for testing

- hosts: localhost

  vars:

    fruits: [apple, banana, orange, kiwi]
    fruit_to_avoid:
      stdout: |
        """orange
        apple
        """

  tasks:

    - name: My action loop
      when: item not in fruit_to_avoid.stdout
      register: fruit_result
      debug:
        msg: "{{ item }}"
      loop: [apple, banana, orange, kiwi]

    - name: My action loop
      register: fruit_result
      debug:
        msg: "{{ item }}"
      loop: "{{ fruits | reject('in', fruit_to_avoid.stdout) }}"
2 Likes