![Logo Ansible](images/logo-ansible.svg) # Roles Ansible Les Roles permettent d'organiser les instructions Ansible de manière à favoriser leur ré-utilisabilité. ![Schéma archi globale](images/ansible-archi-roles.png) ## Qu'est-ce qu'un Role ? * Un Role Ansible défini une action précise telle que : - Installer et configurer un serveur Apache - Installer et configurer un serveur Mariadb * Un Role Ansible peut être appelé dans un ou plusieurs Playbook. ## Avantages des Roles * Organisation - Découpage en plusieurs dossiers et fichiers - Facilite la compréhension et la maintenance du code. * Ré-utilisabilité - Les Roles peuvent facilement être ré-utilisés au sein de plusieurs Playbooks. * Partage - Les Roles peuvent être partagés sous la forme de catalogues. ## Organisation d'un Role ```none roles/ ├── my-role │   ├── README.md │   ├── defaults <= Variables par défaut du Role │   │   └── main.yaml │   ├── files <= Fichiers pouvant être déployés par le Role │   │   └── my-file.yaml │   ├── handlers <= Handlers à exécuter │   │   └── main.yaml │   ├── meta <= Métadonnées sur le Role │   │   └── main.yaml │   ├── tasks <= Tâches à exécuter │   │   └── main.yaml │   └── templates <= Templates de fichiers │   │ └── my-template.j2 │   └── vars <= Autres variables pour le Role │   └── main.yaml ``` * Un Role doit inclure au minimum un des dossiers suivants `defaults`, `files`, `handlers`, `tasks`, `templates`, `vars`. * Si un dossier est déclaré, il doit contenir au minimum un fichier nommé `main.yaml`. ## Utiliser un Role La méthode classique est la suivante : `playbook.yaml` ```yaml - hosts: my-group-of-servers roles: - my-role-1 - my-role-2 ``` ## Ordre d'exécution des tâches L'ordre d'exécution des tâches dans un Playbook est le suivant : 1. Tâches définies dans `pre_tasks` 2. Handlers déclenchés jusque là 3. Tâches définies dans `roles` 4. Tâches définies dans le playbook (`tasks`) 5. Handlers déclenchés jusque là 6. Tâches définies dans `post_tasks` 7. Handlers déclenchés jusque là ## pre_tasks, post_tasks * _tasks_ Tâches définies dans la section `tasks`. Elles sont lancées après les Rôles et avant les tâches définies dans `post_tasks`. * _pre_tasks_ Tâches lancées avant les Rôles. * _post_tasks_ Tâches lancées après les tâches de la section `tasks` (et donc après les Rôles). ## Exemple Définition de pre_tasks, roles, tasks et post_tasks. ```yaml - hosts: ansible-1 pre_tasks: - name: Pre tasks debug: msg: 'I am executed before the Roles.' roles: - my-role tasks: - name : Tasks debug: msg: 'I am executed right after the Roles and just before the Post Tasks.' post_tasks: - name: Post tasks debug: msg: 'I am executed after the main Tasks.' ``` L'ordre de déclaration n'a pas d'importance. ## Ordre réel d'exécution ```none $ ansible-playbook -v -i inventories/formation/hosts my-playbook.yaml PLAY [ansible-1] ******************************************************* TASK [Pre tasks] *************************************************************** ok: [ansible-1] => { "msg": "I am executed before the Roles." } TASK [my-role : Role] ********************************************************** ok: [ansible-1] => { "msg": "I am running after Pre Tasks and before Tasks." } TASK [Tasks] ******************************************************************* ok: [ansible-1] => { "msg": "I am executed right after the Roles and just before the Post Tasks." } TASK [Post tasks] ************************************************************** ok: [ansible-1] => { "msg": "I am executed after the main Tasks." } ... ``` ## Exemple de découpage en Roles `playbook.yaml` ```yaml - hosts: web roles: - apache - wordpress ``` Le Playbook exécute les Roles `apache` et `wordpress`. ### Tâches du Role apache `roles/install-apache/tasks/install.yaml` ```yaml - name: Installation of Apache Package yum: name: httpd state: present update_cache: yes - name: Ensure Apache is running (and enable it at boot) service: name: httpd state: started enabled: yes ``` ### Tâches du Role apache (suite) `roles/configure-apache/tasks/configure.yaml` ```yaml - name: Modify permission of directory {{ app_directory }} file: dest: '{{ app_directory }}' mode: 0755 owner: '{{ app_user }}' group: '{{ app_group }}' recurse: yes - name: Modify Apache configuration lineinfile: dest: /etc/httpd/conf/httpd.conf regexp: '^Listen ' line: 'Listen {{ apache_listen_port }}' notify: Reload Apache ``` ### Variables du Role apache `roles/configure-apache/vars/main.yaml` ```yaml apache_listen_port: 8081 app_directory: /var/www/html app_user: apache app_group: apache ``` ### Handlers du Role apache `roles/configure-apache/handlers/main.yaml` ```yaml - name: Reload Apache service: name: httpd state: reloaded ``` ### Exécution du playbook ```none $ ansible-playbook -i ./hosts playbook.yaml PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [web1.formation.sii.fr] ok: [web2.formation.sii.fr] TASK [apache : Installation of Apache Package] ********************************* ok: [web2.formation.sii.fr] ok: [web1.formation.sii.fr] TASK [apache : Ensure Apache is running (and enable it at boot)] *************** ok: [web1.formation.sii.fr] ok: [web2.formation.sii.fr] TASK [apache : Modify permission of directory /var/www/html] ******************* ok: [web1.formation.sii.fr] ok: [web2.formation.sii.fr] TASK [apache : Modify Apache configuration] ************************************ changed: [web1.formation.sii.fr] changed: [web2.formation.sii.fr] RUNNING HANDLER [apache : Reload Apache] *************************************** changed: [web1.formation.sii.fr] changed: [web2.formation.sii.fr] PLAY RECAP ********************************************************************* web1.formation.sii.fr : ok=6 changed=2 unreachable=0 failed=0 web2.formation.sii.fr : ok=6 changed=2 unreachable=0 failed=0 ``` Les Roles sont exécutés séquentiellement. ## Importer des fichiers de tâches * Dans un Role le fichier `tasks/main.yaml` peut appeler d'autres fichiers contenant des tâches avec `import_tasks` ou `include_tasks`. * Exemple : `roles/my-role/tasks/main.yaml` ```yaml tasks: - import_tasks: install.yaml - import_tasks: configure.yaml # ou - include_tasks: install.yaml - include_tasks: configure.yaml ``` ## Gérer un import par type d'OS * L'import de tâches permet notamment de gérer les différences d'implémentations entre systèmes. * Exemple : `roles/my-role/tasks/main.yaml` ```yaml - name: specific redhat/centos tasks import_tasks: redhat.yaml when: ansible_facts['os_family']|lower == 'redhat' - name: specific debian/ubuntu tasks import_tasks: debian.yaml when: ansible_facts['os_family']|lower == 'debian' ``` `roles/my-role/tasks/redhat.yaml` ```yaml - yum: name: "httpd" state: present ``` `roles/my-role/tasks/debian.yaml` ```yaml - apt: name: "apache2" state: present ``` Il est possible de passer des variables aux tâches importées : ```yaml tasks: - import_tasks: wordpress.yaml vars: wp_user: bob ``` ## Exécution partielle d'un Playbook * L'utilisation de _tags_ permet l'exécution ciblée d'un sous-ensemble de tâches. ```yaml - hosts: web roles: - { role: install-apache, tags: install } - { role: configure-apache, tags: [install, configure] } ``` * Lors du lancement du playbook, le ciblage s'effectue avec `--tags` ou `--skip-tags`. ```none $ ansible-playbook playbook.yaml -i ./hosts --tags configure PLAY [web] ********************************************************************* TASK [setup] ******************************************************************* ok: [web1.formation.sii.fr] ok: [web2.formation.sii.fr] TASK [configure-apache : Modify permission of directory /var/www/html] ********* changed: [web1.formation.sii.fr] changed: [web2.formation.sii.fr] TASK [configure-apache : Modify Apache configuration] ************************** changed: [web1.formation.sii.fr] changed: [web2.formation.sii.fr] RUNNING HANDLER [configure-apache : Reload Apache] ***************************** changed: [web1.formation.sii.fr] changed: [web2.formation.sii.fr] PLAY RECAP ********************************************************************* web1.formation.sii.fr : ok=4 changed=3 unreachable=0 failed=0 web2.formation.sii.fr : ok=4 changed=3 unreachable=0 failed=0 ``` ## Dépendances entre Roles * Un Role peut dépendre d'un ou plusieurs autres Roles. * Les dépendances d'un Role peuvent être indiquées dans le fichier : `roles/mon-role/meta/main.yaml` `roles/my-appli/meta/main.yaml` ```yaml dependencies: - role: common - role: apache vars: apache_port: 80 ``` * Ici les Roles `common` et `apache` seront exécutés avant le role `mon-appli`. * Attention : les Roles marqués en dépendances seront exécutés sur les mêmes machines cibles que le Role `mon-appli`. ## Travaux pratiques ![Travaux pratiques](images/tp.gif) [TP Ansible : roles](travaux-pratiques/tp-ansible-roles.html)