Création d’une application sans serveur de traitement de fichiers - AWS Lambda

Création d’une application sans serveur de traitement de fichiers

L’un des cas d’utilisation les plus courants de Lambda consiste à effectuer des tâches de traitement de fichiers. Par exemple, vous pouvez utiliser une fonction Lambda pour créer automatiquement des fichiers PDF à partir de fichiers HTML ou d’images, ou pour créer des miniatures lorsqu’un utilisateur télécharge une image.

Dans cet exemple, vous créez une application qui chiffre automatiquement les fichiers PDF lorsqu’ils sont chargés dans un compartiment Amazon Simple Storage Service (Amazon S3). Pour mettre en œuvre cette application, vous créez les ressources suivantes :

  • Un compartiment S3 dans lequel les utilisateurs peuvent charger des fichiers PDF

  • Une fonction Lambda en Python qui lit le fichier téléchargé et en crée une version cryptée et protégée par mot de passe

  • Un deuxième compartiment S3 dans lequel Lambda pourra enregistrer le fichier chiffré

Vous créez également une politique AWS Identity and Access Management (IAM) pour octroyer à votre fonction Lambda l’autorisation d’effectuer des opérations de lecture et d’écriture sur vos compartiments S3.

Schéma illustrant le flux de données entre un compartiment S3, une fonction Lambda et un autre compartiment S3
Astuce

Si vous utilisez Lambda pour la première fois, nous vous recommandons de commencer avec le didacticiel Création de votre première fonction Lambda avant de créer cet exemple d’application.

Vous pouvez déployer votre application manuellement en créant et en configurant des ressources à l’aide de l’AWS Management Console ou de l’AWS Command Line Interface (AWS CLI). Vous pouvez également déployer l’application en utilisant AWS Serverless Application Model (AWS SAM). AWS SAM est un outil d’infrastructure en tant que code (IaC). Avec l’IaC, vous ne créez pas de ressources manuellement, mais vous les définissez dans le code, puis vous les déployez automatiquement.

Si vous souhaitez en savoir plus sur l’utilisation de Lambda avec l’IaC avant de déployer cet exemple d’application, consultez Utilisation de Lambda avec infrastructure en tant que code (IaC).

Créer les fichiers de code source de la fonction Lambda

Créez les fichiers suivants dans le répertoire de votre projet :

  • lambda_function.py : le code de fonction Python de la fonction Lambda qui effectue le chiffrement de fichiers

  • requirements.txt : un fichier manifeste définissant les dépendances requises par le code de votre fonction Python

Développez les sections suivantes pour afficher le code et pour en savoir plus sur le rôle de chaque fichier. Pour créer les fichiers sur votre machine locale, copiez et collez le code ci-dessous ou téléchargez les fichiers depuis le référentiel GitHub aws-lambda-developer-guide.

Copiez et collez le code suivant dans un fichier nommé lambda_function.py.

from pypdf import PdfReader, PdfWriter import uuid import os from urllib.parse import unquote_plus import boto3 # Create the S3 client to download and upload objects from S3 s3_client = boto3.client('s3') def lambda_handler(event, context): # Iterate over the S3 event object and get the key for all uploaded files for record in event['Records']: bucket = record['s3']['bucket']['name'] key = unquote_plus(record['s3']['object']['key']) # Decode the S3 object key to remove any URL-encoded characters download_path = f'/tmp/{uuid.uuid4()}.pdf' # Create a path in the Lambda tmp directory to save the file to upload_path = f'/tmp/converted-{uuid.uuid4()}.pdf' # Create another path to save the encrypted file to # If the file is a PDF, encrypt it and upload it to the destination S3 bucket if key.lower().endswith('.pdf'): s3_client.download_file(bucket, key, download_path) encrypt_pdf(download_path, upload_path) encrypted_key = add_encrypted_suffix(key) s3_client.upload_file(upload_path, f'{bucket}-encrypted', encrypted_key) # Define the function to encrypt the PDF file with a password def encrypt_pdf(file_path, encrypted_file_path): reader = PdfReader(file_path) writer = PdfWriter() for page in reader.pages: writer.add_page(page) # Add a password to the new PDF writer.encrypt("my-secret-password") # Save the new PDF to a file with open(encrypted_file_path, "wb") as file: writer.write(file) # Define a function to add a suffix to the original filename after encryption def add_encrypted_suffix(original_key): filename, extension = original_key.rsplit('.', 1) return f'{filename}_encrypted.{extension}'
Note

Dans cet exemple de code, un mot de passe pour le fichier chiffré (my-secret-password) est codé en dur dans le code de fonction. Dans une application de production, n’incluez pas d’informations sensibles telles que des mots de passe dans votre code de fonction. Créez plutôt un secret AWS Secrets Manager, puis utilisez l’extension Lambda AWS Parameters and Secrets pour récupérer vos informations d’identification dans votre fonction Lambda.

Le code de la fonction python contient trois fonctions : la fonction de gestion que Lambda exécute lorsque votre fonction est invoquée, et deux fonctions distinctes nommées add_encrypted_suffix et encrypt_pdf que le gestionnaire appelle pour effectuer le chiffrement du PDF.

Lorsque votre fonction est invoquée par Amazon S3, Lambda transmet un argument d’événement au format JSON à la fonction contenant des informations sur l’événement à l’origine de l’invocation. Dans ce cas, les informations incluent le nom du compartiment S3 et les clés d’objet pour les fichiers téléchargés. Pour de plus amples informations sur le format de l’objet d’événement pour Amazon S3, consultez Traiter les notifications d’événements Amazon S3 avec Lambda.

Votre fonction utilise ensuite le AWS SDK pour Python (Boto3) pour télécharger les fichiers PDF spécifiés dans l’objet d’événement vers son répertoire de stockage temporaire local, avant de les chiffrer à l’aide de la bibliothèque pypdf.

Enfin, la fonction utilise le kit SDK Boto3 pour stocker le fichier chiffré dans votre compartiment de destination S3.

Copiez et collez le code suivant dans un fichier nommé requirements.txt.

boto3 pypdf

Dans cet exemple, le code de votre fonction ne comporte que deux dépendances qui ne font pas partie de la bibliothèque Python standard : le kit SDK pour Python (Boto3) et le package pypdf utilisé par la fonction pour effectuer le chiffrement du PDF.

Note

Une version du kit SDK pour Python (Boto3) est incluse dans l’environnement d’exécution Lambda, de sorte que votre code s’exécute sans ajouter Boto3 au package de déploiement de votre fonction. Toutefois, pour garder le contrôle total des dépendances de votre fonction et éviter d’éventuels problèmes de désalignement de version, la bonne pratique pour Python consiste à inclure toutes les dépendances de fonction dans le package de déploiement de votre fonction. Pour en savoir plus, veuillez consulter Dépendances d’exécution dans Python.

Déployer l’application

Vous pouvez créer et déployer les ressources pour cet exemple d’application manuellement ou à l’aide d’AWS SAM. Dans un environnement de production, nous vous recommandons d’utiliser un outil d’IaC comme AWS SAM pour déployer rapidement et de manière répétitive des applications complètes sans serveur sans recourir à des processus manuels.

Pour déployer votre application manuellement :

  • Créez les compartiments Amazon S3 source et destination

  • Créez une fonction Lambda qui chiffre un fichier PDF et enregistre la version chiffrée dans un compartiment S3

  • Configurez un déclencheur Lambda qui invoque votre fonction lorsque des objets sont chargés dans votre compartiment source

Avant de commencer, assurez-vous que Python est installé sur votre machine de génération.

Création de deux compartiments S3

Créez deux compartiments S3. Le premier compartiment est le compartiment source dans lequel vous allez charger vos fichiers PDF. Le second compartiment est utilisé par Lambda pour enregistrer les fichiers chiffrés lorsque vous invoquez votre fonction.

Console
Pour créer les compartiments S3 (console)
  1. Ouvrez la page Compartiments à usage général de la console Amazon S3.

  2. Sélectionnez la Région AWS la plus proche de votre emplacement géographique. Vous pouvez modifier votre région à l’aide de la liste déroulante en haut de l’écran.

    Image montrant le menu déroulant des régions dans la console S3
  3. Choisissez Create bucket (Créer un compartiment).

  4. Sous Configuration générale, procédez comme suit :

    1. Pour le type de compartiment, veillez à sélectionner Usage général.

    2. Pour le nom du compartiment, saisissez un nom unique au monde qui respecte les règles de dénomination du compartiment Amazon S3. Les noms de compartiment peuvent contenir uniquement des lettres minuscules, des chiffres, de points (.) et des traits d’union (-).

  5. Conservez les valeurs par défaut de toutes les autres options et choisissez Créer un compartiment.

  6. Répétez les étapes 1 à 4 pour créer votre compartiment de destination. Pour Nom du compartiment, saisissez amzn-s3-demo-bucket-encrypted, où amzn-s3-demo-bucket est le nom du compartiment source que vous venez de créer.

AWS CLI

Avant de commencer, assurez-vous d’avoir installé AWS CLI sur la machine de génération.

Pour créer les compartiments Amazon S3 (AWS CLI)
  1. Exécutez la commande CLI suivante pour créer votre compartiment source. Le nom que vous choisissez pour votre compartiment doit être unique au monde et respecter les Règles de dénomination du compartiment Amazon S3. Les noms peuvent contenir uniquement des lettres minuscules, des chiffres, de points (.) et des traits d’union (-). Pour region et LocationConstraint, choisissez la Région AWS la plus proche de votre emplacement géographique.

    aws s3api create-bucket --bucket amzn-s3-demo-bucket --region us-east-2 \ --create-bucket-configuration LocationConstraint=us-east-2

    Plus loin dans le didacticiel, vous devez créer votre fonction Lambda dans la même Région AWS que votre compartiment source, notez donc bien la région que vous avez choisie.

  2. Exécutez la commande suivante pour créer votre compartiment de destination. Pour le nom du compartiment, vous devez utiliser amzn-s3-demo-bucket-encrypted, où amzn-s3-demo-bucket est le nom du compartiment source que vous avez créé à l’étape 1. Pour region et LocationConstraint, choisissez la même Région AWS que celle que vous avez utilisée pour créer votre compartiment source.

    aws s3api create-bucket --bucket amzn-s3-demo-bucket-encrypted --region us-east-2 \ --create-bucket-configuration LocationConstraint=us-east-2

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

Le rôle d’exécution est un rôle IAM qui accorde à la fonction Lambda l’autorisation d’accéder aux Services AWS et aux ressources. Pour donner à votre fonction un accès en lecture et en écriture à Amazon S3, vous attachez la politique gérée par AWS AmazonS3FullAccess.

Console
Créer un rôle IAM et l’attacher à la politique gérée par AmazonS3FullAccess (console)
  1. Ouvrez la page Roles (Rôles) dans la console IAM.

  2. Sélectionnez Créer un rôle.

  3. Pour Type d’entité approuvée, sélectionnez Service AWS, et pour Cas d’utilisation, sélectionnez Lambda.

  4. Choisissez Suivant.

  5. Ajoutez la politique gérée AmazonS3FullAccess en procédant comme suit :

    1. Dans Politiques d’autorisations, saisissez AmazonS3FullAccess dans la barre de recherche.

    2. Activez la case à cocher en regard de la stratégie.

    3. Choisissez Suivant.

  6. Dans Détails du rôle, saisissez LambdaS3Role pour Nom du rôle.

  7. Choisissez Create Role (Créer un rôle).

AWS CLI
Pour créer un rôle IAM et l’attacher à la politique gérée par AmazonS3FullAccess (AWS CLI)
  1. Enregistrez le JSON suivant dans un fichier nommé trust-policy.json. Cette politique d’approbation permet à Lambda d’utiliser les autorisations du rôle en donnant au principal de service lambda.amazonaws.com l’autorisation d’appeler l’action AWS Security Token Service (AWS STS) AssumeRole.

    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
  2. À partir du répertoire dans lequel vous avez enregistré le document de politique d’approbation JSON, exécutez la commande CLI suivante pour créer le rôle d’exécution.

    aws iam create-role --role-name LambdaS3Role --assume-role-policy-document file://trust-policy.json
  3. Pour associer la politique gérée AmazonS3FullAccess, exécutez la commande de la CLI suivante.

    aws iam attach-role-policy --role-name LambdaS3Role --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

Créer le package de déploiement de la fonction

Pour créer votre fonction, vous créez un package de déploiement contenant le code de votre fonction et ses dépendances. Pour cette application, votre code de fonction utilise une bibliothèque distincte pour le chiffrement du PDF.

Pour créer le package de déploiement
  1. Accédez au répertoire du projet contenant les fichiers lambda_function.py et requirements.txt que vous avez créés ou téléchargés depuis GitHub plus avant et créez un répertoire nommé package.

  2. Installez les dépendances spécifiées dans le fichier requirements.txt de votre répertoire package en exécutant la commande suivante.

    pip install -r requirements.txt --target ./package/
  3. Créez un fichier .zip contenant le code de votre application et ses dépendances. Sous Linux ou macOS, exécutez les commandes suivantes depuis votre interface de ligne de commande.

    cd package zip -r ../lambda_function.zip . cd .. zip lambda_function.zip lambda_function.py

    Sous Windows, utilisez l’outil zip de votre choix pour créer le fichier lambda_function.zip. Assurez-vous que votre fichier lambda_function.py et les dossiers contenant vos dépendances sont installés à la racine du fichier .zip.

Vous pouvez également créer votre package de déploiement à l’aide d’un environnement virtuel Python. Consultez Travailler avec des archives de fichiers .zip pour les fonctions Lambda Python

Créer la fonction Lambda

Vous utilisez maintenant le package de déploiement que vous avez créé à l’étape précédente pour déployer votre fonction Lambda.

Console
Pour créer une fonction (console)

Pour créer votre fonction Lambda à l’aide de la console, vous devez d’abord créer une fonction de base contenant du code « Hello world ». Vous remplacez ensuite ce code par votre propre code de fonction en chargeant le fichier .zip que vous avez créé à l’étape précédente.

Pour garantir que votre fonction n’expire pas lors du chiffrement de fichiers PDF volumineux, configurez les paramètres de mémoire et de délai d’expiration de la fonction. Définissez également le format de journal de la fonction sur JSON. La configuration de journaux au format JSON est nécessaire lors de l’utilisation du script de test fourni afin que celui-ci puisse lire l’état d’invocation de la fonction depuis CloudWatch Logs afin de confirmer la réussite de l’invocation.

  1. Ouvrez la page Functions (Fonctions) de la console Lambda.

  2. Assurez-vous que vous travaillez dans la même Région AWS que celle dans laquelle vous avez créé votre compartiment S3. Vous pouvez modifier votre région à l’aide de la liste déroulante en haut de l’écran.

    Image montrant le menu déroulant des régions dans la console Lambda
  3. Choisissez Créer une fonction.

  4. Choisissez Créer à partir de zéro.

  5. Sous Informations de base, procédez comme suit :

    1. Sous Nom de la fonction, saisissez EncryptPDF.

    2. Pour Environnement d’exécution, choisissez Python 3.12.

    3. Pour Architecture, choisissez x86_64.

  6. Associez le rôle d’exécution que vous avez créé à l’étape précédente en procédant comme suit :

    1. Développez la section Changer le rôle d’exécution par défaut.

    2. Sélectionnez Utiliser un rôle existant.

    3. Sous Rôle existant, sélectionnez votre rôle (LambdaS3Role).

  7. Choisissez Créer une fonction.

Pour charger le code de fonction (console)
  1. Dans le volet Source du code, choisissez Charger à partir de.

  2. Choisissez Fichier .zip.

  3. Choisissez Charger.

  4. Dans le sélecteur de fichiers, sélectionnez votre fichier .zip et choisissez Ouvrir.

  5. Choisissez Enregistrer.

Pour configurer la mémoire et le délai d’expiration d’une fonction (console)
  1. Sélectionnez l’onglet Configuration correspondant à votre fonction.

  2. Dans le volet de Configuration générale, choisissez Modifier.

  3. Réglez Mémoire sur 256 Mo et Délai d’expiration sur 15 secondes.

  4. Choisissez Enregistrer.

Pour configurer le format de journal (console)
  1. Sélectionnez l’onglet Configuration correspondant à votre fonction.

  2. Sélectionnez Outils de surveillance et d’exploitation.

  3. Dans le volet de configuration de la journalisation, choisissez Modifier.

  4. Pour Configuration de journalisation, sélectionnez JSON.

  5. Choisissez Enregistrer.

AWS CLI
Pour créer la fonction (AWS CLI)
  • Exécutez la commande suivante depuis le répertoire contenant votre fichier lambda_function.zip. Pour le paramètre region, remplacez us-east-2 par la région dans laquelle vous avez créé vos compartiments S3.

    aws lambda create-function --function-name EncryptPDF \ --zip-file fileb://lambda_function.zip --handler lambda_function.lambda_handler \ --runtime python3.12 --timeout 15 --memory-size 256 \ --role arn:aws:iam::123456789012:role/LambdaS3Role --region us-east-2 \ --logging-config LogFormat=JSON

Configuration d’un déclencheur Amazon S3 pour invoquer la fonction

Pour que votre fonction Lambda s’exécute lorsque vous chargez un fichier dans votre compartiment source, vous devez configurer un déclencheur pour votre fonction. Vous pouvez configurer le déclencheur Amazon S3 à l’aide de la console ou de la AWS CLI.

Important

Cette procédure configure le compartiment S3 pour qu'il invoque votre fonction chaque fois qu'un objet est créé dans le compartiment. Veillez à configurer cela uniquement pour le compartiment source. Si votre fonction Lambda crée des objets dans le même compartiment que celui qui l’invoque, votre fonction peut être invoquée en continu dans une boucle. Cela peut entraîner la facturation de frais imprévus sur votre Compte AWS.

Console
Pour configurer le déclencheur Amazon S3 (console)
  1. Ouvrez la page Fonctions de la console Lambda et choisissez votre fonction (EncryptPDF).

  2. Choisissez Add trigger (Ajouter déclencheur).

  3. Sélectionnez S3.

  4. Sous Compartiment, sélectionnez votre compartiment source.

  5. Sous Types d’événements, sélectionnez Tous les événements de création d’objets.

  6. Sous Invocation récursive, cochez la case pour confirmer qu’il n’est pas recommandé d’utiliser le même compartiment S3 pour les entrées et les sorties. Vous pouvez en savoir plus sur les modèles d’invocation récursive dans Lambda en lisant la rubrique Modèles récursifs qui provoquent des fonctions Lambda incontrôlables dans Serverless Land.

  7. Choisissez Ajouter.

    Lorsque vous créez un déclencheur à l’aide de la console Lambda, ce dernier crée automatiquement une politique basée sur une ressource pour donner au service que vous sélectionnez l’autorisation d’invoquer votre fonction.

AWS CLI
Pour configurer le déclencheur Amazon S3 (AWS CLI)
  1. Ajoutez une politique basée sur les ressources à votre fonction qui permet à votre compartiment source Amazon S3 d’invoquer votre fonction lorsque vous ajoutez un fichier. Une déclaration de politique basée sur les ressources autorise d’autres Services AWS à invoquer votre fonction. Pour autoriser Amazon S3 à invoquer votre fonction, exécutez la commande CLI suivante. Veillez à remplacer le paramètre source-account par votre propre ID de Compte AWS et à utiliser votre propre nom de compartiment source.

    aws lambda add-permission --function-name EncryptPDF \ --principal s3.amazonaws.com --statement-id s3invoke --action "lambda:InvokeFunction" \ --source-arn arn:aws:s3:::amzn-s3-demo-bucket \ --source-account 123456789012

    La politique que vous définissez à l’aide de cette commande permet à Amazon S3 d’invoquer votre fonction uniquement lorsqu’une action a lieu sur votre compartiment source.

    Note

    Bien que les noms des compartiments S3 soient globalement uniques, il est préférable de spécifier que le compartiment doit appartenir à votre compte lorsque vous utilisez des politiques basées sur les ressources. En effet, si vous supprimez un compartiment, un autre Compte AWS peut créer un compartiment avec le même Amazon Resource Name (ARN).

  2. Enregistrez le JSON suivant dans un fichier nommé notification.json. Lorsqu’il est appliqué à votre compartiment source, ce JSON configure le compartiment pour qu’il envoie une notification à votre fonction Lambda chaque fois qu’un nouvel objet est ajouté. Remplacez le numéro de Compte AWS et la Région AWS dans l’ARN de la fonction Lambda avec votre propre numéro de compte et votre région.

    { "LambdaFunctionConfigurations": [ { "Id": "EncryptPDFEventConfiguration", "LambdaFunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:EncryptPDF", "Events": [ "s3:ObjectCreated:Put" ] } ] }
  3. Exécutez la commande CLI suivante pour appliquer les paramètres de notification du fichier JSON que vous avez créé à votre compartiment source. Remplacez amzn-s3-demo-bucket par le nom de votre propre compartiment source.

    aws s3api put-bucket-notification-configuration --bucket amzn-s3-demo-bucket \ --notification-configuration file://notification.json

    Pour en savoir plus sur la commande put-bucket-notification-configuration et l’option notification-configuration, consultez la section put-bucket-notification-configuration dans la référence des commandes de la CLI AWS.

Avant de commencer, assurez-vous que Docker et la dernière version de AWS SAMCLI sont installés sur votre machine de génération.

  1. Dans le répertoire de votre projet, copiez et collez le code suivant dans un fichier nommé template.yaml. Remplacez les espaces réservés des noms des compartiments :

    • Pour le compartiment source, remplacez amzn-s3-demo-bucket par un nom conforme aux règles de dénomination des compartiments S3.

    • Pour le compartiment de destination, remplacez amzn-s3-demo-bucket-encrypted par <source-bucket-name>-encrypted, où <source-bucket> est le nom que vous avez choisi pour votre compartiment source.

    AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Resources: EncryptPDFFunction: Type: AWS::Serverless::Function Properties: FunctionName: EncryptPDF Architectures: [x86_64] CodeUri: ./ Handler: lambda_function.lambda_handler Runtime: python3.12 Timeout: 15 MemorySize: 256 LoggingConfig: LogFormat: JSON Policies: - AmazonS3FullAccess Events: S3Event: Type: S3 Properties: Bucket: !Ref PDFSourceBucket Events: s3:ObjectCreated:* PDFSourceBucket: Type: AWS::S3::Bucket Properties: BucketName: amzn-s3-demo-bucket EncryptedPDFBucket: Type: AWS::S3::Bucket Properties: BucketName: amzn-s3-demo-bucket-encrypted

    Le modèle AWS SAM définit les ressources que vous créez pour votre application. Dans cet exemple, le modèle définit une fonction Lambda utilisant le type AWS::Serverless::Function et deux compartiments S3 utilisant le type AWS::S3::Bucket. Les noms de compartiments spécifiés dans le modèle sont des espaces réservés. Avant de déployer l’application à l’aide de AWS SAM, vous devez modifier le modèle pour renommer les compartiments avec des noms uniques au niveau mondial conformes aux règles de dénomination des compartiments S3. Cette étape est expliquée plus en détail dans Déploiement des ressources à l’aide d’AWS SAM.

    La définition de la ressource de fonction Lambda configure un déclencheur pour la fonction à l’aide de la propriété d’événement S3Event. Ce déclencheur entraîne l’invocation de votre fonction chaque fois qu’un objet est créé dans votre compartiment source.

    La définition de la fonction spécifie également une politique AWS Identity and Access Management (IAM) à associer au rôle d’exécution de la fonction. La politique gérée par AWS AmazonS3FullAccess donne à votre fonction les autorisations dont elle a besoin pour lire et écrire des objets sur Amazon S3.

  2. Exécutez la commande suivante dans le répertoire où vous avez enregistré les fichiers template.yaml, lambda_function.py et requirements.txt.

    sam build --use-container

    Cette commande rassemble les artefacts de compilation pour votre application et les place dans le format et l’emplacement appropriés pour les déployer. En spécifiant l’option --use-container, vous créez votre fonction à l’intérieur d’un conteneur Docker de type Lambda. Nous l’utilisons ici, vous n’avez donc pas besoin d’installer Python 3.12 sur votre machine locale pour que la compilation fonctionne.

    Pendant le processus de génération, AWS SAM recherche le code de la fonction Lambda à l’emplacement que vous avez spécifié avec la propriété CodeUri dans le modèle. Dans ce cas, nous avons spécifié le répertoire actuel comme emplacement (./).

    Si un fichier requirements.txt est présent, AWS SAM l’utilise pour rassembler les dépendances spécifiées. Par défaut, AWS SAM crée un package de déploiement .zip avec le code de votre fonction et les dépendances. Vous pouvez également choisir de déployer votre fonction sous forme d’image de conteneur à l’aide de la propriété PackageType.

  3. Pour déployer votre application et créer les ressources Lambda, Amazon S3 et DynamoDB spécifiées dans votre modèle AWS SAM, exécutez la commande suivante.

    sam deploy --guided

    L’utilisation du drapeau --guided signifie qu’AWS SAM affiche des invites pour vous guider tout au long du processus de déploiement. Pour ce déploiement, acceptez les options par défaut en appuyant sur Entrée.

Au cours du processus de déploiement, AWS SAM crée les ressources suivantes dans votre Compte AWS :

  • Une pile CloudFormation nommée sam-app

  • Une fonction Lambda nommée EncryptPDF

  • Deux compartiments S3 portant les noms que vous avez choisis lorsque vous avez modifié le fichier modèle AWS SAM template.yaml

  • Un rôle d’exécution IAM pour votre fonction avec le format de nom sam-app-EncryptPDFFunctionRole-2qGaapHFWOQ8

Lorsque AWS SAM a fini de créer vos ressources, vous devriez voir s’afficher le message suivant :

Successfully created/updated stack - sam-app in us-east-2

Tester l'application

Pour tester votre application, chargez un fichier PDF dans votre compartiment source et vous confirmez que Lambda crée une version chiffrée du fichier dans votre compartiment de destination. Dans cet exemple, vous pouvez le tester manuellement à l’aide de la console ou de l’AWS CLI, ou en utilisant le script de test fourni.

Pour les applications de production, vous pouvez utiliser des méthodes et techniques de test traditionnelles, telles que les tests unitaires, pour confirmer le bon fonctionnement de votre code de fonction Lambda. Les pratiques exemplaires consistent également à effectuer des tests comme ceux du script de test fourni, qui réalisent des tests d’intégration avec des ressources réelles, basées sur le cloud. Les tests d’intégration dans le cloud confirment que votre infrastructure a été correctement déployée et que les événements circulent entre les différents services comme prévu. Pour en savoir plus, veuillez consulter la section Commenter tester des fonctions et des applications sans serveur.

Vous pouvez tester votre fonction manuellement en ajoutant un fichier PDF à votre compartiment source Amazon S3. Lorsque vous ajoutez votre fichier au compartiment source, votre fonction Lambda doit être automatiquement invoquée et doit stocker une version chiffrée du fichier dans votre compartiment cible.

Console
Pour tester votre application en chargeant un fichier (console)
  1. Pour charger un fichier PDF dans votre compartiment S3, procédez comme suit :

    1. Ouvrez la page Compartiments de la console Amazon S3 et choisissez votre compartiment source.

    2. Choisissez Charger.

    3. Choisissez Ajouter des fichiers et utilisez le sélecteur de fichiers pour sélectionner le fichier PDF que vous souhaitez charger.

    4. Choisissez Ouvrir, puis Charger.

  2. Vérifiez que Lambda a enregistré une version chiffrée de votre fichier PDF dans votre compartiment cible en procédant comme suit :

    1. Retournez à la page Compartiments de la console Amazon S3 et choisissez votre compartiment de destination.

    2. Dans le volet Objets, vous devriez maintenant voir un fichier au format de nom filename_encrypted.pdf (où filename.pdf était le nom du fichier que vous avez chargé dans votre compartiment source). Pour télécharger votre PDF chiffré, sélectionnez le fichier, puis choisissez Télécharger.

    3. Vérifiez que vous pouvez ouvrir le fichier téléchargé avec le mot de passe avec lequel votre fonction Lambda l’a protégé (my-secret-password).

AWS CLI
Pour tester votre application en chargeant un fichier (AWS CLI)
  1. À partir du répertoire contenant le fichier PDF que vous souhaitez charger, exécutez la commande de la CLI suivante. Remplacez le paramètre --bucket par le nom de votre compartiment source. Pour les paramètres --key et --body, utilisez le nom de fichier de votre fichier de test.

    aws s3api put-object --bucket amzn-s3-demo-bucket --key test.pdf --body ./test.pdf
  2. Vérifiez que votre fonction a créé une version chiffrée de votre fichier et l’a enregistrée dans votre compartiment S3 cible. Exécutez la commande CLI suivante, en remplaçant amzn-s3-demo-bucket-encrypted par le nom de votre compartiment de destination.

    aws s3api list-objects-v2 --bucket amzn-s3-demo-bucket-encrypted

    Si votre fonction s’exécute correctement, vous obtiendrez un résultat similaire à celui qui suit. Votre compartiment cible doit contenir un fichier au format de nom <your_test_file>_encrypted.pdf, où <your_test_file> est le nom du fichier que vous avez chargé.

    { "Contents": [ { "Key": "test_encrypted.pdf", "LastModified": "2023-06-07T00:15:50+00:00", "ETag": "\"7781a43e765a8301713f533d70968a1e\"", "Size": 2763, "StorageClass": "STANDARD" } ] }
  3. Pour télécharger le fichier que Lambda a enregistré dans votre compartiment de destination, exécutez la commande de la CLI suivante. Remplacez le paramètre --bucket par le nom de votre compartiment de destination. Pour le paramètre --key, utilisez le nom de fichier <your_test_file>_encrypted.pdf, où <your_test_file> est le nom du fichier de test que vous avez chargé.

    aws s3api get-object --bucket amzn-s3-demo-bucket-encrypted --key test_encrypted.pdf my_encrypted_file.pdf

    Cette commande télécharge le fichier dans votre répertoire actuel et l’enregistre sous my_encrypted_file.pdf.

  4. Vérifiez que vous pouvez ouvrir le fichier téléchargé avec le mot de passe avec lequel votre fonction Lambda l’a protégé (my-secret-password).

Créez les fichiers suivants dans le répertoire de votre projet :

  • test_pdf_encrypt.py : un script de test que vous pouvez utiliser pour tester automatiquement votre application

  • pytest.ini : un fichier de configuration pour le script de test

Développez les sections suivantes pour afficher le code et pour en savoir plus sur le rôle de chaque fichier.

Copiez et collez le code suivant dans un fichier nommé test_pdf_encrypt.py. Veillez à remplacer les espaces réservés de nom de compartiment :

  • Dans la fonction test_source_bucket_available, remplacez amzn-s3-demo-bucket par le nom de votre compartiment source.

  • Dans la fonction test_encrypted_file_in_bucket, remplacez amzn-s3-demo-bucket-encrypted par source-bucket-encrypted, où source-bucket> est le nom de votre compartiment source.

  • Dans la fonction cleanup, remplacez amzn-s3-demo-bucket par le nom de votre compartiment source et remplacez amzn-s3-demo-bucket-encrypted par le nom de votre compartiment source.

import boto3 import json import pytest import time import os @pytest.fixture def lambda_client(): return boto3.client('lambda') @pytest.fixture def s3_client(): return boto3.client('s3') @pytest.fixture def logs_client(): return boto3.client('logs') @pytest.fixture(scope='session') def cleanup(): # Create a new S3 client for cleanup s3_client = boto3.client('s3') yield # Cleanup code will be executed after all tests have finished # Delete test.pdf from the source bucket source_bucket = 'amzn-s3-demo-bucket' source_file_key = 'test.pdf' s3_client.delete_object(Bucket=source_bucket, Key=source_file_key) print(f"\nDeleted {source_file_key} from {source_bucket}") # Delete test_encrypted.pdf from the destination bucket destination_bucket = 'amzn-s3-demo-bucket-encrypted' destination_file_key = 'test_encrypted.pdf' s3_client.delete_object(Bucket=destination_bucket, Key=destination_file_key) print(f"Deleted {destination_file_key} from {destination_bucket}") @pytest.mark.order(1) def test_source_bucket_available(s3_client): s3_bucket_name = 'amzn-s3-demo-bucket' file_name = 'test.pdf' file_path = os.path.join(os.path.dirname(__file__), file_name) file_uploaded = False try: s3_client.upload_file(file_path, s3_bucket_name, file_name) file_uploaded = True except: print("Error: couldn't upload file") assert file_uploaded, "Could not upload file to S3 bucket" @pytest.mark.order(2) def test_lambda_invoked(logs_client): # Wait for a few seconds to make sure the logs are available time.sleep(5) # Get the latest log stream for the specified log group log_streams = logs_client.describe_log_streams( logGroupName='/aws/lambda/EncryptPDF', orderBy='LastEventTime', descending=True, limit=1 ) latest_log_stream_name = log_streams['logStreams'][0]['logStreamName'] # Retrieve the log events from the latest log stream log_events = logs_client.get_log_events( logGroupName='/aws/lambda/EncryptPDF', logStreamName=latest_log_stream_name ) success_found = False for event in log_events['events']: message = json.loads(event['message']) status = message.get('record', {}).get('status') if status == 'success': success_found = True break assert success_found, "Lambda function execution did not report 'success' status in logs." @pytest.mark.order(3) def test_encrypted_file_in_bucket(s3_client): # Specify the destination S3 bucket and the expected converted file key destination_bucket = 'amzn-s3-demo-bucket-encrypted' converted_file_key = 'test_encrypted.pdf' try: # Attempt to retrieve the metadata of the converted file from the destination S3 bucket s3_client.head_object(Bucket=destination_bucket, Key=converted_file_key) except s3_client.exceptions.ClientError as e: # If the file is not found, the test will fail pytest.fail(f"Converted file '{converted_file_key}' not found in the destination bucket: {str(e)}") def test_cleanup(cleanup): # This test uses the cleanup fixture and will be executed last pass

Le script de test automatique exécute trois fonctions de test pour confirmer le bon fonctionnement de votre application :

  • Le test test_source_bucket_available confirme que votre compartiment source a été créé avec succès en y téléchargeant un fichier PDF de test.

  • Le test test_lambda_invoked interroge le dernier flux de journaux CloudWatch Logs correspondant à votre fonction afin de confirmer que lorsque vous avez chargé le fichier de test, votre fonction Lambda s’est exécutée et a signalé un succès.

  • Le test test_encrypted_file_in_bucket confirme que votre compartiment de destination contient le fichier chiffré test_encrypted.pdf.

Une fois tous ces tests exécutés, le script exécute une étape de nettoyage supplémentaire pour supprimer les fichiers test.pdf et test_encrypted.pdf de vos compartiments source et de destination.

Comme pour le modèle AWS SAM, les noms des compartiments spécifiés dans ce fichier sont des espaces réservés. Avant d’exécuter le test, vous devez modifier ce fichier avec les noms de compartiment réels de votre application. Cette étape est expliquée plus en détail dans Test de l’application avec le script automatique.

Copiez et collez le code suivant dans un fichier nommé pytest.ini.

[pytest] markers = order: specify test execution order

Cela est nécessaire pour spécifier l’ordre dans lequel les tests du script test_pdf_encrypt.py s’exécutent.

Pour exécuter l’exemple, procédez comme suit :

  1. Assurez-vous que le module pytest est installé dans votre environnement local. Vous pouvez installer pytest en exécutant les commandes suivantes :

    pip install pytest
  2. Enregistrez un fichier PDF nommé test.pdf dans le répertoire contenant les fichiers test_pdf_encrypt.py et pytest.ini.

  3. Ouvrez un terminal ou un exécuteur shell et exécutez la commande suivante depuis le répertoire contenant les fichiers de test.

    pytest -s -v

    Lorsque le test est terminé, vous devriez obtenir un résultat semblable à celui qui suit :

    ============================================================== test session starts ========================================================= platform linux -- Python 3.12.2, pytest-7.2.2, pluggy-1.0.0 -- /usr/bin/python3 cachedir: .pytest_cache hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/home/pdf_encrypt_app/.hypothesis/examples') Test order randomisation NOT enabled. Enable with --random-order or --random-order-bucket=<bucket_type> rootdir: /home/pdf_encrypt_app, configfile: pytest.ini plugins: anyio-3.7.1, hypothesis-6.70.0, localserver-0.7.1, random-order-1.1.0 collected 4 items test_pdf_encrypt.py::test_source_bucket_available PASSED test_pdf_encrypt.py::test_lambda_invoked PASSED test_pdf_encrypt.py::test_encrypted_file_in_bucket PASSED test_pdf_encrypt.py::test_cleanup PASSED Deleted test.pdf from amzn-s3-demo-bucket Deleted test_encrypted.pdf from amzn-s3-demo-bucket-encrypted =============================================================== 4 passed in 7.32s ==========================================================

Étapes suivantes

Maintenant que vous avez créé cet exemple d’application, vous pouvez utiliser le code fourni comme base pour créer d’autres types d’applications de traitement de fichiers. Modifiez le code du fichier lambda_function.py pour mettre en œuvre la logique de traitement de fichiers adaptée à votre cas d’utilisation.

De nombreux cas d’utilisation typiques du traitement de fichiers impliquent le traitement d’image. Lorsque vous utilisez Python, les bibliothèques de traitement d’image les plus populaires telles que pillow contiennent généralement des composants C ou C++. Afin de garantir que le package de déploiement de votre fonction est compatible avec l’environnement d’exécution Lambda, il est important d’utiliser le binaire de distribution source adéquat.

Lorsque vous déployez vos ressources avec AWS SAM, vous devez prendre des mesures supplémentaires pour inclure la distribution source appropriée dans votre package de déploiement. Dans la mesure où AWS SAM n’installera pas de dépendances pour une plateforme différente de celle de votre machine de création, la spécification de la distribution source correcte (fichier .whl) dans votre fichier requirements.txt ne fonctionnera pas si votre machine de création utilise un système d’exploitation ou une architecture différente de l’environnement d’exécution Lambda. Au lieu de cela, vous devriez procéder à l’une des opérations suivantes :