← Retour aux tutoriels

Introduction à AWS Lambda : guide pour développeurs intermédiaires

aws lambdaserverlessawsfonctionsarchitecture événementielleiamcloudwatchdéploiement

Introduction à AWS Lambda : guide pour développeurs intermédiaires

AWS Lambda est un service serverless qui exécute du code en réponse à des événements, sans que vous ayez à provisionner ni administrer des serveurs. En tant que développeur intermédiaire, vous connaissez probablement déjà les bases (fonction, déclencheur, logs). Ce guide vise à aller plus loin : modèle d’exécution, packaging, observabilité, sécurité, performances, déploiement automatisé, et bonnes pratiques de conception.


1) Modèle mental : ce que fait réellement Lambda

1.1 Événements, invocations et cycle de vie

Une fonction Lambda est invoquée par un événement (API Gateway, SQS, EventBridge, S3, etc.). Chaque invocation s’exécute dans un environnement d’exécution isolé. Deux notions sont cruciales :

Lambda sépare conceptuellement :

Exemple (Node.js) : le client est créé hors handler pour être réutilisé lors des warm starts.

// index.mjs
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
const ddb = new DynamoDBClient({}); // initialisation (souvent une seule fois)

export const handler = async (event) => {
  // invocation
  return { ok: true, input: event };
};

1.2 Concurrence et scalabilité

Lambda scale automatiquement en créant plusieurs environnements si plusieurs invocations arrivent en parallèle. Deux paramètres influencent fortement votre architecture :

1.3 Timeout, mémoire, CPU et coût

Le coût dépend principalement :

Augmenter la mémoire peut réduire la durée, donc parfois réduire le coût total. Il faut mesurer.


2) Prérequis et configuration locale

2.1 Installer AWS CLI et configurer un profil

Installez AWS CLI v2, puis configurez vos identifiants.

aws --version
aws configure

Vous pouvez aussi utiliser des profils :

aws configure --profile dev
export AWS_PROFILE=dev
aws sts get-caller-identity

2.2 Choisir une région

export AWS_REGION=eu-west-3
aws configure set region "$AWS_REGION"

3) Créer une fonction Lambda de zéro (CLI) + rôle IAM minimal

3.1 Créer un rôle d’exécution

Une Lambda a besoin d’un rôle IAM (trust policy) permettant au service Lambda d’assumer ce rôle, et de permissions pour écrire des logs, accéder à d’autres services, etc.

Créez un fichier trust-policy.json :

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "lambda.amazonaws.com" },
      "Action": "sts:AssumeRole"
    }
  ]
}

Créez le rôle :

aws iam create-role \
  --role-name lambda-demo-role \
  --assume-role-policy-document file://trust-policy.json

Attachez la politique gérée pour CloudWatch Logs :

aws iam attach-role-policy \
  --role-name lambda-demo-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

Récupérez l’ARN du rôle :

ROLE_ARN=$(aws iam get-role --role-name lambda-demo-role --query 'Role.Arn' --output text)
echo "$ROLE_ARN"

3.2 Écrire le code et packager

Exemple Python lambda_function.py :

import json
import os
import time

def handler(event, context):
    return {
        "statusCode": 200,
        "headers": {"content-type": "application/json"},
        "body": json.dumps({
            "message": "Bonjour depuis Lambda",
            "region": os.environ.get("AWS_REGION"),
            "requestId": context.aws_request_id,
            "input": event
        })
    }

Zippez le fichier :

zip function.zip lambda_function.py

3.3 Créer la fonction

aws lambda create-function \
  --function-name lambda-demo \
  --runtime python3.12 \
  --handler lambda_function.handler \
  --zip-file fileb://function.zip \
  --role "$ROLE_ARN" \
  --timeout 10 \
  --memory-size 256

3.4 Invoquer la fonction

aws lambda invoke \
  --function-name lambda-demo \
  --payload '{"source":"cli","action":"test"}' \
  response.json

cat response.json

Afficher les logs dans CloudWatch (via AWS CLI) :

aws logs describe-log-groups --log-group-name-prefix /aws/lambda/lambda-demo
aws logs tail /aws/lambda/lambda-demo --follow

4) Variables d’environnement, configuration et secrets

4.1 Variables d’environnement

aws lambda update-function-configuration \
  --function-name lambda-demo \
  --environment "Variables={APP_ENV=dev,FEATURE_X=true}"

Dans le code, lisez os.environ (Python) ou process.env (Node.js).

4.2 Secrets : éviter de stocker des mots de passe en clair

Bonnes options :

Exemple : lire un paramètre sécurisé depuis SSM (Python, avec boto3) nécessite d’ajouter des permissions IAM (ex. ssm:GetParameter). Politique minimale (exemple) :

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ReadOneParameter",
      "Effect": "Allow",
      "Action": ["ssm:GetParameter"],
      "Resource": "arn:aws:ssm:eu-west-3:123456789012:parameter/monapp/db_password"
    }
  ]
}

Attacher une politique inline :

aws iam put-role-policy \
  --role-name lambda-demo-role \
  --policy-name lambda-ssm-read \
  --policy-document file://ssm-policy.json

5) Déclencheurs courants et implications d’architecture

5.1 API Gateway (synchrone)

Cas d’usage : API HTTP. Vous devez gérer :

Pour un flux synchrone, votre Lambda doit répondre rapidement. Si vous avez des traitements longs, préférez :

5.2 SQS (asynchrone, robuste)

SQS + Lambda est un pattern très utilisé. Lambda lit des messages par batch, et gère les retries.

Points importants :

5.3 EventBridge (événements métier)

EventBridge est idéal pour un bus d’événements. Vous publiez des événements structurés et déclenchez des règles.

Exemple d’envoi d’événement :

aws events put-events --entries '[
  {
    "Source":"monapp.commandes",
    "DetailType":"CommandeCreee",
    "Detail":"{\"commandeId\":\"c-123\",\"montant\":42.5}",
    "EventBusName":"default"
  }
]'

6) Packaging avancé : dépendances, couches et images conteneur

6.1 Zip + dépendances (Python)

Pour Python, si vous avez des dépendances, vous devez les inclure dans le zip.

mkdir -p build/python
pip install -r requirements.txt -t build/
cp lambda_function.py build/
cd build && zip -r ../function.zip .
cd ..

Attention aux dépendances natives : elles doivent être compilées pour l’environnement compatible Lambda (Amazon Linux). Souvent, on utilise Docker pour builder.

6.2 Lambda Layers (couches)

Les layers permettent de partager des bibliothèques entre plusieurs fonctions ou de séparer le code applicatif des dépendances.

Créer un layer Python :

mkdir -p layer/python
pip install requests -t layer/python
cd layer && zip -r ../requests-layer.zip .
cd ..

aws lambda publish-layer-version \
  --layer-name requests-layer \
  --zip-file fileb://requests-layer.zip \
  --compatible-runtimes python3.12

Attacher le layer à la fonction :

LAYER_ARN=$(aws lambda list-layer-versions --layer-name requests-layer --query 'LayerVersions[0].LayerVersionArn' --output text)

aws lambda update-function-configuration \
  --function-name lambda-demo \
  --layers "$LAYER_ARN"

6.3 Images conteneur

Les images conteneur sont utiles si :

Flux typique :

  1. construire une image conforme Lambda
  2. pousser sur ECR
  3. créer/mettre à jour la Lambda avec l’image

Créer un dépôt ECR :

aws ecr create-repository --repository-name lambda-demo-image

Connexion Docker à ECR :

ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
aws ecr get-login-password --region "$AWS_REGION" \
  | docker login --username AWS --password-stdin "$ACCOUNT_ID.dkr.ecr.$AWS_REGION.amazonaws.com"

7) Observabilité : logs, métriques, traces

7.1 CloudWatch Logs : structurer vos logs

Loggez en JSON pour faciliter la recherche. En Python :

import json, time

def log(level, msg, **fields):
    print(json.dumps({
        "level": level,
        "message": msg,
        "ts": int(time.time() * 1000),
        **fields
    }))

Puis :

log("INFO", "Traitement démarré", requestId=context.aws_request_id)

7.2 Métriques et alarmes

Lambda expose des métriques : Invocations, Errors, Duration, Throttles. Créez une alarme sur les erreurs :

aws cloudwatch put-metric-alarm \
  --alarm-name lambda-demo-errors \
  --metric-name Errors \
  --namespace AWS/Lambda \
  --statistic Sum \
  --period 60 \
  --threshold 1 \
  --comparison-operator GreaterThanOrEqualToThreshold \
  --evaluation-periods 1 \
  --dimensions Name=FunctionName,Value=lambda-demo \
  --treat-missing-data notBreaching

7.3 Traces avec AWS X-Ray

X-Ray aide à comprendre la latence (cold start, appels externes). Activez le tracing :

aws lambda update-function-configuration \
  --function-name lambda-demo \
  --tracing-config Mode=Active

8) Sécurité : IAM, réseau, chiffrement, moindre privilège

8.1 IAM : permissions minimales

Évitez les politiques trop larges (*). Donnez :

8.2 Accès réseau : VPC ou pas ?

Par défaut, Lambda accède à Internet si elle n’est pas dans un VPC. Si vous placez la Lambda dans un VPC pour accéder à une base privée (RDS, ElastiCache), vous devez gérer :

Mettre une Lambda dans un VPC peut augmenter la latence et complexifier l’exploitation. Ne le faites que si nécessaire.

8.3 Chiffrement


9) Performance : réduire la latence et maîtriser les coûts

9.1 Réduire les cold starts

Stratégies :

9.2 Réutiliser les connexions

Pour les bases de données, réutilisez les clients hors handler. Pour RDS, attention au nombre de connexions : le scaling de Lambda peut saturer la base. Solutions :

9.3 Ajuster mémoire et timeout

Testez plusieurs tailles mémoire et mesurez Duration. Un réglage typique consiste à :

  1. augmenter la mémoire par paliers (256, 512, 1024…)
  2. mesurer la durée p95
  3. choisir le meilleur compromis coût/latence

10) Gestion des erreurs, retries et idempotence

10.1 Différence sync vs async

10.2 Idempotence

Une fonction idempotente peut être appelée plusieurs fois avec le même événement sans effet de bord indésirable. Techniques :

Exemple de stratégie DynamoDB : “traiter une seule fois” via PutItem conditionnel.


11) Déploiement automatisé avec AWS SAM (pratique et réaliste)

AWS SAM (Serverless Application Model) simplifie la définition et le déploiement. Même si vous pouvez tout faire en CLI, SAM apporte :

11.1 Installer SAM CLI

Vérifiez :

sam --version

11.2 Initialiser un projet

sam init

Choisissez un runtime (par exemple Python) et un template “Hello World”, puis explorez la structure.

11.3 Construire et déployer

sam build
sam deploy --guided

Pendant --guided, vous définissez :

11.4 Tester localement

SAM peut émuler l’exécution via Docker :

sam local invoke

Ou lancer une API locale :

sam local start-api
curl -i http://127.0.0.1:3000/hello

12) Versioning, alias et déploiements progressifs

Lambda supporte :

Publier une version :

aws lambda publish-version --function-name lambda-demo

Créer/mettre à jour un alias :

aws lambda create-alias \
  --function-name lambda-demo \
  --name prod \
  --function-version 1

aws lambda update-alias \
  --function-name lambda-demo \
  --name prod \
  --function-version 2

Cette approche est essentielle pour :


13) Bonnes pratiques de conception (retour d’expérience)

13.1 Fonctions petites, responsabilités claires

Évitez la “Lambda monolithe” qui fait tout. Préférez :

13.2 Schémas et validation

Validez les entrées (API ou événements). Sans validation, les erreurs deviennent difficiles à diagnostiquer et les retries peuvent amplifier le problème.

13.3 Timeouts cohérents

13.4 Limiter les dépendances

Chaque dépendance :


14) Nettoyage des ressources (éviter les coûts inutiles)

Supprimer la fonction :

aws lambda delete-function --function-name lambda-demo

Détacher la politique et supprimer le rôle (après suppression de la fonction) :

aws iam detach-role-policy \
  --role-name lambda-demo-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

aws iam delete-role --role-name lambda-demo-role

15) Check-list finale pour une Lambda “production-ready”


Conclusion

AWS Lambda est simple à démarrer mais riche en subtilités dès qu’on vise la production : concurrence, retries, idempotence, packaging, observabilité et sécurité. En appliquant les patterns présentés (rôles IAM minimaux, logs structurés, déclencheurs adaptés, versioning/alias, et déploiement automatisé), vous obtenez des fonctions robustes, économiques et faciles à faire évoluer.

Si vous voulez, je peux proposer une architecture complète (API Gateway + SQS + Lambda + DynamoDB) avec commandes de création, politiques IAM minimales et stratégie de déploiement progressive par alias.