Chris Midgley
Chris Midgley

Reputation: 1631

How do I apply an Ansible with_items loop to the included tasks?

The documentation for import_tasks mentions

Any loops, conditionals and most other keywords will be applied to the included tasks, not to this statement itself.

This is exactly what I want. Unfortunately, when I attempt to make import_tasks work with a loop

- import_tasks: msg.yml
  with_items:
    - 1
    - 2
    - 3

I get the message

ERROR! You cannot use loops on 'import_tasks' statements. You should use 'include_tasks' instead.

I don't want the include_tasks behaviour, as this applies the loop to the included file, and duplicates the tasks. I specifically want to run the first task for each loop variable (as one task with the standard with_items output), then the second, and so on. How can I get this behaviour?


Specifically, consider the following:

Suppose I have the following files:

playbook.yml

---                       

- hosts: 192.168.33.100
  gather_facts: no
  tasks:
  - include_tasks: msg.yml
    with_items:
      - 1
      - 2

msg.yml

---

- name: Message 1
  debug:
    msg: "Message 1: {{ item }}"

- name: Message 2
  debug:
    msg: "Message 2: {{ item }}"

I would like the printed messages to be

Message 1: 1
Message 1: 2
Message 2: 1
Message 2: 2

However, with import_tasks I get an error, and with include_tasks I get

Message 1: 1
Message 2: 1
Message 1: 2
Message 2: 2

Upvotes: 16

Views: 49339

Answers (2)

Chris Midgley
Chris Midgley

Reputation: 1631

You can add a with_items loop taking a list to every task in the imported file, and call import_tasks with a variable which you pass to the inner with_items loop. This moves the handling of the loops to the imported file, and requires duplication of the loop on all tasks.


Given your example, this would change the files to:

playbook.yml

---

- hosts: 192.168.33.100
  gather_facts: no
  tasks:
  - import_tasks: msg.yml
    vars:
      messages:
        - 1
        - 2

msg.yml

---

- name: Message 1
  debug:
    msg: "Message 1: {{ item }}"
  with_items:
    - "{{ messages }}"

- name: Message 2
  debug:
    msg: "Message 2: {{ item }}"
  with_items:
    - "{{ messages }}"

Upvotes: 14

Konstantin Suvorov
Konstantin Suvorov

Reputation: 68229

It is not possible. include/import statements operate with task files as a whole.

So with loops you'll have:

Task 1 with Item 1
Task 2 with Item 1
Task 3 with Item 1
Task 1 with Item 2
Task 2 with Item 2
Task 3 with Item 2
Task 1 with Item 3
Task 2 with Item 3
Task 3 with Item 3

Upvotes: 1

Related Questions