Lambda

Premiers pas avec Lambda

Lambda aws est le service FaaS d’Amazon (function as a service), c’est un service d’exécution de code qui impose son environnement (taille max, durée d’exécution). Il est tarifé à l’utilisation et est le pilier des architecture serverless.

Plusieurs langages sont possible (NodeJS, python, Go, Java, Ruby), l’aspect évenementiel de NodeJS me plait et je l’ai donc choisi pour débuter ici, mais n’hésitez pas à utiliser votre langage preféré car l’adaptation sera triviale pour vous.

A noter que Rust (pas dispo nativement) semble se démarquer du lot niveau légèreté et donc performance, et qui dit rapide dit moins cher avec du FaaS.

Pour suivre ce tutoriel il vous faut d’abord un compte AWS, je vous invite à le créer si ce n’est pas le cas. Nous utiliserons ici uniquement la console web (clicouille).

Vous pouvez utiliser Lambda sans compte AWS depuis un hébergement Netlify en quelques clics, c’est très pratique mais je le trouve un peu réducteur car l’intérêt pour le sysadmin est surtout de pouvoir s’interconnecter avec les différents services AWS (Cloudwatch, ELB, API Gateway, Alexa, Step Functions, etc).

Nous allons faire ici quelque chose de useless mais intéressant quand même, à savoir une simple API Rest avec un GET qui retourne des informations sur notre adresse IP publique.

Création de notre fonction Lambda

Dans vos services Amazon sélectionnez Lambda dans la catégorie Calcul puis cliquez sur créer une fonction.

Sélectionnez “créer à partir de zéro”, nous allons la nommer monIP, choisir Node.js 8.10 pour l’exécution et sélectionner le rôle existant lambda_basic_execution. Cliquez maintenant sur “Créer une fonction”.

Sur la nouvelle page vous pouvez visualiser le code de la fonction, normalement il est pré-remplis, on va d’abord le laisser comme ça tester son exécution sans risque d’erreur.

La page vous propose d’ajouter différents déclencheurs, nous n’allons en sélectionner aucun pour l’instant nous y reviendrons plus tard.

Test de notre fonction Lambda

Tout simple : cliquez sur “Tester”, vous aller pouvoir simuler l’évenement de votre choix, prenez celui qui vous plait le plus, par exemple j’ai choisi “Amazon Alexa Start Session”, pris comme nom “Alexa”, laissez le json ainsi (notez tous les arguments auxquels vous pourrez accéder plus dans votre fonction lambda) puis cliquez sur “Créer”.

Vous pouvez maintenant lancer le test, recliquez sur “Tester” et vous aurez le résultat de votre test en détail. Notez bien que vous avez la durée d’exécution et la durée facturée qui est mentionné, dans mon cas 11ms de durée d’exécution pour 100ms facturé, c’est bien arrondi au dessus ! 😩

Maintenant relancez encore une fois le même test, et comparez la durée d’exécution. Dans mon cas j’ai le deuxième coup 0.53ms et toujours 100ms de facturé.

Pourquoi ? C’est le démarrage à froid, la première fois notre applicatif est chargé en mémoire ce qui prend environ 10ms, la deuxième fois il est déjà chargé. Attention il ne reste pas en mémoire bien longtemps le démarrage à froid restera donc dans bien des cas un problème pour la réactivité de votre fonction Lambda. Notez que la durée de démarrage à froid n’est pas facturée.

Déploiement de notre fonction Lambda à travers une API

Pour tester notre fonction Lambda depuis l’extérieur nous allons devoir maintenant l’associer à un déclencheur, pour commencer on va la connecter au service Amazon “API Gateway”.

Choisissez “Créer une API”, sélectionnez REST - Nouvelle API et précisez le nom de l’API dans notre cas “monIP” avec un point d’extrémité régional (permettra un accès public, le Edge est une optimisation via les points de connexion optimisés basé sur Cloudfront inutile dans notre cas).

Maintenant que votre API est définie vous pouvez l’alimenter avec une méthode d’accès que l’on va connecter à notre fonction Lambda : Ressources -> Action -> Créer une méthode “GET”.

Type d’intégration vous choisissez bien sûr “Fonction Lambda” puis saisissez le nom de votre fonction Lambda “monIP”, laissez désactivé “Utilisez une intégration proxy Lambda”.

Maintenant il ne vous reste plus qu’a déployé l’API, pour ce faire cliquez sur “action” et sélectionnez “deploy”, créez votre étape, par exemple test et déployez votre code, vous aurez alors enfin une URL externe pour pouvoir tester votre fonction Lambda :

1
2
curl https://XXXXXXXXXXX.execute-api.eu-west-3.amazonaws.com/test
{"statusCode":200,"body":"\"Hello from Lambda!\""}

Et voilà 💪, nous avons enfin notre Hello world remarquez que finalement tout ça était plutôt intuitif mais maintenant que l’essentiel est fait on va enfin pouvoir s’amuser un peu. 😁

Récupérer l’ip utilisé pour contacter API Gateway

Voici toutes les variables de contexte disponible pour API Gateway : Doc AWS

Nous ce qui nous intéresse c’est ceci :

1
2
3
$context.identity.sourceIp 	

The source IP address of the TCP connection making the request to API Gateway.

Super exactement ce qu’il nous faut ! Cependant tous ces paramètres, propres au contexte d’API Gateway, ne sont pas transmis à la fonction Lambda, et le contexte de la fonction Lambda se limite à celle ci : durée d’exécution, arn de la fonction, etc.

Correctif

En fait si on coche l’option “Utiliser une intégration proxy Lambda” on pourra accéder au contexte de la requête via la variable env

Pour cela nous allons un modèle de mappage dans la section “demande d’intégration” de notre fonction Lambda, créez y un modèle avec le contenu json suivant :

1
2
3
{
"source_ip" : "$context.identity.sourceIp"
}

Enregistrez et allons maintenant modifier notre fonction Lambda ainsi :

1
2
3
4
5
6
7
exports.handler = async (event) => {
console.log('Source IP' + event.source_ip);
const response = {
ip: `${event.source_ip}`
};
return response;
};

Redéployer vos modifications

Maintenant pensez bien à redéployer votre méthode GET d’API Gateway et relancez votre curl de test :

1
2
curl https://XXXXXXXXXXX.execute-api.eu-west-3.amazonaws.com/test
{"ip":"90.118.158.37"}

💪

Conclusion

J’espère que ce petit tour d’horizon vous motivera à aller plus loin, n’hésitez pas à laisser vos suggestions en commentaire !

Pour aller plus loin, je vous conseille d’utiliser l’excellent framework serverless qui vous facilera la vie.

Pour la suite j’aimerai faire un example plus complet avec une utilisation de librairies NodeJS, puis une automatisation des exécutions via python sur des instances EC2, à bientôt !

Liens utile

Votre fonction Lambda avec Rust (en)
Démarrer avec aws lambda et nodejs (en)