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 :
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
hello
est 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 !