Setup initial avec ansible

This commit is contained in:
Daniel Allaire 2026-06-19 23:31:49 -04:00
parent 9213a140d5
commit 1823341c94
52 changed files with 2103 additions and 2 deletions

373
AGENTS.md Normal file
View file

@ -0,0 +1,373 @@
# AGENTS.md — Set-OPS
## Rôle du dépôt
Ce dépôt contient les playbooks, rôles, inventaires et templates Ansible servant à construire, configurer, maintenir et documenter les serveurs de Chezlepro Inc.
Objectif principal : produire une infrastructure reproductible, lisible, sobre, sécuritaire et administrable sans dépendance inutile au cloud.
Ce dépôt doit permettre de reconstruire progressivement lenvironnement serveur à partir de modèles propres, principalement basés sur Debian 13.
---
## Règle dor IA
Un seul agent IA travaille dans ce dépôt à la fois.
- Soit Codex.
- Soit Claude Code.
- Jamais les deux simultanément.
Tout changement significatif doit être consigné dans `CHANGELOG.md`.
---
## Principes de travail
1. Toujours lire lexistant avant de modifier.
2. Ne jamais présumer de linventaire réel sans le vérifier.
3. Ne jamais introduire de secret en clair.
4. Ne jamais casser lidempotence Ansible.
5. Ne jamais exécuter daction destructive sans confirmation explicite.
6. Préférer la simplicité à lingénierie excessive.
7. Documenter ce qui est utile à lexploitation réelle.
8. Produire des playbooks relisibles par un humain fatigué en situation dincident.
---
## Style Ansible attendu
Les playbooks doivent être :
- idempotents ;
- lisibles ;
- découpés en rôles lorsque pertinent ;
- compatibles avec Debian 13 sauf exception documentée ;
- testables avec `--check` autant que possible ;
- sécuritaires par défaut ;
- sans dépendances SaaS ou cloud inutiles.
Préférer les modules Ansible standards :
- `ansible.builtin.apt`
- `ansible.builtin.template`
- `ansible.builtin.copy`
- `ansible.builtin.service`
- `ansible.builtin.lineinfile`
- `ansible.builtin.file`
- `ansible.builtin.user`
- `ansible.builtin.group`
- `ansible.builtin.systemd`
Éviter les commandes `shell` et `command` sauf nécessité réelle.
Lorsquune commande shell est nécessaire, elle doit être encadrée avec les paramètres appropriés selon le cas :
- `changed_when`
- `failed_when`
- `creates`
- `removes`
---
## Structure recommandée
Le dépôt doit tendre progressivement vers cette structure :
```text
Set-OPS/
├── AGENTS.md
├── README.md
├── CHANGELOG.md
├── ansible.cfg
├── inventories/
│ ├── lab/
│ │ ├── hosts.yml
│ │ └── group_vars/
│ └── production/
│ ├── hosts.yml
│ └── group_vars/
├── playbooks/
│ ├── bootstrap.yml
│ ├── baseline.yml
│ ├── hardening.yml
│ ├── updates.yml
│ ├── nginx.yml
│ ├── monitoring.yml
│ └── users.yml
├── roles/
│ ├── common/
│ ├── users/
│ ├── ssh/
│ ├── sudo/
│ ├── qemu_guest_agent/
│ ├── chrony/
│ ├── firewall/
│ ├── unattended_updates/
│ ├── nginx/
│ ├── monitoring_agent/
│ └── vm_template_cleanup/
├── templates/
├── files/
├── scripts/
└── docs/
```
Ne pas créer toute cette structure inutilement dun seul coup. La créer selon les besoins réels.
---
## Conventions de nommage
Utiliser des noms clairs, sobres et prévisibles.
Exemples de playbooks :
```text
baseline.yml
hardening.yml
debian13-template.yml
nginx-static-site.yml
monitoring-agent.yml
```
Exemples de rôles :
```text
roles/common
roles/ssh
roles/sudo
roles/nginx
roles/qemu_guest_agent
```
Exemples de variables :
```yaml
chezlepro_timezone: "America/Toronto"
chezlepro_admin_user: "ansible"
chezlepro_ssh_port: 22
```
---
## Cibles connues
Contexte dexploitation Chezlepro Inc. :
- hyperviseurs Proxmox ;
- stockage TrueNAS iSCSI ;
- VM Debian 13 ;
- administration par Ansible ;
- préférence pour logiciels libres ;
- préférence pour services sobres, locaux, documentés ;
- éviter les dépendances cloud ;
- usage de comptes techniques dédiés ;
- SSH par clé à terme ;
- compte `ansible` avec sudo sans mot de passe lorsque nécessaire.
---
## Modèle Debian 13 de base
Les rôles liés au modèle Debian 13 doivent viser :
- système minimal ;
- pas denvironnement graphique ;
- SSH installé ;
- `qemu-guest-agent` installé et actif ;
- `sudo` installé ;
- utilisateur `ansible` présent ;
- sudo NOPASSWD pour `ansible`, lorsque demandé ;
- timezone correcte ;
- hostname propre ;
- mises à jour appliquées ;
- logs et caches nettoyables avant conversion en template ;
- aucune clé privée ;
- aucun secret ;
- aucune donnée propre à une VM clonée.
---
## Sécurité
Ne jamais commiter :
- mots de passe ;
- clés privées SSH ;
- tokens API ;
- secrets Ansible Vault non chiffrés ;
- fichiers `.env` sensibles ;
- exports de configuration contenant des secrets ;
- certificats privés ;
- backups réels ;
- fichiers de production non anonymisés.
Créer ou maintenir un `.gitignore` adapté.
Toute variable sensible doit être placée dans un mécanisme approprié :
- Ansible Vault ;
- fichier local non versionné ;
- secret injecté hors dépôt ;
- gestionnaire de secrets externe explicitement approuvé.
---
## SSH
État transitoire accepté pendant la construction :
```text
PasswordAuthentication yes
```
État cible recommandé :
```text
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
```
Ne jamais désactiver lauthentification par mot de passe avant davoir confirmé que laccès par clé fonctionne.
---
## Sudo
Le compte technique `ansible` peut être configuré ainsi :
```text
ansible ALL=(ALL) NOPASSWD:ALL
```
Cette règle doit être placée dans :
```text
/etc/sudoers.d/90-ansible
```
Toujours valider avec :
```bash
visudo -cf /etc/sudoers.d/90-ansible
```
---
## Playbooks destructifs
Toute action pouvant causer une perte daccès ou de données doit être protégée.
Exemples dactions destructives :
- suppression de paquets critiques ;
- modification SSH bloquante ;
- redémarrage massif ;
- formatage disque ;
- modification de partitions ;
- suppression dutilisateurs ;
- modification firewall ;
- purge de données ;
- changement réseau pouvant couper laccès.
Pour ces actions, exiger une variable explicite :
```yaml
confirm_destructive_action: true
```
Et refuser lexécution autrement.
---
## Documentation
Chaque rôle important doit contenir au minimum :
```text
roles/nom_du_role/README.md
roles/nom_du_role/defaults/main.yml
roles/nom_du_role/tasks/main.yml
```
Le README du rôle doit expliquer :
- ce que le rôle fait ;
- sur quelles distributions il est prévu ;
- les variables principales ;
- les effets de bord ;
- les commandes de test.
---
## Tests minimaux
Avant de proposer un changement comme terminé, vérifier autant que possible :
```bash
ansible-playbook --syntax-check playbooks/nom.yml
ansible-playbook -i inventories/lab/hosts.yml playbooks/nom.yml --check
ansible-lint
```
Si `ansible-lint` nest pas disponible, le mentionner clairement sans inventer un résultat.
---
## CHANGELOG
Chaque modification significative doit être inscrite dans `CHANGELOG.md`.
Format recommandé :
```markdown
## YYYY-MM-DD
### Ajouté
- ...
### Modifié
- ...
### Corrigé
- ...
```
---
## Comportement attendu de Codex
Avant de modifier :
1. Lire `README.md`, `CHANGELOG.md`, `ansible.cfg` et larborescence existante.
2. Identifier la portée exacte de la demande.
3. Proposer le plus petit changement utile.
4. Préserver les conventions existantes.
5. Ne pas réorganiser massivement le dépôt sans demande explicite.
Après modification :
1. Résumer les fichiers modifiés.
2. Indiquer les commandes de validation.
3. Signaler clairement ce qui na pas été testé.
4. Mettre à jour `CHANGELOG.md` si pertinent.
---
## Philosophie Set-OPS
Set-OPS doit rester un outil dexploitation réelle, pas une démonstration technique.
Priorités :
- reproductibilité ;
- sobriété ;
- clarté ;
- sécurité ;
- maintenance ;
- autonomie ;
- résilience.
La complexité doit toujours être justifiée par un bénéfice opérationnel clair.

9
CHANGELOG.md Normal file
View file

@ -0,0 +1,9 @@
# CHANGELOG — Set-OPS
## 2026-06-19
### Ajouté
- Ajout dune structure globale pour `Set-OPS`.
- Ajout dun espace dédié aux templates VM sans rendre le dépôt exclusif à Proxmox.
- Ajout des playbooks `vm_templates/debian13_proxmox_*`.
- Ajout de rôles classés par domaine : `base`, `security`, `vm_template`.

221
CLAUDE.md Normal file
View file

@ -0,0 +1,221 @@
# CLAUDE.md — Set-OPS
## Instruction principale
Claude Code doit lire et respecter `AGENTS.md` avant toute modification dans ce dépôt.
`AGENTS.md` est la source dautorité principale pour :
- les principes Ansible ;
- la structure du dépôt ;
- les règles de sécurité ;
- les conventions de nommage ;
- la gestion du `CHANGELOG.md` ;
- les limites sur les actions destructives ;
- la règle : Codex ou Claude Code, jamais les deux en même temps.
En cas de contradiction entre `CLAUDE.md` et `AGENTS.md`, suivre `AGENTS.md`.
---
## Règle dor IA
Un seul agent IA travaille dans ce dépôt à la fois.
- Soit Codex.
- Soit Claude Code.
- Jamais les deux simultanément.
Avant de modifier quoi que ce soit, vérifier létat du dépôt :
```bash
git status --short
```
Ne pas continuer si des changements non compris sont présents.
---
## Comportement attendu de Claude Code
Avant de modifier :
1. Lire `AGENTS.md`.
2. Lire `README.md`, `CHANGELOG.md` et `ansible.cfg` sils existent.
3. Inspecter larborescence existante.
4. Identifier la portée exacte de la demande.
5. Proposer le plus petit changement utile.
6. Préserver les conventions existantes.
7. Ne pas réorganiser massivement le dépôt sans demande explicite.
Après modification :
1. Résumer les fichiers modifiés.
2. Indiquer les commandes de validation.
3. Signaler clairement ce qui na pas été testé.
4. Mettre à jour `CHANGELOG.md` si pertinent.
---
## Limites de sécurité
Ne jamais commiter ou générer :
- mots de passe ;
- clés privées SSH ;
- tokens API ;
- secrets non chiffrés ;
- fichiers `.env` sensibles ;
- certificats privés ;
- backups réels ;
- exports de production non anonymisés ;
- fichiers contenant des informations confidentielles de Chezlepro Inc.
Toute variable sensible doit être gérée hors dépôt ou avec un mécanisme explicitement prévu, par exemple :
- Ansible Vault ;
- fichier local non versionné ;
- secret injecté hors dépôt.
---
## Actions destructives
Toute action pouvant causer une perte daccès, de données ou de disponibilité doit être protégée.
Exemples :
- suppression de paquets critiques ;
- modification SSH bloquante ;
- modification firewall ;
- redémarrage massif ;
- formatage disque ;
- modification de partitions ;
- suppression dutilisateurs ;
- purge de données ;
- changement réseau pouvant couper laccès.
Pour ces actions, exiger une confirmation explicite ou une variable du type :
```yaml
confirm_destructive_action: true
```
Sans cette confirmation, refuser lexécution.
---
## SSH
État transitoire accepté pendant la construction :
```text
PasswordAuthentication yes
```
État cible recommandé :
```text
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
```
Ne jamais désactiver lauthentification par mot de passe avant davoir confirmé que laccès SSH par clé fonctionne.
---
## Sudo
Le compte technique `ansible` peut être configuré avec sudo sans mot de passe lorsque cest requis pour lautomatisation :
```text
ansible ALL=(ALL) NOPASSWD:ALL
```
Cette règle doit être placée dans :
```text
/etc/sudoers.d/90-ansible
```
Toujours valider avec :
```bash
visudo -cf /etc/sudoers.d/90-ansible
```
---
## Ansible
Les playbooks doivent rester :
- idempotents ;
- lisibles ;
- sobres ;
- compatibles Debian 13 sauf exception documentée ;
- testables avec `--check` autant que possible ;
- exempts de dépendances SaaS ou cloud inutiles.
Préférer les modules `ansible.builtin.*`.
Éviter `shell` et `command` sauf nécessité réelle. Si une commande shell est utilisée, elle doit être encadrée avec les paramètres appropriés :
- `changed_when`
- `failed_when`
- `creates`
- `removes`
---
## Validation minimale
Avant de considérer une modification comme terminée, tenter les validations pertinentes :
```bash
ansible-playbook --syntax-check playbooks/nom.yml
ansible-playbook -i inventories/lab/hosts.yml playbooks/nom.yml --check
ansible-lint
```
Si une commande de validation na pas été exécutée ou si un outil est absent, le signaler clairement.
---
## CHANGELOG
Chaque modification significative doit être inscrite dans `CHANGELOG.md`.
Format recommandé :
```markdown
## YYYY-MM-DD
### Ajouté
- ...
### Modifié
- ...
### Corrigé
- ...
```
---
## Résumé opérationnel
Set-OPS est un dépôt dexploitation réelle pour les serveurs de Chezlepro Inc.
Priorités :
- reproductibilité ;
- sobriété ;
- clarté ;
- sécurité ;
- maintenance ;
- autonomie ;
- résilience.
La complexité doit toujours être justifiée par un bénéfice opérationnel clair.

View file

@ -1,3 +1,87 @@
# Set-OPS
# Set-OPS — exploitation Ansible Chezlepro
Création et configuration des systèmes Chezlepro Inc.
`Set-OPS` est le dépôt Ansible central pour construire, configurer, maintenir et documenter les systèmes de Chezlepro Inc.
Ce dépôt nest pas exclusif à la création du template Proxmox.
Le template Debian 13 nest quun premier chantier dans une structure plus large.
## Portée du dépôt
Le dépôt doit pouvoir accueillir progressivement :
- les templates de VM Proxmox ;
- les socles Debian ;
- le durcissement SSH ;
- les utilisateurs et sudo ;
- le reverse proxy ;
- les serveurs web statiques ;
- les bases de données ;
- la supervision ;
- les sauvegardes ;
- les services applicatifs ;
- les tâches de maintenance ;
- les validations et audits ;
- la documentation dexploitation.
## Principe dorganisation
Les playbooks sont classés par domaine fonctionnel :
```text
playbooks/
├── bootstrap/
├── baseline/
├── hardening/
├── maintenance/
├── monitoring/
├── networking/
├── storage/
├── proxmox/
├── vm_templates/
├── web/
├── database/
├── identity/
├── backup/
└── applications/
```
Les rôles sont également classés par domaine :
```text
roles/
├── base/
├── security/
├── proxmox/
├── vm_template/
├── web/
├── database/
├── monitoring/
├── backup/
├── identity/
├── storage/
└── applications/
```
## Template Debian 13 Proxmox
La préparation du modèle Debian 13 se trouve dans :
```text
playbooks/vm_templates/debian13_proxmox_prepare.yml
playbooks/vm_templates/debian13_proxmox_verify.yml
playbooks/vm_templates/debian13_proxmox_cleanup.yml
```
Les rôles associés se trouvent principalement dans :
```text
roles/base/
roles/security/
roles/vm_template/
```
## Règle importante
Le template de VM doit contenir seulement le socle commun.
Les logiciels applicatifs lourds — NGINX, PostgreSQL, MariaDB, Docker/Podman, Redis, Nextcloud, GitLab, monitoring complet — doivent être installés par des playbooks dédiés sur les clones, pas directement dans le template.

12
ansible.cfg Normal file
View file

@ -0,0 +1,12 @@
[defaults]
inventory = inventories/lab/hosts.yml
roles_path = roles
interpreter_python = auto_silent
host_key_checking = False
retry_files_enabled = False
stdout_callback = default
[privilege_escalation]
become = True
become_method = sudo
become_user = root

View file

@ -0,0 +1,26 @@
# Architecture Set-OPS
`Set-OPS` est un dépôt global dexploitation.
## Domaines
```text
bootstrap : premier accès, comptes, prérequis
baseline : socle commun Debian
hardening : sécurité et durcissement
maintenance : mises à jour, nettoyage, redémarrages contrôlés
monitoring : supervision
networking : DNS, pare-feu, réseau
storage : stockage, montages, clients
proxmox : opérations hyperviseur
vm_templates : modèles de VM
web : NGINX, sites, reverse proxy
database : PostgreSQL, MariaDB
identity : IAM, Keycloak, annuaires
backup : sauvegardes
applications : services applicatifs
```
## Règle
Le template Debian 13 Proxmox est un composant de `Set-OPS`, pas le dépôt au complet.

View file

@ -0,0 +1,783 @@
# Procédure manuelle — VM Debian 13 prête à convertir en template Proxmox
## Objet du document
Ce document décrit le travail manuel à effectuer pour créer une VM Debian 13 propre dans Proxmox, jusquau moment où elle est prête à être convertie en modèle/template.
Le résultat attendu est une VM minimale, sobre, clonable, compatible avec cloud-init, prête à être prise en charge par Ansible et par le dépôt `Set-OPS`.
Ce document sarrête juste avant la conversion finale en template Proxmox.
---
## 1. Objectif du modèle
Le modèle Debian 13 doit servir de base commune pour les futurs serveurs de Chezlepro Inc.
Objectifs :
- système Debian 13 minimal ;
- aucun environnement graphique ;
- SSH actif ;
- compte technique `ansible` disponible ;
- `ansible` autorisé à utiliser sudo sans mot de passe ;
- `qemu-guest-agent` installé ;
- `cloud-init` installé ;
- partitionnement simple et agrandissable ;
- aucune partition swap bloquant la croissance du disque ;
- aucune donnée propre à une VM finale ;
- aucune clé privée ;
- aucun secret ;
- prêt à être converti en template Proxmox.
---
## 2. Création de la VM dans Proxmox
### Paramètres généraux
Créer une nouvelle VM dans Proxmox avec des paramètres sobres.
Exemple :
```text
Nom de la VM : debian13-template
VMID : 9000 ou autre ID réservé aux modèles
OS : Debian 13
BIOS : OVMF / UEFI
Machine : q35
```
### Disque EFI Proxmox
Avec OVMF/UEFI, Proxmox crée un petit disque EFI, par exemple :
```text
efidisk0 : 4 Mo
```
Ce disque ne remplace pas la partition EFI de Debian.
Il sert à conserver les variables du firmware UEFI virtuel :
- ordre de démarrage ;
- entrées de boot ;
- variables UEFI ;
- paramètres liés à Secure Boot, si utilisé.
Il faut le garder.
---
## 3. Disque virtuel principal
### Type de disque
Pour une VM Linux moderne :
```text
Bus/Device : SCSI
SCSI Controller : VirtIO SCSI single
IO thread : activé si disponible
Cache : Default / No cache
Discard : selon stockage, seulement si pertinent
SSD emulation : oui si le stockage est réellement SSD/NVMe
```
Même si le stockage réel est sur TrueNAS iSCSI, le disque présenté à la VM doit rester :
```text
SCSI via VirtIO SCSI single
```
Le choix SCSI ici concerne le bus virtuel vu par la VM, pas le protocole réel entre Proxmox et TrueNAS.
### Taille du disque
Pour le modèle de base :
```text
Disque : 16 Go
```
Cest suffisant pour une base Debian minimale.
Des clones pourront ensuite être agrandis avant le premier démarrage cloud-init.
---
## 4. Processeur
Pour un modèle portable entre plusieurs hôtes Proxmox :
```text
CPU Type : x86-64-v2-AES
Sockets : 1
Cores : 2
```
Éviter `host` pour un modèle générique, sauf si tous les nœuds Proxmox sont strictement homogènes et que la portabilité nest pas une priorité.
---
## 5. Mémoire
Pour le modèle Debian 13 minimal :
```text
Mémoire : 2048 MiB
```
Le ballooning peut être activé, mais si la VM na pas de swap, éviter de descendre trop bas.
Réglage prudent :
```text
RAM max : 2048 MiB
RAM minimum : 1536 MiB ou 2048 MiB
```
Pour un modèle simple, il est acceptable de laisser 2048 MiB fixe.
---
## 6. Carte graphique virtuelle
Pour un serveur Debian minimal :
```text
Display : Default / Standard VGA
```
Ne pas installer denvironnement graphique.
SPICE et VirtIO-GPU ne sont pas nécessaires pour un modèle serveur administré par SSH et Ansible.
---
## 7. Installation Debian 13
Démarrer la VM sur lISO Debian 13.
Loption `Graphical install` est acceptable : elle ne signifie pas quun environnement graphique sera installé. Elle ne concerne que linterface de linstallateur.
---
## 8. Partitionnement
### Objectif
Le disque doit rester facile à agrandir après clonage.
Ne pas créer de partition swap à la fin du disque, car cela bloquerait lagrandissement direct de la partition racine avec `growpart`.
### Partitionnement recommandé
Utiliser un partitionnement manuel :
```text
/dev/sda1 EFI System Partition 512 Mo FAT32 /boot/efi
/dev/sda2 Linux root reste ext4 /
```
Ne pas créer :
```text
partition swap
LVM
/home séparé
/var séparé
```
### Pourquoi éviter LVM dans le modèle
Le stockage réel contient déjà plusieurs couches :
```text
TrueNAS ZFS
→ zvol iSCSI
→ Proxmox
→ disque virtuel
→ Debian
```
Ajouter LVM dans la VM complique le modèle sans bénéfice clair pour une base minimale.
### Pourquoi éviter la partition swap
Un exemple à éviter :
```text
/dev/sda1 EFI
/dev/sda2 /
/dev/sda3 swap
```
Si le disque est agrandi plus tard, lespace libre sera après la swap. La partition `/` ne sera donc plus la dernière partition, ce qui complique ou empêche lusage direct de :
```bash
growpart /dev/sda 2
resize2fs /dev/sda2
```
### Swap
Pour le modèle :
```text
Swap : aucun
```
Lavertissement de Debian au sujet de labsence de swap peut être ignoré.
Si un clone a besoin de swap plus tard, utiliser plutôt :
- un swapfile ;
- ou un deuxième disque virtuel dédié au swap.
Exemple de swapfile futur :
```bash
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
```
---
## 9. Choix du noyau Debian
Si linstallateur demande quel noyau installer, choisir :
```text
linux-image-amd64
```
Ne pas choisir une version fixe du noyau sauf besoin très particulier.
Le méta-paquet `linux-image-amd64` suivra les mises à jour normales de Debian.
---
## 10. Image initrd
Si linstallateur demande le type dimage initrd, choisir :
```text
image générique : comporte tous les pilotes disponibles
```
Cest le meilleur choix pour un modèle Proxmox, car la VM doit rester portable même si certains paramètres virtuels changent plus tard.
---
## 11. Sélection des logiciels Debian
Dans lécran de sélection des logiciels, cocher seulement :
```text
[x] serveur SSH
[x] utilitaires usuels du système
```
Laisser décoché :
```text
[ ] environnement de bureau Debian
[ ] GNOME
[ ] KDE Plasma
[ ] XFCE
[ ] LXDE
[ ] LXQt
[ ] MATE
[ ] serveur web
[ ] serveur dimpression
```
Le serveur web, les rôles applicatifs et les services métier seront installés plus tard par Ansible.
---
## 12. Premier démarrage après installation
Après linstallation, démarrer la VM et se connecter en console ou par SSH.
Passer root :
```bash
su -
```
ou, si sudo est déjà disponible :
```bash
sudo -i
```
---
## 13. Mise à jour du système
Exécuter :
```bash
apt update
apt full-upgrade -y
```
---
## 14. Paquets de base
Installer les paquets nécessaires au modèle :
```bash
apt install -y \
sudo \
qemu-guest-agent \
cloud-init \
cloud-guest-utils \
curl \
wget \
ca-certificates \
gnupg \
vim \
nano \
bash-completion \
htop \
lsof \
ncdu \
tree \
net-tools \
iproute2 \
dnsutils \
chrony
```
Rôle des paquets principaux :
```text
sudo : délégation administrative
qemu-guest-agent : communication Proxmox ↔ VM
cloud-init : personnalisation au premier boot du clone
cloud-guest-utils : fournit notamment growpart
chrony : synchronisation du temps
```
---
## 15. Activation du QEMU Guest Agent
Activer le service :
```bash
systemctl enable --now qemu-guest-agent
```
Vérifier :
```bash
systemctl status qemu-guest-agent --no-pager
```
Dans Proxmox, activer aussi :
```text
VM → Options → QEMU Guest Agent → Enabled
```
---
## 16. Configuration du compte ansible
### Ajouter le compte au groupe sudo
```bash
usermod -aG sudo ansible
```
### Autoriser sudo sans mot de passe
Créer le fichier dédié :
```bash
cat > /etc/sudoers.d/90-ansible <<'EOF'
ansible ALL=(ALL) NOPASSWD:ALL
EOF
```
Appliquer les permissions :
```bash
chmod 440 /etc/sudoers.d/90-ansible
```
Valider la syntaxe :
```bash
visudo -cf /etc/sudoers.d/90-ansible
```
Le résultat attendu est :
```text
/etc/sudoers.d/90-ansible: parsed OK
```
Tester depuis le compte `ansible` :
```bash
sudo -n true && echo OK
```
Résultat attendu :
```text
OK
```
---
## 17. SSH
### État transitoire
Pendant la construction du modèle, lauthentification par mot de passe peut rester active :
```text
PasswordAuthentication yes
```
Cest pratique tant que la clé SSH nest pas encore injectée.
### État cible
Quand laccès par clé SSH est confirmé, létat cible sera :
```text
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
```
Ne pas désactiver le login par mot de passe avant davoir confirmé que laccès par clé fonctionne.
### Tester une connexion SSH par mot de passe
Depuis un poste dadministration :
```bash
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no ansible@IP_DE_LA_VM
```
---
## 18. Cloud-init dans Debian
Vérifier que cloud-init est installé :
```bash
cloud-init --version
```
Vérifier le service :
```bash
systemctl status cloud-init --no-pager
```
Cloud-init servira à appliquer, au premier démarrage dun clone :
- hostname ;
- utilisateur initial ;
- clé SSH publique ;
- IP ;
- passerelle ;
- DNS ;
- agrandissement de la partition racine si le disque a été étendu.
Cloud-init ne doit pas remplacer Ansible pour les rôles serveur complexes.
Séparation recommandée :
```text
cloud-init : identité initiale de la VM
Ansible : configuration réelle du serveur
```
---
## 19. Ajout du CloudInit Drive dans Proxmox
Éteindre la VM :
```bash
shutdown -h now
```
Dans Proxmox :
```text
VM → Hardware → Add → CloudInit Drive
```
Ou en ligne de commande Proxmox :
```bash
qm set VMID --ide2 STORAGE:cloudinit
```
Exemple :
```bash
qm set 9000 --ide2 local-lvm:cloudinit
```
ou :
```bash
qm set 9000 --ide2 truenas-lvm:cloudinit
```
Le nom exact du stockage dépend de la configuration Proxmox.
---
## 20. Paramètres cloud-init dans Proxmox
Après ajout du CloudInit Drive, Proxmox permet de définir les paramètres cloud-init.
Exemple DHCP :
```bash
qm set 9000 --ciuser ansible
qm set 9000 --sshkeys ~/.ssh/id_ed25519.pub
qm set 9000 --ipconfig0 ip=dhcp
```
Exemple IP statique :
```bash
qm set 9000 --ciuser ansible
qm set 9000 --sshkeys ~/.ssh/id_ed25519.pub
qm set 9000 --ipconfig0 ip=192.168.11.150/24,gw=192.168.11.1
qm set 9000 --nameserver 192.168.11.1
```
Pour le modèle, éviter de lui donner une identité finale trop spécifique.
Lidentité définitive doit plutôt être appliquée aux clones.
---
## 21. Vérifications avant nettoyage
Redémarrer la VM une dernière fois si nécessaire, puis vérifier :
```bash
lsblk
df -h
swapon --show
ip a
hostnamectl
timedatectl
systemctl status ssh --no-pager
systemctl status qemu-guest-agent --no-pager
cloud-init --version
```
État attendu :
```text
/boot/efi présent
/ sur ext4
aucun swap actif
qemu-guest-agent actif
ssh actif
cloud-init installé
compte ansible fonctionnel
sudo NOPASSWD fonctionnel pour ansible
```
---
## 22. Nettoyage avant conversion en template
Avant de convertir la VM en modèle, nettoyer létat propre à cette installation.
Exécuter dans la VM :
```bash
sudo cloud-init clean --logs
sudo apt clean
```
Nettoyer lidentifiant machine :
```bash
sudo truncate -s 0 /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id
sudo ln -s /etc/machine-id /var/lib/dbus/machine-id
```
Optionnel : vider les journaux persistants si présents :
```bash
sudo journalctl --rotate
sudo journalctl --vacuum-time=1s
```
Optionnel : supprimer lhistorique shell du compte courant :
```bash
history -c
```
Puis éteindre :
```bash
sudo shutdown -h now
```
---
## 23. Point darrêt : VM prête à convertir
À ce stade, la VM doit être arrêtée.
Elle est prête à être convertie en template Proxmox.
État attendu côté Proxmox :
```text
VM arrêtée
BIOS OVMF / UEFI
Machine q35
EFI Disk présent
Disque principal SCSI / VirtIO SCSI single
CloudInit Drive présent
QEMU Guest Agent activé dans les options
CPU x86-64-v2-AES
RAM 2048 MiB
Aucun environnement graphique
```
État attendu côté Debian :
```text
Debian 13 minimal
SSH installé
qemu-guest-agent installé
cloud-init installé
cloud-guest-utils installé
sudo installé
compte ansible présent
sudo NOPASSWD pour ansible
partition EFI 512 Mo
partition / ext4
aucune partition swap
aucun LVM
machine-id nettoyé
cloud-init nettoyé
apt cache nettoyé
VM éteinte
```
---
## 24. Conversion en template Proxmox
Cette commande nest exécutée quaprès validation finale :
```bash
qm template VMID
```
Exemple :
```bash
qm template 9000
```
À partir de là, le modèle peut être cloné.
---
## 25. Flux normal après conversion
Après conversion du modèle :
```text
1. Cloner le template.
2. Agrandir le disque si nécessaire.
3. Définir hostname, IP, DNS et clé SSH via cloud-init.
4. Démarrer la VM.
5. Laisser cloud-init appliquer lidentité initiale.
6. Se connecter en SSH.
7. Appliquer les rôles Ansible depuis Set-OPS.
```
Exemple :
```bash
qm clone 9000 101 --name web-01 --full true
qm resize 101 scsi0 32G
qm set 101 --ciuser ansible
qm set 101 --sshkeys ~/.ssh/id_ed25519.pub
qm set 101 --ipconfig0 ip=192.168.11.101/24,gw=192.168.11.1
qm set 101 --nameserver 192.168.11.1
qm start 101
```
Puis :
```bash
ssh ansible@192.168.11.101
```
Ensuite seulement :
```bash
ansible-playbook -i inventories/production/hosts.yml playbooks/baseline.yml
```
---
## 26. Résumé court
Le modèle idéal est simple :
```text
Debian 13 minimal
UEFI / OVMF
q35
SCSI / VirtIO SCSI single
16 Go
2 Go RAM
2 cores
partition EFI 512 Mo
partition / ext4
pas de LVM
pas de swap
SSH
sudo
qemu-guest-agent
cloud-init
cloud-guest-utils
compte ansible
sudo NOPASSWD pour ansible
cloud-init clean
machine-id vidé
VM éteinte
```
La philosophie :
```text
Proxmox crée la VM.
Cloud-init donne son identité au clone.
Ansible configure le vrai serveur.
Set-OPS documente et automatise lensemble.
```

View file

@ -0,0 +1,29 @@
# Template Debian 13 Proxmox
## Playbooks
Préparation :
```bash
ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_prepare.yml --ask-pass --ask-become-pass
```
Vérification :
```bash
ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_verify.yml
```
Nettoyage final :
```bash
ansible-playbook -i inventories/lab/hosts.yml playbooks/vm_templates/debian13_proxmox_cleanup.yml -e confirm_template_cleanup=true
```
## Conversion Proxmox
Après extinction :
```bash
qm template VMID
```

View file

@ -0,0 +1,64 @@
---
chezlepro_timezone: "America/Toronto"
chezlepro_admin_user: "ansible"
chezlepro_ssh_password_authentication: "yes"
chezlepro_ssh_permit_root_login: "no"
chezlepro_ssh_pubkey_authentication: "yes"
chezlepro_disable_systemd_ssh_auto: true
cloud_init_ssh_pwauth: true
cloud_init_manage_etc_hosts: true
cloud_init_disable_root: true
cloud_init_ssh_deletekeys: true
confirm_template_cleanup: false
chezlepro_common_packages:
- sudo
- openssh-server
- qemu-guest-agent
- cloud-init
- cloud-guest-utils
- python3
- python3-apt
- python3-pip
- acl
- curl
- wget
- ca-certificates
- gnupg
- git
- vim
- nano
- bash-completion
- tmux
- rsync
- unzip
- zip
- tar
- jq
- htop
- iotop
- iftop
- sysstat
- lsof
- ncdu
- tree
- file
- less
- dnsutils
- iproute2
- iputils-ping
- net-tools
- traceroute
- mtr-tiny
- tcpdump
- netcat-openbsd
- socat
- chrony
- logrotate
- unattended-upgrades
- apt-listchanges
- needrestart

20
inventories/lab/hosts.yml Normal file
View file

@ -0,0 +1,20 @@
all:
children:
vm_templates:
hosts:
basiqueChezlepro:
ansible_host: 192.168.11.150
ansible_user: ansible
ansible_become: true
web_servers:
hosts: {}
database_servers:
hosts: {}
monitoring_servers:
hosts: {}
proxmox_hosts:
hosts: {}

View file

@ -0,0 +1,2 @@
---
# Variables globales de production à remplir progressivement.

View file

@ -0,0 +1,16 @@
all:
children:
vm_templates:
hosts: {}
web_servers:
hosts: {}
database_servers:
hosts: {}
monitoring_servers:
hosts: {}
proxmox_hosts:
hosts: {}

View file

@ -0,0 +1,10 @@
---
- name: Appliquer le socle Debian commun
hosts: all
become: true
gather_facts: true
roles:
- role: base/common_packages
- role: base/chrony
- role: security/ssh_baseline

View file

@ -0,0 +1,9 @@
# Playbooks database
Espace réservé aux futurs playbooks de bases de données :
- PostgreSQL ;
- MariaDB ;
- sauvegardes ;
- réplication ;
- durcissement.

View file

@ -0,0 +1,19 @@
---
- name: Mettre à jour les serveurs Debian
hosts: all
become: true
gather_facts: true
tasks:
- name: Mettre à jour le cache APT
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Appliquer les mises à jour
ansible.builtin.apt:
upgrade: full
- name: Supprimer les paquets inutiles
ansible.builtin.apt:
autoremove: true

View file

@ -0,0 +1,9 @@
# Playbooks monitoring
Espace réservé aux futurs playbooks de supervision :
- agents ;
- sondes ;
- Icinga/Nagios ;
- exporters ;
- règles dalerte.

View file

@ -0,0 +1,5 @@
# Playbooks Proxmox
Espace réservé aux opérations Proxmox.
Attention : les actions sur les hyperviseurs et le stockage doivent être protégées par confirmation explicite.

12
playbooks/site.yml Normal file
View file

@ -0,0 +1,12 @@
---
- name: Point dentrée général Set-OPS
hosts: all
gather_facts: true
become: true
tasks:
- name: Afficher un message volontairement non destructif
ansible.builtin.debug:
msg:
- "Set-OPS est un dépôt global."
- "Utiliser un playbook spécialisé : baseline, vm_templates, web, database, monitoring, etc."

View file

@ -0,0 +1,8 @@
---
- name: Nettoyage final avant conversion en template Proxmox
hosts: vm_templates
become: true
gather_facts: true
roles:
- role: vm_template/template_cleanup

View file

@ -0,0 +1,45 @@
---
- name: Préparer le template Debian 13 Proxmox Chezlepro
hosts: vm_templates
become: true
gather_facts: true
pre_tasks:
- name: Vérifier que la cible est Debian
ansible.builtin.assert:
that:
- ansible_facts.distribution == "Debian"
fail_msg: "Ce playbook est prévu pour Debian seulement."
- name: Avertir si la version Debian n'est pas 13
ansible.builtin.debug:
msg: "Attention : Debian {{ ansible_facts.distribution_version }} détecté. Le modèle cible est Debian 13."
when: ansible_facts.distribution_major_version != "13"
roles:
- role: base/common_packages
- role: base/qemu_guest_agent
- role: base/cloud_init
- role: security/sudo_ansible
- role: base/chrony
- role: security/ssh_baseline
- role: vm_template/systemd_ssh_auto
- role: base/motd
post_tasks:
- name: Afficher le statut cloud-init
ansible.builtin.command: cloud-init status --long
register: cloud_init_status
changed_when: false
failed_when: false
- name: Résultat cloud-init
ansible.builtin.debug:
var: cloud_init_status.stdout_lines
- name: Rappel
ansible.builtin.debug:
msg:
- "Préparation terminée."
- "Si GRUB a été modifié, redémarrer la VM avant validation finale."
- "Ne pas convertir en template avant le playbook de nettoyage."

View file

@ -0,0 +1,41 @@
---
- name: Vérifier le template Debian 13 Proxmox Chezlepro
hosts: vm_templates
become: true
gather_facts: true
tasks:
- name: Afficher les partitions
ansible.builtin.command: lsblk -f
register: lsblk_output
changed_when: false
- name: Résultat lsblk
ansible.builtin.debug:
var: lsblk_output.stdout_lines
- name: Vérifier l'absence de swap actif
ansible.builtin.command: swapon --show
register: swapon_output
changed_when: false
failed_when: swapon_output.stdout | length > 0
- name: Collecter les services
ansible.builtin.service_facts:
- name: Valider les services de base
ansible.builtin.assert:
that:
- ansible_facts.services['ssh.service'].state == 'running'
- ansible_facts.services['qemu-guest-agent.service'].state == 'running'
- ansible_facts.services['chrony.service'].state == 'running'
fail_msg: "Un service de base n'est pas actif."
- name: Vérifier cloud-init
ansible.builtin.command: cloud-init --version
register: cloud_init_version
changed_when: false
- name: Afficher cloud-init
ansible.builtin.debug:
var: cloud_init_version.stdout

9
playbooks/web/README.md Normal file
View file

@ -0,0 +1,9 @@
# Playbooks web
Espace réservé aux futurs playbooks web :
- reverse proxy ;
- NGINX ;
- sites statiques ;
- certificats ;
- publication locale.

View file

@ -0,0 +1,3 @@
# applications
Rôles applications : services applicatifs Chezlepro.

3
roles/backup/README.md Normal file
View file

@ -0,0 +1,3 @@
# backup
Rôles backup : clients, politiques, intégration PBS ou autres.

View file

@ -0,0 +1,11 @@
---
- name: Installer chrony
ansible.builtin.apt:
name: chrony
state: present
- name: Activer et démarrer chrony
ansible.builtin.systemd:
name: chrony
enabled: true
state: started

View file

@ -0,0 +1,5 @@
---
cloud_init_ssh_pwauth: true
cloud_init_manage_etc_hosts: true
cloud_init_disable_root: true
cloud_init_ssh_deletekeys: true

View file

@ -0,0 +1,32 @@
---
- name: Installer cloud-init et cloud-guest-utils
ansible.builtin.apt:
name:
- cloud-init
- cloud-guest-utils
state: present
- name: Déployer la configuration cloud-init Chezlepro
ansible.builtin.template:
src: 99_chezlepro.cfg.j2
dest: /etc/cloud/cloud.cfg.d/99_chezlepro.cfg
owner: root
group: root
mode: "0644"
- name: Activer les services cloud-init Debian 13
ansible.builtin.systemd:
name: "{{ item }}"
enabled: true
loop:
- cloud-init-local.service
- cloud-init-main.service
- cloud-init-network.service
- cloud-config.service
- cloud-final.service
failed_when: false
- name: Vérifier cloud-init
ansible.builtin.command: cloud-init --version
register: cloud_init_version
changed_when: false

View file

@ -0,0 +1,23 @@
# Managed by Ansible — Set-OPS
# Configuration cloud-init pour template Debian 13 Chezlepro.
datasource_list: [ NoCloud, ConfigDrive, None ]
preserve_hostname: false
manage_etc_hosts: {{ cloud_init_manage_etc_hosts | bool | lower }}
disable_root: {{ cloud_init_disable_root | bool | lower }}
ssh_pwauth: {{ cloud_init_ssh_pwauth | bool | lower }}
ssh_deletekeys: {{ cloud_init_ssh_deletekeys | bool | lower }}
ssh_genkeytypes:
- rsa
- ecdsa
- ed25519
growpart:
mode: auto
devices:
- /
ignore_growroot_disabled: false
resize_rootfs: true

View file

@ -0,0 +1,2 @@
---
chezlepro_common_packages: []

View file

@ -0,0 +1,18 @@
---
- name: Mettre à jour le cache APT
ansible.builtin.apt:
update_cache: true
cache_valid_time: 3600
- name: Appliquer les mises à jour disponibles
ansible.builtin.apt:
upgrade: full
- name: Installer les paquets communs
ansible.builtin.apt:
name: "{{ chezlepro_common_packages }}"
state: present
- name: Supprimer les dépendances devenues inutiles
ansible.builtin.apt:
autoremove: true

View file

@ -0,0 +1,8 @@
---
- name: Déployer le MOTD Chezlepro
ansible.builtin.template:
src: motd.j2
dest: /etc/motd
owner: root
group: root
mode: "0644"

View file

@ -0,0 +1,2 @@
Système Chezlepro
Gestion : Set-OPS / Ansible

View file

@ -0,0 +1,11 @@
---
- name: Installer qemu-guest-agent
ansible.builtin.apt:
name: qemu-guest-agent
state: present
- name: Activer et démarrer qemu-guest-agent
ansible.builtin.systemd:
name: qemu-guest-agent
enabled: true
state: started

3
roles/database/README.md Normal file
View file

@ -0,0 +1,3 @@
# database
Rôles database : PostgreSQL, MariaDB, sauvegardes, réplication.

3
roles/identity/README.md Normal file
View file

@ -0,0 +1,3 @@
# identity
Rôles identity : IAM, Keycloak, annuaires.

View file

@ -0,0 +1,3 @@
# monitoring
Rôles monitoring : agents, sondes, exporters, alertes.

3
roles/proxmox/README.md Normal file
View file

@ -0,0 +1,3 @@
# proxmox
Rôles Proxmox : opérations hyperviseur, avec prudence.

View file

@ -0,0 +1,4 @@
---
chezlepro_ssh_password_authentication: "yes"
chezlepro_ssh_permit_root_login: "no"
chezlepro_ssh_pubkey_authentication: "yes"

View file

@ -0,0 +1,11 @@
---
- name: Validate and reload ssh
block:
- name: Valider la configuration SSH
ansible.builtin.command: sshd -t
changed_when: false
- name: Recharger SSH
ansible.builtin.systemd:
name: ssh
state: reloaded

View file

@ -0,0 +1,28 @@
---
- name: Installer openssh-server
ansible.builtin.apt:
name: openssh-server
state: present
- name: Créer le répertoire sshd_config.d
ansible.builtin.file:
path: /etc/ssh/sshd_config.d
state: directory
owner: root
group: root
mode: "0755"
- name: Déployer la configuration SSH Chezlepro
ansible.builtin.template:
src: 10-chezlepro.conf.j2
dest: /etc/ssh/sshd_config.d/10-chezlepro.conf
owner: root
group: root
mode: "0644"
notify: Validate and reload ssh
- name: Activer et démarrer SSH
ansible.builtin.systemd:
name: ssh
enabled: true
state: started

View file

@ -0,0 +1,8 @@
# Managed by Ansible — Set-OPS
PermitRootLogin {{ chezlepro_ssh_permit_root_login }}
PubkeyAuthentication {{ chezlepro_ssh_pubkey_authentication }}
PasswordAuthentication {{ chezlepro_ssh_password_authentication }}
KbdInteractiveAuthentication no
X11Forwarding no
UsePAM yes

View file

@ -0,0 +1,2 @@
---
chezlepro_admin_user: ansible

View file

@ -0,0 +1,23 @@
---
- name: S'assurer que le groupe sudo existe
ansible.builtin.group:
name: sudo
state: present
- name: S'assurer que le compte technique existe
ansible.builtin.user:
name: "{{ chezlepro_admin_user }}"
shell: /bin/bash
groups: sudo
append: true
create_home: true
state: present
- name: Déployer sudo NOPASSWD pour le compte technique
ansible.builtin.template:
src: 90-ansible.j2
dest: "/etc/sudoers.d/90-{{ chezlepro_admin_user }}"
owner: root
group: root
mode: "0440"
validate: "visudo -cf %s"

View file

@ -0,0 +1,2 @@
# Managed by Ansible — Set-OPS
{{ chezlepro_admin_user }} ALL=(ALL) NOPASSWD:ALL

3
roles/storage/README.md Normal file
View file

@ -0,0 +1,3 @@
# storage
Rôles storage : montages, clients NFS/iSCSI, volumes.

View file

@ -0,0 +1,2 @@
---
chezlepro_disable_systemd_ssh_auto: true

View file

@ -0,0 +1,4 @@
---
- name: Update grub
ansible.builtin.command: update-grub
changed_when: true

View file

@ -0,0 +1,17 @@
---
- name: Déployer le paramètre GRUB pour désactiver systemd.ssh_auto
ansible.builtin.template:
src: 99-chezlepro-systemd-ssh-auto.cfg.j2
dest: /etc/default/grub.d/99-chezlepro-systemd-ssh-auto.cfg
owner: root
group: root
mode: "0644"
when: chezlepro_disable_systemd_ssh_auto | bool
notify: Update grub
- name: Supprimer le paramètre si désactivé dans les variables
ansible.builtin.file:
path: /etc/default/grub.d/99-chezlepro-systemd-ssh-auto.cfg
state: absent
when: not (chezlepro_disable_systemd_ssh_auto | bool)
notify: Update grub

View file

@ -0,0 +1,2 @@
# Managed by Ansible — Set-OPS
GRUB_CMDLINE_LINUX="${GRUB_CMDLINE_LINUX} systemd.ssh_auto=no"

View file

@ -0,0 +1,2 @@
---
confirm_template_cleanup: false

View file

@ -0,0 +1,54 @@
---
- name: Refuser le nettoyage sans confirmation explicite
ansible.builtin.assert:
that:
- confirm_template_cleanup | bool
fail_msg: "Nettoyage refusé. Relancer avec -e confirm_template_cleanup=true"
- name: Nettoyer cloud-init
ansible.builtin.command: cloud-init clean --logs
changed_when: true
- name: Nettoyer le cache APT
ansible.builtin.apt:
clean: true
- name: Supprimer les paquets devenus inutiles
ansible.builtin.apt:
autoremove: true
- name: Rotation des journaux systemd
ansible.builtin.command: journalctl --rotate
changed_when: true
failed_when: false
- name: Vider les anciens journaux systemd
ansible.builtin.command: journalctl --vacuum-time=1s
changed_when: true
failed_when: false
- name: Vider /etc/machine-id
ansible.builtin.copy:
dest: /etc/machine-id
content: ""
owner: root
group: root
mode: "0444"
- name: Supprimer l'ancien machine-id D-Bus
ansible.builtin.file:
path: /var/lib/dbus/machine-id
state: absent
- name: Recréer le lien D-Bus vers /etc/machine-id
ansible.builtin.file:
src: /etc/machine-id
dest: /var/lib/dbus/machine-id
state: link
force: true
- name: Message final
ansible.builtin.debug:
msg:
- "Nettoyage final terminé."
- "Éteindre la VM puis convertir en template Proxmox."

3
roles/web/README.md Normal file
View file

@ -0,0 +1,3 @@
# web
Rôles web : reverse proxy, NGINX, sites statiques.