Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Gérer Incus avec Ansible : connection plugin et provisioning

  • 20 min

Par mis à jour le

Améliorer cette page

Ansible et Incus se rejoignent sur deux usages qu'il faut bien distinguer : configurer l'intérieur d'instances déjà là (le connection plugin community.general.incus, qui passe par incus exec sans SSH), et créer les instances elles-mêmes (le provisioning). Ce guide déroule les deux, avec un point d'honnêteté important : il n'existe pas de module Ansible natif dédié à Incus, on provisionne via lxd_container. Tout est testé sur Incus 7.0 avec Ansible core 2.19 et community.general 11.

  • La différence entre connection plugin et provisioning.
  • Gérer une instance existante avec community.general.incus (sans SSH).
  • Créer une instance Incus via community.general.lxd_container.
  • L'état réel des modules Ansible pour Incus.
  • Ansible installé avec la collection community.general (fournie avec le paquet ansible complet, sinon ansible-galaxy collection install community.general).
  • Le client incus sur la machine qui exécute Ansible : les deux approches passent par lui (incus exec, socket local).
  • Des bases d'Incus : voir Premiers pas avec Incus.

Avant de coder, il faut choisir le bon outil selon le besoin. Le tableau ci-dessous résume la répartition, qui structure tout le reste du guide.

BesoinOutilComment
Configurer l'intérieur d'une instance existanteConnection plugin community.general.incusAnsible fait incus exec, pas de SSH
Lister les instances existantesPlugin d'inventaire community.general.incusAnsible interroge la CLI incus
Créer / supprimer une instanceModule community.general.lxd_containerVia l'API, socket Incus explicite
Construire une imagePacker + AnsibleVoir le guide dédié

Le plugin community.general.incus traite une instance comme une machine distante, mais sans SSH : chaque tâche passe par incus exec. C'est la voie pour appliquer une configuration à un conteneur déjà lancé.

L'inventaire déclare la connexion et le nom de l'instance côté Incus.

inventory.yml
all:
hosts:
tf-web:
ansible_connection: community.general.incus
ansible_incus_remote: local
ansible_incus_project: default
ansible_incus_host: tf-web
ansible_user: root

Le playbook installe d'abord Python si besoin (via raw, qui ne dépend pas de Python), puis applique des tâches normales.

play-connect.yml
- name: Configurer une instance existante via incus
hosts: tf-web
gather_facts: false
tasks:
- name: S'assurer que python3 est présent
ansible.builtin.raw: command -v python3 || (apt-get update -qq && apt-get install -y -qq python3)
changed_when: false
- name: Déposer un fichier témoin
ansible.builtin.copy:
content: "géré par ansible via le connection plugin incus\n"
dest: /root/ansible-marker.txt
mode: "0644"

L'exécution passe par incus exec et non par le réseau : aucune clé SSH, aucun port ouvert dans l'instance.

PLAY [Configurer une instance existante via incus] *****
TASK [S'assurer que python3 est présent] ***************
TASK [Déposer un fichier témoin] ***********************
tf-web : ok=3 changed=2 unreachable=0 failed=0

Découvrir les instances avec le plugin d'inventaire

Section intitulée « Découvrir les instances avec le plugin d'inventaire »

Écrire l'inventaire à la main cesse de tenir dès que les instances vont et viennent. Le plugin d'inventaire community.general.incus, ajouté dans community.general 12.0.0, construit la liste en interrogeant la CLI incus :

incus.yml
plugin: community.general.incus
filters:
- type=virtual-machine
- status=running
Fenêtre de terminal
ansible-inventory -i incus.yml --graph

L'option filters accepte les mêmes expressions que incus list : l'inventaire se resserre exactement sur les instances visées. Le plugin couvre plusieurs remotes via remotes, se limite à un projet avec la syntaxe remote:project, et nomme par défaut les hôtes INSTANCE.PROJECT.REMOTE, ce qui distingue deux instances de même nom dans des projets différents. Posez host_fqdn: false pour revenir au nom court.

Combiné au connection plugin, cela donne un montage où rien ne s'écrit à la main : l'inventaire reflète ce qui tourne réellement, et chaque tâche atteint l'instance sans SSH.

Pour créer une instance, on utilise le module community.general.lxd_container. Ce module cible LXD par défaut : pour viser Incus, il faut pointer explicitement son socket avec url: unix:/var/lib/incus/unix.socket.

play-provision.yml
- name: Provisionner une instance Incus
hosts: localhost
connection: local
gather_facts: false
tasks:
- name: Créer et démarrer ans-web sur Incus
community.general.lxd_container:
name: ans-web
url: unix:/var/lib/incus/unix.socket
state: started
source:
type: image
mode: pull
server: https://images.linuxcontainers.org
protocol: simplestreams
alias: debian/13
profiles: ["default"]
wait_for_ipv4_addresses: true
timeout: 150

Le module est idempotent : un second passage ne recrée rien. L'instance apparaît côté Incus, ici placée sur node2 du cluster.

localhost : ok=2 changed=1 unreachable=0 failed=0
+---------+---------+-----------+----------+
| NAME | STATE | TYPE | LOCATION |
+---------+---------+-----------+----------+
| ans-web | RUNNING | CONTAINER | node2 |
+---------+---------+-----------+----------+
  • Deux usages distincts : configurer l'intérieur (connection plugin) vs créer (provisioning).
  • community.general.incus exécute les tâches via incus exec, sans SSH.
  • Une image images: minimale exige d'installer Python en raw avant les modules.
  • On provisionne avec lxd_container + url: unix:/var/lib/incus/unix.socket.
  • Pas de module Incus natif officiel : lxd_container, ou la CLI/API en direct.

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn