Resources attached to the Road To DevOps tutorial https://blog.noobtoroot.xyz/road-to-devops/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

410 lines
10 KiB

<!-- .slide: data-state="nologo-slide" style="text-align: center" -->
![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
<!-- .slide: data-state="small-code" -->
```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.
<!-- .slide: data-state="small-code" -->
```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
<!-- .slide: data-state="small-code" -->
```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
<!-- .slide: data-state="medium-code" -->
`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)
<!-- .slide: data-state="medium-code" -->
`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
<!-- .slide: data-state="medium-code" -->
`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
<!-- .slide: data-state="medium-code" -->
`roles/configure-apache/handlers/main.yaml`
```yaml
- name: Reload Apache
service:
name: httpd
state: reloaded
```
### Exécution du playbook
<!-- .slide: data-state="small-code" -->
```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
<!-- .slide: data-state="medium-code" -->
* 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`.
<!-- .slide: data-state="small-code" -->
```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
<!-- .slide: data-state="nologo-slide" style="text-align: center" -->
![Travaux pratiques](images/tp.gif)
<small>[TP Ansible : roles](travaux-pratiques/tp-ansible-roles.html)</small>