Aller au contenu principal

Générer des playbooks Ansible avec ChatGPT

· 5 minutes de lecture
Stéphane ROBERT
Consultant DevOps

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.