There are a few different ways to invoke one or more roles in a playbook.
- roles
- import_playbook
- import_role (this article)
- include_role
- include_tasks
- import_tasks
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
Your main.yml playbook could have the following, to import the foo and bar roles. This assumes that the "foo" and "bar" roles are included in one of your roles search directories.
---
- hosts: localhost
tasks:
- ansible.builtin.import_role:
name: foo
- ansible.builtin.import_role:
name: bar
...
Running the main.yml playbook should return the following.
~]$ ansible-playbook main.yml
PLAY [localhost]
TASK [Gathering Facts]
ok: [localhost]
TASK [touch /tmp/foo.txt]
changed: [localhost]
TASK [touch /tmp/bar.txt]
changed: [localhost]
PLAY RECAP
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Let's say the foo and bar roles directories contain multiple YAML files.
├── /usr/local
│ ├── main.yml
│ ├── roles
│ │ ├── foo
│ │ ├── ├── tasks
│ │ ├── ├── ├── main.yml
│ │ ├── ├── ├── other.yml
│ │ ├── bar
│ │ ├── ├── tasks
│ │ ├── ├── ├── main.yml
│ │ ├── ├── ├── other.yml
Perhaps main.yml creates /tmp/foo.txt and other.yml deletes /tmp/foo.txt.
~]$ cat roles/foo/tasks/main.yml
- ansible.builtin.file:
path: /tmp/foo.txt
state: touch
~]$ cat roles/foo/tasks/other.yml
- ansible.builtin.file:
path: /tmp/bar.txt
state: absent
tasks_from can be used to specify the YAML file in the role directory that you want to import.
---
- hosts: localhost
tasks:
- ansible.builtin.import_role:
name: foo
tasks_from: main.yml
- ansible.builtin.import_role:
name: foo
tasks_from: other.yml
...
Running the main.yml playbook should return the following.
Running the main.yml playbook should return the following.
~]$ ansible-playbook main.yml
PLAY [localhost]
TASK [Gathering Facts]
ok: [localhost]
TASK [touch /tmp/foo.txt]
changed: [localhost]
TASK [absent /tmp/foo.txt]
changed: [localhost]
PLAY RECAP
localhost : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Be aware that you cannot use loops with import_role. For example, like this.
---
- hosts: localhost
tasks:
- ansible.builtin.import_role:
name: foo
with_items:
- /tmp/hello.txt
- /tmp/world.txt
...
Running a playbook with import_role and loop should return something like this.
ERROR! You cannot use loops on 'import_role' statements. You should use 'include_role' instead.
As the error suggests, use include_role if you want to loop.
---
- hosts: localhost
tasks:
- ansible.builtin.include_role:
name: foo
with_items:
- /tmp/hello.txt
- /tmp/world.txt
...
Did you find this article helpful?
If so, consider buying me a coffee over at