Voici, extrait de la documentation Ansible sur les “Best Practice”, l’une des organisations de référence d’un projet ansible de configuration d’une infrastructure:
production # inventory file for production servers
staging # inventory file for staging environment
group_vars/
group1.yml # here we assign variables to particular groups
group2.yml
host_vars/
hostname1.yml # here we assign variables to particular systems
hostname2.yml
site.yml # master playbook
webservers.yml # playbook for webserver tier
dbservers.yml # playbook for dbserver tier
roles/
common/ # this hierarchy represents a "role"
... # role code
webtier/ # same kind of structure as "common" was above, done for the webtier role
monitoring/ # ""
fooapp/ # ""
Plusieurs remarques:
--inventory production
.group_vars
et host_vars
. On met à l’intérieur un fichier <nom_du_groupe>.yml
qui contient un dictionnaire de variables.playbooks
ou operations
pour certaines opérations ponctuelles. (cf cours 4)library
du projet ou d’un rôle et on le précise éventuellement dans ansible.cfg
.common
: il est utilisé ici pour rassembler les tâches de base et communes à toutes les machines. Par exemple s’assurer que les clés ssh de l’équipe sont présentes, que les dépôts spécifiques sont présents, etc.Découper les tâches de configuration en sous-ensembles réutilisables (une suite d’étapes de configuration).
Ansible est une sorte de langage de programmation et l’intérêt du code est de pouvoir créer des fonctions regroupées en librairies et les composer. Les rôles sont les “librairies” Ansible en quelque sorte.
Comme une fonction, un rôle prend généralement des paramètres qui permettent de personnaliser son comportement.
Tout le nécessaire doit y être (fichiers de configurations, archives et binaires à déployer, modules personnels dans library
etc.)
Remarque : ne pas confondre modules et roles. file
est un module, geerlingguy.docker
est un rôle. On doit écrire des rôles pour coder correctement en Ansible, on peut écrire des modules mais c’est largement facultatif car la plupart des actions existent déjà.
Présentation d’un exemple de rôle : https://github.com/geerlingguy/ansible-role-docker
docker_edition
.README
pour en décrire l’usage et un fichier meta/main.yml
qui décrit la compatibilité et les dépendances, en plus de la licence et l’auteur.ansible-galaxy
.Un rôle est un dossier avec des sous-dossiers conventionnels:
roles/
my_role/ # hiérarchie du rôle "my_role"
tasks/ #
main.yml # <-- le fichier de tâches exécuté par défaut
handlers/ #
main.yml # <-- les handlers
templates/ # <-- dossier des templates
ntp.conf.j2 # <------- les templates finissent par .j2
files/ #
foo.sh # <-- d'autres fichiers si nécessaire
vars/ #
main.yml # <-- variables internes du rôle
defaults/ #
main.yml # <-- variables par défaut pour le rôle
meta/ #
main.yml # <-- informations sur le rôle
On constate que les noms des sous-dossiers correspondent souvent à des sections du playbook. En fait le principe de base est d’extraire les différentes listes de tâches ou de variables dans des sous-dossiers.
Remarque : les fichiers de liste doivent nécessairement s’appeler main.yml" (pas très intuitif)
Remarque 2 : main.yml
peut en revanche importer d’autres fichiers aux noms personnalisés (ex: rôle docker de geerlingguy)
Le dossier defaults
contient les valeurs par défaut des paramètres du rôle. Ces valeurs ne sont jamais prioritaires (elles sont écrasées par n’importe quelle autre définition de la même variable ailleurs dans le code Ansible)
Le fichier meta/main.yml
est facultatif mais conseillé et contient des informations sur le rôle
Le dossier files
contient les fichiers qui ne sont pas des templates (pour les module copy
ou sync
, script
etc).
C’est le store de rôles officiel d’Ansible : https://galaxy.ansible.com/
C’est également le nom d’une commande ansible-galaxy
qui permet d’installer des rôles et leurs dépendances depuis internet. Un sorte de gestionnaire de paquets pour Ansible.
Elle est utilisée généralement sour la forme ansible install -r roles/requirements.yml -p roles <nom_role>
, ou plus simplement ansible-galaxy install <role>
(mais installe dans /etc/ansible/roles
dans ce cas).
Tous les rôles Ansible sont communautaires (pas de rôles officiels) et généralement stockés sur Github ou Gitlab.
Mais on peut voir la popularité (étoiles Github), et la présence de tests (avec un outil Ansible appelé Molecule), qui garantissement la plus ou moins grande fiabilité et qualité du rôle.
Il existe des rôles pour installer un peu n’importe quelle application serveur courante aujourd’hui. Passez du temps à explorer le web avant de développer quelque chose avec Ansible.
requirements.yml
Conventionnellement on utilise un fichier requirements.yml
situé dans roles
pour décrire la liste des rôles nécessaires à un projet.
- src: geerlingguy.repo-epel
- src: geerlingguy.haproxy
- src: geerlingguy.docke
# from GitHub, overriding the name and specifying a specific tag
- src: https://github.com/bennojoy/nginx
version: master
name: nginx_role
ansible-galaxy install -r roles/requirements.yml -p roles
.Il est possible d’importer le contenu d’autres fichiers dans un playbook:
import_tasks
: importe une liste de tâches (atomiques)import_playbook
: importe une liste de play contenus dans un playbook.Les deux instructions précédentes désignent un import statique qui est résolu avant l’exécution.
Au contraire, include_tasks
permet d’intégrer une liste de tâche dynamiquement pendant l’exécution.
Par exemple :
vars:
apps:
- app1
- app2
- app3
tasks:
- include_tasks: install_app.yml
loop: "{{ apps }}"
Ce code indique à Ansible d’exécuter une série de tâches pour chaque application de la liste. On pourrait remplacer cette liste par une liste dynamique. Comme le nombre d’imports ne peut pas facilement être connu à l’avance on doit utiliser include_tasks
.
Savoir si on doit utiliser include
ou import
se fait selon les cas et avec tâtonnement le plus souvent.