Aller au contenu
Conteneurs & Orchestration medium

Gérer Incus avec Ansible : connection plugin et provisioning

6 min de lecture

logo incus

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
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 est exécutée via incus exec. C'est idéal 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

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 site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn