Partie 1 : Présentation et prérequis
Partie 2 : Bases et premiers Playbook
Partie 3 : Les Variables
Partie 4 : Les Collections
ââ
Seconde partie de la sĂ©rie d’article consacrĂ©e Ă Ansible. L’objectif est toujours le mĂȘme, monter en puissance sur l’outil en s’appuyant sur des cas d’usages. De mĂȘme que pour la partie prĂ©requis, ce sera un mĂ©lange de bonnes pratiques provenant de l’Ă©diteur mais aussi de mon retour d’expĂ©rience.
Dans cet article, on revient sur les bases du produit ainsi que sur la rĂ©alisation d’un premier Playbook. On va commencer le dĂ©ploiement du Stack TIG (Telegraf, InfluxDB, Grafana) pour la supervision d’un environnement VMware (vCenter + ESXi), ce sera notre fil rouge :)
Pour rappel, les prĂ©requis c’est ici.
Le code des exemples qui suivent est sur GitHub
Introduction et objectifs d’Ansible
J’avais dĂ©jĂ eu l’occasion de faire une rapide introduction Ă Ansible dans la premiĂšre partie, ici on va approfondir en citant quelques cas dâusage, puis on couvrira principales fonctionnalitĂ©s avec une explication plus thĂ©orique.
A lâorigine, le produit a Ă©tĂ© dĂ©veloppĂ© pour la gestion de la configuration de serveurs Linux. Il est sans agent, il sâappuie donc sur SSH pour lâaccĂšs aux nĆuds (serveurs qui seront gĂ©rĂ©s par Ansible). Une fois connectĂ© sur les nĆuds, câest du code Python qui est exĂ©cutĂ©. Pour moi les points forts du produit :
- Agentless
- Utilisation de SSH qui va permettre dâaccĂ©der Ă©galement Ă des Ă©quipements rĂ©seaux ou de sĂ©curitĂ© et ainsi Ă©largir le panel des nĆuds gĂ©rĂ©s.
- Exécution de code Python (2 et 3), qui est présent par défaut sur une majorité de systÚme
On notera Ă©galement quâil est possible de gĂ©rer des nĆuds Windows avec PowerShell mais Ă©galement nâimporte quel Ă©quipement ou application que lâon peut accĂ©der via des web services (Rest API par exemple). Dans ce dernier cas, le code Python est exĂ©cutĂ© en local.
Si vous avez rĂ©alisĂ© les Ă©tapes listĂ©es dans les prĂ©requis, vous devez avoir un environnement Ansible prĂȘt pour Ă©crire vos premiers Playbook. Comme vous lâavez vu, câest plutĂŽt simple Ă mettre en place. Un Playbook s’exĂ©ucte un peu Ă la maniĂšre script Python ou PowerShell, avec la commande ansible-playbook suivi du Playbook :
|
|
Cas d’usage
Un des cas dâusage le plus souvent citĂ© quand on parle dâAnsible, câest le dĂ©ploiement et la configuration, sur un serveur Linux, dâun ensemble applicatif (par exemple serveur web + base de donnĂ©es). Du fait de lâidempotence native des modules, on peut rejouer le Playbook sur le serveur Linux, il nây aura pas dâincidence, au contraire on corrigera une Ă©ventuelle dĂ©rive de la configuration.
En vrac, quelques cas d’usages:
- Automatiser le dĂ©ploiement dâĂ©quipements rĂ©seaux
- DĂ©ploiement de machines virtuelles
- Configuration de serveurs ESXi
- DĂ©ploiement d’un stack applicatif
Composants
- Control Node : LĂ oĂč on installe Ansible.
- Managed Nodes : Equipements pilotés à distance. Ils sont listés dans le fichier Inventory
- Tower : Portail web de pilotage. AWX est l’Upstream de Tower.
- Playbook : Description de la configuration souhaitée
- Modules : Code qui est exĂ©cutĂ© sur les nĆuds
On reviendra sur les Playbook et Modules un peu plus loin dans l’article.
Fichiers nécessaires
Pour commencer on va parler des fichiers les plus importants, ceux qui sont suffisants pour faire un premier Playbook qui sera fonctionnel.
Playbook
Dans le Playbook on dĂ©crit la configuration que lâon souhaite retrouver appliquĂ©e sur les nĆuds. A la diffĂ©rence dâun script, on dĂ©crit des Ă©tats que lâon souhaite obtenir, plutĂŽt que des tĂąches prĂ©cises Ă exĂ©cuter.
Les Playbook sont Ă©crits en YAML, un langage proche du JSON. Explication sur la syntaxe ici : https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html
Inventaire
C’est dans le fichier d’inventaire que l’on dĂ©clare les nĆuds qui pourront ĂȘtre accĂ©dĂ©s avec le Playbook. Il en existe un par dĂ©faut : /etc/ansible/hosts.
Le fichier inventaire peut ĂȘtre sous deux formats :
- Fichier .ini
- Fichier .yml
Format .ini
Vous retrouverez plus souvent l’inventaire sous le format .ini, mais le second n’est pas Ă ignorer car suivant l’inventaire souhaitĂ©, il peut apporter davantage de souplesse.
Dans notre exemple oĂč l’on va dĂ©ployer le stack TIG, voici Ă quoi pourrait ressembler le fichier inventaire en .ini :
|
|
Si on décompose le fichier :
- [tig] est le nom du groupe et qui intĂ©gĂšre les 3 lignes suivantes. Le groupe peut-ĂȘtre utilisĂ© dans le Playbook.
- influxdb est le nom que l’on souhaite donner au host. Il peut Ă©galement ĂȘtre utilisĂ© dans le Playbook.
- ansible_host est une variable associĂ©e au host, chaque variable est sĂ©parĂ©e par un espace, puis on indique sa valeur prĂ©cĂ©dĂ© de =. Dans ce cas c’est l’ip du host.
J’ai ajoutĂ© un second groupe (qui ne servira pas dans notre exemple) pour montrer que l’on peut en crĂ©er autant que l’on souhaite. Il n’est pas indispensable de prĂ©ciser l’ip du host si on une rĂ©solution de nom fonctionnelle.
Et enfin, un host qui n’appartient Ă aucun groupe, lĂ encore il ne sera utilisĂ© dans l’exemple
Pour la dĂ©monstration, on va installer les 3 produits sur le mĂȘme serveur, donc on ne mettra qu’une seule ligne.
Format YAML
Voici l’Ă©quivalent en YAML :
|
|
Je pense que c’est suffisament clair pour comprendre la logique de ce format. A noter que les mots clĂ©s “all”, “hosts” et “children” sont rĂ©servĂ©s. Point important, “all” est implicitement prĂ©sent dans le fichier inventaire.ini, il correspond Ă l’ensemble des hosts prĂ©sent dans l’inventaire.
Inventaire dynamique
Je ne vais pas rentrer dans les dĂ©tails sur les inventaires dynamiques dans cet article, car on n’en aura pas besoin tout de suite. Mais sachez que c’est trĂšs pratique qu’un inventaire puisse ĂȘtre gĂ©rĂ© depuis une source de donnĂ©es externe. Deux exemples :
- Un serveur vCenter, permet d’avoir une liste VM Ă jour dans l’inventaire
- Un IPAM qui sert de Source of Truth, comme l’excellent NetBox
Je vous encourage Ă vous rendre sur la documentation officielle pour approfondir la gestion des inventaires avec Ansible : https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html
Mode interactif
La fonction premiĂšre d’Ansible est bien d’exĂ©cuter des Playbook, mais Ă des fins de test/debug, il est possible de l’utiliser en mode interactif. Par exemple si on souhaite savoir si un nĆud est accessible :
|
|
Ici on se connecte Ă lâhĂŽte grafana qui est dĂ©fini dans le fichier dâinventaire inventory.ini avec lâutilisateur jlg. Sur cet hĂŽte on exĂ©cute le module ping.
RĂ©sultat attendu :
|
|
On retrouve la documentation de chaque module via la commande :
|
|
Ou directement sur le site d’Ansible : https://docs.ansible.com/ansible/latest/modules/modules_by_category.html
Un autre exemple est l’utilisation du module command qui est celui par dĂ©faut (on a donc pas besoin de le prĂ©ciser). Ce module attend un argument qui correspond Ă la commande Ă exĂ©cuter sur lâhĂŽte. Exemple :
|
|
Comme indiquĂ©, on ne prĂ©cise pas le nom du module command car il est sĂ©lectionnĂ© par dĂ©faut, cependant on prĂ©cise lâargument avec -a, ici il va donc exĂ©cuter la commande hostname et nous renvoyer le rĂ©sultat :
|
|
Enfin, la fonctionnalitĂ© la plus utile en mode interactif est la dĂ©couverte et l’affichage des Facts. Je reviendrai plus en dĂ©tail sur les Facts et variables avec Ansible dans le prochain article. Ce qu’il faut retenir ici, c’est la capacitĂ© qu’a Ansible Ă dĂ©couvrir des informations sur le nĆud gĂ©rĂ© et Ă les enregistrer dans des variables. Par exemple :
- Informations Hardware, CPU, mĂ©moire, disques, rĂ©seau etcâŠ
- Informations systĂšmes comme les adresses IP, nom et version de lâOS
- Et plein dâautres choses
Le mieux étant encore de le tester, pour cela on exécute le module setup, sans argument :
|
|
Le résultat est trÚs long, voici une partie :
|
|
On peut Ă©galement appliquer un filtre afin de limiter l’affichage, ici un exemple pour affichier les points de montage :
|
|
Toutes ces informations vont pouvoir ĂȘtre rĂ©utilisĂ©es plus tard dans le Playbook, par exemple si vous souhaitez faire un contrĂŽle sur une version d’OS avant d’exĂ©cuter un tĂąche.
Composition d’un Playbook
On arrive maintenant au Playbook, on va rester simple ici aussi, le but Ă©tant d’introduire le concept.
Voici le Playbook que l’on va exĂ©cuter :
|
|
MĂȘme si un Playbook a le mĂ©rite d’ĂȘtre comprĂ©hensible, il mĂ©rite quelques explications đ
- Configuration de la Timezone
- Mise Ă jour de tous les paquets
- Ajout du Repository apt d’InfluxData (Ă©diteur de de InfluxDB et Telegraf) avec la clĂ© associĂ©e
- Ici on a exemple de l’utilisation des Facts vu plus haut avec la rĂ©cupĂ©ration de l’OS (ubuntu) et de la version (focal)
- Si InfluxDB n’est pas prĂ©sent, on l’installe.
- Ici on prĂ©cise present et non pas latest, on veut que InfluxDB soit installĂ©, si c’est dĂ©jĂ le cas, on ne souhaite pas le mettre Ă jour.
- Enfin on dĂ©marre le service et on l’active (dĂ©marrage automatique)
Play
Un Playbook est divisé en plusieurs Play, ici on en retrouve deux, le premier commence dÚs le début avec :
|
|
Le fait qu’il commence par un tiret indique que c’est une liste, et donc qu’il est proabable qu’il y en est plusieurs.
Un Play correspond Ă une liste de tĂąches qui seront exĂ©cutĂ©es suivant les informations dans l’en-tĂȘte. Ces tĂąches seront exĂ©cutĂ©es dans l’odre, sur chacun des nĆuds. Cependant le traitement se fait en parallĂšle sur les nĆuds (si on a prĂ©cisĂ© un groupe au lieu d’un hĂŽte simple).
En-tĂȘte
Une en-tĂȘte par Play, la premiĂšre :
|
|
On retrouve des informations qu’on avait dĂ©jĂ pu prĂ©ciser dans le mode interactif comme le host (ou groupe de hosts, on aurait pu mettre all ou grafana). On retrouve aussi l’utilisateur pour se connecter exĂ©ucter les actions. On y prĂ©cise quelques informations supplĂ©mentaires comme le fait qu’on rĂ©cupĂšre les Facts, ainsi que le besoins d’obtenir une Ă©lĂ©vation de privilĂšge (become).
Task
C’est avec les Tasks qu’on indique quel est l’Ă©tat souhaitĂ© sur le nĆud. Si on regarde la premiĂšre Task :
|
|
Le nom indiquĂ© est optionnel et servira notamment pour obtenir un affichage clair, mais aussi de marqueur si on souhaite relancer le Playbook depuis une tĂąche prĂ©cise. Ensuite vient l’appel du module timezone auquel on passe un argument correspondant Ă la Timezone.
L’objectif de cette Task est donc de configurer la Timezone indiquĂ© en argument, sur le host. Si la configuration est dĂ©jĂ correct, il remontera un statut Ok, si il doit la modifier, il prĂ©cisera Changed. On s’attend donc Ă ce que si on relance le Playbook, le statut sera Ok
Module
Enfin le module est le composant qui renferme le code Python qui sera exĂ©cutĂ© sur le nĆud, c’est lui qui doit ĂȘtre idempotent et donc s’assurer de ne faire des modifications que si nĂ©cessaire. Les modules sont accessibles directement sur Github : https://github.com/ansible/ansible/tree/stable-2.9/lib/ansible/modules.
La version 2.10 intÚgre une refonte de la gestion des modules, ils sont maintenant disponibles sous forme de collections, je ferai un article dédié sur le sujet.
Explication des changements ici : https://github.com/ansible-collections/overview
Les collections ici : https://github.com/ansible-collections/
Exemple pour VMware : https://github.com/ansible-collections/vmware/tree/main/plugins/modules
Exécution du Playbook
Enfin, on peut exécuter ce premier Playbook avec la commande suivante :
|
|
Cette fois on ne prĂ©cise pas d’utilisateur ni de nĆud sur lequel exĂ©cuter le Playbook, ces informations sont indiquĂ©es dans l’en-tĂȘte des Plays. On a cependant ajoutĂ© l’option -K afin que le prompt nous sollicite pour saisir le mot de passe permettant l’Ă©levation de privilĂšge (sudo par dĂ©faut).
Je vous encourage à le relancer plusieurs fois afin de voir la différence.
Cya!