|
|
|
|
<!-- .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>
|