View a markdown version of this page

Creare un'app di elaborazione file serverless - AWS Lambda

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Creare un'app di elaborazione file serverless

Uno dei casi d'uso più comuni di Lambda è l'esecuzione di attività di elaborazione dei file. Ad esempio, è possibile utilizzare una funzione Lambda per creare automaticamente file PDF da file o immagini HTML o per creare miniature quando un utente carica un'immagine.

In questo esempio, viene creata un'app che crittografa automaticamente i file PDF quando vengono caricati in un bucket Amazon Simple Storage Service (Amazon S3). Per creare questa app, crea le risorse seguenti:

  • Un bucket S3 in cui gli utenti possono caricare i file PDF

  • Una funzione Lambda in Python che legge il file caricato e ne crea una versione crittografata e protetta da password

  • Un secondo bucket S3 per Lambda in cui salvare il file crittografato

Crei anche una policy AWS Identity and Access Management (IAM) per autorizzare la tua funzione Lambda a eseguire operazioni di lettura e scrittura sui tuoi bucket S3.

Diagramma che mostra il flusso di dati tra un bucket S3, una funzione Lambda e un altro bucket S3.
Suggerimento

Se non conosci Lambda, ti consigliamo di iniziare con il tutorial Crea la tua prima funzione Lambda prima di creare questa app di esempio.

Puoi distribuire la tua app manualmente creando e configurando le risorse con Console di gestione AWS o the AWS Command Line Interface ().AWS CLI Puoi anche distribuire l'app utilizzando (). AWS Serverless Application Model AWS SAM AWS SAM è uno strumento Infrastructure as code (IaC). Con IaC, non crei risorse manualmente, ma le definisci in codice e poi le distribuisci automaticamente.

Se desideri saperne di più sull'utilizzo di Lambda con IaC prima di implementare questa app di esempio, consulta Utilizzo di Lambda con l'infrastructure as code (IaC).

Crea i file di codice sorgente della funzione Lambda

Create i seguenti file nella cartella del progetto:

  • lambda_function.py: il codice della funzione Python per la funzione Lambda che esegue la crittografia del database

  • requirements.txt: un file manifesto che definisce le dipendenze richieste dal codice della funzione Python

Espandi le seguenti sezioni per visualizzare il codice e per saperne di più sul ruolo di ciascun file. Per creare i file sul tuo computer locale, copia e incolla il codice seguente oppure scarica i file dal repository GitHub aws-lambda-developer-guide.

Copia e incolla il codice seguente in un nuovo file 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}'
Nota

In questo codice di esempio, una password per il file crittografato (my-secret-password) è inserita nel codice della funzione. In un'applicazione di produzione, non includere informazioni sensibili come le password nel codice funzione. Invece, crea un AWS Secrets Manager segreto e poi usa l'estensione Lambda AWS Parameters and Secrets per recuperare le tue credenziali nella tua funzione Lambda.

Il codice della funzione python contiene tre funzioni: la funzione handler che Lambda esegue quando la funzione viene richiamata e due funzioni separate denominate add_encrypted_suffix e encrypt_pdf che l'handler chiama per eseguire la crittografia del PDF.

Quando la funzione viene richiamata da Amazon S3, Lambda passa un argomento di evento in formato JSON alla funzione che contiene dettagli sull'evento che ha causato l'invocazione. In questo caso, le informazioni includono il nome del bucket S3 e le chiavi oggetto per i file caricati. Per maggiori informazioni sul formato dell'oggetto evento per Amazon S3, consulta Elaborare le notifiche di eventi Amazon S3 con Lambda.

La tua funzione utilizza quindi AWS SDK for Python (Boto3) per scaricare i file PDF specificati nell'oggetto evento nella sua directory di archiviazione temporanea locale, prima di crittografarli utilizzando la libreria pypdf. https://pypi.org/project/pypdf/

Infine, la funzione utilizza l'SDK Boto3 per archiviare il file crittografato nel bucket di destinazione S3.

Copia e incolla il codice seguente in un nuovo file requirements.txt.

boto3 pypdf

Per questo esempio, il codice della funzione ha solo due dipendenze che non fanno parte della libreria Python standard: l'SDK per Python (Boto3) e il pacchetto pypdf utilizzato dalla funzione per eseguire la crittografia PDF.

Nota

Una versione dell'SDK for Python (Boto3) è inclusa come parte del runtime Lambda, quindi il codice può essere eseguito senza aggiungere Boto3 al pacchetto di implementazione della funzione. Tuttavia, per mantenere il pieno controllo delle tue dipendenze ed evitare possibili problemi di disallineamento della versione, la best practice per Python è includere tutte le dipendenze della funzione nel pacchetto di implementazione della tua funzione. Per ulteriori informazioni, consulta Dipendenze di runtime in Python.

Distribuisci l'app

Puoi creare e distribuire le risorse per questa app di esempio manualmente o utilizzando. AWS SAM In un ambiente di produzione, ti consigliamo di utilizzare uno strumento IaC, AWS SAM ad esempio per distribuire in modo rapido e ripetibile intere applicazioni serverless senza utilizzare processi manuali.

Per distribuire la tua app manualmente:

  • Creare bucket Amazon S3 di origine e di destinazione

  • Creare una funzione Lambda che crittografa un file PDF e salva la versione crittografata in un bucket S3

  • Configurare un trigger Lambda che richiama la tua funzione quando gli oggetti vengono caricati nel bucket di origine

Prima di iniziare, assicurati che Python sia installato sulla tua macchina di compilazione.

Creare due bucket S3

Per prima cosa, crea due bucket S3. Il primo bucket è il bucket sorgente in cui carichi i tuoi file PDF. Il secondo bucket è utilizzato da Lambda per salvare il file crittografato quando richiami la tua funzione.

Console
Per creare i bucket S3 (console)
  1. Apri la pagina General Purpose buckets della console Amazon S3.

  2. Seleziona quello più Regione AWS vicino alla tua posizione geografica. Puoi modificare la regione utilizzando l'elenco a discesa nella parte superiore dello schermo.

    Immagine che mostra il menu a discesa della regione nella console S3.
  3. Scegliere Create bucket (Crea bucket).

  4. In General configuration (Configurazione generale), eseguire le operazioni seguenti:

    1. Per il tipo di secchio, assicurati che sia selezionato Uso generale.

    2. Per Nome bucket, inserisci un nome univoco globale che soddisfi le regole di denominazione dei bucket di Amazon S3. I nomi dei bucket possono contenere solo lettere minuscole, numeri, punti (.) e trattini (-).

  5. Lascia tutte le altre opzioni impostate sui valori predefiniti e scegli Crea bucket.

  6. Ripeti i passaggi da 1 a 4 per creare il bucket di destinazione. Per Nome del bucket, inserisci amzn-s3-demo-bucket-encrypted, dove amzn-s3-demo-bucket è il nome del bucket di origine che hai appena creato.

AWS CLI

Prima di iniziare, assicurati che AWS CLI sia installato sulla tua macchina di compilazione.

Per creare i bucket Amazon S3 (AWS CLI)
  1. Esegui il comando della CLI sotto riportato per creare il bucket di origine. Il nome scelto per il bucket deve essere univoco a livello globale e seguire le regole di denominazione dei bucket di Amazon S3. I nomi possono contenere solo lettere minuscole, numeri, punti (.) e trattini (-). Per region e LocationConstraint, scegli la Regione AWS più vicina alla tua posizione geografica.

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

    Più avanti nel tutorial, devi creare la tua funzione Lambda nello stesso Regione AWS bucket di origine, quindi prendi nota della regione che hai scelto.

  2. Esegui il comando sotto riportato per creare il bucket di destinazione. Per il nome del bucket, devi usare amzn-s3-demo-bucket-encrypted, dove amzn-s3-demo-bucket è il nome del bucket di origine che hai creato nel passaggio 1. Per region eLocationConstraint, scegli lo stesso Regione AWS che hai usato per creare il tuo bucket sorgente.

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

Creazione di un ruolo di esecuzione

Un ruolo di esecuzione è un ruolo IAM che concede a una funzione Lambda l'autorizzazione all'accesso Servizi AWS e alle risorse. Per concedere alla funzione l'accesso in lettura e scrittura ad Amazon S3, è necessario collegare la policy gestita da AWS AmazonS3FullAccess.

Console
Per creare un ruolo di esecuzione e allegare la policy AmazonS3FullAccess gestita (console)
  1. Aprire la pagina Roles (Ruoli) nella console IAM.

  2. Scegli Crea ruolo.

  3. Per il tipo di entità attendibile, seleziona AWS il servizio e, per Caso d'uso, seleziona Lambda.

  4. Scegli Next (Successivo).

  5. Aggiungi la policy AmazonS3FullAccess gestita procedendo come segue:

    1. In Politiche di autorizzazione, AmazonS3FullAccess accedi alla barra di ricerca.

    2. Seleziona la casella di controllo accanto alla policy.

    3. Scegli Next (Successivo).

  6. Nei dettagli del ruolo, immettere LambdaS3Role il nome del ruolo.

  7. Selezionare Crea ruolo.

AWS CLI
Per creare un ruolo di esecuzione e allegare la policy AmazonS3FullAccess gestita (AWS CLI)
  1. Salva il seguente JSON in un file denominato trust-policy.json. Questa politica di fiducia consente a Lambda di utilizzare le autorizzazioni del ruolo concedendo al responsabile del servizio il lambda.amazonaws.com permesso di chiamare l'azione Servizio di token di sicurezza AWS (AWS STS)AssumeRole.

    { "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "lambda.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
  2. Nella directory in cui hai salvato il documento della policy di attendibilità JSON, esegui il comando della CLI sotto riportato per creare il ruolo di esecuzione.

    aws iam create-role --role-name LambdaS3Role --assume-role-policy-document file://trust-policy.json
  3. Per collegare la policy gestita da AmazonS3FullAccess, esegui il comando della CLI seguente.

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

Creazione del pacchetto di implementazione della funzione

Per creare la funzione, occorre creare un pacchetto di implementazione contenente la funzione e le rispettive dipendenze. Per questa applicazione, il codice della funzione utilizza una libreria separata per la crittografia dei PDF.

Per creare il pacchetto di implementazione
  1. Passa alla directory del progetto contenente i lambda_function.py requirements.txt file che hai creato o scaricato in GitHub precedenza e crea una nuova directory denominata. package

  2. Installa le dipendenze specificate nel file requirements.txt nella tua directory package eseguendo il comando seguente.

    pip install -r requirements.txt --target ./package/
  3. Crea un file .zip contenente il codice dell'applicazione e le relative dipendenze. Su Linux o MacOS, esegui i comandi riportati di seguito dall'interfaccia della linea di comando.

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

    Su Windows, usa il tuo strumento di compressione preferito per creare il file lambda_function.zip. Assicurati che il tuo file lambda_function.py e le cartelle contenenti le tue dipendenze si trovino tutti nella directory principale del file .zip.

Puoi creare il tuo pacchetto di implementazione anche utilizzando un ambiente virtuale Python. Per informazioni, consultare Utilizzo di archivi di file .zip per le funzioni Lambda in Python.

Creazione della funzione Lambda

Ora usi il pacchetto di implementazione creato nel passaggio precedente per implementare la tua funzione Lambda.

Console
Creazione della funzione (console)

Per creare la tua funzione Lambda usando la console, devi prima creare una funzione di base contenente del codice «Hello world». Quindi, sostituisci questo codice con il codice della tua funzione caricando il file .zip creato nel passaggio precedente.

Per garantire che la funzione non scada durante la crittografia di file PDF di grandi dimensioni, configura le impostazioni di memoria e timeout della funzione. Puoi anche impostare il formato di log della funzione su JSON. La configurazione dei log in formato JSON è necessaria quando si utilizza lo script di test fornito, in modo che possa leggere lo stato di richiamo della funzione da Logs per confermare l'avvenuta invocazione. CloudWatch

  1. Aprire la pagina Funzioni della console Lambda.

  2. Assicurati di lavorare nello stesso Regione AWS ambiente in cui hai creato il bucket S3. Puoi modificare la regione utilizzando l'elenco a discesa nella parte superiore dello schermo.

    Immagine che mostra il menu a discesa della regione nella console Lambda.
  3. Selezionare Create function (Crea funzione).

  4. Scegli Author from scratch (Crea da zero).

  5. In Basic information (Informazioni di base) eseguire queste operazioni:

    1. Nel campo Function name (Nome funzione), immettere EncryptPDF.

    2. In Runtime, scegli Python 3.12.

    3. In Architecture (Architettura), scegli x86_64.

  6. Allega il ruolo di esecuzione che hai creato nel passaggio precedente procedendo come segue:

    1. Espandi la sezione Change default execution role (Cambia ruolo di esecuzione predefinito).

    2. Seleziona Utilizza un ruolo esistente.

    3. In Ruolo esistente, seleziona il tuo ruolo (LambdaS3Role).

  7. Scegli Crea funzione.

Caricamento del codice della funzione (console)
  1. Nel riquadro Origine del codice, scegli Carica da.

  2. Scegli File .zip.

  3. Scegli Carica.

  4. Nel selettore di file, seleziona il tuo file .zip e scegli Apri.

  5. Scegli Save (Salva).

Per configurare la memoria e il timeout della funzione (console)
  1. Seleziona la scheda Configurazione per la tua funzione.

  2. Nel riquadro Configurazione generale, scegli Modifica.

  3. Imposta Memoria su 256 MB e Timeout su 15 secondi.

  4. Scegli Save (Salva).

Per configurare il formato di log (console)
  1. Seleziona la scheda Configurazione per la tua funzione.

  2. Seleziona Strumenti di monitoraggio e operazioni.

  3. Nel riquadro Configurazione della registrazione, scegli Modifica.

  4. Per Configurazione della registrazione, seleziona JSON.

  5. Scegli Save (Salva).

AWS CLI
Per creare la funzione (AWS CLI)
  • Esegui il comando seguente dalla directory contenente il file lambda_function.zip. Per il parametro region, sostituisci us-east-2 con la regione in cui hai creato i bucket 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

Configurare un trigger Amazon S3 per richiamare la funzione

Affinché la funzione Lambda venga eseguita quando carichi un file nel bucket di origine, devi configurare un trigger per la funzione. È possibile configurare il trigger Amazon S3 utilizzando la console Lambda o la AWS CLI.

Importante

Questa procedura configura il bucket S3 per richiamare la funzione ogni volta che un oggetto viene creato nel bucket. Assicurati di configurare questa opzione solo sul bucket di origine. Se la tua funzione Lambda crea oggetti nello stesso bucket che la richiama, la tua funzione può essere richiamata continuamente in un ciclo ricorsivo (loop). Ciò può comportare la fatturazione di addebiti imprevisti al tuo Account AWS.

Console
Configurazione del trigger Amazon S3 (console)
  1. Apri la pagina Funzioni della console Lambda e scegli la tua funzione (EncryptPDF).

  2. Selezionare Add trigger (Aggiungi trigger).

  3. Seleziona S3.

  4. In Bucket, seleziona il tuo bucket di origine.

  5. In Tipi di eventi, seleziona Tutti gli eventi di creazione di oggetti.

  6. In Invocazione ricorsiva, seleziona la casella di controllo per confermare che non è consigliabile utilizzare lo stesso bucket S3 per input e output. Per maggiori informazioni sui modelli di invocazione ricorsivi in Lambda, consulta Schemi ricorsivi che causano loop indeterminati delle funzioni Lambda in Serverless Land.

  7. Scegliere Aggiungi.

    Quando crei un trigger utilizzando la console Lambda, Lambda crea automaticamente una policy basata sulle risorse per concedere al servizio selezionato l'autorizzazione a richiamare la funzione.

AWS CLI
Per configurare il trigger di Amazon S3 (AWS CLI)
  1. Aggiungi una policy basata sulle risorse alla tua funzione che consenta al bucket di origine di Amazon S3 di richiamare la tua funzione quando aggiungi un file. Una dichiarazione di policy basata sulle risorse fornisce altre Servizi AWS autorizzazioni per invocare la tua funzione. Per autorizzare Amazon S3 a richiamare la tua funzione, esegui il comando della CLI comando sotto riportato. Assicurati di sostituire il source-account parametro con il tuo Account AWS ID e di utilizzare il tuo nome di bucket di origine.

    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 policy che definisci con questo comando consente ad Amazon S3 di richiamare la tua funzione solo quando viene eseguita un'operazione sul tuo bucket di origine.

    Nota

    Sebbene i nomi dei bucket S3 siano univoci a livello globale, quando utilizzi policy basate sulle risorse è consigliabile specificare che il bucket deve appartenere al tuo account. Questo perché se elimini un bucket, è possibile che un altro ne Account AWS crei uno con lo stesso Amazon Resource Name (ARN).

  2. Salva il seguente JSON in un file denominato notification.json. Quando viene applicato al tuo bucket di origine, questo JSON configura il bucket in modo che invii una notifica alla funzione Lambda ogni volta che viene aggiunto un nuovo oggetto. Sostituisci il Account AWS numero e Regione AWS nella funzione Lambda ARN con il tuo numero di account e la tua regione.

    { "LambdaFunctionConfigurations": [ { "Id": "EncryptPDFEventConfiguration", "LambdaFunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:EncryptPDF", "Events": [ "s3:ObjectCreated:Put" ] } ] }
  3. Esegui il comando della CLI comando sotto riportato per applicare le impostazioni di notifica nel file JSON che hai creato al tuo bucket di origine. Sostituisci amzn-s3-demo-bucket con il nome del tuo bucket di origine.

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

    Per ulteriori informazioni sul comando put-bucket-notification-configuration e sull'opzione notification-configuration, consulta put-bucket-notification-configuration in Riferimento ai comandi di AWS CLI.

Prima di iniziare, assicurati che Docker e la versione più recente AWS SAMCLI siano installati sulla macchina di compilazione.

  1. Nella directory del progetto, copia e incolla il codice seguente in un file denominatotemplate.yaml. Sostituisci i nomi dei bucket segnaposto:

    • Per il bucket sorgente, sostituiscilo amzn-s3-demo-bucket con qualsiasi nome conforme alle regole di denominazione dei bucket S3.

    • Per il bucket di destinazione, sostituisci amzn-s3-demo-bucket-encrypted con <source-bucket-name>-encrypted, dove <source-bucket> è il nome che hai scelto per il bucket di origine.

    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

    Il AWS SAM modello definisce le risorse che crei per la tua app. In questo esempio, il modello definisce una funzione Lambda utilizzando il tipo AWS::Serverless::Function e due bucket S3 che utilizzano il tipo AWS::S3::Bucket. I nomi dei bucket specificati nel modello sono segnaposti. Prima di distribuire l'app utilizzando AWS SAM, è necessario modificare il modello per rinominare i bucket con nomi univoci a livello globale che soddisfino le regole di denominazione dei bucket S3. Questo passaggio viene spiegato ulteriormente in Distribuisci le risorse utilizzando AWS SAM.

    La definizione della risorsa della funzione Lambda configura un trigger per la funzione utilizzando la proprietà dell'evento S3Event. Questo trigger fa sì che la funzione venga richiamata ogni volta che viene creato un oggetto nel bucket di origine.

    La definizione della funzione specifica anche una policy AWS Identity and Access Management (IAM) da allegare al ruolo di esecuzione della funzione. Definizione delle autorizzazioni della funzione Lambda con un ruolo di esecuzione La policy gestita da AWS AmazonS3FullAccess fornisce alla tua funzione le autorizzazioni necessarie per leggere e scrivere oggetti su Amazon S3.

  2. Eseguire il comando seguente nella directory in cui sono stati salvati i file template.yaml, lambda_function.py e requirements.txt.

    sam build --use-container

    Questo comando raccoglie gli artefatti di compilazione per l'applicazione e li colloca nel formato e nella posizione corretti per l'implementazione. Specificando l'--use-containeropzione si crea la funzione all'interno di un Lambda-like contenitore Docker. Lo usiamo qui quindi non è necessario che Python 3.12 sia installato sul computer locale per far funzionare la build.

    Durante il processo di compilazione, AWS SAM cerca il codice della funzione Lambda nella posizione specificata con la CodeUri proprietà nel modello. In questo caso, abbiamo specificato la directory corrente come posizione (./).

    Se è presente un requirements.txt file, lo AWS SAM utilizza per raccogliere le dipendenze specificate. Per impostazione predefinita, AWS SAM crea un pacchetto di distribuzione .zip con il codice della funzione e le dipendenze. Puoi anche scegliere di distribuire la tua funzione come immagine del contenitore utilizzando la proprietà. PackageType

  3. Per distribuire l'applicazione e creare le risorse Lambda e Amazon S3 specificate nel AWS SAM modello, esegui il comando seguente.

    sam deploy --guided

    L'uso del --guided flag significa che ti AWS SAM verranno mostrate istruzioni per guidarti nel processo di distribuzione. Per questa implementazione, accetta le opzioni predefinite premendo Invio.

Durante il processo di distribuzione, AWS SAM crea le seguenti risorse nel tuo: Account AWS

  • Una CloudFormation pila denominata sam-app

  • Una funzione Lambda con il nome EncryptPDF

  • Due bucket S3 con i nomi che hai scelto quando hai modificato il file modello template.yaml AWS SAM

  • Un ruolo di esecuzione IAM per la tua funzione con il formato del nome sam-app-EncryptPDFFunctionRole-2qGaapHFWOQ8

Al AWS SAM termine della creazione delle risorse, dovresti visualizzare il seguente messaggio:

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

Esecuzione del test dell'app

Per testare la tua app, carica un file PDF nel bucket di origine e conferma che Lambda crei una versione crittografata del file nel bucket di destinazione. In questo esempio, puoi testarlo manualmente utilizzando la console o il AWS CLI, oppure utilizzando lo script di test fornito.

Per le applicazioni di produzione, puoi utilizzare metodi e tecniche di test tradizionali, come il test di unità, per confermare il corretto funzionamento del codice di funzione Lambda. La best practice consiste anche nell'eseguire test come quelli dello script di test fornito, che eseguono test di integrazione con risorse reali basate sul cloud. I test di integrazione nel cloud confermano che l'infrastruttura è stata implementata correttamente e che gli eventi fluiscono tra i diversi servizi come previsto. Per ulteriori informazioni, consulta Come eseguire test di funzioni e applicazioni serverless.

Puoi testare la tua funzione manualmente aggiungendo un file PDF al bucket di origine Amazon S3. Quando aggiungi un file al bucket di origine, la tua funzione Lambda dovrebbe essere richiamata automaticamente e dovrebbe memorizzare una versione crittografata del file nel bucket di destinazione.

Console
Per testare l'app caricando un file (console)
  1. Per caricare un file PDF nel bucket S3, procedi come segue:

    1. Apri la pagina Bucket della console Amazon S3 e scegli il bucket di origine.

    2. Scegli Carica.

    3. Scegli Aggiungi file e utilizza il selettore di file per scegliere il file PDF da caricare.

    4. Seleziona Apri, quindi Carica.

  2. Verifica che Lambda abbia salvato una versione crittografata del tuo file PDF nel bucket di destinazione effettuando le seguenti operazioni:

    1. Torna alla pagina Bucket della console Amazon S3 e scegli il bucket di destinazione.

    2. Nel riquadro Oggetti, ora dovresti vedere un file con il formato del nome filename_encrypted.pdf (dove filename.pdf era il nome del file che hai caricato nel bucket di origine). Per scaricare il PDF crittografato, seleziona il file, quindi scegli Scarica.

    3. Conferma di poter aprire il file scaricato con la password con cui la funzione Lambda lo ha protetto (my-secret-password).

AWS CLI
Per testare la tua app caricando un file (AWS CLI)
  1. Dalla directory contenente il file PDFche desideri caricare, esegui il comando della CLI sotto riportato. Sostituisci il parametro --bucket con il nome del bucket di origine. Per i parametri --key e --body, usa il nome del file di test.

    aws s3api put-object --bucket amzn-s3-demo-bucket --key test.pdf --body ./test.pdf
  2. Verifica che la funzione abbia creato una versione crittografata del file e l'abbia salvata nel bucket S3 di destinazione. Esegui il comando della CLI sotto riportato sostituendo amzn-s3-demo-bucket-encrypted con il nome del tuo bucket di destinazione.

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

    Se la funzione viene eseguita correttamente, vedrai un risultato simile al seguente. Il bucket di destinazione deve contenere un file con il formato del nome <your_test_file>_encrypted.pdf, dove <your_test_file> dov'è il nome del file che hai caricato.

    { "Contents": [ { "Key": "test_encrypted.pdf", "LastModified": "2023-06-07T00:15:50+00:00", "ETag": "\"7781a43e765a8301713f533d70968a1e\"", "Size": 2763, "StorageClass": "STANDARD" } ] }
  3. Per scaricare il file salvato da Lambda nel bucket di destinazione, esegui il comando della CLI sotto riportato. Sostituire il parametro --bucket con il nome del tuo bucket di destinazione. Per il parametro --key, usa il nome del file <your_test_file>_encrypted.pdf, dove <your_test_file> è il nome del file di test che hai caricato.

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

    Questo comando scarica il file nella directory corrente e lo salva come my_encrypted_file.pdf.

  4. Conferma di poter aprire il file scaricato con la password con cui la funzione Lambda lo ha protetto (my-secret-password).

Create i seguenti file nella cartella del progetto:

  • test_pdf_encrypt.py: uno script di test che puoi utilizzare per testare automaticamente l'applicazione

  • pytest.ini: un file di configurazione per lo script di test

Espandi le seguenti sezioni per visualizzare il codice e per saperne di più sul ruolo di ciascun file.

Copia e incolla il codice seguente in un nuovo file test_pdf_encrypt.py. Assicurati di sostituire i nomi dei bucket segnaposto:

  • Nella funzione test_source_bucket_available, sostituisci amzn-s3-demo-bucket con il nome del tuo bucket di origine.

  • Nella funzione test_encrypted_file_in_bucket, sostituisci amzn-s3-demo-bucket-encrypted con source-bucket-encrypted, dove source-bucket> è il nome del tuo bucket di origine.

  • Nella cleanup funzione, sostituisci amzn-s3-demo-bucket con il nome del bucket di origine e sostituisci amzn-s3-demo-bucket-encrypted con il nome del bucket di destinazione.

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

Lo script di test automatizzato esegue tre funzioni di test per confermare il corretto funzionamento dell'app:

  • Il test test_source_bucket_available conferma che il bucket di origine è stato creato correttamente caricando un file PDF di prova nel bucket.

  • Il test test_lambda_invoked interroga il flusso di CloudWatch log di Logs più recente per la funzione per confermare che quando hai caricato il file di test, la funzione Lambda è stata eseguita e ha riportato un esito positivo.

  • Il test test_encrypted_file_in_bucket conferma che il bucket di destinazione contiene il file crittografato test_encrypted.pdf.

Dopo l'esecuzione di tutti questi test, lo script esegue un ulteriore passaggio di pulizia per eliminare i file test.pdf e test_encrypted.pdf dai bucket di origine e di destinazione.

Come per il AWS SAM modello, i nomi dei bucket specificati in questo file sono segnaposto. Prima di eseguire il test, devi modificare questo file con i nomi reali dei bucket dell'app. Questo passaggio viene spiegato ulteriormente in Test dell'app con lo script automatico.

Copia e incolla il codice seguente in un nuovo file pytest.ini.

[pytest] markers = order: specify test execution order

È necessario per specificare l'ordine in cui vengono eseguiti i test nello script test_pdf_encrypt.py.

Per eseguire i test, procedere come segue:

  1. Assicuratevi che il pytest modulo sia installato nel vostro ambiente locale. È possibile installare pytest eseguendo il comando seguente:

    pip install pytest
  2. Salvate un file PDF denominato test.pdf nella directory contenente i pytest.ini file test_pdf_encrypt.py e.

  3. Apri un programma di terminale o di shell ed esegui il comando sotto riportato dalla directory contenente i file di test.

    pytest -s -v

    Una volta completato il test, l'output dovrebbe essere simile al seguente:

    ============================================================== 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 ==========================================================

Fasi successive

Ora che hai creato questa app di esempio, puoi utilizzare il codice fornito come base per creare altri tipi di applicazioni per l'elaborazione di file. Modifica il codice nel file lambda_function.py per implementare la logica di elaborazione dei file per il tuo caso d'uso.

Numerosi casi d'uso tipici dell'elaborazione di file riguardano l'elaborazione delle immagini. Quando si usa Python, le librerie di elaborazione delle immagini più popolari come pillow contengono in genere componenti C o C++. Per garantire che il pacchetto di distribuzione della funzione sia compatibile con l'ambiente di esecuzione Lambda, è importante utilizzare il binario di distribuzione dei sorgenti corretto.

Quando distribuisci le tue risorse con AWS SAM, devi eseguire alcuni passaggi aggiuntivi per includere la giusta distribuzione dei sorgenti nel pacchetto di distribuzione. Poiché AWS SAM non installa le dipendenze per una piattaforma diversa da quella della macchina di compilazione, specificare la corretta distribuzione dei sorgenti (.whlfile) nel requirements.txt file non funzionerà se la macchina di compilazione utilizza un sistema operativo o un'architettura diversi dall'ambiente di esecuzione Lambda. Invece, effettua una delle seguenti operazioni: