Roles """"" About Roles =========== * roles organize content like ``tasks``, ``handlers``, ``templates`` and ``files`` * a 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_path`` * the default role path is ``roles`` * two main purposes for roles * run once * parameterized .. hint:: If you write the same tasks in multiple playbooks -> create a role. Directory structure =================== * The directory structure of roles is defined * Ansible loads the ``main.yml`` file of the directories ``defaults``, ``handlers``, ``meta``, ``tasks`` and ``vars`` * the folders are optional, you don't have to define all the directories .. code-block:: bash . ├── 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`` Links ----- * http://docs.ansible.com/ansible/playbooks_best_practices.html#directory-layout 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`` .. code-block:: bash # main.yml --- - name: install apache2 apt: name: apache2 state: latest .. hint:: Create your role step-by-step, not all tasks at once. Integrate Roles in Playbooks ---------------------------- * Create a new playbook * Use ``roles:`` instead of ``tasks:`` * Add your rolename as list item * Save the file as ``apache2-role.yml`` * Run the playbook ``ansible-playbook apache2-role.yml`` .. code-block:: yaml # file: apache2-role.yml --- - hosts: web1.pascal.lab roles: - apache2 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 .. code-block:: yaml # file: tasks/main.yml - name: configure apache template: src: template.j2 dest=/etc/foo.conf notify: - restart apache .. code-block:: yaml # 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! 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. .. code-block:: yaml # 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 Flush Handlers -------------- * if you need to flush all handler commands immediately, use ``meta: flush_handlers`` .. code-block:: yaml - name: exectue now all triggered handlers meta: flush_handlers Links ----- * http://docs.ansible.com/ansible/playbooks_intro.html#handlers-running-operations-on-change 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 .. code-block:: yaml # 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 .. code-block:: yaml # 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``. Links ----- * http://docs.ansible.com/ansible/playbooks_roles.html#role-dependencies * http://docs.ansible.com/ansible/galaxy.html#advanced-control-over-role-requirements-files 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. Links ----- * http://docs.ansible.com/ansible/latest/playbooks_reuse_roles.html +Role Variables =============== Requirement: Variable chapter Role Defaults ------------- * Role default variables allow you to set default variables * ``defaults/main.yml`` file 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 ``_``. .. important:: Use default variables to ensure the reuse of a role without specify additional variables. Role Variables -------------- * To ensure a role variable is absolutely used in that role and not overwritten * ``vars/main.yml`` file in your role directory Links ----- * http://docs.ansible.com/ansible/playbooks_roles.html#role-default-variables +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! .. code-block:: yaml # 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 Links ----- * http://docs.ansible.com/ansible/playbooks_roles.html