Pas un slide d'avant-vente, pas un schéma théorique sur LinkedIn. Une vraie plateforme, déployée, sécurisée, avec des pipelines qui tournent en production pendant que vous dormez sur vos deux oreilles.
C'est le pari que je me suis lancé il y a quelques mois. Un POC mené par sessions, quand le planning le permettait, avec une règle simple : zéro cloud américain, zéro SaaS propriétaire, zéro clic dans une console. Tout en infrastructure as code, tout en open source, tout chez un cloud provider français.
Spoiler : ça marche. Mais entre le premier terraform apply et la plateforme qui ronronne aujourd'hui, il y a eu quelques ajustements, et une leçon d'humilité sur l'écart entre la stack dont tout le monde parle et celle dont on a vraiment besoin.
Pourquoi souverain, pourquoi maintenant ?
Soyons honnêtes deux minutes. Quand on dit « modern data stack », tout le monde pense Snowflake, Databricks, BigQuery. Des outils excellents, je les utilise en mission, je ne vais pas cracher dans la soupe. Mais ils ont deux points communs : vos données partent chez un acteur américain, et votre facture est un abonnement dont vous ne maîtrisez ni la courbe ni les conditions.
En 2026, la question de la souveraineté n'est plus un sujet de conférence pour juristes. Entre le CLOUD Act, les tensions géopolitiques et les DSI qui découvrent que leur « région Europe » reste juridiquement soumise au droit américain, de plus en plus d'organisations se demandent sérieusement ce qu'une alternative européenne donnerait en pratique. Et je vous épargne le cirque du feuilleton tarifaire qu'on nous fait subir depuis quelques années.
Ma question était plus terre à terre : est-ce qu'un data engineer seul, avec un budget serré, peut construire une plateforme data complète, sécurisée et automatisée sans toucher un hyperscaler US ?
J'ai choisi Scaleway, cloud français, région fr-par. Mes données ne quittent jamais Paris. Et chaque brique de la stack est open source et self-hosted. Si demain je veux tout déplacer chez un autre provider, je prends mon Terraform et mes charts Helm sous le bras et je déménage.
Le cahier des charges : trois principes non négociables
Avant d'écrire la première ligne de HCL, je me suis fixé trois principes. Pas pour faire joli dans un README, mais parce que chaque POC que j'ai vu mourir en entreprise est mort d'avoir ignoré l'un des trois.
- Zéro valeur en dur. Aucun endpoint, aucun nom de bucket, aucun secret écrit en dur nulle part. Tout vient des variables et des outputs Terraform. Les workflows CI/CD eux-mêmes interrogent
terraform outputpour récupérer les valeurs dynamiques. Résultat : la même base de code peut déployer un environnementdev,stgouprden changeant une variable. Et la donnée suit la même logique, du data as code : les extractions sont déclarées en YAML, les transformations en SQL dbt, le tout versionné dans git. Un pipeline se relit, se review et se rejoue comme n'importe quel code. Et en 2026, ça change tout : avec les agents IA, on déploie désormais une data platform as code robuste et production-ready plus vite qu'en cliquant dans une console. L'agent a tout le code à disposition pour comprendre la plateforme, chaque amélioration devient plus simple. Une plateforme cliquée reste une boîte noire, une plateforme codée devient un vrai outil de travail. - Sécurité par défaut. HTTPS partout avec Let's Encrypt, whitelist IP à l'ingress, SSO avec MFA, NetworkPolicies en default-deny sur tous les namespaces, TLS obligatoire vers PostgreSQL. Et tous les réseaux sont privés, certains non routables depuis Internet : PostgreSQL et les nœuds du cluster vivent dans un VPC, seul le load balancer est exposé. Un POC n'est pas une excuse pour laisser un port 8080 ouvert sur Internet.
- Pipelines déclaratifs. Ajouter une source de données ne doit jamais nécessiter d'écrire du code d'orchestration. Quelques fichiers YAML et SQL, un push, et le pipeline existe. Si onboarder une source demande de comprendre Airflow en profondeur, la plateforme a échoué. J'irai même plus loin : chaque ajout de source doit être extrêmement rapide. Si vous perdez deux jours à chaque nouvelle source, vous avez sûrement un problème de design.
Acte 1 : le socle, Kapsule comme colonne vertébrale
La fondation tient en quelques briques, toutes provisionnées par Terraform dans des fichiers numérotés par ordre de dépendance (du réseau vers les applications) :
- Kapsule (Kubernetes 1.35 managé) : le socle de compute, control plane gratuit
- Apache Airflow 3.1.8 : orchestration,
KubernetesExecutor - Keycloak 26 : SSO OIDC + MFA pour tous les accès
- PostgreSQL 17 managé : métadonnées Airflow et Keycloak, réseau privé uniquement
- dlthub : extraction vers du Parquet sur Object Storage (bronze)
- dbt + dbt-clickhouse : transformations silver et gold
- ClickHouse OSS : le warehouse, self-hosted dans le cluster
La colonne vertébrale de la stack, c'est Kapsule, le Kubernetes managé de Scaleway. Le produit est simple et robuste : control plane gratuit, node pools avec autoscaling, réseau et stockage intégrés. Je ne suis pas devops de métier et la prise en main a été immédiate, un terraform apply et le cluster est là. Beau travail de l'équipe Scaleway sur ce produit.
Transparence au passage : chez SFEIR, nous sommes partenaires Scaleway, et nos ingénieurs déploient déjà des stacks en tous genres chez nos clients. Ce partenariat nous offre la chance d'échanger régulièrement avec des ingénieurs très compétents sur leurs produits, de participer aux bêta-tests, de leur faire des retours terrain et d'avoir de la visibilité sur leur roadmap produit.
Le flux de données est un lakehouse-light assumé :
API / DB source → dlthub → S3 Parquet (bronze)
→ dbt-clickhouse → ClickHouse MergeTree (silver, gold)
Flux de données de test
Le bronze reste sur Object Storage, immuable et quasi gratuit. Le silver et le gold vivent dans ClickHouse sur un volume persistant, là où la performance analytique compte.

Petit aparté HTTPS : Let's Encrypt exige un nom de domaine et je n'allais pas en acheter un pour un POC.nip.io, un DNS wildcard qui encode l'IP dans le nom, pluscert-manageravec un solver HTTP-01, et la question est réglée : des certificats valides surairflow.<IP>.nip.io,keycloak.<IP>.nip.ioetclickhouse.<IP>.nip.io. Du vrai TLS, zéro euro, zéro registrar.
Deuxième choix structurant : l'isolation en deux namespaces. Le namespace airflow héberge le scheduler, l'API server et les workers. Il ne possède aucun credential vers les données : pas d'accès aux bases sources, pas d'accès au warehouse. Ses seules clés S3 servent à synchroniser les DAGs et à écrire les logs. Les jobs d'extraction et de transformation tournent dans un namespace séparé, airflow-jobs, où vivent les secrets de données. Airflow ne fait que créer des pods via KubernetesPodOperator.
Si demain quelqu'un compromet l'interface web d'Airflow, il obtient le droit de lancer des pods. Pas celui de lire mes données. Le blast radius est contenu par construction, pas par vigilance.
Et aucune interface n'est en accès libre : tous les accès web passent par le SSO Keycloak, avec MFA obligatoire.
Les pipelines déclaratifs : quatre fichiers et zéro code d'orchestration
C'est la colonne vertébrale de la data, l'endroit où tournent tous les pipelines. Il faut en prendre le plus grand soin pour pouvoir délivrer rapidement une fois le produit en place.
Un générateur de DAGs lit deux dossiers de configuration YAML : extractions/ et transformations/. Ajouter une extraction, c'est écrire ceci :
pipeline_name: extract_prix_carburants
source_type: prix_carburants
dataset_name: bronze.api_prix_carburants
schedule: "0 */6 * * *"
description: "Extract French fuel prices from data.economie.gouv.fr"
exemple de déclaration d'un pipeline d'ingestion
Ce fichier génère un DAG qui lance un pod dlthub, lequel appelle l'API open data des prix des carburants et écrit du Parquet dans le bronze. Toutes les six heures.
La partie élégante vient d'Airflow 3 et de ses Assets, que les dernières versions d'Airflow 2 appelaient encore Datasets. Chaque DAG d'extraction produit un Asset avec une URI de la forme dlt://prix_carburants/bronze.api_prix_carburants. Et les DAGs de transformation n'ont pas de schedule du tout :
project_name: prix_carburants
triggers:
- dlt://prix_carburants/bronze.api_prix_carburants
command: "dbt run --select silver.prix_carburants gold.prix_carburants"
Exemple de déclaration d'un pipeline de transformation de la donnée
Le DAG dbt se déclenche automatiquement quand l'Asset amont est mis à jour. Fini les schedules décalés de trente minutes « pour être sûr que l'extraction est finie », fini les sensors qui font du polling. L'extraction publie, la transformation consomme. C'est du data engineering event-driven avec deux fichiers YAML.
Le bonus caché de ce modèle, c'est la cohérence. Si une transformation dépend de trois sources et qu'une seule n'est pas à jour, rien ne se lance. Pas de tableau de bord à moitié rafraîchi, pas de jointure entre des données d'hier et d'aujourd'hui : l'état de la donnée reste cohérent par construction. Et ça scale sans friction. Chaque tâche est un pod indépendant, dix extractions peuvent tourner en parallèle sans se marcher dessus.

Au total, ajouter une source complète demande une stratégie d'extraction Python (une classe qui étend SourceStrategy), deux YAML, et les modèles dbt. Aucune ligne de code Airflow.
Acte 2 : la tentation du lakehouse, ou tester ce dont tout le monde parle
C'est ici que commence le détour annoncé en introduction.
La première version avec ClickHouse fonctionnait. Mais Trino et Iceberg sont partout dans les conversations sur la plateforme moderne : tout le monde en parle, presque personne ne les teste vraiment. J'ai voulu me faire mon propre avis, avec en prime des produits que je ne croise pas en mission aujourd'hui. Alors j'ai tout migré : Lakekeeper comme catalogue REST Iceberg, Trino comme moteur de requête distribué, Lightdash comme couche BI, le tout branché sur du Parquet Iceberg dans l'Object Storage.
Sur le papier, c'était magnifique. Un catalogue standard, un moteur fédéré, un outil BI moderne avec la sémantique dbt intégrée. Trois projets open source respectés. La stack qu'on montre en meetup. Cerise sur le gâteau, elle promettait même de coûter un peu moins cher que la version ClickHouse, le stockage chaud en moins.
La réalité, maintenant.
Lightdash, dans sa version de l'époque, n'avait pas de connecteur OIDC générique compatible avec Keycloak. Mon principe « SSO partout » venait de rencontrer un mur. J'ai tenté de monter de version : la nouvelle image cassait l'entrypoint du chart Helm. J'ai tenté les contournements : chaque fix en appelait deux autres.
Et pendant ce temps, la complexité s'accumulait ailleurs. Trino devait s'authentifier auprès de Lakekeeper en OAuth2 avec un service account dédié. Keycloak avait besoin d'audience mappers spécifiques. Trois charts Helm supplémentaires, trois namespaces avec leurs NetworkPolicies, quatre secrets de plus à gérer. Chaque brique était raisonnable individuellement. L'ensemble était devenu une usine à gaz OIDC, disproportionnée pour un POC dont l'objectif est de simuler une vraie mise en production.
Le constat, au fil des tests, était sans appel. La stack lakehouse, plus élégante sur le papier, n'avait jamais atteint un état utilisable derrière le SSO. Lightdash servait des requêtes, mais impossible d'en sécuriser l'accès de façon propre et optimale. Pendant ce temps, l'ancienne version ClickHouse, plus modeste, avait fonctionné dès sa mise en place.
J'avais construit une data stack incapable de respecter les specs minimales de sécurité.
Acte 3 : le pivot, ou l'éloge de la brique qui fait tout
Le commit de pivot est probablement le plus satisfaisant de tout le projet. En une soirée, les charts Helm de Lakekeeper, Trino et Lightdash disparaissent, avec leurs secrets, leurs NetworkPolicies et le bucket Iceberg. On passe sur ClickHouse, mais en OSS self-hosted : un seul StatefulSet avec un volume de 20 Gi, que je peux éteindre le soir et le week-end pour alléger la facture.
Note de choix d'architecture : j'ai choisi du self-hosted pour mon POC pour pouvoir l'éteindre, notamment la nuit. J'ai testé aussi la version managée Scaleway qui fonctionne très bien. D'ailleurs, je vous la recommande pour de la production, notamment pour sa mise en œuvre beaucoup plus simple.

Le self-hosted remplace une stack qui coince en SSO par une brique que je connais. Et cette brique embarque nativement le Play UI, un éditeur SQL accessible en HTTPS sur /play. Pour un POC analytique, cet écran remplace purement et simplement l'outil BI. Besoin d'un vrai client ? DBeaver ou DataGrip se connectent en JDBC à travers l'ingress, sur le port 443 :
jdbc:clickhouse://clickhouse.<IP>.nip.io:443?ssl=true
chaîne de connexion au datawarehouse
Le protocole natif de ClickHouse, lui, reste interne au cluster. Tout ce qui vient de l'extérieur passe par l'interface HTTP, avec le TLS terminé au niveau du nginx-ingress.
Note : pour les versions ClickHouse managées ou OSS, ce sont les mêmes consoles pour le moment. Si vous souhaitez une interface améliorée, vous pouvez par exemple rajouter CloudBeaver sur Kapsule.
Toute la brique BI, celle qui refusait obstinément de parler OIDC, venait d'être remplacée par une fonctionnalité native du warehouse que j'avais déjà testée.
La morale de ce détour tient en une phrase : testez par vous-même au lieu de croire ce qui se dit. Iceberg, Trino et les catalogues REST résolvent des problèmes réels, à l'échelle où plusieurs moteurs se partagent des péta-octets. À mon échelle, non seulement ils ne résolvaient rien, mais un ClickHouse mono-nœud qui lit ses MergeTree en local est nettement plus rapide qu'un Trino qui scanne du Parquet sur Object Storage.
Les pièges à éviter : ce que les tutos ne racontent jamais
Une plateforme qui marche, c'est surtout une collection de problèmes résolus dont personne ne parle. Florilège, pour vous épargner les mêmes détours.
- Le
CrashLoopBackOff. 🏆 Le scheduler Airflow redémarrait en boucle, sans erreur applicative claire. J'ai suspecté la base, les migrations, les NetworkPolicies. Le coupable : lastartupProbepar défaut, qui laissait 20 secondes au scheduler pour démarrer. Airflow 3 sur des petites instances en demande davantage. Une fois la probe élargie à 60 secondes, plus jamais un crash. Beaucoup de fausses pistes pour deux lignes de YAML. - Bitnami a déménagé sans laisser d'adresse. Les images Bitnami que tout le monde utilise ont été déplacées vers
bitnamilegacy/sur Docker Hub. Du jour au lendemain, des pulls qui échouent. Si vous dépendez de charts Bitnami, vérifiez vos références d'images avant qu'elles ne le fassent pour vous. - Keycloak 26, le triathlon. Trois découvertes coup sur coup.
KC_HOSTNAME_BACKCHANNEL_DYNAMIC=trueest indispensable quand l'issuer public est en HTTPS mais que les échanges internes passent en HTTP. Le mode production du chart exige des certificats TLS sur le pod lui-même, incompatible avec une terminaison TLS à l'ingress. EtKC_HOSTNAME_STRICTrefuse les hostnamesnip.io. Ces trois pièges ont une racine commune : pas de vrai nom de domaine ni de certificat sur le pod, conséquence directe du choixnip.io. La parade dépend de votre contexte. Pour un POC, assumeznip.ioet posez les trois réglages :KC_HOSTNAME_BACKCHANNEL_DYNAMIC=true, mode production du chart désactivé avec le TLS terminé à l'ingress, etKC_HOSTNAME_STRICT=false. Dès qu'il y a de vrais utilisateurs, prenez un vrai domaine à quelques euros par an avec de vrais certificats : les trois pièges disparaissent d'eux-mêmes. Autre piste, soufflée par l'ingénieur Scaleway avec qui j'échange régulièrement : Authentik, plus simple à intégrer que Keycloak, m'aurait sûrement évité une partie de ces problèmes. À tester dans une prochaine itération. - Airflow 3, les angles morts. Le check
waitForMigrationsdu chart Helm timeout même quand les migrations sont à jour, il faut le désactiver composant par composant. Les opérateurs deferrable deKubernetesPodOperatorsont incompatibles avec leKubernetesExecutor. Et la synchronisation des rôles OIDC à la connexion ne fonctionnait pas de manière fiable dans mon setup, l'endpointuserinfoétant bloqué par mes NetworkPolicies et le chart n'offrant pas de quoi injecter la configuration nécessaire sur l'api-server. J'ai fini par gérer les rôles via la CLI. Airflow 3 est une excellente version, mais son écosystème Helm a encore des points durs. - Scaleway, les petites surprises. Les labels de nœuds Kapsule sont
k8s.scaleway.com/pool-nameet non le label standard Kubernetes : ciblez celui-là dans vosnodeSelectoret vos affinités, sinon vos pods ne se placeront jamais. Et l'attribut Terraformendpoint_ipd'une base managée retournenullquand elle est sur un réseau privé : lisez l'IP dansprivate_network[0].ipà la place. Rien de bloquant, et tout est écrit dans la documentation Scaleway. Mais soyons honnêtes : cette page de doc, on ne la lit qu'après avoir marché dessus.
Aucun de ces pièges ne figure dans les quickstarts. Tous sont désormais documentés dans le dépôt, parce qu'une plateforme sans mémoire de ses pannes est condamnée à les revivre.
La facture : le moment où tout le monde sort sa calculette
Parlons argent, puisque c'est souvent le premier argument contre le self-hosted. Voici la facture mensuelle réelle, sortie de l'API billing de Scaleway sur un mois complet, région fr-par, en euros HT :
- Control plane Kapsule : 0 €
- Nœuds système (DEV1-M, autoscaling 2 à 4) : 33,07 €
- Nœuds worker (DEV1-L, autoscaling 1 à 5) : 30,98 €
- Public Gateway (NAT sortant) + IPs : 25,92 €
- Block Storage (volumes nœuds + PVC ClickHouse) : 22,24 €
- Load Balancer + IP : 20,16 €
- IPs flexibles des nœuds : 11,80 €
- PostgreSQL managé (3 bases) : 11,44 €
- Local SSD des nœuds : 6,08 €
- Object Storage, Registry, Secret Manager : ~0,50 €
- Total : ~162 € HT (Environ 195 euros TTC par mois)
Pour une plateforme complète avec orchestrateur, SSO avec MFA, warehouse analytique, ingestion automatisée, transformations dbt, HTTPS, monitoring et logs centralisés.
Un aveu au passage : ma première estimation tournait autour de 100 euros, et la facture réelle est de 160. Rien de scandaleux là-dedans. J'avais chiffré à grosse maille, ce n'était pas un projet client et je n'avais jamais estimé l'infrastructure Scaleway. L'autoscaling qui monte un nœud de plus que prévu, les IPs flexibles facturées par nœud, la gateway plus chère qu'attendue, tout ça ne s'apprend qu'en déployant. C'est exactement à ça que sert un bon POC : remplacer les hypothèses par une facture réelle. Et quoi qu'il en soit, pour une plateforme data complète qui tourne toute seule, ça reste ridiculement peu cher.
Et il reste de la marge. Voici ce que donnerait la même plateforme après optimisation, poste par poste :
- Supprimer la Public Gateway et ses IPs, le NAT sortant passant par les IPs publiques des nœuds : −26 €
- Verrouiller le pool système à 2 nœuds et le worker à 1, l'autoscaling m'ayant coûté un nœud de plus en moyenne sur chaque pool : −25 €
- Moins de nœuds, donc moins de volumes et d'IPs flexibles : −9 €
- Total optimisé : ~102 € HT (Environ 122 euros TTC)
C'est la fourchette honnête : 100 à 160 euros HT par mois selon que vous laissez l'autoscaling respirer ou que vous serrez la vis. Mais je préfère afficher le chiffre constaté plutôt que le chiffre flatteur.
Un dernier mot sur le rapport entre coût et valeur. La stack lakehouse n'a jamais servi une seule requête dans les conditions de sécurité que je m'étais fixées, sa facture était donc du pur coût. La stack ClickHouse tourne toutes les six heures et produit des tables gold interrogeables. Le coût d'une plateforme ne se lit pas sur la facture du provider, il se lit sur ce qu'elle produit.
L'audit honnête : solide pour un POC, pas encore pour une prod
Soyons transparents jusqu'au bout.
Voilà ce que cette plateforme a déjà de sérieux :
- Containers non-root, NetworkPolicies en default-deny sur les six namespaces
- Secrets de données isolés dans un namespace sans UI ni ingress
- HTTPS Let's Encrypt, TLS obligatoire vers PostgreSQL, whitelist IP, SSO avec MFA
- Réseaux privés partout, services managés jamais exposés
- Zéro valeur en dur, tout reproductible par Terraform
Et voilà ce qu'il manquerait encore pour une prod solide :
- Du TLS aussi sur le trafic interne au cluster (dbt parle à ClickHouse en HTTP)
- Des limits et requests sur les pods de jobs, avec des quotas par namespace
- De la haute dispo et des backups : ClickHouse est mono-nœud et son volume n'est pas sauvegardé
- Une vraie gestion des secrets : rotation automatique et un opérateur
external-secrets - Du scan d'images dans la CI et des PodSecurity standards sur le cluster
- Un vrai nom de domaine, des certificats propres et Keycloak en mode production
- De l'alerting : Cockpit collecte métriques et logs, mais personne n'est notifié quand ça casse
- Des environnements séparés (le multi-env est prêt côté code, pas déployé)
Rien d'insurmontable, et c'est exactement la valeur d'un POC : la liste ci-dessus n'est plus une page blanche, c'est un backlog.
Ce que cette aventure m'a vraiment appris
Je suis parti pour prouver qu'une data stack souveraine était possible. J'ai fini par apprendre autre chose.
Oui, la souveraineté est atteignable. Scaleway tient la route pour ce cas d'usage, l'écosystème open source couvre chaque couche de la stack, et le tout coûte moins cher qu'un abonnement à n'importe quel outil SaaS de la même catégorie. Vos données peuvent rester en Europe sans que votre plateforme ressemble à un projet de musée.
Mais la vraie leçon est ailleurs. Le moment décisif de ce projet n'est pas un terraform apply réussi. C'est le soir où j'ai supprimé trois charts Helm fraîchement déployés pour revenir à plus simple. Être tenace et aller au bout des choses est une compétence. Savoir pivoter, s'adapter quand on réalise qu'on est sorti du chemin et se remettre en question en est une autre, plus rare, et vous la trouverez rarement sur un CV ou en entretien.
La souveraineté n'est finalement pas un sacrifice technique qu'on s'impose par principe. C'est une contrainte de conception qui force à comprendre chaque brique qu'on déploie, puisqu'aucun vendeur ne viendra la maintenir à votre place. Et cette compréhension-là, aucun SaaS ne vous la vendra.
La suite logique ? Cette plateforme a une couche gold pleine de données propres, et Scaleway loue des GPU. Si vous voulez pousser plus loin que ce POC, voilà une idée : branchez un RAG souverain avec un modèle open weights ou européen au-dessus de vos tables gold. Les données ne quittent jamais l'infrastructure, le modèle non plus. Et pour le faire sérieusement, Thomas Gruson a détaillé les techniques qui font passer un RAG du démonstrateur au produit. Voilà qui ferait un joli prochain projet. 😏
D'ici là, un conseil : prenez un week-end, un budget de POC et une ou plusieurs sources de données qui vous amusent. Construisez petit, cassez des choses, faites évoluer la plateforme. Les docs techniques et les certifications posent les bases, mais l'expertise réelle vient de la mise en œuvre. Ce sont vos blocages et vos échecs qui vous apprendront le plus.