Skip to content

🚀 DĂ©ploiement ​

Cette page explique comment les services passent du dĂ©pĂŽt Infrastructure, public, aux serveurs. Tout ce que dĂ©ploie Ansible y est dĂ©crit, et un changement passe toujours par une pull request vĂ©rifiĂ©e par l’intĂ©gration continue avant d’ĂȘtre appliquĂ©. Ce site a son propre dĂ©pĂŽt et sa propre publication (voir Ce site).

📁 Organisation du dĂ©pĂŽt ​

DossierContenu
services/<service>/Un dossier par service : playbook deploy.yml, fichier compose.yml, configurations et modÚles copiés
hosts/Playbooks propres aux hĂŽtes : compte d’automatisation, rĂ©plication, mises Ă  jour
dns/Un playbook par zone DNS Cloudflare (voir DNS)
inventory/HĂŽtes, un groupe par service indiquant l’hĂŽte qui le porte, rĂ©glages propres Ă  chaque hĂŽte
roles/RÎles partagés : compose_service, zitadel_applications
opentofu/zitadel/Applications OIDC de Zitadel (voir Architecture)
vault/Sous-module privé contenant les secrets chiffrés (voir Sécurité)
site.ymlImporte le playbook de chaque service, Traefik en premier

Les dossiers et groupes portent le nom de la fonction du service (authentification, deploiement, etat
), pas celui du logiciel : remplacer un logiciel ne change pas l’organisation.

L’inventaire associe chaque service Ă  un hĂŽte. DĂ©placer un service revient Ă  changer son groupe dans inventory/hosts.yml ; les faits propres Ă  un hĂŽte (dossier racine des services, rĂ©seau du proxy, noms DNS) sont dans ses variables d’hĂŽte, jamais dans les playbooks.

đŸ§± RĂŽle compose_service ​

Chaque service Docker Compose est dĂ©ployĂ© par le mĂȘme rĂŽle, roles/compose_service. Le playbook d’un service se limite Ă  lui passer des paramĂštres. Le rĂŽle :

  1. crĂ©e le dossier du service sous la racine des services de l’hĂŽte (les permissions ne sont posĂ©es qu’à la crĂ©ation : les dossiers existants de TrueNAS gardent leurs ACL) ;
  2. copie compose.yml et les fichiers de configuration, rend les modĂšles Jinja ;
  3. Ă©crit le fichier .env (lisible par son seul propriĂ©taire) avec les variables et secrets du service, dont l’utilisateur et le groupe sous lesquels tournent les conteneurs ;
  4. crĂ©e Ă  l’avance les fichiers montĂ©s dans les conteneurs, sinon Docker crĂ©erait un dossier Ă  leur place, ainsi que les rĂ©seaux externes dĂ©clarĂ©s ;
  5. dĂ©marre la pile : les conteneurs ne sont recréés que si leur image ou leur configuration change, et redĂ©marrĂ©s quand un fichier de configuration change (sauf pour les fichiers que le service recharge lui-mĂȘme) ;
  6. fait pointer les enregistrements DNS du service vers l’hĂŽte, en public ou en privĂ© (voir DNS).

Le rĂŽle signale aussi un rĂ©seau existant qui ne correspond plus Ă  sa dĂ©claration, sans jamais le recrĂ©er de lui-mĂȘme : recrĂ©er un rĂ©seau dĂ©connecterait tous ses conteneurs.

Un seul service Ă©chappe au rĂŽle : le coffre de signature de Xila (OpenBao), qui gĂšre lui-mĂȘme son certificat et doit rester descellĂ©.

Le rÎle est testé par Molecule sur une pile de test locale : création, idempotence, redémarrage quand un fichier change.

đŸ› ïž Outils ​

Les versions des outils sont figées : Python, Ansible, ansible-lint et yamllint par uv (pyproject.toml, uv.lock), OpenTofu par mise (mise.toml), les collections Ansible dans requirements.yml. Les commandes courantes sont des tùches mise :

bash
mise install && mise run setup                    # outils et collections
mise preview site.yml --limit bruxelles           # ce qui changerait (--check --diff), sans rien changer
mise deploy services/<service>/deploy.yml         # déployer un service
mise deploy site.yml --limit bruxelles            # tous les services d’un hîte
mise lint                                         # yamllint, ansible-lint, docker compose config
mise test                                         # scénarios Molecule des rÎles

Les zones DNS ne sont pas appliquées par site.yml : chacune a son propre playbook, lancé séparément.

Les playbooks lisent leurs secrets dans un coffre chiffré, dont le mot de passe reste dans le trousseau du systÚme (voir Sécurité).

✅ IntĂ©gration continue ​

Chaque pull request et chaque push sur main lancent des vĂ©rifications sur GitHub Actions. L’intĂ©gration continue n’a pas accĂšs aux secrets : les playbooks sont analysĂ©s avec des fichiers de coffre vides, ce qui oblige chaque playbook Ă  rester lisible sans eux.

VérificationContenu
yamllint, ansible-lintStyle YAML, bonnes pratiques Ansible (modules complets, changed_when, gestionnaires
)
Composedocker compose config sur chaque service, avec des valeurs factices pour les variables
MoleculeRÎles compose_service et zitadel_applications exécutés sur des piles de test
OpenTofuFormatage et validation de la configuration Zitadel
Routes TraefikLes routes de Bruxelles sont rendues puis chargĂ©es dans un vrai Traefik : chaque routeur doit ĂȘtre actif et conforme
SupervisionLa supervision est dĂ©marrĂ©e avec des mĂ©triques d’exemple : les rĂšgles d’alerte doivent se dĂ©clencher comme prĂ©vu
ProtectionCrowdSec et Traefik sont démarrés ensemble : une adresse bannie est refusée, le réseau local et le VPN passent toujours

Une vérification unique, exigée par les rÚgles de la branche main, attend le succÚs de toutes les autres.

🔄 Mises à jour ​

Chaque image Docker est figĂ©e sur une version exacte : jamais latest, jamais d’image sans Ă©tiquette. Dependabot ouvre chaque lundi une pull request groupĂ©e par Ă©cosystĂšme (images Docker Compose, actions GitHub, outils Python). Elle passe par les mĂȘmes vĂ©rifications que tout autre changement. Les collections Ansible, la version de Python et l’extension CrowdSec de Traefik, que Dependabot ne suit pas, sont mises Ă  jour Ă  la main.

đŸ›Ąïž Principes de sĂ©curitĂ© du dĂ©ploiement ​

  • Branche protĂ©gĂ©e : main n’accepte que des pull requests dont l’intĂ©gration continue est passĂ©e, fusionnĂ©es en un seul commit.
  • Aperçu avant application : mise preview montre les changements (--check --diff) avant tout dĂ©ploiement rĂ©el.
  • Configuration dĂ©crite dans le dĂ©pĂŽt : ce que dĂ©ploie Ansible vient du dĂ©pĂŽt ; ce qu’Ansible ne peut pas rĂ©gler lui-mĂȘme (interface TrueNAS notamment), il le vĂ©rifie et indique les Ă©tapes Ă  faire.
  • Ports publiĂ©s sous contrĂŽle : le dĂ©ploiement de Traefik vĂ©rifie qu’aucun autre conteneur n’occupe les ports web et, sur Bruxelles, liste les ports publiĂ©s qui ne sont pas attendus (voir SĂ©curitĂ©).
  • Compte dĂ©diĂ© : Ansible se connecte avec un compte d’automatisation Ă  clĂ© SSH, distinct des comptes personnels (voir SĂ©curitĂ©).

đŸ€– Semaphore ​

Semaphore est une interface web pour lancer les playbooks depuis Bruxelles, sans passer par l’ordinateur portable. Son service est fusionnĂ© dans le dĂ©pĂŽt ; sa mise en service est Ă  venir (voir la feuille de route).

  • Il est privĂ© : accessible uniquement depuis le rĂ©seau local ou le VPN.
  • Il clone le dĂ©pĂŽt public, et le sous-module des secrets avec un accĂšs en lecture seule limitĂ© Ă  ce seul dĂ©pĂŽt.
  • Il se connecte aux hĂŽtes avec sa propre clĂ© SSH, autorisĂ©e sur le compte d’automatisation comme celle de l’ordinateur portable.
  • Chaque playbook a deux modĂšles de tĂąche : un aperçu (--check --diff) et une exĂ©cution, lancĂ©s Ă  la main.
  • Le provisionnement de Zitadel (OpenTofu) reste lancĂ© depuis l’ordinateur portable.

🌐 Ce site ​

Ce site est construit avec VitePress dans le dĂ©pĂŽt Infrastructure_website, indĂ©pendant du dĂ©pĂŽt Infrastructure : aucun dĂ©ploiement Ansible n’est nĂ©cessaire pour le mettre Ă  jour. AprĂšs chaque fusion sur main, GitHub Actions le construit et le publie sur GitHub Pages ; la publication peut aussi ĂȘtre lancĂ©e Ă  la main depuis l’onglet Actions du dĂ©pĂŽt.

Pour proposer une modification, créer une branche, puis, depuis la racine du dépÎt :

bash
npm ci             # dépendances
npm run docs:dev   # serveur local, qui affiche l’adresse à ouvrir
npm run check      # vérification Prettier, puis construction du site

npm run docs:build puis npm run docs:preview montrent le rĂ©sultat de production. Les sources sont dans src ; une nouvelle page de documentation s’ajoute Ă  src/documentation/index.md et Ă  la barre latĂ©rale de .vitepress/config.mts. Ouvrir ensuite une pull request vers main.