Un export peut arriver à 3h du matin, un autre à midi etc... donc planifier un job qui vérifie "est-ce que le fichier est là ?" toutes les 10 minutes, ce n'est pas optimal et peu créer du retard.
La bonne approche, c'est avoir un code qui se déclenche tout seul au moment où le fichier arrive. Sur AWS, c'est Lambda, des fonctions exécutées à l'événement, facturées à la milliseconde.
On va traiter ce classique, donc les fichiers arrivent dans une zone landing/, une Lambda vérifie chaque fichier à l'arrivée (bon format et non vide) et le range simplement dans raw/ à la bonne place, dans la partition du jour. Le contrôle d'entrée du lake, automatique.
Créer la fonction
- Ouvre le service Lambda, clique sur "Create function".
- Garde "Author from scratch", nomme-la
fn-landing-vers-raw, runtime Python 3.14. - Laisse Lambda créer un nouveau rôle d'exécution par défaut, et valide.

Le rôle créé sait juste écrire des logs, il faut lui donner accès à S3. Onglet "Configuration", puis "Permissions", clique sur le nom du rôle (ça ouvre IAM), et attache pour l'instant la policy AmazonS3FullAccess. (On la limitera plus précisément plus tard dans l'article sur IAM car un rôle ne doit pas avoir un accès full)
Le code
Onglet "Code", remplace le contenu par cette fonction. On retrouve boto3, le même SDK que dans le script de collecte, sauf que ici il tourne chez AWS.
import boto3
import urllib.parse
from datetime import date
s3 = boto3.client("s3")
def lambda_handler(event, context):
# L'événement S3 contient le bucket et le fichier qui vient d'arriver
record = event["Records"][0]
bucket = record["s3"]["bucket"]["name"]
key = urllib.parse.unquote_plus(record["s3"]["object"]["key"])
taille = record["s3"]["object"]["size"]
fichier = key.split("/")[-1] # commandes.csv
source = fichier.rsplit(".", 1)[0] # commandes
# Validation : format CSV et fichier non vide
if not fichier.endswith(".csv") or taille == 0:
print(f"REJET : {key} (taille={taille})")
return
# Rangement dans raw, dans la partition du jour
destination = f"raw/{source}/date_export={date.today().isoformat()}/{fichier}"
s3.copy_object(Bucket=bucket, CopySource={"Bucket": bucket, "Key": key}, Key=destination)
s3.delete_object(Bucket=bucket, Key=key)
print(f"OK : {key} -> {destination}")
Trois choses à noter. Le event reçu contient tout ce qu'il faut savoir sur le fichier arrivé, bucket, chemin, taille, pas besoin d'aller le chercher. Le unquote_plus gère les noms de fichiers avec espaces ou accents, un piège classique. Et la destination utilise le format date_export= de l'article partitionnement, le fichier atterrit directement dans une partition propre.
Clique sur "Deploy" pour enregistrer.

Brancher le trigger S3
- En haut du schéma de la fonction, clique sur "Add trigger".
- Source S3, sélectionne le bucket
s3/ibdata-datalake-formation. - Event type "All object create events", et surtout, Prefix :
landing/. - AWS affiche un avertissement sur la récursion, coche la case et valide.


L'avertissement est importante car une Lambda qui écrit dans le préfixe qu'elle écoute se déclenche elle-même et donc en boucle, à l'infini, et la facture suit. Dans notre cas, elle écoute landing/ et écrit dans raw/, donc pas de boucle possible.
Tester en conditions réelles
On envoie un fichier dans landing et on regarde ce qui se passe mais avant on duplique le fichier commandes.csv et le renommer simplement à commandes_lambda.csv pour tester.
aws s3 cp commandes_lambda.csv s3://ibdata-datalake-formation/landing/
# Quelques secondes plus tard, il doit être rangé dans raw
aws s3 ls s3://ibdata-datalake-formation/raw/commandes_lambda/ --recursive

Le fichier apparaît sous raw/commandes_lambda/date_export=.../ et landing est vide. Maintenant le test du rejet, un fichier vide.
#créer un fichier avec 0 oct
New-Item vide.csv -ItemType File -Force
aws s3 cp vide.csv s3://ibdata-datalake-formation/landing/
Celui-là ne doit pas bouger. Pour vérifier ce que la fonction a décidé, direction les logs. Onglet "Monitor", puis "View CloudWatch logs", ouvre le dernier log stream. Chaque print() du code est là, avec le OK du premier fichier et le REJET du second.

et si on regarde les logs dans CloudWatch

"Garde bien ce réflexe debug sur toutes les Lambda, regarder directement les logs CloudWatch car on n'a pas de console pour voir le code tourner. Et pense à bien tracer ton code avec des print pour que tout soit clair et simple à debugger.
Ce que ça coûte
Lambda est dans les services toujours gratuits du Free Tier avec 1 million d'invocations et 400 000 Go-secondes par mois. Donc nos quelques déclenchements de 200 ms ne factureront jamais rien et à mon avis c'est le service le plus généreux d'AWS.
La checklist finale
- [ ] Fonction fn-landing-vers-raw créée, rôle complété avec l'accès S3.
- [ ] Code déployé, validation + rangement en partition date_export=.
- [ ] Trigger S3 branché sur le préfixe landing/ uniquement.
- [ ] Les deux tests passés, fichier rangé dans raw, fichier vide rejeté, le tout visible dans CloudWatch.
La suite ?
Le lake se remplit et se nettoie tout seul mais il manque la pièce que les équipes BI vont réclamer un DWH pour les dashboards qlik sense ou power bi.
On va voir dans le prochain article, Redshift Serverless, le chargement depuis S3 avec COPY.
Aller plus loin
Le programme complet du parcours est sur la page de la formation AWS.
Tu prépares la certification AWS Certified Data Engineer Associate (DEA-C01) ? Lambda, les triggers S3 et CloudWatch sont des sujets qui reviennent à chaque session. Pour t'entraîner, j'ai créé des questions d'examen blanc en français.
👉 S'entraîner sur DataCertification.fr
Tu veux que je t'accompagne sur ton projet data (AWS, Snowflake, dbt, modélisation, coûts) ?
👉 Réserver un appel de 30 minutes
Questions fréquentes
C'est quoi AWS Lambda ?
Un service qui exécute du code (Python, Node.js, java etc..) en réponse à des événements, sans serveur à gérer. On paye à l'invocation et à la milliseconde d'exécution.
Comment déclencher une Lambda quand un fichier arrive dans S3 ?
En ajoutant un trigger S3 sur la fonction, avec le type d'événement (création d'objet) et un préfixe pour cibler le bon dossier. À chaque fichier déposé sous ce préfixe, S3 invoque la fonction avec les détails du fichier dans l'événement.
Pourquoi ma Lambda S3 tourne en boucle ?
Parce qu'elle écrit dans le préfixe qu'elle écoute. Chaque fichier qu'elle crée redéclenche une invocation, à l'infini. La règle, le préfixe de sortie doit toujours être différent du préfixe du trigger.
Lambda peut-il remplacer Glue pour transformer les données ?
Non. Lambda est limité à 15 minutes d'exécution et une mémoire plafonnée, il sert à réagir aux événements et à enchaîner les services. Les transformations lourdes restent le rôle de Glue et de Spark. Le duo classique, Lambda détecte l'arrivée d'un fichier et déclenche le job Glue.
Où voir les logs d'une fonction Lambda ?
Dans CloudWatch, accessible depuis l'onglet Monitor de la fonction. Chaque exécution écrit un log stream, et tous les print() du code y apparaissent. C'est le seul moyen de voir ce que la fonction a fait.
