Aller au contenu

Architecture et profils

Mise en place de l'arborescence Ansible, du système de state par variables prefixees, et des profils de configuration.


Couches d'infrastructure

graph TB
    subgraph "Image VDI Linux"
        SEC["Securite<br/>fail2ban, firewall, SSH"]
        SES["Service de session<br/>XFCE + xRDP"]
        APP["Services applicatifs<br/>LibreOffice, Firefox, VS Code"]
        SHR["Shared services<br/>Podman + QEMU"]
        K8S["Orchestration<br/>K3s standalone"]
    end
    SEC --> SES
    SES --> APP
    SES --> SHR
    SHR --> K8S
Couche Rôle Ansible Responsabilité
Service de session desktop XFCE, xRDP, locale, clavier
Service applicatif apps, k3s Outils bureautiques, dev, orchestration
Shared services podman, qemu Conteneurisation, compilation croisee
Sécurité security fail2ban, firewall, SSH hardening

Arborescence des rôles

Créez la structure complète :

mkdir -p packer-vdi-linux/{packer,ansible/{profiles,group_vars}}
mkdir -p packer-vdi-linux/ansible/roles/{desktop,apps,podman,qemu,k3s,security}/{tasks,handlers,defaults}

Structure cible :

ansible/
├── playbook.yml
├── profiles/
│   ├── developer.yml
│   ├── office.yml
│   └── full.yml
├── group_vars/
│   ├── ubuntu.yml
│   └── rocky.yml
└── roles/
    ├── desktop/
    │   ├── tasks/
    │   │   ├── main.yml
    │   │   └── validate.yml
    │   ├── handlers/main.yml
    │   └── defaults/main.yml
    ├── apps/
    │   ├── tasks/
    │   │   ├── main.yml
    │   │   └── validate.yml
    │   └── defaults/main.yml
    ├── podman/
    │   ├── tasks/
    │   │   ├── main.yml
    │   │   └── validate.yml
    │   └── defaults/main.yml
    ├── qemu/
    │   ├── tasks/
    │   │   ├── main.yml
    │   │   └── validate.yml
    │   └── defaults/main.yml
    ├── k3s/
    │   ├── tasks/
    │   │   ├── main.yml
    │   │   └── validate.yml
    │   └── defaults/main.yml
    └── security/
        ├── tasks/
        │   ├── main.yml
        │   └── validate.yml
        ├── handlers/main.yml
        └── defaults/main.yml

Système de state

Chaque rôle utilise des variables prefixees par son nom. Cela evite les collisions et rend la configuration lisible :

# Variables du role desktop
desktop_enabled: true
desktop_xrdp_port: 3389
desktop_locale: "fr_FR.UTF-8"
desktop_keyboard_layout: "fr"
desktop_run_rdp_test: false

# Variables du role apps
apps_enabled: true
apps_libreoffice: true
apps_vscode: true
apps_firefox: true
apps_test_user: "vdi-user"

# Variables du role podman
podman_enabled: true
podman_rootless: true
podman_registries: ["docker.io", "ghcr.io"]
podman_test_user: "vdi-user"

# Variables du role qemu
qemu_enabled: true
qemu_user_static: true
qemu_system: false

# Variables du role k3s
k3s_enabled: false
k3s_rootless: true

# Variables du role security
security_enabled: true
security_fail2ban: true
security_ufw: true
security_firewalld: true
security_ssh_hardening: true

Convention de nommage

Préfixe = nom du rôle. Exemple : podman_rootless, desktop_locale, k3s_enabled. Aucune variable ne peut entrer en conflit avec un autre rôle.

Profils

Un profil est un fichier YAML qui définit un ensemble cohérent de flags. Les flags individuels peuvent être overrides en extra-vars.

Profil developer

# profiles/developer.yml
desktop_enabled: true
desktop_locale: "fr_FR.UTF-8"
apps_enabled: true
apps_vscode: true
apps_libreoffice: false
apps_firefox: true
podman_enabled: true
podman_rootless: true
qemu_enabled: true
qemu_user_static: true
qemu_system: false
k3s_enabled: true
k3s_rootless: true
security_enabled: true

Profil office

# profiles/office.yml
desktop_enabled: true
desktop_locale: "fr_FR.UTF-8"
apps_enabled: true
apps_vscode: false
apps_libreoffice: true
apps_firefox: true
podman_enabled: false
qemu_enabled: false
k3s_enabled: false
security_enabled: true

Profil full

# profiles/full.yml
desktop_enabled: true
desktop_locale: "fr_FR.UTF-8"
apps_enabled: true
apps_vscode: true
apps_libreoffice: true
apps_firefox: true
podman_enabled: true
podman_rootless: true
qemu_enabled: true
qemu_user_static: true
qemu_system: true
k3s_enabled: true
k3s_rootless: true
security_enabled: true

Playbook principal

Le playbook charge le profil puis exécuté les rôles conditionnellement :

# ansible/playbook.yml
---
- name: Build VDI Linux image
  hosts: all
  become: true

  pre_tasks:
    - name: Charger le profil
      ansible.builtin.include_vars:
        file: "profiles/{{ profile | default('full') }}.yml"

  roles:
    - role: desktop
      when: desktop_enabled | default(false)
    - role: apps
      when: apps_enabled | default(false)
    - role: podman
      when: podman_enabled | default(false)
    - role: qemu
      when: qemu_enabled | default(false)
    - role: k3s
      when: k3s_enabled | default(false)
    - role: security
      when: security_enabled | default(false)

Multi-OS avec group_vars

Les différences entre Ubuntu et Rocky sont isolées dans group_vars/ :

# group_vars/ubuntu.yml
desktop_packages:
  - xfce4
  - xfce4-goodies
  - xrdp
  - xorgxrdp
desktop_xrdp_service: xrdp
security_firewall_package: ufw
security_firewall_service: ufw
pkg_manager: apt

podman_package: podman
qemu_user_static_package: qemu-user-static
# group_vars/rocky.yml
desktop_packages:
  - "@Xfce"
  - xrdp
  - xorgxrdp
desktop_xrdp_service: xrdp
security_firewall_package: firewalld
security_firewall_service: firewalld
pkg_manager: dnf

podman_package: podman
qemu_user_static_package: qemu-user-static

Détection de l'OS

Ansible détecté automatiquement ansible_os_family (Debian ou RedHat). Les group_vars sont charges selon l'inventaire ou via un pre_task qui set le groupe dynamiquement.

Assertions

Chaque rôle contient un fichier tasks/validate.yml exécuté en fin de rôle. Les assertions sont a deux niveaux :

Niveau Objectif Exemple
Technique Le composant est installé et actif podman --version retourné un résultat
Cas d'usage Le parametrage permet le use-case attendu Un user non-root peut lancer un conteneur Podman
# Exemple : inclusion dans tasks/main.yml
- name: Validation du role
  ansible.builtin.include_tasks: validate.yml
  tags: [validate]

Exécuter les assertions seules

Lancez uniquement les validations avec le tag validate :

ansible-playbook playbook.yml --tags validate