Utiliser les customs facts Ansible
Petit rappel : Chaque fois que vous exécutez un playbook Ansible, la
première tache qui est exécuté est la collecte des facts. A moins que vous
l'ayez désactivé avec le paramètre de playbook gather_facts: false
.
Cette collecte rassemble toute une série d'informations présentes sur la ou les machines distantes : adresses IP, liste des disques, version du système d’exploitation, etc. Dans le langage Ansible on appelle ça des « facts ».
Mais, saviez-vous que vous pouvez également ajouter vos propres facts
qu'Ansible collectera de la même manière que vous pourrez utiliser ensuite dans
les conditions ou comme paramètre de module. On les appelle les customs facts
.
Les customs facts bien qu'évoqué dans le module setup, celui qui est appelé implicitement et contrôlé par le paramètre gather_facts, ne sont pas très documenté et c'est cela que je vous propose de vous exposer.
Où créer des customs facts ?
Les customs facts sont en fait assez faciles à mettre en œuvre. Sur chaque
noeud de votre inventaire Ansible, il suffit de créer un répertoire
dans lequel vous pourrez déposer un ou plusieurs fichiers nommés avec
l'extension .fact
.
Lors de l'exécution implicite du module setup Ansible cherche ses fichiers de
facts dans le répertoire /etc/ansible/facts.d/
. Il est pour le moment
impossible de lui indiquer un autre chemin.
Par contre, vous pouvez désactiver cette collecte implicite et exécuter le
module setup de manière contrôlé et là en lui indiquant le chemin où se trouve
ces fichiers facts. Il suffit d'utiliser le paramètre fact_path
.
Voici comment écrire une telle invocation :
---
- name: Update OS of servers
hosts: webservers
become: true
gather_facts: false
tasks:
- name: Collects facts
ansible.builtin.setup:
fact_path: /custom/facts/path/
gather_subset: !all,min
En utilisant ce pattern, vous pouvez optimiser le temps d'exécution de vos playbooks en ne collectant que les facts nécessaires à sa bonne exécution. En effet, la collecte des facts est assez consommatrice et c'est pour cela qu'il est possible d'utiliser un mécanisme de cache avec divers outils spécialisés.
Que mettre dans ces fichiers de customs facts ?
Les fichiers de facts doivent afficher des données au format json
ou
ini
. Donc il est tout à fait possible d'utiliser un script bash
, python
,
ou tout autre langage.
Le format ini
Par exemple si vous créer le fichier preference.fact
dans le dossier
/etc/ansible/facts.d
avec ce contenu :
[general]
function=War
family=Destruction
Lors de la collecte des facts vous devriez les voir apparaître ainsi :
"ansible_local": {
"preference": {
"general": {
"family": "Destruction",
"function": "War"
}
}
},
Vous pouvez le tester sur votre machine en créant le fichier et en exécutant le module setup de cette manière :
all -m setup -a 'gather_subset=!all,min' -c local -i localhost,all
Un script qui retourne du json
On peut tout à fait utiliser un script écrit dans le langage de votre choix
tant qu'il retourne de l'information sous le format json
ou ini
:
Exemple de script bash :
#!/bin/bash
DATE=$(date)
echo {\"date\" : \"${DATE}\"}
Lançons le playbook et voyons ce qu'il retourne :
"ansible_local": {
"date": {
"date": "mer. 20 avril 2022 07:42:23 CEST"
},
"preference": {
"general": {
"family": "Destruction",
"function": "War"
}
}
},
Donc, vous voyez qu'il suffit de créer des fichiers qui retournent des données
dans le format de votre choix. Vous les retrouverez dans la liste
ansible_local
ou chaque fichier est une liste portant de son fichier sans
l'extension.
Quand et comment créer ses fichiers de customs facts ?
Le plus simple est de le créer au moment où vous provisionnez vos machines. Par
exemple si vous utilisez Terraform, créer les avec un
provisionner
de type file
. Vous pouvez aussi utiliser
Ansible pour les créer avec ce contenu qui pourrait
devenir par la suite un rôle :
---
- name: Update OS of servers
hosts: webservers
become: true
gather_facts: false
tasks :
- name: "Create custom fact directory"
ansible.builtin.file:
path: "/etc/ansible/facts.d"
state: "directory"
- name: "Insert custom fact file"
ansible.builtin.copy:
src: files/date.fact
dest: /etc/ansible/facts.d/custom.fact
mode: 0755
Ces fichiers pourraient être aussi créé par des scripts qui s'exécuteraient de régulièrement via des jobs cron, ou des workflows AWX.
Plus loin
Tout est envisageable. Je l'ai mis en oeuvre par exemple pour mettre en place un
système de patch d'OS automatique. La mise à jour des packages de l'OS ne
s'exécutait que si le paramètre gel_applicatif
se trouvait à false
. D'autres
paramètres contrôlaient le jour de la semaine et l'heure à laquelle cette mise à
jour pouvait s'appliquer...
Il y a plein de cas d'usage possible de ces customs facts
comme alimenter les
données d'une CMDB. On n'y pense pas assez souvent, mais plus maintenant !