AWS Lambda : exécution en NodeJS

AWS Lambda est un service qui vous permet d’exécuter du code sans nécessiter la mise en service ni la gestion de serveurs.

Il exécute le code uniquement lorsque cela est indispensable et s’adapte automatiquement, qu’il s’agisse de quelques demandes par jour ou de milliers par seconde. Actuellement, les langages compatibles sont Node.js, Java, C#, Go et Python. Nous allons voir les différentes façons d’exécuter AWS Lambda, en NodeJS.

 

 

INSTALLATION

AWS CLI

La première chose à faire, c’est d’installer le CLI d’AWS en Python. Grâce à ce CLI, nous aurons accès à l’ensemble de l’écosystème AWS.

pip install aws-cli

AWS SDK NodeJS

Vient ensuite l’installation du SDK NodeJS, qui permet exécuter AWS dans l’ecosystème NodeJS.

npm i -g aws-sdk

Grâce à ces installations, il est désormais possible d’accéder à AWS sans problème.  

CONFIGURATION

Installer AWS ne suffit pas; il faut aussi pouvoir s’identifier avec un profil. Pour cela, vous aurez besoin de vos identifiants (Key / Secret). Une fois vos identifiants récupérés, vous avez deux possibilités :

  • Configurer AWS via la CLI, avec la commande aws configure
  • Créer les fichiers de configuration manuellement

Nous allons utiliser la deuxième possibilité. Cela est d’autant plus utile si vous avez plusieurs comptes à gérer, ainsi que des rôles différents. Voici le tuto de démarrage AWS à ce sujet, dont nous allons grandement nous inspirer.  

CREDENTIALS

Pour commencer, il vous faudra créer un fichier credentials dans le dossier. aws (qu’il faudra créer aussi), dans ce chemin :

  • Windows : C:\Users\USERNAME\.aws\credentials
  • Mac : ~/.aws/credentials

Ce fichier va pouvoir accueillir des profils d’identification. AWS a besoin au minimum d’un compte par défaut. Si vous ne spécifiez pas de profil lors de l’exécution d’une commande du SDK AWS, ce dernier ira chercher le profil par défaut. Voici à quoi ressemble le fichier credentials avec un profil par défaut, et vos identifiants.

[default]
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY

Avec ces 3 lignes, vous pouvez désormais exécuter du code via le SDK AWS. Si vous souhaitez ajouter d’autres profils, vous n’avez qu’à suivre la même procédure pour ajouter un profil dans les credentials. Par exemple, mon ficher en contient trois. Mon perso par défaut, et deux autres liés à des rôles au sein de SQLI (Comité technique et communauté Cloud).

[default]
aws_access_key_id = AKI...
aws_secret_access_key = Z/t...
[CT-CLI]
aws_access_key_id = AKI...
aws_secret_access_key = DxA...


[Cloud-CLI]
aws_access_key_id = AKI...
aws_scret_access_key = A32...

On peut ajouter que le nommage des ces profils est libre. Vous pouvez les nommer comme vous le souhaitez. Attention toutefois, car vos identifiants sont liés à des policies qui vous confèrent des droits. Si vous n’avez pas de droits sur un service particulier, vous ne pourrez pas exécuter votre code.  

CONFIGURATION

Le fichier credentials suffit à faire fonctionner le SDK d’AWS. Mais, toutes vos requêtes auront par défaut, la région us-east-1. Si vos lambdas se trouve en France, cela ne fonctionnera pas. Pour cela, vous allez créer, dans votre dossier. aws, un fichier config. Il prendra la forme du fichier credentials.

[default]
region = eu-west-1

Si, comme moi, vous avez plusieurs profils, pas de souci.

[default]
region = eu-west-1
[profile CT-CLI]
region = eu-west-1
[profile Cloud-CLI]
region = eu-west-1

Vous remarquerez une petite différence, à savoir que la déclaration de profil, est préfixé par le terme profile.  

TESTONS TOUT CELA

Maintenant que notre configuration est en place, nous allons créer un exemple de Lambda, afin de voir comment cela fonctionne.

CRÉATION DE LA LAMBDA SUR AWS

En premier lieu, rendez-vous sur l’interface Lambda depuis AWS. Créer une fonction avec Node.JS 10.X en Runtime. Une fois la lambda créée, vous devriez avoir ceci dans votre code.

exports.handler = async (event) => {
  const response = {
      statusCode: 200,
      body: JSON.stringify('Hello from Lambda!'),
  };
  return response;
};

Que devons-nous comprendre ?

  • Premièrement, le exports.handler, est le mot-clé pour l’exécution de la lambda.
  • La async (event) permet d’exécuter la lambda de manière asynchrone. Quant à l’event, il passe les informations liées au contexte de déclenchement de la lambda. Nous n’en avons pas besoin dans notre exemple.
  • La const response, est un object qui sera renvoyé dans la requête HTTP. Elle possède donc les keys nécessaires pour le bon affichage de la réponse.
  • Le return en fin de fonction renvoie donc un object pour la requête HTTP. Précisons qu’en asynchrone, on utilise le return. Par contre, quand on fait du synchrone, on utilise le callback.

CUSTOMISATION

Un peu de personnalisation pour rendre la lambda moins triste. Commençons par l’ajout d’une petite librairie, UUID, qui permettra de générer une chaîne de caractères aléatoires (utile pour créer des clés uniques). Cela sera intéressant de voir la valeur du body changer à chaque appel de Lambda. Mais avant ça, créez un projet vide, avec un package.json et un index.js (très important d’utiliser index.js, sinon, il faudra modifier le handler de la Lambda). Puis, ajoutez la libraire UUID.

npm i uuid

Une fois la librairie installée, voici le code à mettre à jour :

var uuidv1 = require('uuid/v1');
exports.handler = async (event) => {
  return {
      statusCode: 200,
      body: uuidv1()
  };
};

J’en profite au passage supprimer la constante, et placer le return directement à la construction de l’objet.  

DÉPLOIEMENT

Maintenant que notre code est prêt, il ne reste plus qu’à l’envoyer sur AWS Lambda.

  • Copiez-collez votre code, et remplacez l’ancien code de la lambda par celui-ci.
  • Faites Save, puis cliquez sur Test juste à côté.
  • Une fenêtre va s’ouvrir (la première fois), en proposant de créer un objet event. Il s’agit des infos que l’on peut faire passer dans la fonction, mais nous ne nous en servons pas dans cet exemple. Vous pouvez donc Save ce test.
  • Recliquez sur Save dans l’interface de la lambda.

Et là, patatra… Une grosse erreur en réponse. Le message d’erreur est assez clair :

{
  "errorMessage": "Error: Cannot find module 'uuid/v1'"
}

Effectivement, il manque le module UUID. Bien que nous l’ayons installé en local, à travers le dossier node_modules, il n’a pas été envoyé sur notre lambda. Il nous faut donc ajouter ce fameux dossier. Pour cela, ouvrez votre fichier package.json, et ajoutez une ligne dans la partie scripts.

"deploy": "zip -r lambda.zip index.js node_modules && aws lambda update-function-code --function-name INSERT_ARN --zip-file fileb://lambda.zip --profile INSERT PROFILE && rm lambda.zip"

Cette exécution à l’air un peu compliquée, mais pas du tout. Examinons-la.

  • zip -r lambda.zip index.js node_modules : à partir du fichier index.js et le dossier node_modules, nous allons créer un fichier ZIP
  • aws lambda update-function-code --function-name INSERT_ARN --zip-file fileb://lambda.zip --profile INSERT PROFILE : on utilise le CLI AWS pour mettre à jour la lambda, via son ARN, que vous trouverez tout en haut de la Lambda. On lui envoie notre fichier ZIP. Optionnellement, on peut lui indiquer le profile. Si vous utilisez celui par défaut, vous pouvez le supprimer.
  • rm lambda.zip : une fois la lambda envoyé, on supprime le zip local.

Maintenant, votre code devrait s’être mis à jour sur votre lambda. Si c’est le cas, refaites un test, et vérifier que votre réponse, contient bien un message comme ceci.

{
  "statusCode": 200,
  "body": "cb10e7a0-9345-11e9-b2f7-6f84d99fddc6"
}

  Voilà, vous venez de voir comment créer une lambda, la coder et la déployer. Vous également vu comment installer AWS sur votre environnement, et le configurer assez simplement.