TP - Structurer le projet avec des rôles
Pour ce TP on va réutiliser soit le dossier du TP2, soit la solution du TP2 :
git clone https://github.com/Uptime-Formation/ansible-tp-solutions -b tp2_correction
Ajouter une installation MySQL simple à une de vos machines avec un rôle trouvé sur Internet
Créez à la racine du projet le dossier
rolesdans lequel seront rangés tous les rôles (c'est une convention ansible à respecter).Les rôles sont sur https://galaxy.ansible.com/, mais difficilement trouvables... cherchons sur GitHub l'adresse du dépôt Git avec le nom du rôle
mysqldegeerlingguy. Il s'agit de l'auteur d'un livre de référence "Ansible for DevOps" et de nombreux rôles de références.Pour décrire les rôles nécessaires pour notre projet il faut créer un fichier
requirements.ymlcontenant la liste de ces rôles. Ce fichier peut être n'importe où mais il faut généralement le mettre directement dans le dossierroles(autre convention).Ajoutez à l'intérieur du fichier:
- src: <adresse_du_depot_git_du_role_mysql>
name: geerlingguy.mysql
Pour installez le rôle lancez ensuite
ansible-galaxy role install -r roles/requirements.yml -p roles.Facultatif : Ajoutez la ligne
geerlingguy.*au fichier.gitignorepour ne pas ajouter les roles externes à votre dépot git.Pour installer notre base de données, ajoutez un playbook
dbservers.ymlappliqué au groupedbserversavec juste une section roles:
- hosts: dbservers
become: yes
roles:
- <nom_role>
- Faire un playbook principal
site.yml(le playbook principal par convention) qui importe juste les deux playbooksappservers.yml(renommer le playbook d'installation d'app enappservers.yml) etdbservers.ymlavecimport_playbook:
- import_playbook: dbservers.yml
- import_playbook: appservers.yml
Lancer la configuration de toute l'infra avec ce playbook.
Dans votre playbook
dbservers.ymlet en lisant le mode d'emploi du rôle (ou bien le fichierdefaults/main.yml), écrasez certaines variables par défaut du rôle par des variables personnalisées. Relancez votre playbook avec--diff(et éventuellement--check) pour observer les différences.
Transformer notre playbook en role
Pour ce TP on va partir de la solution du TP2 :
git clone https://github.com/Uptime-Formation/ansible-tp-solutions -b tp2_correction tp3_roles_base
- Si ce n'est pas fait, créez à la racine du projet le dossier
rolesdans lequel seront rangés tous les roles (c'est une convention ansible à respecter). - Créer un dossier
flaskappdansroles. - Ajoutez à l'intérieur l'arborescence:
flaskapp
├── defaults
│ └── main.yml
├── handlers
│ └── main.yml
├── tasks
│ ├── deploy_app_tasks.yml
│ └── main.yml
└── templates
├── app.service.j2
└── nginx.conf.j2
Les templates et les listes de handlers/tasks sont a mettre dans les fichiers correspondants (voir plus bas)
Le fichier
defaults/main.ymlpermet de définir des valeurs par défaut pour les variables du role.Si vous avez fait l'amélioration 2 du TP2 "Rendre le playbook dynamique avec une boucle"
- Mettez à l'intérieur une application par défaut dans la variable
flask_apps
- Mettez à l'intérieur une application par défaut dans la variable
flask_apps:
- name: defaultflask
domain: defaultflask.test
repository: https://github.com/e-lie/flask_hello_ansible.git
version: master
user: defaultflask
- Sinon :
- Mettez à l'intérieur des valeurs par défaut pour la variable
app:
- Mettez à l'intérieur des valeurs par défaut pour la variable
app:
name: defaultflask
domain: defaultflask.test
repository: https://github.com/e-lie/flask_hello_ansible.git
version: master
user: defaultflask
Ces valeurs seront écrasées par celles fournies dans le dossier group_vars (la liste de deux applications du TP2), ou bien celles fournies dans le playbook (si vous n'avez pas déplacé la variable flask_apps). Elle est présente pour éviter que le rôle plante en l'absence de variable (valeurs de fallback).
Découpage des tasks du rôle
Occupons-nous maintenant de la liste de tâches de notre rôle. Une règle simple : il n'y a jamais de playbooks dans un rôle : il n'y a que des listes de tâches.
L'idée est la suivante :
on veut avoir un playbook final qui n'aie que des variables (section
vars:), un groupe dehosts:et l'invocation de notre rôledans le rôle dans le dossier
taskson veut avoir deux fichiers :- un
main.ymlqui sert à invoquer une "boucle principale" (avecinclude_tasks:etloop:) - ...et la liste de tasks à lancer pour chaque item de la liste
flask_apps
- un
Copiez les tâches (juste la liste de tirets sans l'intitulé de section
tasks:) contenues dans le playbookflask_deploy.ymldans le fichiertasks/main.yml.De la même façon copiez le handler dans
handlers/main.ymlsans l'intituléhandlers:.Copiez également le fichier
deploy_flask_tasks.ymldans le dossiertasks.Déplacez vos deux fichiers de template dans le dossier
templatesdu role (et non celui à la racine que vous pouvez supprimer).Pour appeler notre nouveau role, supprimez les sections
tasks:ethandlers:du playbookappservers.ymlet ajoutez à la place:
roles:
- flaskapp
- Votre role est prêt : lancez
appservers.ymlet debuggez le résultat le cas échéant.
Facultatif: Ajouter un paramètre d'exécution à notre rôle pour mettre à jour l'application
Facultatif :
Notre rôle flaskapp est jusqu'ici concu pour être un rôle de configuration, idéalement lancé régulièrement à l'aide d'un cron ou de AWX. En particulier, nous avons mis les paramètres update à yes mais force à false au niveau de notre tâche qui clone le code avec git. Ces paramètres indiquent si la tâche doit récupérer systématiquement la dernière version. Dans notre cas il pourrait être dangereux de mettre à jour l'application à chaque fois donc nous avons mis false pour éviter d'écraser l'application existante avec une version récente.
Nous aimerions maintenant créer un playbook upgrade_apps.yml qui contrairement à appservers.yml devrait être lancé ponctuellement pour mettre à jour l'application. Il serait bête de ne pas réutiliser notre role pour cette tâche : nous allons rajouter un paramère flask_upgrade_apps.
Remplacez dans la tâche
gitla valeurfalsedes paramètresupdateetforcepar cette variable.Ajoutez deux variables
repositoryetversionpour l'adresse du dépôt git et la version de l'applicationmasterpar défaut.Remplacez dans la tâche
gitles valeurs nécessaires.
Vous noterez que son nom commence par flask_ car elle fait partie du role flaskapp. Cette façon de créer une sorte d'espace de nom simple pour chaque rôle est une bonne pratique.
Ajoutez une valeur par défaut
nooufalsepour cette variable dans le rôle (defaults/main.yml).Créez le playbook
upgrade_apps.ymlqui appelle le role mais avec une sectionvars:qui définit la variable upgrade àyesoutrue.Pour tester votre playbook et pouvoir constater une modification de version vous pouvez éditer
group_vars/appservers.ymlpour changer la version des deux applications àversion2. Le playbook installera alors une autre version de l'application présente dans le dépot git.Charger l'application dans un navigateur avec l'une des IPs. Vous devriez voir "version: 2" apparaître en bas de la page.
Solution
- Pour la solution, clonons le dépôt via cette commande :
cd # Pour revenir dans notre dossier home
git clone https://github.com/Uptime-Formation/ansible-tp-solutions -b tp3_correction tp3_correction
Vous pouvez également consulter la solution directement sur le site de Github : https://github.com/Uptime-Formation/ansible-tp-solutions/tree/tp3_correction