Pattern de tâches *Ansible* pour vérifier la version d'une application à installer
Lorsqu’on développe des rôles Ansible on peut être amené à installer un logiciel sans gestionnaire de packages (PKG, APT, YUM) mais en récupérant directement l’application (ou sa source) auprès de l’éditeur.
L’idempotence de nos rôles Ansible impose de ne pas re-récupérer (inutilement) un logiciel déjà installé : il va donc falloir préalablement tester si le logiciel est installé, si oui, dans quelle version et ensuite comparer à la version demandée par le rôle.
Je vous partage un petit modèle de tâches qui permet ceci.
Le processus complet est relativement simple :
- Quelle est la version demandée ?
- Dernière version (voir explication plus bas) : on récupère ce numéro de version auprès d’un site/API/…
- Version spécifique : on a donc le numéro de version.
- Logiciel déjà installé ?
- Non : On télécharge la version demandée.
- Oui :
- Est à la version demandée ? : Rien à faire.
- N’est pas à la version demandée ? : On télécharge la version demandée et on l’installe (à la place de la précédente installation).
Dans les explications suivantes j’utiliserais le logiciel Adminer comme exemple.
Tout d’abord, il faut avoir une variable Ansible qui indique la version souhaitée : adminer_version
.
Afin de pouvoir aisément mettre à jour le logiciel via le même rôle Ansible, je fais le choix d’autoriser une valeur
spéciale “latest
” qui indiquera que, dans ce cas, on souhaite la toute dernière version disponible (un peu moins
idempotent mais assez pratique).
|
|
Maintenant qu’on sait quelle version on doit installer il nous fait savoir si le logiciel est déjà installé et si oui, à quelle la version.
Le test d’installation dépends du logiciel (existence de dossier/fichier, disponibilité d’une commande, résultat de
dpkg -l
). Dans mon cas il s’agit de vérifier qu’un fichier existe.
Pour simplifier la gestion/modularité du rôle j’utilise une variable pour définir l’emplacement où est/sera installé le
logiciel : adminer_installation_filepath
.
|
|
La tâche de test est simpliste :
|
|
Ensuite, si la version demandée est latest
, on va interroger le site web de téléchargement du logiciel (ici GitHub)
pour récupérer la dernière version.
Je pourrais utiliser community.general.github_release
mais j’ai rencontré des problèmes à installer sa dépendance
(github3.py
) sur Debian 12, j’ai donc préféré utilisé la bonne vieille méthode du curl|grep
de l’API publique de
GitHub.
La tâche suivante récupère donc le numéro de version de la dernière release GitHub, uniquement lorsqu’il a été
demandé d’installer la dernière version (adminer_version == 'latest'
) :
|
|
Le résultat (le nom de la release, qui est -ici- le numéro de version précédé d’un v
) est stocké dans une variable
temporaire __adminer_release_to_install
qui désigne « la version qu’il faut avoir/installer ».
Dans le cas où une version spécifique à été désignée (adminer_version != 'latest'
), la version à avoir/installé est
presque le contenu de la variable adminer_version
(le préfixe v
diffère).
Pour simplifier le code Ansible et ne pas avoir à gérer séparément les 2 cas de adminer_version
, je créer
manuellement ma variable __adminer_release_to_install
via un set_fact
:
|
|
Je trouve qu’il est pertinent d’avoir ici un petit test sur le bon déroulement de l’interrogation de GitHub avec
message explicite, ce que permet la tâche assert
suivante :
|
|
Maintenant qu’on sait quelle est la version à avoir/installer, on peut vérifier la version actuelle.
Vu le mode d’installation d’Adminer (une seule action) je peut placer cette tâche de test avant la tâche d’installation car cette dernière s’occupera, de fait, de désinstaller l’ancienne version.
Dans le cas d’Adminer, une des façons de savoir quelle est le numéro de version installé est de regarder le contenu du
script PHP car celui-ci est indiqué dans le tag @version
du DocBlock.
La tâche suivante regarde la version installée et la compare à la version attendue (__adminer_release_to_install
) :
|
|
Le résultat se retrouvera dans la variable __adminer_installed_with_correct_version
, indiquant au choix :
- « Oui, Adminer a la bonne version. »
- « Non, Adminer n’a pas la bonne version. »
Dans le cas spécifique d’Adminer et afin d’avoir un rôle plus complet je dois gérer le fait qu’Adminer existe en 2 variantes :
- La variante complète qui gère plusieurs serveurs de base de données (SQL et NoSQL)
- La variante ne gérant que MySQL/MariaDB
Je rajoute donc une variable qui permet de préciser quelle variante le rôle doit installer : adminer_mysql_variant
.
Comme il n’existe que 2 variantes (pour l’instant ?), la variable peut n’être qu’un simple booléen :
|
|
La tâche suivante est similaire à celle qui vérifie la version, elle regarde le code source. Malheureusement cette information n’est pas dans le DocBlock et donc la solution que j’ai retenu est de chercher si la chaîne PostgreSQL apparaît dans le code, signe d’une variante “complète”.
Bien entendu, inutile de faire ce test si la version installée n’est pas la bonne.
|
|
Le résultat se retrouvera dans la variable _adminer_installed_with_correct_variant
, indiquant au choix :
- « Oui, Adminer a la bonne variante. »
- « Non, Adminer n’a pas la bonne variante. »
Maintenant qu’on connait :
- La version et la variante attendues/demandées
- Si le logiciel est installé et dans quelle version et variante
Il est temps d’installer (si besoin) la version et variante demandée.
S’agissait ici d’un simple script PHP à placer à l’endroit configuré, la tâche d’installation n’est qu’un simple get_url
sur une URL construite en conséquence.
Cette tâche d’installation ne devant se déclencher que lorsque l’une des conditions suivante survient :
- Le logiciel n’est pas déjà installé
- Le logiciel est installé dans la mauvaise version
- Le logiciel est installé dans la mauvaise variante
|
|
Et voici le bout de code Ansible complet qui applique ce pattern avec 2/3 tâches secondaires (mais nécessaires) :
|
|
Voilà, j’espère que ce pattern d’installation manuelle d’une version spécifique pour Ansible pourra vous servir.
Si vous aimez le contenu, vous pouvez aider
Sponsor