Exercice 07 : Créer et invoquer une fonction Lambda
🎯 Objectifs
À la fin de cet exercice, vous serez capable de :
- ✅ Créer une fonction Lambda en Python depuis la console AWS
- ✅ Invoquer la Lambda manuellement et via un événement de test
- ✅ Déclencher automatiquement la Lambda lors d'un upload S3
- ✅ Consulter les logs d'exécution dans CloudWatch Logs
Durée estimée : 35 minutes
Difficulté : ⭐⭐⭐☆☆ (Intermédiaire)
Prérequis : Exercice 05 (S3) complété, notions de Python
📖 Contexte
Lambda est le service "Functions as a Service" (FaaS) d'AWS. Vous écrivez du code, AWS l'exécute à la demande - sans gérer de serveur. Vous payez uniquement le temps d'exécution (facturation à la milliseconde). Le Free Tier offre 1 million d'invocations et 400 000 Go-secondes par mois.
Cas d'usage typiques : traitement d'images lors d'un upload, envoi d'emails, webhooks, automatisation de tâches planifiées.
📋 Énoncé
Créez une Lambda Python, déclenchez-la manuellement puis automatiquement lors d'un upload S3.
🧭 Déroulement de l'exercice
Tâche 1 : Créer la fonction Lambda
- Console AWS → Lambda → Créer une fonction
Configuration :
- Méthode : Créer à partir de rien
- Nom de la fonction :
traitement-upload - Runtime : Python 3.12
- Architecture : x86_64
- Rôle d'exécution : Créer un nouveau rôle avec autorisations Lambda de base
- Dans l'éditeur de code, remplacer le code par :
import json
import boto3
import urllib.parse
from datetime import datetime
def lambda_handler(event, context):
"""
Fonction Lambda déclenchée lors d'un upload S3.
Affiche les informations de l'objet uploadé.
"""
print(f"[{datetime.now().isoformat()}] Invocation reçue")
print(f"Événement : {json.dumps(event, indent=2)}")
# Si déclenché par S3
if 'Records' in event:
for record in event['Records']:
bucket = record['s3']['bucket']['name']
key = urllib.parse.unquote_plus(
record['s3']['object']['key'],
encoding='utf-8'
)
taille = record['s3']['object']['size']
print(f"Nouveau fichier détecté !")
print(f" Bucket : {bucket}")
print(f" Fichier : {key}")
print(f" Taille : {taille} octets")
return {
'statusCode': 200,
'body': json.dumps({
'message': f'Traitement de {len(event["Records"])} fichier(s) terminé',
'timestamp': datetime.now().isoformat()
})
}
# Invocation directe (test)
return {
'statusCode': 200,
'body': json.dumps({
'message': 'Lambda invoquée directement',
'input': event,
'timestamp': datetime.now().isoformat()
})
}- Cliquer Déployer
Tâche 2 : Invoquer manuellement avec un événement de test
- Dans la console Lambda → onglet Test → Créer un nouvel événement
- Nom :
test-direct - Template : hello-world
- JSON :
{
"nom": "Alice",
"action": "test",
"valeur": 42
}- Cliquer Tester
- Lire le résultat dans la section "Détails de l'exécution" :
- Status : Succeeded
- Durée : < 50ms
- Mémoire utilisée : < 50MB
# Via CLI
aws lambda invoke \
--function-name traitement-upload \
--payload '{"source": "cli", "action": "test"}' \
--cli-binary-format raw-in-base64-out \
response.json
cat response.jsonTâche 3 : Déclencher depuis S3
Configurer le trigger S3 :
- Console Lambda → onglet Configuration → Déclencheurs → Ajouter un déclencheur
- Source : S3
- Bucket : votre bucket de l'Exercice 05
- Types d'événements : PUT (upload de fichier)
- Préfixe :
uploads/(ne déclencher que pour les fichiers dans ce dossier) - Confirmer → Ajouter
Autoriser Lambda à accéder à S3 :
Dans la console Lambda → Configuration → Autorisations → cliquer sur le rôle d'exécution.
Ajouter la politique AmazonS3ReadOnlyAccess.
Tester le trigger :
BUCKET="devops-exercice-<votre-prenom>-2024"
# Uploader un fichier dans le dossier surveillé
echo "Fichier de test pour Lambda" > test-lambda.txt
aws s3 cp test-lambda.txt s3://$BUCKET/uploads/
# La Lambda est automatiquement déclenchée !Tâche 4 : Consulter les logs CloudWatch
# Via CLI : voir les derniers logs
aws logs describe-log-groups --query 'logGroups[?starts_with(logGroupName, `/aws/lambda/traitement`)].logGroupName'
# Lire les dernières entrées de log
LOG_GROUP="/aws/lambda/traitement-upload"
LOG_STREAM=$(aws logs describe-log-streams \
--log-group-name $LOG_GROUP \
--order-by LastEventTime \
--descending \
--limit 1 \
--query 'logStreams[0].logStreamName' \
--output text)
aws logs get-log-events \
--log-group-name $LOG_GROUP \
--log-stream-name "$LOG_STREAM" \
--query 'events[*].message' \
--output textSur la console AWS → CloudWatch → Groupes de journaux → /aws/lambda/traitement-upload
Indice : Chaque invocation Lambda crée un log stream séparé dans CloudWatch. Les logs incluent START, END et REPORT (durée, mémoire utilisée). Tout ce que vous écrivez avec
print()(Python) ouconsole.log()(Node.js) apparaît dans CloudWatch Logs.
✅ Vérification du résultat
- La Lambda répond au test manuel avec
statusCode: 200 - L'upload d'un fichier dans
s3://$BUCKET/uploads/déclenche automatiquement la Lambda - Les logs CloudWatch affichent le nom du fichier uploadé
- Le temps d'exécution est inférieur à 100ms
💡 À retenir
Modèle d'exécution Lambda :
Événement → Trigger → Lambda invoquée → Exécution → Résultat → Logs CloudWatch
↓ ↓
(S3 upload, (print/console.log)
API Gateway,
EventBridge...)Limites importantes :
| Limite | Valeur par défaut |
|---|---|
| Timeout maximum | 15 minutes |
| Mémoire | 128 Mo - 10 Go |
| Package de déploiement | 50 Mo (zip) / 250 Mo (décompressé) |
| Accès disque temporaire | 10 Go (/tmp) |
Free Tier Lambda : 1 million d'invocations/mois et 400 000 Go-secondes/mois - toujours gratuit (pas limité aux 12 premiers mois).
✨ Solution Complète
import json
def lambda_handler(event, context):
# Toujours inclure les 2 paramètres
# event : données d'entrée (dict)
# context : infos runtime (function_name, memory_limit_in_mb, etc.)
print(f"Invoqué avec : {json.dumps(event)}")
return {
'statusCode': 200,
'body': json.dumps({'status': 'ok'})
}