Ansible - Utiliser MySQL comme inventaire dynamique
Publié le : 6 octobre 2020 | Mis à jour le : 22 janvier 2023Parfois votre CMDB peut être stocké dans une base de données comme Mysql. C’est mon cas où un script python utilisant les résultats de la command nmap et des gather_facts d’Ansible stocke les machines dans la base mysql.
L’inventaire dynamique classique consiste à obtenir la liste des hôtes via un script externe et à la renvoyer à la commande ansible dans le format requis.
Ici on va utiliser deux astuces qui sont :
- la commande add_host permettant d’ajouter une machine à un groupe dynamiquement ;
- la possibilité de définir plusieurs sections avec différents groupes cible ;
Récupération des machines stockés dans votre base mysql
La première partie du playbook est un simple appel à la commande mysql via le module shell. Vous aurez juste à modifier les champs entre <> pour utiliser ce playbook. Cette requête vient récupérer les adresses IP qui sont ensuite stockées dans une variable nommée stuff
---
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Retrieve stuff from mysql
shell: mysql --user=<user> --password=<secret> <schema> --host=<ip> --port=<port> --batch --skip-column_names
--execute="SELECT ipaddr FROM cmdb WHERE state like 'up'"
register: stuff
Création du groupe
Toujours dans lé même section du playbook on va utiliser la commande add_host pour constituer le groupe qui sera ensuite utilisé dans la seconde section du playbook.
- name: Add host
add_host:
hostname: "{{item}}"
groups: running_hosts
with_items: "{{ stuff.stdout_lines }}"
Utilisation du groupe dans la seconde section du playbook
Maintenant il suffit juste d’ajouter une nouvelle section à votre playbook utilisant cette fois le groupe running_hosts. Ici je vais créer un fichier de facts persos (via un template jinja) qui seront récupérés par la collecte des facts si elle est activée.
Le code complet :
---
- hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Retrieve stuff from mysql
shell: mysql --user=<user> --password=<secret> <schema> --host=<ip> --port=<port> --batch --skip-column_names
--execute="SELECT ipaddr FROM cmdb WHERE state like 'up'"
register: stuff
- name: Add host
add_host:
hostname: "{{item}}"
groups: running_hosts
with_items: "{{ stuff.stdout_lines }}"
- hosts: running_hosts
strategy: host_pinned
gather_facts: no
tasks:
- name: create folder
file:
path: /etc/ansible/facts.d
mode: '0644'
state: directory
- name: get install_date
shell: stat /root/install.log | grep "Modif" | tail -1 | cut -d" " -f2,3| cut -d"." -f1
register: install_date
- name: Create file
template:
src: local_fact.j2
dest: /etc/ansible/facts.d/defaults.fact
Le fichier jinja :
jinja2: trim_blocks:False
[informations]
reboot_date={% if reboot_date.stdout_lines != [] %}{{reboot_date.stdout_lines[0]}}{% else %}{% endif %}
install_date={% if install_date.stdout_lines != [] %}{{install_date.stdout_lines[0]}}{% else %}{% endif %}
Voilà vous pouvez je suis sûr que vous trouverez des use-case utilisant cette technique.
La suite de la formation ansible dans de prochains billets.