Avec les années, les pratiques de développement évoluent, mais force est de constater que certains changements prennent du temps. L’ère de “la stack technique unique” comme seule réponse à tous les problèmes a, par exemple, été appliqué bien souvent avec un aveuglement qui force l’admiration. Et je le clame d’autant plus, que moi-même j’ai contribué à ce genre de design. Aujourd’hui, une certaine mouvance, encore trop timide à mon goût, rappelle avec une évidente justesse, qu’il faut le bon outil pour résoudre un problème donné. Oui c’est une lapalissade, mais cela fait du bien de le rappeler de temps en temps.
Les architectures micro-services ont d’ailleurs, dès le départ, soutenu ce postulat en expliquant qu’elles allaient enfin permettre de traiter chaque fonctionnalité avec la bonne stack technique, la bonne base de données et … soyons fou, le bon langage. Et quitte à faire des micro-services, allons y gaiement et faisons en sorte de pouvoir en faire des “nano”, et déployons simplement des fonctions :)
Le GAM (J’appellerai ainsi le conglomérat composé de Google Amazon et Microsoft) a dans un premier temps, adapté ses offres en afin de proposer toutes une gamme “Serverless”, implémentée au format FaaS “Function as a Service”. Cela fut un véritable succès, à tel point que c’est aujourd’hui d’un usage très répandu sur les projets… Mais, à y regarder de plus près, cette approche a selon moi 2 inconvénients majeurs :
#1 On ne peut pas utiliser TOUS les langages
- Amazon propose ses lambdas avec Java, Node.js, C# et Python
- Azure a mis en place ses functions et supporte C#, Javascript, F#, Java, PowerShell, Python, TypeScript (transpilation en JS) et de manière expérimentale encore, du bash, batch et Php.
- Google qui avait sur ce genre de concept une belle avance avec les AppEngine, a mis en place, assez tardivement, les functions et ne supporte que NodeJS, Python et Go.
En résumé, si vous êtes un fan inconditionnel d’une autre techno back-end (au hasard Rust, un langage un peu tendance actuellement mais à juste titre) ou que votre cas d’usage nécessite une autre technologie… le FaaS n’est tout simplement pas fait pour vous… #oups
Les seuls langages communs à ces 3 plateformes sont JavaScript/Node.js (1) et Python, ce qui limite considérablement les choix techniques si on a comme critère de se réserver le droit de migrer son code ailleurs… #reoups.
#2 Le code est TROP lié à l’environnement de déploiement
Votre code serverless doit se comporter comme un plugin… et comme il n’y a aucune norme à ce niveau… le code est, en partie, à repenser pour chaque environnement cloud (cette considération couvre aussi les aspects sécurités très spécifiques à chaque provider cloud). Rien d’insurmontable, mais ce principe de “Cloud Provider Locking” est tout de même à considérer dans votre mise en oeuvre… #rereoups.
A cela on se doit aussi de vérifier les versions supportées. Si on parle de Node.js, Google ne permet que les versions 8 et 10 (on est actuellement à la v12.3.1 au moment où j’écris ces lignes) et comme cela prend du temps de valider une stack… on se retrouve parfois à devoir composer avec des versions un peu anciennes. Cela réduit encore un peu plus la portabilité de votre code… et donc la pertinence de cette approche… #rerereBIGoups.

Des DevCloud…
Avant de poursuivre avec ce pseudo-buzzword, je tiens a préciser que tous les inconvénients que j’évoquent précédemment, sont balayées par les gains obtenu par ces services serverless/FaaS.
Beaucoup de développeur Front ont une bonne connaissance du JS, et il est donc évident pour eux de développer leurs middlewares avec ce langage. Le mode FaaS les déchargeants de toutes les fastidieuses tâches de gestion des environnements, ils peuvent se focaliser réellement sur les besoins métiers et on peut dire que globalement la promesse de ces services est bien tenue.
Si on ajoute à cela la popularité des bases NoSQL utilisant abondamment le format JSON, il n’est pas étonnant de constater l’importante adoption des MBaaS (Mobile Backend as a Service) et plus particulièrement celui de Google, Firebase, qui est l’un des plus complets sur le marché.
Nous avons donc de plus en plus de développeur qui sont autonomes pour construire de A à Z des dispositifs performants (2) et cela les rend…
… de plus en plus exigeants
Mais au fur et à mesure que les retours d’expérience se font, on constate que les besoins évoluent. Pour poursuivre mon propos, je mets en exergue quelques attentes de plus en plus fréquentes:
- Construire un asset technique nécessite une maitrise exhaustive de l’intégralité du processus. Toutes les technos récentes abordent de mieux en mieux ces aspects, et les derniers entrants sur la scène sont souvent d’une redoutable et surprenante maturité au niveau des outils de packaging et de build.
- Même si on accepte de plus en plus de lier nos actifs à un provider cloud dans le but d’obtenir plus d’efficacité et de performance, une solution plus agnostique et équivalente sera potentiellement préférée.
- La latence d’obtention du service doit-être la plus faible possible et ne pas nécessiter de recourir à des artifices discutables. Ce problème de démarrage est flagrant avec Java, et très perceptible avec Node.js… Mais de là à faire toutes les X minutes un call pour maintenir des ressources artificiellement…. Certains murmurent même dans leurs barbes que le FaaS n’a pas trop de sens en mode transactionnel, mais serait plus recommandé pour faire des batchs (ou des events asynchrones ne nécessitant pas de performance particulière). Côté Java on cherchera plus d’efficacité avec Quarkus par exemple… mais on doit alors quitter le giron des FaaS.
- On doit pouvoir facilement faire un rollback si nécessaire vers la précédente version du service.
- On se doit d’être le plus économe possible en ressource, pour des questions de coût, mais aussi pour la planète.
- Tester nos services ne doit pas être une galère. Que ce soit localement ou de pouvoir maîtriser l’environnement d’intégration.
- On doit pouvoir exécuter le code que l’on souhaite, selon les compétences des développeurs ou selon les exigences du projet. Une part croissante de développeurs expriment aussi des attentes sur les qualités intrinsèques des technologies utilisées:
- Le code doit être plus safe.
- Un vrai compilateur doit produire un code optimisé selon la plateforme cible.
- Le ticket d’entrée doit être faible, quelques jours pour commencer à être productif, quelques semaines pour maîtriser les subtilités.
Tous ces besoins sont assez incompatibles avec l’approches FaaS qui nécessite de “brancher” chaque stack technique. On arrive paradoxalement à un point où nos chers mastodontes de l’internet ne peuvent plus être assez agiles pour suivre sans cesse les innovations techniques.
Knative
Google a semble-t-il bien perçu ces aspirations. Fort de son expérience sur le périmètre des Container as a Service avec Kubernetes, il propose depuis plus d’un an Knative:

La promesse est assez simple:
- produisez votre code qui sera packagé dans des conteneurs automatiquement déployés sur votre infra Kubernetes/Istio
- le code est agnostique de la plateforme d’exécution
- et surtout, on peut faire du down scaling à 0 c’est à dire la possibilité de faire du CaaS/Serverless.
Une seule contrainte, seul le port 8080 est utilisable…
Knative couvre bien les besoins évoqués à la section précédente, il introduit cette notion de serverless, avec le down scaling à 0, mais il reste encore à ce stade un problème majeur: Nous avons toujours besoin de provisionner un cluster Kubernetes…
Google Cloud Run
Du coup, dans la continuité de Knative, Google a sorti :
Cloud Run permet à une équipe projet de se passer des fastidieuses tâches de mise en place et de monitoring d’une infrastructure Kubernetes, qui devient une commodité très facile à mettre en oeuvre. Un micro-service, un petit site dans une vielle techno, un middleware ou que sais-je encore qui peut se mettre dans un docker, peut-être déployé de manière très simple pour un usage ponctuelle ou intensif.
Mini REX pour le mot de la fin
Il y a quelques mois j’ai commencé à faire des tests avec quelques lignes de Haskell/Servant et j’ai été assez impressionné par la vitesse de démarrage, que je peine à distinguer de celle d’une exécution nominale. Depuis nous avons poursuivi nos travaux (3) sur divers POCs ou petits projets et les retours sont assez positifs. J’espère pouvoir rapidement faire de prochains tests avec Rust afin d’évaluer mieux encore cette technologie.
Azure et AWS ont aussi déployé leurs solutions. Avec Container Instance depuis 2017/2018 pour Azure (basé sur du Kubelet?) et qui insiste beaucoup sur un paradigme cloud-hybride dans leur approche commerciale. Côté AWS on a Fargate, depuis novembre 2017, qui repose sur l’infrastructure ECS/EC2. Je ne ferai pas ici une analyse plus détaillée des écarts entre ces différentes propositions techniques, et j’avoue que la grande simplicité de Cloud Run me suffit amplement dans mes projets d’aujourd’hui.
Nous avons vu ces dernières années Kubernetes se répandre au sein de tous les acteurs. Knative s’inscrit parfaitement dans cette suite logique et, pour une fois, nous pouvons peut-être espérer le déploiement d’une première “vraie norme de facto” pour adresser les besoins serverless.
(1) Et du coup la majorité de ce qui peut transpiler en JS… je me suis même amusé à tester Elm en backend :)
(2) Cette démarche DevCloud s’accentue d’année en année, et on voit poindre parfois un future mode #NoOps sur certains projets (mince encore un buzzword).
(3) Comme trop souvent, Google fait durer le plaisir avec ses versions béta… et cela réduit les possibilités de déploiement, mais bon la concurrence est déjà en PROD, alors tout va bien ;)