Infrastructure as Code à la maison : OpenTofu et Ansible au service du Home Lab
OpenTofu pour provisionner les LXC sur Proxmox, Ansible pour configurer les services : voici comment une approche Infrastructure as Code transforme un homelab en plateforme reproductible, versionnée, et proche des standards professionnels.
Dans le précédent article, je mentionnais que l'ensemble du cluster est géré en Infrastructure as Code. C'est probablement la décision la plus structurante de ce homelab — et celle qui le rapproche le plus d'une infrastructure professionnelle. Voici comment ça s'articule.
Pourquoi l'IaC à la maison ?
La réponse tient en un scénario : si l'un de mes nœuds Proxmox tombe demain, combien de temps me faut-il pour tout reconstruire ?
Sans IaC : des heures à retrouver les bonnes versions, les bons paramètres, les bons mots de passe. Avec IaC : une commande, et le conteneur est recréé à l'identique, avec ses dépendances et sa configuration.
C'est le principe "cattle, not pets" — l'infrastructure ne doit pas être chouchoutée à la main, elle doit être décrite, versionnée, et reproductible. Même à la maison.
Une approche en deux couches
L'infrastructure repose sur deux outils distincts qui se complètent :
- OpenTofu (fork open source de Terraform) provisionne les conteneurs LXC sur Proxmox : CPU, RAM, disque, réseau. Il s'occupe de ce qui existe.
- Ansible configure ce qui tourne à l'intérieur : Docker, services, fichiers de configuration. Il s'occupe de ce qui fait quoi.
Chaque service a son propre répertoire OpenTofu et son propre rôle Ansible. Tout est versionné dans un dépôt Git.
OpenTofu : le provisioning Proxmox
OpenTofu dialogue avec l'API Proxmox via un provider dédié. Pour chaque service, un répertoire décrit le conteneur LXC souhaité : ses ressources, son réseau, son image de base. Un tofu apply plus tard, le conteneur existe sur le bon nœud.
Les paramètres sensibles (credentials Proxmox, tokens API) sont isolés dans un fichier secret.tfvars exclu du dépôt Git.
Ansible : la configuration des services
Une fois le conteneur créé, Ansible prend le relais. L'inventaire définit les groupes de machines (infra-core, media-server, home-automation, web-server), et chaque groupe a son playbook.
Les rôles sont conçus pour être paramétrables : un même rôle peut être appelé en mode base-directory, server, backup selon ce qu'on veut accomplir. Les templates Jinja2 génèrent les fichiers Docker Compose et les configurations applicatives à partir des variables définies par groupe ou par host.
Les secrets (mots de passe, tokens, clés API) sont chiffrés avec ansible-vault directement dans les fichiers de variables. Rien de sensible ne transite en clair dans le dépôt.
Ajouter un nouveau service : le workflow
La procédure est devenue systématique :
- Créer le répertoire OpenTofu du service et appliquer : le LXC est provisionné sur Proxmox
- Bootstrapper le nouveau conteneur avec un playbook dédié qui crée l'utilisateur Ansible et dépose la clé SSH
- Écrire le playbook et les rôles Ansible du service
- Lancer le playbook : le service est configuré et opérationnel
Du premier tofu apply au service qui tourne : une procédure reproductible, documentée, et rejouable à l'identique.
Un Makefile pour ne jamais retaper les mêmes commandes
Les commandes Ansible et OpenTofu sont puissantes mais verbeuses : fichier d'inventaire, vault password file, tags, variables... Retaper tout ça à chaque déploiement est une source d'erreurs.
Un Makefile centralise toutes ces commandes sous des alias courts et documentés. Déployer uniquement Caddy sur infra-core, bootstrapper un nouveau conteneur, lancer un tofu apply sur un service spécifique, chiffrer un nouveau secret pour vault — tout est accessible en une commande, sans avoir à se souvenir de la syntaxe exacte.
Un simple make help liste l'ensemble des cibles disponibles, organisées par groupe de machines et par service. C'est le point d'entrée quotidien du repo.
Ce que ça change au quotidien
Mettre à jour un service, c'est modifier un template et relancer un playbook. Tester un changement de configuration, c'est brancher un tag Ansible sur un seul host. Reconstruire un conteneur après une panne, c'est une commande.
C'est aussi un formidable terrain d'apprentissage : les mêmes outils, les mêmes pratiques qu'en production, mais avec le droit à l'erreur.
Les prochains articles entreront dans le détail : la structure des rôles Ansible, la gestion des secrets avec vault, et la configuration spécifique de quelques services clés.