Aller au contenu principal

Utiliser MySQL comme inventaire Ansible

· 3 minutes de lecture
Stéphane ROBERT
Consultant DevOps

**Parfois 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.