Jean Philippe GOUIGOUX, architecte et directeur technique du groupe Salvia Développement et David GUIODO, responsable technique chez Dawizz, présentent sous la forme d’un dialogue informel un retour d’expérience sur la mise en place d’une architecture servicialisée au sein d’une plateforme de catalogage de données (Data Catalog).

Jean Philippe et David ont longtemps collaboré chez un éditeur Morbihannais dans une précédente vie, ils ont donc vécu ensemble la longue phase de servicialisation d’un produit monolithique et s’appuient sur cette expérience pour analyser la mise en place d’un produit de catalogage de données, from scratch !

Rencontre entre deux experts

JP : En tant qu’architecte, ce n’est pas souvent qu’on a la chance de partir d’une feuille blanche et de mettre en place une structure applicative complète à partir de rien. La plupart des startups sont trop dépendantes de la rapidité d’arrivée sur le marché pour se pencher sur ces problématiques (ce qui leur coûte parfois cher lors de leur croissance). Les très grandes entreprises ont toujours du legacy qui impacte fortement les architectures choisies. De plus en plus d’entreprises se rendent toutefois compte avec la digitalisation qu’une grande partie de leur valeur provient de leur système d’information. Il me semble que c’est le cas de Dawizz, qui a dès le début investi fortement sur son architecture logicielle ?

D : Oui, en effet. Et ce choix est fortement lié à la genèse de Dawizz. Nous avons eu la chance d’évoluer au sein de notre précédente société dans un projet de Big Bang (nous faisant passer d’un monolithe à une architecture servicialisée), sur une période de plusieurs années ! Nous avons donc fait pas mal d’erreurs, consommé beaucoup de jours et de ce fait appris énormément sur les bénéfices d’une architecture à la fois agile, automatisée et solide ! Tout ceci couplé avec une transition des équipes en mode SCRUM… Pour faire simple, je pense que tu seras d’accord avec moi, « pas d’agilité sans les outils qui vont avec » !

Partant de ce constat, et convaincus de l’énorme bénéfice du « diviser pour mieux régner » (je parle du code, pas des équipes ;-)), nous avons pris le parti d’outiller immédiatement la plateforme (pas de déploiement manuel : tout sort obligatoirement de pipelines de tâches automatisées) et de créer un service par responsabilité métier. Bien entendu, le démarrage est assez lent (en méthode SCRUM, on parle du sprint 0), mais la courbe de productivité a rapidement tendance à croître.

 

 

JP : Nous ne nous sommes pas présentés au début de cet entretien, mais il faut peut-être en dire plus aux lecteurs, et expliquer que nous avons travaillé ensemble pendant de longues années sur plusieurs architectures dans une entreprise très innovante techniquement et ouverte à des changements majeurs issus de la veille technologique et d’une forte proximité avec le milieu de la recherche. J’ai été l’architecte et le directeur technique de cette entreprise, et j’ai en particulier été placé à ce poste pour mettre en œuvre cette architecture pensée dès 2011 comme urbanisée et déployée en production dès 2014 avec Docker, ce qui représentait une avance considérable sur la concurrence, et a positionné idéalement l’entreprise pour surfer sur la vague de l’APIsation des applications.

D : Oui, notre longue collaboration, pour ma part en tant que responsable d’équipe puis responsable de la cartographie des services, nous a enseigné énormément, et nous avons la chance tous les deux de pouvoir comparer l’avant / après dans ce type de projet.

 

L’ARCHITECTE TECHNIQUE DE DAWIZZ

JP : De ce que je comprends des besoins, les enjeux principaux étaient de pouvoir rapidement apporter de nouvelles fonctionnalités sur vos services en ligne tout en vous assurant de ne pas déstabiliser l’existant, mais aussi d’obtenir une architecture logicielle suffisamment souple pour pouvoir être déployée par vos soins en SaaS, mais également directement chez vos clients en mode On Premise, voire même leur donner la possibilité de créer eux-mêmes un SaaS en marque blanche avec vos produits pour leurs propres clients ? Avec ce type de cahier des charges, je peux sans peine imaginer qu’un déploiement par conteneurs a été choisi ?

D : Effectivement. Une fois les premiers services livrés, le challenge est d’être capable à la fois de faire évoluer ces services indépendamment les uns des autres (cycles de vies distincts), sans régression, mais également de pouvoir livrer de nouveaux services sans pour autant remettre en cause une installation existante. Nous avions également comme objectif de pouvoir déployer notre mode SAAS dawizz.fr au même titre que n’importe quelle instance on-premise : nous appliquer strictement les mêmes contraintes qu’à nos clients. Ce dernier point n’est pas anodin, car nous avons du coup cherché la technologie la plus simple pour déployer notre infrastructure. Ce fut Docker et les résultats sont au dessus de nos attentes. L’installation consiste en un installer qui prend en entrée un fichier de paramètres, rend en sortie un fichier docker-compose et lance le déploiement des conteneurs dockers.

Notre production, ainsi que les instances on-premise de nos clients, n’exécutent qu’une seule commande, à la fréquence choisie (conseillée à une fois par semaine), à savoir docker pull. Notre chaine d’intégration constitue automatiquement les images Docker sur notre repository privé, il suffit d’attribuer à chaque compte on-premise une clef d’accès à celui-ci, et voilà !

Nous avons franchi une étape le jour où nous avons réalisé que l’installer était lui même un service versionné et maintenu au même titre qu’un service métier : nous avons ainsi résolu la problématique de la livraison de nouveaux services. Le service installer est lui même dockerisé ! Cela peut paraitre anodin, mais ce point nous a vraiment aidé dans notre développement !

Nous délivrons notre outil en marque blanche, nous avons donc des comptes prescripteurs qui vendent notre solution sous leur propre marque par un simple paramétrage à l’installation.

 

QUELS SONT LES AVANTAGES DE VOTRE ARCHITECTURE ?

JP : Cette capacité de découper en modules effectivement autonomes est le nerf de la guerre. En fait, seul un alignement très fort des contrats d’API sur le métier permet d’avoir une compatibilité ascendante et donc une stabilité de la plateforme dans le long terme. D’après votre nombre de modules et le périmètre de votre métier, il me paraît clair que vous avez choisi une bonne découpe intermédiaire, alignée sur le fonctionnel. Les entreprises qui misent tout sur le caractère distribué des applications, indispensable pour les applications internet grand public, ont un découpage très fin, qui devient purement technique ; leurs API sont alors complexes à utiliser. A l’inverse, si l’application est trop monolithique et pas assez découpée, les couplages restent forts et les API évoluent alors trop souvent. J’imagine que vous avez créé des contrats d’API ?

D : Oui, chaque service (nous en avons à ce jour un peu plus de 15) porte son propre contrat d’API et donc d’entités. Dans notre précédente vie, nous avions une grosse expérience des web services SOAP avant de commuter sur REST et, du fait de la verbosité de SOAP, avons rencontré pas mal de soucis liés à la perte de compatibilité ascendante, difficilement gérable dans ces gros fichiers XML… REST nous a apporté la simplicité notamment des contrats JSON : donc OUI, il est interdit de rendre une entité non compatible ascendante sans avoir mûrement réfléchi aux impacts, livré une nouvelle version, déprécié celle-ci, … Nos contrats de départ devaient être corrects car nous avons été peu confrontés à cette situation, même si bien entendu, certaines entités métiers mériteraient un petit dépoussiérage de printemps !

Un point est important au sujet de la compatibilité ascendante : nos APIs sont consommées par des partenaires. Donc, crois-moi, en cas de perte de compatibilité, nous serions vite au courant !

 

JP : Oui, c’est une grande responsabilité que de faire partie du SI des clients, et une belle marque de confiance dans la stabilité de votre plateforme. Ce contrat, c’est ce qui vous permet de garantir que l’application évolue rapidement, en faisant en sorte de réduire quasiment à zéro les chances qu’un changement sur un des modules se répercute de manière négative sur un autre. Par contre, nous savons tous les deux que, pour ce qui est de l’interface graphique, cette découpe est souvent difficile à réaliser, car il reste nécessaire de produire une seule page sur internet et qu’elle apparaisse comme quelque chose d’unifiée. Il faut alors prendre en compte la gestion centralisée des thèmes, mais surtout avoir une très bonne structure de page. Certains architectes poussent à l’utilisation d’iframe, qui sont une sorte de page web à l’intérieur d’une zone d’une autre page web ; la séparation est très forte, mais il y a des défis techniques à relever. D’autres recommandent d’abandonner plus ou moins cette découpe sur l’interface graphique et d’assumer que l’interface est d’un seul tenant. Quelle a été votre approche ?

D : Ah le sujet de l’iframe !!! Forcément, ce terme peut donner des convulsions à certains puristes si je leur demande d’intégrer des UI de services de cette façon ! Je parle en connaissance de cause ! Mais il faut avouer qu’il est assez déprimant de découper une infrastructure en responsabilités métiers et de ne pas être en capacité d’avoir un service qui agrégerait les UI au même titre que les APIs sont agrégées dans des outils comme Swagger / OpenAPI… Donc, comme le font Google, Microsoft et beaucoup d’autres fournisseurs de services, nous avons pris le parti d’utiliser les iframes pour offrir une vraie composition de services, ceci uniquement quand c’est possible.

En abuser serait toutefois une erreur ; par exemple, nos pages qui présentent des fonctionnalités de thésaurus au sein de nos applications appellent des APIs de notre service thesaurus et de notre service catalogue, seule vraie solution pour obtenir une UI ergonomique. Mais dans beaucoup de cas, l’UI du service peut très simplement être embarquée dans une iframe, reflétant un lien entre les objets (par exemple une application possède des documents, un simple onglet embarque une iframe avec le service document embarqué). Donc quand les responsabilités métiers sont bien distinctes ergonomiquement, pourquoi s’en priver ? Ouest France utilise pas moins de 14 iframes dans sa page d’accueil : quel lien entre une publicité, la météo, les abonnements et une actualité ?

Cette technique nous permet de releaser un service sans aucun impact sur le service « maître » qui l’encapsule par iframe : un vrai gain en maintenance pour une petite équipe !

 

JP : Si on passe maintenant complètement de l’autre côté de l’application et qu’on s’intéresse à la persistance des données, je serais curieux d’en savoir plus sur vos choix techniques et, peut-être, vos compromis. Les partisans d’une approche pure des microservices insistent sur une base de données séparées pour chaque module ; c’est vrai que si la base est partagée, le couplage recréé n’est finalement pas tellement réduit par rapport à avoir les différents modules réunis dans un seul processus. Ceci étant dit, à partir du moment où on reste sur des domaines métiers proches, le problème de consistance est réduit puisqu’un même domaine est justement défini par le fait que ses concepts sont proches les uns des autres, et beaucoup plus distants des concepts des autres domaines fonctionnels. De ce que je perçois, vous avez résolu le problème en alignant votre découpe de service sur les domaines métiers, c’est bien cela ?

D : Le problème de la consistance des données est à mon avis le sujet le plus délicat, surtout pour des profils comme les nôtres, élevés à coups d’intégrité référentielle dans le monde SQL… Finalement, je comparerais ces deux approches aux méthodologies cycle en V / agile : d’un côté, on tente de formaliser des règles qui auront bien du mal à être respectées dans le monde réel (intégrité référentielle, règles de gestion, …), de l’autre, on accepte l’imperfection à un instant T pour tendre vers le mieux au fil du temps…

Donc, le cap à passer est d’accepter une inconsistance de données à un instant donné : par exemple, une information peut être désynchronisée entre un service d’authentification et un service métier. Un libellé d’utilisateur ne sera pas identique entre deux services à 14h, mais est-ce si important au final du moment qu’il finit par se synchroniser à la fin de la journée. Nous faisons le choix de laisser des services fonctionner dans un mode dégradé afin d’offrir quand même un service à l’utilisateur (je peux toujours me connecter à la plateforme) du moment qu’à terme la consistance est retrouvée. Si cette approche est assez classique pour des systèmes qui interopèrent, elle l’est moins au sein de son propre produit !

Nous avons donc fait le choix de découper nos services en nous alignant sur les domaines métiers : authentification, catalogage, thesaurus, normalisation, statistiques, licences, portail, sonde, document, documentation, … Cela s’avère très efficace pour la maintenance (pas besoin de la connaissance du métier 1 pour intervenir sur le métier 2) et pour l’intégration d’un nouveau membre à l’équipe de développement.

Il reste le problème des entités partagées (nous avons une entité source de données qui est partagée par plusieurs services) : l’idéal dans ce cas serait d’avoir un repository des versions d’entités publiques, utilisé par les différents services. Nous irons sans doute sur cette voie, mais pour l’instant nous nous en sortons par synchronisation manuelle des entités.

 

JP : Oui, la consistance a posteriori est quelque chose de difficile à faire avaler à des habitués du mode transactionnel pur. C’est pourtant comme cela que les banques fonctionnent depuis des décennies, en enregistrant des ordres de mouvement et en ajustant l’état des comptes bancaires en fin de journée… Donc, pour résumer, dans la majorité des cas, la découpe suffit à ce que vous n’ayez pas de problématique de consistance, et dans les autres cas, vous avez parié sur l’asynchronisme. Un peu comme dans un bureau où il n’y a pas nécessairement une seule personne qui connait la vérité complète du business à elle seule, mais des personnes qui connaissent chacune un petit bout de la vérité et qui se connaissent suffisamment pour que, lorsque l’une d’entre elle a besoin d’une donnée d’une autre, elle vérifie d’abord avec elle si la donnée est stable avant de l’utiliser. Par exemple, une personne en charge du courrier irait d’abord voir la personne responsable des tiers pour vérifier qu’il n’y a pas un changement d’adresse en cours d’enregistrement, avant de mettre cette adresse sur le courrier et de le passer au service d’expédition. Cela doit être particulièrement utile pour les déploiements, car cela veut dire que vous n’êtes pas obligé de mettre à jour tous les services d’un seul coup : ils savent continuer à travailler même si les autres n’ont pas encore fini leur montée en version, c’est bien ça ?

D : Oui c’est exactement cela, ce point était vital pour nous ! Ou comment une petite équipe arrive à gérer un produit très complet tout en assurant la qualité des livrables ! J’en reviens toujours au même adage : « diviser pour mieux règner ! ». De plus, grâce à cette facilité de publication, nous avons petit à petit basculé en mode feature. Il n’est pas rare de publier plusieurs versions d’un service dans la même semaine : mais attention, ceci n’est possible QUE grâce à une bonne couverture de notre code par des tests automatisés (en moyenne au dessus de 80 %, voire 95% pour certains services très sensibles).

 

COMMENT DÉPLOYEZ-VOUS VOTRE SOLUTION ?

JP : Parlons maintenant du déploiement. C’est un sujet qui me tient à cœur car j’ai écrit plusieurs livres et tourné des vidéos à ce propos, non seulement sur Docker, mais aussi sur Swarm et sur Kubernetes. Tous vos services sont déployés dans des conteneurs Docker, mais comment avez-vous géré l’orchestration de l’ensemble ? Y a-t-il un chart Helm pour la solution de Dawizz que vous utilisez pour déployer sur Kubernetes ?

D : Non, pour l’instant nous avons fait le choix d’un simple docker-compose sur une machine unique, mais puissante. Kubernetes fait partie de notre roadmap pour pouvoir s’insérer dans les infrastructures basées dessus. A ce jour, notre choix répond à nos besoins, notamment d’un déploiement très simple : nous pouvons déployer une nouvelle machine en moins d’une heure !

 

JP : C’est une approche originale, et qui a le gros avantage de rendre possible pour vos propres clients de déployer eux-mêmes l’application sans avoir à mettre en place une infrastructure complexe. Il est vrai que gérer un cluster Kubernetes peut être complexe et que de nombreuses entreprises préfèrent dédier cette tâche à une solution dans le cloud. C’était un choix dès le début de Dawizz ?

D : Oui, nous faisons en sorte de nous appliquer à nous même ce que nous demandons à nos clients… donc notre déploiement est devenu très simple et performant !

 

JP : Et donc, pour la gestion des tenants, c’est une installation par tenant client, tout simplement ?

D : Oui, comme l’installation d’une instance d’application a besoin d’une seule ligne de commande, ça rend très simple de démarrer un tenant. Mais nous travaillons également sur un mode SAAS et un mode marque blanche. Donc nos services sont eux-même multi-tenant. Dawizz.fr est donc disponible en mode SAAS par création d’organisations, et nos clients prescripteurs peuvent eux-même gérer un mode SAAS sous leur propre marque et leur propre instance déployée. Le débat du multi-tenant applicatif ou par déploiement est donc clos : les deux sont possibles !

 

JP : Excellente approche ! Simple et efficace. On voit tant d’entreprises avec des difficultés sur Kubernetes parce que c’est trop complexe par rapport à leurs besoins, mais qu’elles voulaient absolument avoir le top du top sans bien en mesurer les contraintes… J’imagine que cette simplicité s’étend aussi à la gestion des modules fonctionnels ? Comment faites-vous lorsqu’il y a besoin de rajouter des fonctionnalités complètement nouvelles, qui nécessitent d’étendre le nombre de briques logicielles ? Certains ont pour pratique de déployer dynamiquement des modules et de faire en sorte que les autres puissent faire sans, en totale autonomie. D’autres préfèrent déployer systématiquement la totalité de l’application et d’utiliser un système de licence pour donner accès à certaines parties de l’application ou pas. De votre côté, comment gérez-vous la licence ?

D : Nous avons fait le choix de déployer systématiquement tous les services, et c’est la licence qui borne les accès aux fonctionnalités. Ainsi nous évitons les questions liées aux déploiements différents d’une infra à l’autre. La licence est elle-même gérée par un service, sur le même mode que l’authentification, par un token.

 

AUTHENTIFICATION ET AUTORISATION : LE CHOIX DE DAWIZZ

JP : OK, et du coup, vous avez un lien possible à l’authentification ? Des licences différenciées peuvent être affectées à différents comptes ? Je pose la question car cette découpe est souvent difficile à atteindre, surtout lorsque les architectes mélangent ces notions avec celles d’autorisations, qui sont pourtant différentes. Et comme parfois la gestion de droits est fortement mélangée avec celle d’authentification et d’identification, le mélange devient potentiellement très complexe. Personnellement, je recommande fortement l’usage de standards et de normes comme OpenID Connect, OAuth, SAML, JWT, XACML, etc. pour être sûr de bien rester dans une découpe qui est propre. Comment ça se passe pour Dawizz ? Tous les services ont leur propre authentification ? Vous mettez en place une passerelle d’authentification en amont de la zone des conteneurs et ils se font ensuite confiance à l’intérieur de cette zone ?

D : Notre service d’authentification délivre un token JWT, de même que notre service de licence. Chaque service est apte à déchiffrer ces tokens et à affecter d’une part les rôles de l’utilisateur connecté, d’autres part les fonctionnalités ouvertes à l’organisation courante. Je trouve la solution plutôt simple et puissante : la mécanique de licence nous permet de répondre aux besoins de nos comptes prescripteurs qui gèrent leur propre mode SAAS.

 

JP : Bref, une approche « zero trust » où chaque service re-vérifie l’identité de la personne connectée. C’est particulièrement adapté en ces temps où la menace cyber est très élevée et où nous devons tous faire particulièrement attention à ce que nos logiciels participent activement à la sécurité des données de nos clients. Dans le cas de Dawizz, cette contrainte est peut-être même encore plus forte que dans la majorité des éditeurs de solution logicielle, non ?

D : Nos contraintes de sécurité ne sont ni plus ni moins fortes que celles qui s’appliquent aujourd’hui à tout éditeur logiciel. Nos plateformes doivent faire en sorte de ne pas être des vecteurs d’attaque, grâce à une surveillance du code source, mais aussi l’architecture modulaire dont nous parlons depuis tout à l’heure, et qui nous permet de bien ajuster le niveau de sécurité pour chaque module. Typiquement, les APIs exposées à l’externe peuvent être durcies par des mesures de sécurité additionnelles, comme un reverse-proxy et un mécanisme de pare-feu.

 

UNE ARCHITECTURE PROPRE POUR UNE VISION A LONG TERME

JP : Je vois que Dawizz a bien fait les choses. En fait, vous êtes partis dès le début sur une architecture extrêmement propre. Ca ne vous a pas coûté beaucoup de temps de développement de mettre en place tout ça ? Quand on démarre un logiciel, beaucoup de startups, comme je le disais au début, ont de forts enjeux de conquêtes rapides du marché et préfèrent une approche « quick and dirty », quitte à prendre du temps ensuite pour reprendre l’architecture et la remettre au propre, ce qui n’est pas toujours facile. Qu’est-ce qui a fait que vous avez pris ce temps ? Une culture technique prééminente ?

D : Voilà, nous avons essayé de faire du « on-time and clean » ! Blague à part, c’est vraiment notre expérience précédente qui nous a permis de construire rapidement cette plateforme (un projet de type BIG BANG est quand même un challenge énorme parsemé d’embûches), nous étions déjà tombés dans la majorité des pièges de ce type d’architecture, les bénéfices ont donc été très rapides ! Et nous restons sur ce mode de fonctionnement, nous n’hésitons pas à investir du temps dans l’automatisation de nos processus, car le retour sur investissement est vraiment rentable.

Par exemple, en ce moment nous travaillons sur un déploiement automatique journalier d’une plateforme de démonstration, à partir d’une machine vierge. Cela nous garantit d’une part que l’installation « from scratch » est bien opérationnelle, et d’autre part, l’injection de données de démonstration par appel de nos APIs valide un test d’intégration et de compatibilité ascendante grandeur nature. Je suis certain que le temps consacré à cette tâche sera très vite amorti en non-régression et donc en maintenance. Et notre service commercial aura à disposition une vraie plateforme de démonstration !

Comme il parait impossible de ne pas avoir d’inconvénients sur un choix d’architecture informatique, je citerais : quelques soucis de communications entre les containers dans certains cas, l’apparente légèreté du JSON qui oblige à être très consciencieux sur les contrats, les volumes des images qui peuvent devenir assez importants dans le temps mais rien de grave. Et franchement, quand je repense à l’avant Docker, à l’avant découpage par responsabilité métier, je ne ferais marche arrière pour rien au monde ! A ce jour, je vois un problème majeur qui peut être rédhibitoire : Docker est un pré-requis. Nous avons croisé quelques structures qui ne connaissent pas encore ou très mal Docker, d’autres qui souhaitent pouvoir connaitre l’intégralité des composants utilisés et qui avancent des problématiques de sécurité. Un peu démunis dans ce cas, à part opposer les 30 et quelques milliards de conteneurs actifs ans le monde, si le client refuse Docker, alors nous ne faisons pas affaire pour un déploiement on-premise. C’est la limite de l’exercice !

 

 


David Guiodo
Cofondateur et responsable Technique au sein de Dawizz

Jean Philippe GOUIGOUX

Architecte et directeur technique du groupe Salvia Développement