Mettre en place une Data Platform n’est pas uniquement une question d’outillage. Les services cloud permettent aujourd’hui de créer très rapidement un data lake fonctionnel : du stockage (Amazon S3), un catalogue (Glue Data Catalog) et un moteur de requête SQL (par exemple, Athena). La mise en place d’un datalake est quelque chose de simple. Ce n’est cependant pas le cas de l’industrialisation des jobs de processing de données (extraction ou transformation).
Face à ce constat, nous avons donc repensé notre approche en transformant notre datalake en une Data Platform. C’est-à-dire, un produit logiciel à part entière. La Data Platform s’appuie sur une architecture modulaire et des bonnes pratiques de gestion de produit pour faciliter le passage à l’échelle des cas d’usage data de notre client.
Cette réflexion s’est articulée autour de trois axes principaux que je vais présenter dans le cadre de cet article :
- Le pattern d’architecture de Data Processing as a Microservice,
- La création d’un framework
- La mise en place et le suivi des bonnes pratiques indispensables à tout produit logiciel.
Data Processing as a Microservice
Les limites de l’approche monolithique
Un premier modèle d’industrialisation de jobs data (extraction, transformation) consiste à les centraliser dans une seule brique de traitement.
Cette brique serait constituée de trois éléments :
- du compute, par exemple EMR Serverless, qui permet de faire tourner du Spark dans AWS)
- un rôle IAM, qui défini les permissions de l’infra dans le Cloud
- le code, packagé par exemple dans une image Docker
Ce modèle pose rapidement problème :
- Traçabilité des coûts : tous les jobs de processing tournant sur la même infrastructure, il est très difficile de scinder les coûts par périmètre métier ou par cas d’usage.
- “Noisy neighbors” : un job trop gourmand en ressources peut impacter tous les jobs en production.
- Évolutivité : faire évoluer l’infrastructure (par exemple une montée en version de Spark) impacte tous les jobs en même temps, avec un risque de panne globale de tous les jobs de processing si l’évolution contenait un bug.
L’approche microservice
À l’inverse, le pattern Data Processing as a Microservice reprend la même brique (compute, rôle et code). Mais il crée une brique par job de processing, décentralisant ainsi chaque job en un microservice “autonome” d’un point de vue infrastructure.
Résultat :
- Les coûts deviennent traçables par périmètre métier,
- Plus de risque de noisy neighbors. Un job trop gourmand en ressources ne fait planter que son infrastructure, pas celle des autres jobs
- L’évolution de l’infrastructure peut se faire brique par brique, limitant ainsi les risques de pannes globales en cas de bug.
De plus, le coût d’un tel pattern n’est pas supérieur à celui d’une approche monolithique. En effet, les ressources serverless utilisées ne consomment que lorsqu’elles sont actives. Donc, maintenir 50 clusters en parallèle ne coûte pas plus cher que d’en avoir qu’un seul !
Construire un Framework de Data Platform
Le découplage microservice peut malgré tout avoir un revers. En effet, chaque nouveau job impose de réécrire du Terraform, du code Airflow ou de la configuration AWS, avec beaucoup de duplication.
Pour éviter cet écueil, on peut factoriser cette logique dans un framework de Data Platform. Celui-ci repose sur trois briques principales :
Airflow DAG Generator
Comme de nombreuses équipes data, nous utilisons Airflow pour orchestrer nos pipelines. Mais écrire les Dags Airflow nous est apparu très répétitif, et donc facilement automatisable. Nous avons donc mis en place une librairie Python qui génère automatiquement le DAG à partir d’une configuration YAML. Résultat : les Data Engineers décrivent ce qu’ils veulent, le framework s’occupe du reste.
Pipeline Factory
Un module Terraform déploie la brique complète (infrastructure + rôle IAM + image Docker contenant le code) à partir du même YAML que le Airflow Dag Generator. Cela permet de créer un pipeline data sans dupliquer le code IaC (Infrastructure As Code).
Data Lake SDK
Le Datalake SDK est une surcouche python permettant aux data engineers de bénéficier d’une boîte à outils dans laquelle ils peuvent piocher certaines fonctionnalités standards. Par exemple :
- Récupération automatique de secrets (AWS Secrets Manager),
- Ecriture simplifiée des DataFrames dans le datalake,
- Exécution SQL “as code” à la manière de dbt.
Le Data Engineer se concentre sur la logique métier, le framework gère l’infrastructure et les aspects répétitifs.
Exemple d’une configuration de pipeline data
Pour plus de concret, voici un exemple de la configuration d’un pipeline data. Ce pipeline est interprété par le Airflow Dag Generator et la Pipeline Factory :

- La configuration du pipeline contient d’abord la configuration du Dag. Par exemple le schedule interval. Il définit l’heure et la fréquence à laquelle le Dag se déclenche. Ou la balise slack taggée lorsque l’exécution du Dag échoue.
- Elle contient ensuite la configuration des tasks. Par exemple, ici une task CustomLambdaSensor. C’est un Operator custom que nous avons développé qui permet d’encapsuler un Sensor dans une fonction AWS Lambda
- Cette configuration de tasks contient aussi d’autres informations, comme la configuration de l’infrastructure de la task (ici un cluster ECS). Cette configuration va dépendre du type d’infrastructure utilisé : EMR Serverless pour les jobs big data ou ECS pour les jobs small data. En effet, étant donné l’hétérogénéité des volumes de données en fonction des sources, nous avons mis en place un système de compute hybride en donnant la possibilité aux Data Engineer de faire du calcul distribué via Spark ou non-distribué via Pandas pour optimiser les coûts.
- La configuration contient aussi les tables lues et écrites par chaque task. Ceci permet de construire les rôles IAM avec la Pipeline Factory et de construire le Dag Airflow. Par exemple : task A écrit table 1, task B lit table 1, donc task B dépend de task A.
Exemple du code d’un job de processing data
Pour être encore plus concret, voici un exemple du code d’un job de processing data, faisant usage du Datalake SDK:

- Le Datalake SDK est embarqué comme dépendance dans tous les jobs de processing. Ceci permet aux Data Engineers de bénéficier d’une boîte à outils de fonctionnalités data
- Exemple de fonctionnalité : les data engineers ont la possibilité de spécifier dans la configuration d’une task une liste de secrets (pouvant contenir les credentials pour accéder à une source de données, par exemple). Le Datalake SDK va automatiquement récupérer la valeur du secret dans le service AWS Secrets Manager.
- Une autre fonctionnalité du Framework est l’écriture de la donnée dans le datalake. Le Data Engineer n’a qu’à retourner le Dataframe qu’il veut écrire et le Datalake SDK gère l’upload. Cette couche d’abstraction permet de faciliter la mise en place de fonctionnalités sous-jacentes, sans impact pour les data engineers. Par exemple, nous avons mis en place une détection d’anomalie sur les volumes d’ingestion. La détection vérifie si le volume ingéré est aberrant comparé au volume ingéré précédemment et lève une alerte si c’est le cas. Cette fonctionnalité a été déployée sans impact pour les utilisateurs. Mieux, ils n’ont eu aucune modification à faire pour en bénéficier dans leurs pipelines.
Le Datalake SDK a une implémentation bicéphale avec une partie permettant de faire du Spark et l’autre permettant de faire du Pandas, selon l’infrastructure choisie par le Data Engineer. Le contrat d’interface étant presque identique entre les deux, il devient presque facile pour les data engineers de commencer leur job sur un ECS et de le migrer sur EMR Serverless s’ils se rendent compte que le volume de donnée à traiter est plus important que prévu.
Avantages
La mise en place d’un Framework Data Platform présente de nombreux avantages :
- Abstraction de la complexité technique : moins de code Terraform et Airflow à écrire, moins de compétences techniques à chercher sur le marché. Les data engineers peuvent se focaliser sur leur création de valeur : l’extraction et la transformation de données. Cela permet en outre d’augmenter la vélocité de développement de pipelines. Et donc, de réduire le time to prod des cas d’usage data.
- Cohérence des pratiques : le code mutualisé garantit que tout est fait de la même façon dans tous les pipelines.
- Évolutivité centralisée : une évolution dans le framework (par exemple modifier le format de table pour passer à Iceberg) bénéficie automatiquement à tous les pipelines. Ceci facilite l’évolutivité des pratiques et des outils.
Gérer la Data Platform comme un Produit Logiciel
Mettre en place un tel framework, c’est créer un produit software. Et comme tout produit logiciel, sa pérennité dépend de la mise en place et du suivi de bonnes pratiques :
Des tests
Le framework doit être testé automatiquement à chaque évolution. Ceci, afin de rendre chaque mise en production du framework sereine (on a une certitude raisonnable que ça marche).
Pour ce faire, nous avons créé une configuration de pipeline data qui utilise toutes les fonctionnalités de la Data Platform. Ce pipeline de test est redéployé et exécuté à chaque modification du Framework. Si tout passe, la release peut sortir.
Des releases versionnées
Les releases visent à fiabiliser les pipelines data existants en production face aux modifications de la Data Platform.
Imaginons que tous les pipelines utilisent la dernière version du Framework. A chaque nouvelle fonctionnalité de la Data Platform, celle-ci est automatiquement propagée dans tous les pipelines en production. Et un bug se glisse à travers les tests fonctionnels, il provoque une panne de tous les jobs d’un coup.
Pour se prémunir de ce problème, le framework publie des releases versionnées (ex. v1.2.3) et laisse les pipelines fixer la version qu’ils utilisent. Ainsi, une nouvelle release n’impacte pas les pipelines existants. Les data engineers ont la possibilité de migrer leurs pipelines quand ils en ont la bande passante pour bénéficier des dernières fonctionnalités du Framework.
Maintenant imaginons qu’un certain nombre de pipelines utilisent une ancienne version de la plateforme et qu’un bug est découvert. L’équipe data platform publie un fix dans une nouvelle version. Mais peut-être que les data engineers n’ont pas la bande passante pour migrer leurs pipelines vers cette nouvelle version dans l’immédiat, ce qui impliquerait une charge de migration potentiellement conséquente en fonction des breaking changes induits. Pour faciliter la vie de nos utilisateurs dans cette situation, nous assurons du MCO (Maintien en Conditions Opérationnelles). C’est-à-dire que l’on publie sur demande les fix sur d’anciennes versions pour corriger des bugs sans forcer les data engineers à migrer leurs pipelines. En revanche, afin de contrôler la charge de run pour l’équipe data platform, nous limitons la durée de vie des versions plateforme en décommissionnant les vieilles releases.
Un contrat d’interface
Lorsque l’on met en place une couche d’abstraction, la façon dont les utilisateurs interagissent avec la logique sous-jacente s’appelle un contrat d’interface. Si l’équipe Data Platform modifie cette interface (par exemple en modifiant le nom d’un paramètre dans une fonction du datalake-sdk), les data engineers devront modifier leur code pour monter de version, ce qui, si cela se produit trop fréquemment, génère beaucoup de frustration. Cela peut conduire à une situation où les data engineers rechignent à mettre à jour leurs pipelines. Ce qui provoque un “vieillissement” progressif des pipelines en production.
Il est donc indispensable de construire un contrat d’interface robuste et stable qui limite les breaking changes et facilite les montées de version des utilisateurs.
Un choix raisonné des fonctionnalités
Cette bonne pratique s’articule autour d’un compromis entre deux principes bien connus de l’informatique : DRY versus YAGNI.
La création du Framework Data Platform visait en partie à mutualiser le code pour éviter les redondances (DRY – Don’t Repeat Yourself). Une fois que l’on a commencé à mutualiser, il va être très tentant de mutualiser tout et n’importe quoi. Parce qu’après tout, ça peut toujours être utile. Sauf que vous vous rendrez parfois compte que ce que vous avez mutualisé n’est en fait utilisé que dans un pipeline. Voire pire, dans aucun. Ce qui rend la fonctionnalité ajoutée superflue (YAGNI – You Aren’t Gonna Need It).
Or ajouter une fonctionnalité dans un framework, c’est ajouter de la complexité. Et la complexité d’un framework nuit à :
- La facilité de prise en main (pour les utilisateurs ou les mainteneurs)
- La maintenabilité (car la base de code grandit)
- L’évolutivité (plus difficile d’ajouter des fonctionnalités)
Tout cela pour dire que parfois, refuser d’implémenter une fonctionnalité demandée par vos utilisateurs (ou refuser de l’implémenter telle que demandée par vos utilisateurs) peut être le meilleur choix pour garantir la pérennité du Framework sur le long terme.
Conclusion : devez-vous construire votre Data Platform ?
Cette question va peut-être vous surprendre en conclusion d’un article expliquant comment construire une Data Platform, mais elle est néanmoins importante. Elle est importante car une fois votre plateforme en place en place, on vous posera la question “Pourquoi ne migre-t-on pas vers du managé” : vos stakeholders vous la poseront, vos métiers vous la poseront, et même parfois vos utilisateurs (les data engineers) vous la poseront.
Nous avons constaté que cette question s’articule autour de deux axes de réflexion principaux.
Le compromis Data Engineering vs YAML Engineering
La data platform, comme n’importe quelle solution managée, abstrait la complexité technique. C’est un gain énorme en productivité pour les utilisateurs, mais cela transforme le métier de Data Engineer : moins d’infra, davantage de configuration et de logique métier. Selon la culture et les profils de votre équipe, cela peut être perçu comme un avantage… ou une frustration. Chez mon client, nous avons adressé cette problématique en faisant évoluer la fiche de poste de nos data engineers au fur et à mesure de la montée en maturité du Framework et du turnover de l’équipe data: moins de compétences infra et automatisation, davantage d’appétence pour les problématiques métiers du client.
Le compromis Build vs Buy
En 2020, construire sa Data Platform était souvent nécessaire : les solutions du marché (Databricks, Snowflake, dbt…) n’avaient pas la maturité qu’elles ont aujourd’hui. Depuis 5 ans, l’arbitrage est devenu plus difficile : vaut-il mieux bâtir sa plateforme ou adopter une solution managée ?
La seule façon de construire une réponse solide à cette question repose sur le suivi de KPIs.
Voici quelques exemples :
- Évolution du time-to-prod de vos cas d’usage data : la data platform est censée faire baisser le time to prod, si celui-ci augmente, c’est un mauvais signe, cela peut induire une trop forte complexité du framework.
- Pourcentage des MEP de cas d’usage data devant être rollback suite à un bug plateforme : un haut pourcentage peut indiquer un manque de stabilité du framework, peut-être dû à un problème de coverage des tests fonctionnels.
- Ratio du temps de l’équipe data platform dédié au build rapporté au temps dédié au run du framework : le temps de run plateforme n’est pas censé être corrélé à l’augmentation du nombre de cas d’usage data, le contraire indiquerait un manque d’autonomie des utilisateurs ou un mauvais coverage des tests fonctionnels.
Construire sa propre Data Platform donne une grande liberté (maîtrise de la roadmap, de la stack, des coûts), mais au prix d’un investissement continu. À l’inverse, acheter une solution managée simplifie la maintenance, mais vous rend dépendants de la roadmap et du pricing d’un éditeur.
Chaque contexte a ses propres problématiques, c’est donc un sujet éminemment difficile à trancher. Néanmoins, le suivi de vos KPIs vous permettra de prendre une décision éclairée : continuer à maintenir la data platform existante ou migrer sur une solution managée ?

