Aller au contenu
CloudServerlesscloud nativeAWSFaaSLambdaSAMRust

Serverless: Révolution ou simple tendance?

Le Serverless, basé sur les Fonctions en tant que Service (FaaS), libère les développeurs des préoccupations d'infrastructure. Son modèle "pay as you go" assure une scalabilité dynamique. Cet article explore son essence et son impact sur le développement dans le paysage technologique actuel.

Serverless Cloud image connectent des différentes composantes
Serverless : révolution ou simple tendance ?

Serverless ou "Sans Serveur" est-il réellement un environnement sans serveur ? Pas tout à fait. Serverless ne signifie pas l'absence de serveur, mais plutôt que les ressources sur lesquelles l'application se base sont managées extérieurement. Ceci reprend un changement de mentalité en profitant du modèle facturé par utilisation (pay as you go). L’équipe informatique se concentre plutôt à créer des valeurs business que de gérer une infrastructure. Il faut dire que le Serverless n'est pas une solution miracle. Il faut évaluer si elle est applicable dans le paysage technologique et dans une structure organisationnelle spécifique de l’entreprise.

Infrastructure

Dans un environnement Serverless, l'infrastructure est normalement mise à disposition.

Représentation du modèle de responsabilité repris de AWS reinvent 2019: https://d1.awsstatic.com/events/reinvent/2019/REPEAT_3_Serverless_architectural_patterns_and_best_practices_ARC307-R3.pdf

Plus on se retrouve dans la partie droite, plus le service est maintenu par le provider. Il n'est plus nécessaire de provisionner, configurer et gérer des serveurs physiques ou virtuels. La gestion de la capacité et la mise à l'échelle manuelle des ressources ne sont plus des préoccupations du développeur. Le service s'adapte automatiquement à la charge de travail. La gestion de la disponibilité et de la redondance des applications deviennent moins complexes.

Dans le monde AWS en retrouve par exemple les composants Serverless suivant :

  • Pour l'exécution de code il existe les fonctions Lambda qui peuvent être exécutées en parallèle en réponse à une demande accrue. Une autre option est Fargate, que s'intègre nativement avec d'autres services AWS tels que Amazon ECS (Elastic Container Service), AWS EKS (Elastic Kubernetes Service) pour, par exemple, des opérations avec une durée de temps d'exécution longue.
  • Pour les bases de données il existe plusieurs options : DynamoDB, une base de données de clés-valeurs et documents. Également Aurora Serverless comme base de données relationnelle avec compatibilité PostgreSQL ou MySQL.
  • S3 (Simple Storage Service) pour stocker toutes formes de fichier (objet) avec des options comme la possibilité de versionner les objets ou de publier des pages statiques web. On retrouve plusieurs modèles de stockage qui différencient le prix ou la performance.
  • AWS SQS (Simple Queue Service), un service de file d'attente de messagerie qui vous permet de découpler et mettre à l'échelle les fonctions Lambda. De l’autre côté SNS (Simple Notification Service) comme service de messagerie entièrement géré pour la communication vers des SQS, Lambda, Mail ou d’autres.
  • AWS Event Bridge, un bus d'événements sans serveur qui vous permet de créer des applications guidées par les évènements, à l'échelle, sur AWS et vos systèmes existants. 
  • AWS Step Functions, un orchestrateur visuel de flux qui permet de séquencer facilement de multiples services AWS dans les applications.              
  • API Gateway, un service entièrement géré qui permet de créer et publier facilement des points accès API.
  • AWS AppSync, un service entièrement géré qui accélère le développement des applications grâce à des API GraphQL évolutives. 
  • Amazon Cognito, un service géré par AWS qui permet d'ajouter facilement l'authentification, l'autorisation et la gestion des utilisateurs à vos applications.
  • et bien d'autres encore !

Pour configurer un environnement Serverless, on peut utiliser Cloud Formation, un service IaC (Infrastructure as Code). Cloud Formation offre plusieurs options pour créer le template d’environnement :

  • Par l’interface Web, qui contient aussi une interface visuelle des composants
  • Par SAM un outil de commande avec un fichier yaml (template.yaml) qu'on peut inclure dans un dépôt GIT. 
  • Par CDK (Cloud Development Kit) pour décrire les composants en language de programmation comme par exemple TypeScript / Java ou autres.


Dans la mesure où l'infrastructure est conçue sous forme de code, le déploiement de la configuration est précédé par une étape de validation. Le système est capable de détecter les modifications qui ont déjà été appliquées et de résumer les actions à entreprendre. Lorsque la configuration est validée, elle est par conséquent mise en application.

Par ailleurs, si une application n'est plus en usage, la configuration sert à identifier et à désinstaller les composants concernés.

FaaS

Les fonctions en tant que Service (FaaS) sont au cœur du paradigme Serverless, offrant une approche granulaire du développement. Les différents fournisseurs cloud offrent leurs solutions, comme AWS Lambda, Azure Functions et Google Cloud Functions.

Il existe aussi des solutions en dehors des fournisseurs cloud, comme par exemple Kubernetes Knative ou côté open source avec Apache OpenWhisk. Cependant, ils doivent doivent être intégrés et maintenus par les propres ressources de l’entreprise.

Sur AWS, les fonctions Lambda n’ont qu’un seul facteur paramétrable pour l'exécution. Celui-ci est la capacité de mémoire entre 128 MB et 10,240 MB. La CPU est proportionnelle à la mémoire mise à disposition. 

Le prix d’une exécution Lambda est donc composé par la mémoire configurée et la dureté de l'exécution de la tâche. La dureté contient aussi la partie démarrage de l'environnement (cold start) dans la partie facturée. Le choix d'un langage de développement pourrait avoir un impact sur les coûts, mais aussi sur le temps de réponse. 

Actuellement, il existe des projets en cours pour réduire ce temps de réponse, comme pour Javascript d' AWS le projet LLRT (Low Latency Runtime) ou Java le projet CraC (Coordinated Restore at Checkpoint). Une fois l'exécution terminée, la fonction peut reprendre une exécution suivante (warm start), pour réduire les coûts. La thématique démarrage et traitement des opérations parallèles est un point à évaluer et suivre pour les différents cas d'implémentation.

Les fonctions Serverless sont conçues pour être sans état, favorisant la scalabilité et la distribution transparente des charges de travail sur plusieurs exécutions de Lambda.

Une limitation significative des Fonctions-as-a-Service (FaaS) réside dans la restriction de la durée d'exécution. Par exemple, sur AWS, la durée d'une exécution Lambda est plafonnée à 15 minutes. Lorsqu'un service requiert une durée d'exécution supérieure, il est possible de se tourner vers des alternatives telles qu'AWS Fargate ou EC2, selon l'option la mieux adaptée au contexte spécifique.

Architecture

Jusqu'à présent, nous avons principalement examiné les aspects techniques. Il convient de noter que les composants ne sont activés qu'en réponse à un événement, ce qui fait de l'architecture événementielle un pilier fondamental du modèle Serverless. Des exemples de tels événements incluent une modification dans une base de données, un message dans une file d'attente ou une requête adressée à une passerelle API. En résumé, cette approche privilégie un environnement orienté vers la réactivité aux événements, comme le souligne le Manifeste Réactif.

  • Réactivité : Les systèmes réactifs sont conçus pour répondre de manière rapide, robuste et résiliante aux changements et aux demandes du système.
  • Évolutivité : Les applications réactives peuvent facilement évoluer pour gérer de manière transparente les variations de charge de travail en utilisant des ressources de manière efficiente.
  • Résilience : La résilience constitue l'essence même des systèmes réactifs, assurant leur capacité à se rétablir promptement face aux erreurs, défaillances et situations inattendues.
  • Orienté Message : Les systèmes réactifs sont orientés message, favorisant la communication asynchrone entre les composants, ce qui contribue à une architecture plus souple et distribuée.

Pour orchestrer des workflows, il est également possible de recourir aux Step Functions d'AWS. Cette solution facilite l'implémentation de branchements conditionnels et la gestion des erreurs. Les Step Functions peuvent également contribuer à minimiser les coûts liés aux temps d'attente et à contourner la contrainte de 15 minutes imposée aux fonctions Lambda, en particulier lorsque l'exécution du code implique des périodes d'attente, en transférant ces étapes via une Step Function.

Un autre élément lié à l'architecture Serverless est Domain Driven Design (DDD). Dans l'approche de la stratégie "diviser pour mieux régner", l'application est décomposée en une architecture qui reflète le domaine d'activité à travers différents secteurs spécifiques, et des fonctions sont appliquées à chaque aspect particulier du problème. Le défi réside dans la capacité à maintenir un équilibre optimal, étant donné que le nombre d'appels aux composants a également un impact sur les coûts, notamment en raison des charges associées au démarrage des fonctions.

Simple cas d'implémentation

Voici un exemple illustrant la conversion de l'application Todo, mentionnée dans l'article (Explorer l'innovation Rust et WebAssembly), en une architecture Serverless. Le code a été modifié afin de permettre l'envoi de requêtes vers des fonctions Lambda via des appels REST.

Les composants utilisé sont:

  • 1 AWS le S3 Bucket pour héberger les pages statiques web, 
  • 1 API Gateway comme point de communication pour les services
  • 5 Lambda fonctions pour représenter les services CRUD
  • 1 CloudWatch groupe de logging pour les fonctions
  • 1 DynamoDB pour enregistrer les tâches

Pour la partie IaC, j’ai repris SAM comme exemple, en décrivant l’application dans le fichier template.yaml. Voici une partie qui décrit une fonction Lambda que est attachée à un API événement get. Le code compilé est repris après le build du répertoire défini dans le bloc CodeUri, avec une configuration mémoire de 128MB.

Resources:
  TodoGetListFunction:
    Type: AWS::Serverless::Function
    Properties:
      Role: !GetAtt TodoExecutionRole.Arn
      CodeUri: target/lambda/get-todos
      MemorySize: 128
      Events:
        CatchAll:
          Type: Api
          Properties:
            Path: /
            Method: get

De la vue Cloud Formation on peut voir la configuration intégrale sous l'éditeur visuel de AWS:

À travers l'API Gateway, on identifie les points d'accès spécifiés pour l'application. Dans cet exemple, ces points d'accès sont publics, accessibles depuis le frontend mais également via des commandes curl. Étant donné que le frontend est hébergé et diffusé via un S3 Bucket, il est nécessaire de configurer également les paramètres CORS pour cette partie.

L'application est déployée par l'outil de ligne de commande, sam-cli. En exécution, les différentes actions de mise en place sont reprises dans un log d'actions :

CloudFormation events from stack operations (refresh every 5.0 seconds)
-------------------------------------------------------------------------
ResourceStatus           ResourceType             LogicalResourceId       
ResourceStatusReason
-------------------------------------------------------------------------
CREATE_COMPLETE          AWS::Logs::LogGroup      TodoLogGroup            
CREATE_COMPLETE          AWS::DynamoDB::Table     TodoDB                  
...

Finalement, quand l'application est déployée, on peut suivre dans les logs de CloudWatch les exécutions des différentes fonctions Lambda's avec aussi leur temps de facturation :

L'exemple complet est disponible sur GitHub, à l'adresse suivante : https://github.com/oxide-byte/todo-serverless. Bien qu'il s'agisse d'un exemple simplifié, il peut néanmoins inspirer des idées ou servir de point de départ pour explorer les différentes composantes.

La thématique Serverless ne fait que commencer ! Pour ma part, je considère cela comme un outil supplémentaire à inclure dans ma liste d'options à proposer comme solutions cloud. Toutefois, il convient d'évaluer son application sur une base cas par cas et de choisir cette option pour les bonnes raisons.

Dernier