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.

AVOID TROUBLE

9 times out of 10, when I would run a playbook that had include_role, the playbook would run just fine with no issues. However, every now and then it would fail with something like this.

TASK [include_role 'foo' main.yml] ************************************
ERROR! Could not find specified file in role: tasks/main.yml

 

I think this is a defect with the include_role module as mentioned in this GitHub issue -> https://github.com/ansible/ansible/issues/22571. For this reason, I always instead use one of the other modules, usually import_role.

 

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 the /tmp/foo.txt file and the bar role creates the /tmp/bar.txt file.

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

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

 

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
...

 

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 a messy ansible.log that might have a bunch of "skipping" tasks.

TASK [/etc/ansible/roles/foo: foo test] 
ok: [server1.example.com] => {
    "msg": "Hello World"
}
 
TASK [/etc/ansible/roles/bar: bar test] 
skipping: [server1.example.com]

 

Sometimes, it's better to use include_role.

---
- 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.

TASK [/etc/ansible/roles/foo: foo test] 
ok: [server1.example.com] => {
    "msg": "Hello World"
}

 

tasks_from

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.

- name: include_role 'roles/foo/tasks/main.yml'
  ansible.builtin.include_role:
    name: foo

 

If you have other yaml files in the role tasks directory, such as roles/foo/tasks/bar.yml, the tasks_from parameter can be used to invoke the tasks in bar.yml.

- name: include_role 'roles/foo/tasks/bar.yml'
  ansible.builtin.include_role:
    name: foo
    tasks_from: bar

 

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 delegate_to

Here is how you can use delegate_to to run all of the tasks in the "foo" 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
...

 




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 dca4f9 in the box below so that we can be sure you are a human.