Search code examples
ansibleansible-role

Ansible role with a loop on variables


I have a role called application_management. In the tasks folder the main.yml contains :

---
- name: "{{ item }}"
  include_tasks: '{{ item }}.yml'
  loop: "{{ role_actions }}"

In my playbook I'm using the role with

- role: application_management
  vars:
    role_actions:
      - taskA
      - taskB

It is working BUT the 2 tasks are first included

TASK [application_management : {{ item }}] *************************************************************************************************************************************************************************************************************
included: /mnt/d/dev/ansible/roles/application_management/tasks/taskA.yml for host01 => (item=taskA)
included: /mnt/d/dev/ansible/roles/application_management/tasks/taskB.yml for host01 => (item=taskB)

and only after both tasks are executed but without anything to distinguish which one it is.

Is there a way of including taskA / executing taskA, including taskB / executing taskB ?

Or a way to retrieve the item variable inside taskA.yml/taskB.yml ?

And I see TASK [application_management : {{ item }}]. Is there a way of getting the item name displayed ?


Solution

  • and only after both tasks are executed but without anything to distinguish which one it is.

    This can be fixed with task naming. In the following example, the said role has named tasks in taskA.yml and nameless tasks in taskB.yml:

    TASK [application_management : Including named tasks] *****************************************************************************************************************************************************
    included: /Users/alexander/IdeaProjects/stackoverflow/77887421/roles/application_management/tasks/taskA.yml for localhost => (item=taskA)
    included: /Users/alexander/IdeaProjects/stackoverflow/77887421/roles/application_management/tasks/taskB.yml for localhost => (item=taskB)
    
    TASK [application_management : task 1 of taskA] ***********************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "I am task 1 in taskA file"
    }
    
    TASK [application_management : task 2 of taskA] ***********************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "I am task 2 in taskA file"
    }
    
    TASK [application_management : debug] *********************************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "I am task 1 in taskB file"
    }
    
    TASK [application_management : debug] *********************************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "I am task 2 in taskB file"
    }
    
    

    Is there a way of including taskA / executing taskA, including taskB / executing taskB ?

    Including in Ansible means dynamic loading. What you're describing is importing (static loading), which is possible using import_tasks module. But it's unsuitable for your use case because it cannot be used with a loop. With that being said, include_tasks, of course, still works as you expect in terms of running the tasks sequentially.

    Or a way to retrieve the item variable inside taskA.yml/taskB.yml ?

    Sure, {{ item }} is a usual variable and will be available everywhere within the loop scope:

    # taskA.yml
    ---
    - name: task 1 of {{ item }}
      debug:
        msg: "I am task 1 in {{ item }} file"
    
    - name: task 2 of {{ item }}
      debug:
        msg: "I am task 2 in {{ item }} file"
    

    However, I would not recommend using it like that because it restricts the reusability of your tasks.

    Is there a way of getting the item name displayed ?

    No because the loop is not applied to it.

    By the way, if you just want to include some tasks from a role and don't need the role to control its execution, you don't need a loop within a role. You can use include_role module with tasks_from:

    # playbook.yaml
    ---
    - hosts: localhost
      gather_facts: false
      tasks:
        - name: Include tasks from the role
          include_role:
            name: application_management
            tasks_from: "{{ item }}"
          loop:
            - taskA
            - taskB