Couverture de l'article Serverless : l'Imhotep de vos lambdas
Retour aux articles

L'agence

WanadevStudio

Serverless : l'Imhotep de vos lambdas

Dans un article précédent, nous vous expliquions comment fonctionnait AWS Lambda. Au delà des avantages de la technologie, on perçoit rapidement qu'il est nécessaire d'avoir une bonne organisation pour l'exploiter sur un gros projet. Serverless, le bien nommé, existe justement pour cadrer tous ça !

En un !

Serverless est un framework qui vous aide à architecturer votre projet et vos multiples fonctions. Il est écrit en Node.js mais peut faire fonctionner d'autres types de runtimes couramment utilisées. Il permet de gérer les principaux providers du marché tel que Microsoft Azure avec Functions, IBM avec Cloud Functions, Google Cloud avec Functions, Oracle avec Fn et évidemment AWS avec lambda.

Serverless ajoute de nombreuses fonctionnalités qui simplifient le test, le déploiement et la gestion des différents services qui gravitent autour de vos fonctions.

Dans la suite de cet article, je décrirais uniquement les cas d'utilisation pour AWS Lambda. Si vous utilisez un autre provider, vous constaterez surement des différences de fonctionnement.

Serverless.yml, une pepita

Le framework Serverless impose une seule chose : avoir un fichier serverless.yml à la racine du projet. Ce fichier est au cœur de la configuration. Pour le reste, libre à vous de ranger vos fonctions dans des dossiers, séparer vos classes métiers de vos utilitaires ou encore utilisez des fichiers de configuration. Serverless reste très flexible. Si vous êtes perdu, vous pouvez vous aider de cet article.

Pour commencer, installez les prérequis (Node.js et Npm) puis le framework :

$ npm install -g serverless

Vous pouvez maintenant lancer la commande d’initialisation (le script va créer un dossier avec le nom de votre projet) :

$ serverless

^ Serverless propose des services complémentaires en ligne pour monitorer et simplifier le management de vos fonctions. Cette partie est optionnelle et vous devrez répondre "non" à la question du monitoring lors de l'initialisation si vous ne souhaitez pas le mettre en place.

Définissez la base de votre configuration dans le fichier serverless.yml :

service: {{ nom de votre projet }}
provider:
  name: aws
  region: {{ zone de déploiement (ex: eu-west-3) }}
  runtime: {{ runtime (ex: nodejs12.x) }}
  memorySize: {{ taille de l'instance (ex: 256q) }}

Nous allons aussi partir d'une structure simple de projet :

![Titre_de_l_image](/uploads/documents/lambda_folders.PNG)

On retrouve évidemment votre package.json qui contiendra les dépendances de vos fonctions mais aussi une première arborescence pour ordonner vos fichiers.

Votre première fonction

Nous allons maintenant déclarer une nouvelle lambda très simplement dans nos fichiers de configuration :

hello:
    handler: src/function1.main

helloest le nom de votre fonction et le handler, le chemin vers celle-ci (comprenant le chemin fichier src/function1.js et la fonction appelée main).

Cette première fonction va juste renvoyer un 'hello' :

module.exports.main = (event, context, callback) => {
  callback(null, {
        statusCode: 500,
        body: 'hello'
      })
}

^ Il y a une notion très importante à connaitre avant de développer une fonction Lambda : le mode d'appel. Vous pouvez en effet appeler vos fonctions soit d'une manière synchrone (retour immédiat du résultat) soit en asynchrone (réponse immédiate mais traitement différé). Le code que vous écrirez sera donc différent en fonction de votre choix.

Vous pouvez maintenant déployer très simplement votre fonction avec la commande serverless ou l'alias sls :

$ serverless deploy

ou

$ serverless deploy function -f hello

Développer en local

Pouvoir développer et tester son code en local est essentiel mais pas évidemment quand son projet repose intégralement sur des solutions en ligne. Serverless propose un plugin d'exécution de votre fonction hors-ligne. Il va monter un serveur local et simuler l'environnement AWS au mieux. Au mieux car évidemment il y a de nombreuses subtilités que vous ne pourrez vérifier que sur un vrai déploiement dans le cloud.

Pour utiliser ce mode offline, il vous suffit d'installer le plugin par la commande :

$serverless plugin offline

puis pour le démarrer : serverless offline. À la fin de la commande, le serveur vous communique les urls d'accès aux fonctions.

^ Surtout ne pensez pas que si votre lambda fonctionne en local, elle marchera une fois chez AWS. Soyez vigilant !

Gestion des environnements

Pour séparer les environnements vous allez devoir utiliser le système de stage. Je recommande de le mettre en place dès le départ car comme nous l'avons vu précédemment, vous allez devoir parfois tester vos lambdas aussi lors de la phase de développement en local. On peut identifier de base trois stages : local, dev et prod.

La notion de stage (d'environnement) va vous permettre de séparer les ressources de votre projet :

stage: ${opt:stage, 'local'}

Vous pouvez maintenant l'utiliser pour isoler certaines de vos ressources ou pour différencier vos fichiers de configuration :

custom:
  config: ${file(./config/config.${opt:stage, self:provider.stage}.json)}
  DynamoTable: ${self:provider.stage}-medical-form
  SQSQueue: https://sqs.eu-west-3.amazonaws.com/xxxxxxxxxx/${self:provider.stage}-submit-form

Au déploiement, vous pouvez indiquer le stage utilisé pour le déploiement (sinon c'est celui par défaut qui est utilisé) :

$ serveless deploy --stage=prod

Accéder à vos fonctions en HTTP

Comme nous l'avons vu dans l'article précédent, une lambda est exécutée à partir d'un événement. Dans notre cas (le plus courant), nous voulons que cela se fasse par un appel HTTP. Pour cela, on va s'appuyer sur le service API Gateway qui permet de monter des urls d'API résilients, capable d'accepter des grosses charges, permettant de gérer des versions mais aussi de mettre en place un système de droit d'accès. On va donc paramétrer ce service à travers notre configuration de fonction :

hello:
    handler: src/function1.main
    events:
      - http:
          path: hello/{id}
          method: GET
          cors: true

La route sera donc ici hello/ avec un paramètre {id}. On précise la méthode d'accès (GET/POST/PUT...) et si l'on autorise les CORS (Cross-origin resource sharing). L'URL complète est affichée en fin de déploiement dans votre shell et prend automatique comme paramètre le stage :

https://{id}.execute-api.{region aws}.amazonaws.com/{stage}/hello/{id}

^ Si vous avez besoin d'appeler votre fonction depuis un autre domaine, activer les CORS dans l'API Gateway ne suffit pas ! Vous devez aussi le faire dans votre code.

Autorisations, erreurs

Comme l'écosystème d'AWS est fermé, vous serez surement amené à utiliser d'autres ressources AWS. Par défaut, elles sont inaccessibles sans une configuration des droits d'accès. Pas besoin d'aller trifouiller dans la console AWS, Serverless vous permet de le faire directement. Pour cela vous devez identifier les ARN de vos ressources mais aussi les droits nécessaires (on évite le droit propriétaire !).

iamRoleStatements:
    - Effect: "Allow"
      Action:
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
      Resource:
        - "arn:aws:dynamodb:eu-west-3:xxxxxxx:table/dev-xxxxx"
        - "arn:aws:dynamodb:eu-west-3:xxxxxxx:table/prod-xxxxx"
    - Effect: "Allow"
      Action:
        - ses:SendEmail 
        - ses:SendRawEmail
      Resource:
        - "*"

Vous pouvez consulter vos logs d'une de vos fonctions grâce à la commande :

$ sls logs -f hello

Authorizer

Comme il est parfois nécessaire de rajouter une couche d’authentifications à vos lambdas, vous devrez alors passer par Authorizer. Pour vous éviter de configurer vous-même cette partie, serverless est encore là pour ça !

authentification:
    handler: src/AuthentificationHandler.post
    events:
      - http:
          path: authentification
          method: post
hello:
    handler: src/function1.get
    events:
      - http:
          path: hello
          method: get
          authorizer: authorizerJWT

authorizerJWT:
    handler: src/AuthorizerHandler.handler
    environment:
      AUTH_PUBLIC_KEY: ${self:custom.public_key}
      AUTH_EXPIRES_IN: ${self:custom.config.AUTH_EXPIRES_IN}

Le principe est simple : Une fonction d'authentification (authentification) va vérifier les informations de connexion et générer un token. Ensuite la fonction authorizer (authorizerJWT) va contrôler devant chacune de vos fonctions que le token est toujours valide.

Prendre de la hauteur

Serverless est l'outil incontournable pour mettre en place des FaaS. Simple et pratique à utiliser, il vous donne toute la flexibilité pour travailler comme bon vous semble. Toutefois, il est encore plus facile à utiliser si vous restez sur du langage node.js.

Il y a plein d'autres choses à découvrir sur Serverless et le projet bénéficie d'une communauté active.De nombreux exemples ont été mis à disposition pour vous aider dans vos implémentations. Je vous conseille très fortement de les consulter.

Commentaires

Il n'y a actuellement aucun commentaire. Soyez le premier !

  • Couverture de l'article Event Bus : Le secret d'une architecture Symfony réellement découplée
    Event Bus : Le secret d'une architecture Symfony réellement découplée

    Il y a 3 semaines

    Imaginez : votre utilisateur clique sur "Commander". En coulisses, le domaine Stock doit décrémenter les quantités, le domaine Facturation doit générer une facture, et le domaine Notification doit envoyer un email de confirmation. Trois domaines, une seule action... et un spaghetti de dépendances en perspective. 🍝

    Et si ces domaines pouvaient collaborer sans jamais se connaître ?

    C'est exactement ce que permet l'Event Bus. Mais avant de foncer tête baissée, une question se pose : Symfony propose déjà l'EventDispatcher pour gérer les événements. Alors pourquoi introduire un nouveau concept ?

    Spoiler : ce ne sont pas les mêmes outils, et les confondre peut vous coûter cher.

    Dans cet article, nous allons démystifier leurs différences et découvrir comment l'Event Bus de Symfony Messenger vous permet de construire une architecture réellement découplée.

    Ce que vous allez apprendre :

    • Les différences fondamentales entre EventDispatcher et Event Bus
    • Quand utiliser l'un plutôt que l'autre
    • Comment configurer un Event Bus avec Symfony Messenger
    • Créer une architecture événementielle découplée
  • Couverture de l'article CQRS avec Symfony Messenger : Domptez la complexité de vos applications
    CQRS avec Symfony Messenger : Domptez la complexité de vos applications

    Il y a 1 mois

    Vous êtes-vous déjà retrouvé face à un controller Symfony surchargé qui gère à la fois la validation, la logique métier, la persistence et les réponses HTTP ? Si oui, le CQRS est fait pour vous !

    Le CQRS (Command Query Responsibility Segregation) est un pattern architectural qui sépare clairement les opérations d'écriture (Commands) et de lecture (Queries). Combiné avec Symfony Messenger, il vous permet de :

    • Organiser votre code de manière claire et maintenable
    • Séparer les responsabilités pour respecter les principes SOLID
    • Valider vos données avant même qu'elles n'atteignent votre logique métier
    • Gérer les transactions de base de données de manière élégante
    • Préparer votre application pour l'asynchrone sans effort

    Dans cet article, nous allons explorer les Commands (écriture) et les Queries (lecture) à travers un exemple concret de gestion de bibliothèque.

  • Couverture de l'article LockPass : automatiser la sauvegarde des mots de passe
    LockPass : automatiser la sauvegarde des mots de passe
    Développement

    Il y a 3 mois

    Chez Wanadev, on a récemment changé de gestionnaire de mot de passe. On est passés de la solution états-unienne Zoho Vault à LockPass, édité par l'entreprise française LockSelf.

    Aussi fiable que puisse être le prestataire choisi, il est essentiel pour nous d'avoir une sauvegarde de nos mots de passe en dehors de chez lui pour ne pas nous retrouver dans la panade le jour où il y a un souci.

  • Couverture de l'article Figma Make : enfin une passerelle prometteuse entre design et code grâce à l'IA
    Figma Make : enfin une passerelle prometteuse entre design et code grâce à l'IA

    Il y a 8 mois

    Depuis quelques années, les outils d'IA pour générer des intégrations d'interfaces à partir de maquettes fleurissent. On en a testé plusieurs chez WanadevDigital : de Locofy à Uizard, en passant par Framer AI. Tous ont leurs qualités, mais jusqu’ici, il manquait un vrai pont stable entre les intentions du designer et la réalité du code front.

    L’arrivée de Figma Make change la donne. Et si je devais résumer son impact en une phrase : ça fonctionne, et ça fonctionne pour tout le monde, designers, développeurs et intégrateurs !

  • Couverture de l'article Maîtriser la traduction (i18n) dans un projet web - Partie 1 : Configurer proprement
    Maîtriser la traduction (i18n) dans un projet web - Partie 1 : Configurer proprement

    Il y a 11 mois

    Mettre en place l'internationalisation (i18n) dans un projet web peut sembler simple. Cependant, de nombreux projets se retrouvent avec des configurations de traduction mal gérées, difficiles à maintenir ou à faire évoluer à mesure que l'application grandit. Une stratégie i18n robuste est essentielle pour offrir une expérience utilisateur fluide dans plusieurs langues.

    Je vous décris ici, les pratiques que nous avons établies chez Wanadev au fil des années d'expérience pour mettre en œuvre et gérer les traductions dans les projets Vue. Bien que les exemples soient spécifiques à Vue, la plupart de ces pratiques peuvent être appliquées à n'importe quel framework.

  • Couverture de l'article Maîtriser la traduction (i18n) dans un projet web - Partie 2 : Conseils pour une localisation gérable et évolutive
    Maîtriser la traduction (i18n) dans un projet web - Partie 2 : Conseils pour une localisation gérable et évolutive

    Il y a 11 mois

    Dans la partie 1, nous nous sommes concentrés sur la mise en place d'une base solide pour la gestion des traductions dans un projet Vue. Maintenant que votre système de traduction est opérationnel, il est temps d'examiner de plus près comment structurer, gérer et faire évoluer vos fichiers de traduction de manière efficace.

    Cette partie couvrira les bonnes pratiques que nous utilisons chez Wanadev pour créer des clés de traduction maintenables, éviter les pièges courants et garantir que vos fichiers de traduction restent propres et évolutifs au fur et à mesure que votre projet grandit.