10. Roles¶
10.1. About Roles¶
roles organize content like
tasks,handlers,templatesandfilesa way to encapsulate tasks and properties for reuse
the directory name is also the rolename
the path, where Ansible searchs for roles is configurable
roles_paththe default role path is
rolestwo main purposes for roles
- run once
- parameterized
Hint
If you write the same tasks in multiple playbooks -> create a role.
10.2. Directory structure¶
- The directory structure of roles is defined
- Ansible loads the
main.ymlfile of the directoriesdefaults,handlers,meta,tasksandvars - the folders are optional, you don’t have to define all the directories
.
├── README.md <- Role description like usage, summary, variables, etc.
├── defaults <- Default lower priority variables, easy override by group_vars, etc.
│ └── main.yml
├── files <- Files picked up by copy/script module
│ └── docker-apt-key.gpg
│ └── foo.sh
├── handlers <- Handler defintions for notify tasks
│ └── main.yml
├── meta <- Meta definiontions like dependencies
│ └── main.yml
├── tasks <- Task files for this role
│ ├── main.yml
│ └── redhat.yml
├── templates <- Files picked up by template module
│ ├── debian
│ │ └── docker.conf.j2
│ └── redhat
│ ├── docker.conf.j2
│ └── docker.repo.j2
└── vars <- Role variables, not made for override
├── Debian.yml
└── RedHat.yml
Hint
You can use the init option of ansible-galaxy to initialize a role structure for a new role: ansible-galaxy init rolename
10.3. Create the first role¶
- Create your role folder
apache2 - Create a sub-folder called
tasks - Create a file
- Start the YAML
--- - Add your first task
- Save the file as
main.yml
# main.yml
---
- name: install apache2
apt:
name: apache2
state: latest
Hint
Create your role step-by-step, not all tasks at once.
10.3.1. Integrate Roles in Playbooks¶
- Create a new playbook
- Use
roles:instead oftasks: - Add your rolename as list item
- Save the file as
apache2-role.yml - Run the playbook
ansible-playbook apache2-role.yml
# file: apache2-role.yml
---
- hosts: web1.pascal.lab
roles:
- apache2
10.4. Handlers¶
- is a special task and the name is important and has to be unique
- triggered / notified after a change of a task
- will run at the end of a play, but only once
# file: tasks/main.yml
- name: configure apache
template:
src: template.j2
dest=/etc/foo.conf
notify:
- restart apache
# file: handlers/main.yml
---
- name: restart apache
service:
name: apache
state: restarted
Hint
If a handler is triggered, but another task fails, the handler will not run! See Flush Handlers
Important
Notify handlers are always run in the same order they are defined, not in the order listed in the notify-statement!
10.4.1. Listen on handlers¶
Since Ansible 2.2, handlers can also listen to generic topics, and tasks can notify those topics.
The handler can be used alone or together in the group.
# combine the handler memcached and apache as "restart web services"
handlers:
- name: restart memcached
service: name=memcached state=restarted
listen: "restart web services"
- name: restart apache
service: name=apache state=restarted
listen: "restart web services"
tasks:
- name: restart everything
command: echo "this task will restart the web services"
notify:
"restart web services"
#- restart apache
#- restart memcached
10.4.2. Flush Handlers¶
- if you need to flush all handler commands immediately, use
meta: flush_handlers
- name: exectue now all triggered handlers
meta: flush_handlers
10.5. Role Dependencies¶
- you can define a role dependency
- defined in
meta/main.yml - contains a list of roles and optional parameters
- will run before the original role
# file: meta/main.yml - short form
---
dependencies:
- ntp
# file: meta/main.yml - needed with aditional arguments
---
dependencies:
- role: ntp
- conditionals can also be used for dependencies
# file: meta/main.yml
---
dependencies:
- role: ntp
when: ansible_os_family == "Debian"
Important
By default - if another role also lists a role dependency it will not be run again. To change this behaviour check out allow_duplicates: yes.
10.6. Run Order¶
- Any pre_tasks defined in the play.
- Any handlers triggered so far will be run.
- Each role listed in roles will execute in turn. Any role dependencies defined in the roles meta/main.yml will be run first, subject to tag filtering and conditionals.
- Any tasks defined in the play.
- Any handlers triggered so far will be run.
- Any post_tasks defined in the play.
- Any handlers triggered so far will be run.
10.7. +Role Variables¶
Requirement: Variable chapter
10.7.1. Role Defaults¶
- Role default variables allow you to set default variables
defaults/main.ymlfile in your role directory- variables will have the lowest priority and can be easily overridden
Hint
It’s recommended to prefix your role variables with <rolename>_<variablename>.
Important
Use default variables to ensure the reuse of a role without specify additional variables.
10.7.2. Role Variables¶
- To ensure a role variable is absolutely used in that role and not overwritten
vars/main.ymlfile in your role directory
10.8. +Parameterized Roles¶
Requirement: Variable chapter
- you can pass a value as a parameter to the role
- the parameter will overwrite a default value
- it’s not mandatory to have a default value!
# example in a playbook
---
- hosts: webservers
roles:
- role: app_instance
dir: /opt/app1
app_port: 8080
- role: app_instance
dir: /opt/app2
app_port: 8081