Bootstrap FreeKB - Ansible - Invoking a role using the include_role module
Ansible - Invoking a role using the include_role module

Updated:   |  Ansible articles

There are a few different ways to invoke one or more roles in a playbook.

Let's say you have the following structure.

├── /usr/local
│   ├── main.yml
│   ├── roles
│   │   ├── foo
│   │   ├── ├── tasks
│   │   ├── ├── ├── main.yml
│   │   ├── bar
│   │   ├── ├── tasks
│   │   ├── ├── ├── main.yml

 

And the foo role creates and then deletes the /tmp/foo.txt file and the bar role creates and then deletes the /tmp/bar.txt file.

~]$ cat roles/foo/tasks/main.yml
- name: touch /tmp/foo.txt
  ansible.builtin.file:
    path: /tmp/foo.txt
    state: touch

- name: delete /tmp/foo.txt    
  ansible.builtin.file:
    path: /tmp/foo.txt
    state: absent

~]$ cat roles/bar/tasks/main.yml
- name: touch /tmp/bar.txt
  ansible.builtin.file:
    path: /tmp/bar.txt
    state: touch
    
- name: delete /tmp/bar.txt    
  ansible.builtin.file:
    path: /tmp/bar.txt
    state: absent    

 

Here is a simple example of how roles "foo" and "bar" could be run using include_role. This assumes that the "foo" and "bar" roles are included in one of your roles search directories.

---
- hosts: localhost
  tasks:
  - name: include_role foo
    ansible.builtin.include_role:
      name: foo

  - name: include_role bar
    ansible.builtin.include_role:
      name: bar
...

 

Running this playbook should return something like this.

PLAY [localhost] *********************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************************************
ok: [localhost]

TASK [include_role foo] **************************************************************************************************************************************************************************************

TASK [foo : touch /tmp/foo.txt] ******************************************************************************************************************************************************************************
changed: [localhost]

TASK [foo : delete /tmp/foo.txt] *****************************************************************************************************************************************************************************
changed: [localhost]

TASK [include_role bar] **************************************************************************************************************************************************************************************

TASK [bar : touch /tmp/bar.txt] ******************************************************************************************************************************************************************************
changed: [localhost]

TASK [bar : delete /tmp/bar.txt] *****************************************************************************************************************************************************************************
changed: [localhost]

PLAY RECAP ***************************************************************************************************************************************************************************************************
localhost                  : ok=5    changed=4    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

 

Let's say you are using when to do something like this.

---
- hosts: all
  roles:
  - role: foo
    when: x is defined

  - role: bar
    when: y is defined
...

 

This is not ideal, as each task in the playbook that is not used will be skipped, making for messy output and a messy ansible.log with a bunch of "skipping" tasks.

PLAY [localhost] *********************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************************************
ok: [localhost]

TASK [foo : touch /tmp/foo.txt] ******************************************************************************************************************************************************************************
skipping: [localhost]

TASK [foo : delete /tmp/foo.txt] *****************************************************************************************************************************************************************************
skipping: [localhost]

TASK [bar : touch /tmp/bar.txt] ******************************************************************************************************************************************************************************
skipping: [localhost]

TASK [bar : delete /tmp/bar.txt] *****************************************************************************************************************************************************************************
skipping: [localhost]

PLAY RECAP ***************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=4    rescued=0    ignored=0

 

One thing that is really nice about include_role is that if the when statement does not evaluate to true the role will just totally be skipped and you won't get a bunch of output with "skipping" tasks.

---
- hosts: all
  tasks:
  - name: include_role foo when x is defined
    ansible.builtin.include_role:
      name: foo
    when: x is defined

  - name: include_role bar when y is defined
    ansible.builtin.nclude_role:
      name: bar
    when: y is defined
...

 

Now, the role will be skipped without iterating through each task in the role.

PLAY [localhost] *********************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************************************************************************************************
ok: [localhost]

TASK [include_role foo] **************************************************************************************************************************************************************************************
skipping: [localhost]

TASK [include_role bar] **************************************************************************************************************************************************************************************
skipping: [localhost]

PLAY RECAP ***************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=2    rescued=0    ignored=0

 

By default, the tasks in the main.yml file in the role will be invoked. In this example, the tasks in roles/foo/tasks/main.yml would be run.

---
- hosts: all
  tasks:
  - name: include_role foo
    ansible.builtin.include_role:
      name: foo
...

 

tasks_from can be used to invoke the tasks in a specific YAML file. In this example, the tasks in roles/foo/tasks/bar.yml would be run.

---
- hosts: all
  tasks:
  - name: include_role foo bar.yml
    ansible.builtin.include_role:
      name: foo
      tasks_from: bar.yml
...

 

Including variables (vars and vars_from)

By default, if there is a "vars" directory that contains a main.yml file in the same directory as the role, the variables in the vars main.yml file will be available in the tasks main.yml file.

roles/foo/tasks/main.yml
roles/foo/vars/main.yml

 

If you have other yaml files in the role vars directory, such as roles/foo/vars/bar.yml, the vars_from parameter can be used to include the variable in bar.yml.

---
- hosts: all
  tasks:
  - name: include the variables in roles/foo/vars/bar.yml
    ansible.builtin.include_role:
      name: foo
      vars_from: bar
...

 

Or, variables can be define using vars.

---
- hosts: all
  tasks:
  - ansible.builtin.include_role:
      name: foo
    vars:
      bar: Hello World
...

 

Apply can be used to use  delegate_to to run all of the tasks in the role on localhost. It almost always makes sense to also have run_once: true since you probably don't want to run the tasks on localhost more than once.

---
- hosts: all
  tasks:
  - ansible.builtin.include_role:
      name: foo
      apply:
        delegate_to: localhost
        run_once: true
...

 

apply can also be used to use in the role so that all tasks in the role are invoked using become.

---
- hosts: all
  tasks:
  - ansible.builtin.include_role:
      name: foo
      apply:
        become: yes
        become_user: jane.doe
...

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 8b698b in the box below so that we can be sure you are a human.