Aller au contenu principal

Générer des playbooks Ansible avec ChatGPT

· 5 minutes de lecture
Stéphane ROBERT
Consultant DevOps

logo ansible

Et voilà après deux semaines de tests, j'ai fini par livrer mon package python permettant de générer des taches ansible assisté par ChatGPT. Je l'ai appelé ansible-aisnippet.

Installation d'ansible-aisnippet

Il s'agit d'un package python. Vous avez donc le choix de l'installer dans votre environnement virtuel, au niveau de votre utilisateur ou encore avec pipx.

Avec pip :

pip install ansible-aisnippet

Avec pipx

sudo pip install pipx
pipx install ansible-aisnippet
installed package ansible-aisnippet 0.1.2, installed using Python 3.10.8
These apps are now globally available
- ansible-aisnippet
done! ✨ 🌟 ✨

Pour le mettre à jour :

pipx update ansible-aisnippet

Utilisation d'ansible-aisnippet

Au préalable, il faut s'enregistrer sur openai et créer un token.

Une fois le token créé. Vous pouvez soit l'ajouter dans votre .zshrc ou votre .bashrc, soit le définir au lancement de votre shell.

Comme j'ai utilisé typer pour générer la CLI, la documentation est disponible ainsi que l'autocomplétion.

Affichage de la documentation :

export  OPENAI_KEY=<your token>

ansible-aisnippet --help

Usage: ansible-aisnippet [OPTIONS] COMMAND [ARGS]...

╭─ Options ─────────────────────────────────────────────────────╮
│ --version -v Show the application's │
│ version and exit. │
│ --install-completion Install completion for the │
│ current shell. │
│ --show-completion Show completion for the │
│ current shell, to copy it or │
│ customize the installation. │
│ --help Show this message and exit. │
╰───────────────────────────────────────────────────────────────╯
╭─ Commands ────────────────────────────────────────────────────╮
│ generate Ask ChatGPT to write an ansible task using a │
│ template │
╰───────────────────────────────────────────────────────────────╯

Generation d'une tache

ansible-aisnippet peut générer une tache ou plusieurs tâches. Voyons comment lui demander de créer une tâche. C'est assez simple, il faut utiliser la commande generate suivi d'une phrase décrivant la tâche. Attention, il faut entrer les descriptions en anglais !

export  OPENAI_KEY=<your token>

ansible-aisnippet generate "execute command to start /opt/application/start.sh create /var/run/test.lock"
Building prefix dict from the default dictionary ...
Loading model from cache /tmp/jieba.cache
Loading model cost 0.686 seconds.
Prefix dict has been built successfully.
name: Execute command to start /opt/application/start.sh create /var/run/test.lock

ansible.builtin.command:
chdir: /opt/application
cmd: ./start.sh && touch /var/run/test.lock
creates: /var/run/test.lock
removes: ''

ansible-aisnippet nous propose une tache utilisant le module ansible command. Il lance le script et en cas de réussite, il pose le lock. Cela permet de ne pas relancer cette commande une seconde fois.

Générer plusieurs taches

ansible-aisnippet peut aussi générer plusieurs taches en se basant sur le contenu d'un fichier YAML. Ce fichier contient simplement une liste de tâches et de blocks.

Exemple :

- task: Install package htop, nginx and net-tools with generic module
- task: Copy file from local file /tmp/toto to remote /tmp/titi set mode 0666 owner bob group www
register: test
- name: A block
when: test.rc == 0
block:
- task: wait for port 6300 on localhost timeout 25
rescue:
- task: Execute command /opt/application/start.sh creates /var/run/test.lock
- task: Download file from https://tmp.io/test/ set mode 0640 and force true

Pour générer un playbook, il suffit d'ajouter l'option -p :

export  OPENAI_KEY=<your token>

ansible-aisnippet generate -f test.yml -p
Building prefix dict from the default dictionary ...
Loading model from cache /tmp/jieba.cache
Loading model cost 0.671 seconds.
Prefix dict has been built successfully.
Result:

- name: Playbook generated with chatgpt
hosts: all
gather_facts: true
tasks:
- name: Install package htop, nginx and net-tools
ansible.builtin.yum:
name:
- htop
- nginx
- net-tools
state: present
- name: Copy file from local file /tmp/toto to remote /tmp/titi
ansible.builtin.copy:
src: /tmp/toto
dest: /tmp/titi
mode: '0666'
owner: bob
group: www
register: test
- name: A block
when: test.rc == 0
block:
- name: Wait for port 6300 on localhost timeout 25
ansible.builtin.wait_for:
host: 127.0.0.1
port: '6300'
timeout: '25'
rescue:
- name: Execute command /opt/application/start.sh creates /var/run/test.lock
ansible.builtin.command:
chdir: /tmp/test
cmd: /opt/application/start.sh
creates: /var/run/test.lock
- name: Download file from https://tmp.io/test/
ansible.builtin.get_url:
backup: false
decompress: true
dest: /tmp/test
force: true
group: root
mode: '0640'
owner: root
timeout: '10'
tmp_dest: /tmp/test
url: https://tmp.io/test/
validate_certs: true

Il est possible de demander à écrire le résultat dans un fichier avec l'option -o.

Fonctionnement

Pour ceux qui ont manqué les deux billets qui ont permis la création de cet outil, je vous renvoie à leur lecture.

En quelques mots. Ansible-aisnippet utilise la librairie gensim pour rechercher parmi des snippets fournis la phrase la plus proche de la description de la tache attendue. Une fois identifié, je demande à chatGPT de générer une tache en se basant dessus pour respecter la consigne de la tache.

Plus loin

Les résultats sont plutôt sympathiques, mais demandent tout de même d'être relus et corriger avant de les appliquer. De même, si on souhaite utiliser des variables.

Comme cet outil se base sur une liste de templates fournis, pour le moment, je n'ai mis que ceux de la collection ansible.builtin. Pourquoi ? Car pour que les résultats de cet outil soient corrects, il faut que les templates fournis soient aussi de qualité. Pour le moment 50% des templates fournis ont été nettoyés des options non obligatoires.

Dans les prochaines versions, je finaliserai cette collection puis j'ajouterai d'autres collections. De même, j'ajouterai la possibilité d'utiliser vos propres collections de templates.

Pour ceux qui veulent m'aider le projet se trouve ici.