Ansible - Roles
Roles allow the grouping of related tasks, files, vars, templates, etc. for easy reuse.
Roles expect specific dir names. This is what the directory structure of a project would normally look like:
site.yml
webservers.yml
fooservers.yml
roles/
common/
tasks/ # main list of tasks
handlers/ # handlers
files/ # files that can be deployed
templates/ # templates go here
vars/ # other vars
defaults/ # default vars
meta/ # meta data
webservers/
tasks/
defaults/
meta/
This file often has platform specific stuff:
tasks/main.yml- name: added in 2.4, previously you used 'include' import_tasks: redhat.yml when: ansible_facts['os_family']|lower == 'redhat' - import_tasks: debian.yml when: ansible_facts['os_family']|lower == 'debian'
Roles are searched for here:
- roles/ ( relative to play book )
- /etc/ansible/roles
Use a role like this ( classic way ):
---
- hosts: webservers
roles:
- common
- webservers
If these files exist:
roles/x/tasks/main.yml | add these tasks to play |
roles/x/handlers/main.yml | add these handlers to play |
roles/x/vars/main.yml | add these vars to play |
roles/x/defaults/main.yml | add these vars to play |
roles/x/meta/main.yml | add these role dependencies to play |
- “Any copy, script, template or include tasks (in the role) can reference files in roles/x/{files,templates,tasks}/ (dir depends on task) without having to path them relatively or absolutely.”
- Default role variables have the lowest priority out of all variables and are defined here: defaults/main.yml
- Roles only run once even when defined multiple times unless:
- params are different
- Add allow_duplicates: true to the meta/main.yml
Execution order:
- pre_tasks in the play
- any triggered handlers
- each role in roles
- tasks in play
- any triggered handlers
- post_tasks in the play
- any triggered handlers
Import role and include role ( new way ):
---
- hosts: webservers
tasks:
- debug:
msg: "before we run our role"
- import_role:
name: example
- include_role:
name: example
- debug:
msg: "after we ran our role"
Full path for a role, just the name, or name as a param and variables included:
---
- hosts: webservers
roles:
- role: '/path/to/my/roles/common'
- common
- role: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
Using include_role with vars:
---
- hosts: webservers
tasks:
- include_role:
name: foo_app_instance
vars:
dir: '/opt/a'
app_port: 5000
Conditionally import a role:
---
- hosts: webservers
tasks:
- include_role:
name: some_role
when: "ansible_facts['os_family'] == 'RedHat'"
Using tags with roles:
---
- hosts: webservers
roles:
- role: foo
tags:
- bar
- baz
# using YAML shorthand, this is equivalent to the above:
- { role: foo, tags: ["bar", "baz"] }
Same, newer syntax:
---
- hosts: webservers
tasks:
- import_role:
name: foo
tags:
- bar
- baz
- Tags in an include_role task are applied to that task but not the role.
Role Dependencies
roles/x/meta/main.yml
---
dependencies:
- role: common
vars:
some_parameter: 3
- role: apache
vars:
apache_port: 80
- role: postgres
vars:
dbname: blarg
other_parameter: 12
Modules can be included in a role. The structure looks like this:
roles/
my_custom_modules/
library/
module1
module2