

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à.

# Guida introduttiva ad applicazioni e modelli di esempio
<a name="example-apps"></a>

Le seguenti risorse possono essere utilizzate per creare e distribuire rapidamente app serverless che implementano alcuni casi d'uso comuni di Lambda. Per ciascuna delle app di esempio, forniamo istruzioni per creare e configurare le risorse manualmente utilizzando o AWS Serverless Application Model per distribuire le risorse utilizzando IaC. Console di gestione AWS Segui le istruzioni della console per saperne di più sulla configurazione delle singole AWS risorse per ogni app o usale per distribuire rapidamente le risorse come faresti in un ambiente di produzione. AWS SAM 

## Elaborazione dei file
<a name="examples-apps-file"></a>
+ **[Applicazione di crittografia PDF](file-processing-app.md)**: crea un'applicazione serverless che crittografa i file PDF quando vengono caricati in un bucket Amazon Simple Storage Service e li salva in un altro bucket, utile per proteggere i documenti sensibili al momento del caricamento.
+ **[Applicazione di analisi delle immagini](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-example-s3.html)**: crea un'applicazione serverless che estrae il testo dalle immagini utilizzando Amazon Rekognition, utile per l'elaborazione di documenti, la moderazione dei contenuti e l'analisi automatizzata delle immagini.

## Integrazione del database
<a name="examples-apps-database"></a>
+ **[Queue-to-Database Applicazione](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html)**: crea un'applicazione serverless che scrive messaggi in coda su un database Amazon RDS, utile per elaborare le registrazioni degli utenti e gestire gli invii degli ordini.
+ **[Database Event Handler](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-example-ddb.html)**: crea un'applicazione serverless che risponda alle modifiche delle tabelle di Amazon DynamoDB, utile per la registrazione degli audit, la replica dei dati e i flussi di lavoro automatizzati.

## Attività pianificate
<a name="examples-apps-scheduled"></a>
+ **[Applicazione di manutenzione del database](scheduled-task-app.md)**: crea un'applicazione serverless che elimina automaticamente le voci più vecchie di 12 mesi da una tabella Amazon DynamoDB utilizzando una pianificazione cron, utile per la manutenzione automatizzata del database e la gestione del ciclo di vita dei dati.
+ **[Crea una regola EventBridge pianificata per le funzioni Lambda](https://docs.aws.amazon.com/eventbridge/latest/userguide/run-lambda-schedule.html)**: utilizza le espressioni pianificate per le regole per attivare una funzione Lambda in base EventBridge a una pianificazione temporizzata. Questo formato utilizza la sintassi cron e può essere impostato con una granularità di un minuto.

## Flussi di lavoro a lunga durata
<a name="examples-apps-workflows"></a>
+ Applicazione di **[elaborazione degli ordini: crea un'applicazione](order-processing-app.md)** serverless utilizzando Durable Functions che gestisce l'evasione degli ordini complessi, tra cui l'elaborazione dei pagamenti, i controlli dell'inventario e il coordinamento delle spedizioni. Questo esempio dimostra come creare flussi di lavoro che possono essere eseguiti per periodi prolungati mantenendo lo stato.

## Risorse aggiuntive
<a name="examples-apps-additional-resources"></a>

Utilizza le seguenti risorse per esplorare ulteriormente Lambda e lo sviluppo di applicazioni serverless:
+ **[Serverless Land](https://serverlessland.com/)**: una libreria di ready-to-use modelli per la creazione di app serverless. Aiuta gli sviluppatori a creare applicazioni più velocemente utilizzando AWS servizi come Lambda, API Gateway e. EventBridge Il sito offre soluzioni predefinite e best practice, che semplificano lo sviluppo di sistemi serverless.
+ Applicazioni di **[esempio Lambda: applicazioni](https://docs.aws.amazon.com/lambda/latest/dg/lambda-samples.html)** disponibili nell' GitHub archivio di questa guida. Questi esempi dimostrano l'uso di vari linguaggi e AWS servizi. Ogni applicazione di esempio include script per semplificare l'implementazione, la pulizia e il supporto delle risorse.
+ **[Esempi di codice per l'utilizzo di Lambda AWS SDKs](https://docs.aws.amazon.com/lambda/latest/dg/service_code_examples.html)**: esempi che mostrano come usare Lambda con i kit di sviluppo AWS software (). SDKs Questi esempi includono nozioni di base, azioni, scenari e contributi della community. AWS Gli esempi riguardano operazioni essenziali, singole funzioni di servizio e attività specifiche che utilizzano più funzioni o AWS servizi.

# Creare un'app di elaborazione file serverless
<a name="file-processing-app"></a>

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

È inoltre possibile creare una policy AWS Identity and Access Management (IAM) per consentire alla funzione Lambda di eseguire operazioni di lettura e scrittura sui bucket S3.

![\[\]](http://docs.aws.amazon.com/it_it/lambda/latest/dg/images/ExampleApps/file_process_resources.png)


**Suggerimento**  
Se non conosci Lambda, ti consigliamo di iniziare con il tutorial [Crea la tua prima funzione Lambda](getting-started.md) prima di creare questa app di esempio.

Puoi distribuire l'app manualmente creando e configurando risorse con Console di gestione AWS o il 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 vengono create risorse manualmente, ma le si definisce in codice e poi le si distribuisce 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)](foundation-iac.md).

## Creare i file del codice sorgente della funzione Lambda
<a name="file-processing-app-download"></a>

Crea i seguenti file nella directory del tuo 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 ogni file. Per creare i file sul computer locale, copia e incolla il codice seguente oppure scarica i file dal [aws-lambda-developer-guide GitHub repository](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/file-processing-python).

### Codice della funzione Python
<a name="file-processing-app-function-code"></a>

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 Gestione dei segreti AWS segreto](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html) e poi [usa l'estensione Lambda AWS Parameters and Secrets](with-secrets-manager.md) per recuperare le credenziali nella funzione Lambda.

Il codice della funzione python contiene tre funzioni: la [funzione handler](python-handler.md) 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](with-s3.md).

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

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

### File manifesto `requirements.txt`
<a name="file-processing-app-dependencies"></a>

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](python-package.md#python-package-dependencies).

## Implementa l'app
<a name="file-processing-app-deploy"></a>

È possibile creare e distribuire le risorse per questa app di esempio manualmente o utilizzando. AWS SAM In un ambiente di produzione, si consiglia di utilizzare uno strumento IaC come quello AWS SAM per distribuire in modo rapido e ripetibile intere applicazioni serverless senza utilizzare processi manuali.

### Implementare le risorse manualmente
<a name="file-processing-app-deploy-manual"></a>

Per distribuire l'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](https://www.python.org/downloads/) sia installato sulla tua macchina di compilazione.

#### Creare due bucket S3
<a name="file-processing-app-deploy-manual-create-buckets"></a>

Per prima cosa, crea due bucket S3. Il primo bucket è il bucket di origine in cui caricherai 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 bucket](https://console.aws.amazon.com/s3/buckets) della console Amazon S3.

1. Seleziona quello più Regione AWS vicino alla tua posizione geografica. Puoi modificare la regione utilizzando l'elenco a discesa nella parte superiore dello schermo.  
![\[\]](http://docs.aws.amazon.com/it_it/lambda/latest/dg/images/console_region_select.png)

1. Scegliere **Create bucket (Crea bucket)**.

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

   1. Per **Tipo di secchio**, assicurati che sia selezionata l'**opzione Uso generale**.

   1. Per **Bucket name, inserisci un nome** univoco globale che soddisfi le regole di denominazione dei [bucket di Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html). I nomi dei bucket possono contenere solo lettere minuscole, numeri, punti (.) e trattini (-).

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

1. 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](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) sul tuo computer di compilazione.

**Creazione dei bucket Amazon S3 (AWS CLI)**

1. Esegui il comando della CLI sotto riportato per creare il bucket di origine. Il nome che scegli per il tuo bucket deve essere univoco a livello globale e seguire le regole di denominazione dei [bucket di Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html). I nomi possono contenere solo lettere minuscole, numeri, punti (.) e trattini (-). Per `region` e `LocationConstraint`, scegli la [Regione AWS](https://docs.aws.amazon.com/general/latest/gr/lambda-service.html) 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 Regione AWS stesso bucket di origine, quindi prendi nota della regione che hai scelto.

1. 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` e`LocationConstraint`, scegli lo stesso Regione AWS che hai usato per creare il 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
<a name="file-processing-app-deploy-manual-create-execution-role"></a>

Un ruolo di esecuzione è un ruolo IAM che concede a una funzione Lambda l'autorizzazione all' Servizi AWS accesso e alle risorse. Per concedere alla funzione l'accesso in lettura e scrittura ad Amazon S3, è necessario collegare la [policy gestita da AWS](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies) `AmazonS3FullAccess`.

------
#### [ Console ]

**Per creare un ruolo di esecuzione e allegare la policy `AmazonS3FullAccess` gestita (console)**

1. Aprire la pagina [Roles (Ruoli)](https://console.aws.amazon.com/iam/home/roles) nella console IAM.

1. Scegli **Crea ruolo**.

1. Per il **tipo di entità affidabile**, seleziona **AWS servizio** e per **Use case**, seleziona **Lambda**.

1. Scegli **Next (Successivo)**.

1. Aggiungi la politica `AmazonS3FullAccess` gestita effettuando le seguenti operazioni:

   1. Nelle **politiche di autorizzazione**, **AmazonS3FullAccess** accedi alla barra di ricerca.

   1. Seleziona la casella di controllo accanto alla politica.

   1. Scegli **Next (Successivo)**.

1. In **Dettagli del ruolo**, per il **nome del ruolo** inserisci**LambdaS3Role**.

1. Selezionare **Crea ruolo**.

------
#### [ AWS CLI ]

**Per creare un ruolo di esecuzione e collegare la policy gestita da `AmazonS3FullAccess` (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 servizio principale l'`lambda.amazonaws.com`autorizzazione a chiamare l'azione AWS Security Token Service ()AWS STS. `AssumeRole`  
****  

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

1. 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
   ```

1. 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
<a name="file-processing-app-deploy-manual-create-function-package"></a>

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 `requirements.txt` file `lambda_function.py` e che hai creato o scaricato in GitHub precedenza e crea una nuova directory denominata. `package`

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

   ```
   pip install -r requirements.txt --target ./package/
   ```

1. 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](python-package.md).

#### Creazione della funzione Lambda
<a name="file-processing-app-deploy-manual-createfunction"></a>

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 utilizzando 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 chiamata della funzione da CloudWatch Logs per confermare l'avvenuta chiamata.

1. Aprire la pagina [Funzioni](https://console.aws.amazon.com/lambda/home#/functions) della console Lambda.

1. Assicurati di lavorare nello stesso bucket in cui hai creato il bucket S3. Regione AWS Puoi modificare la regione utilizzando l'elenco a discesa nella parte superiore dello schermo.  
![\[\]](http://docs.aws.amazon.com/it_it/lambda/latest/dg/images/console_region_select.png)

1. Selezionare **Create function (Crea funzione)**.

1. Scegli **Author from scratch** (Crea da zero).

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

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

   1. In **Runtime**, scegli **Python 3.12**.

   1. In **Architecture** (Architettura), scegli **x86\$164**.

1. Allega il ruolo di esecuzione che hai creato nel passaggio precedente effettuando le seguenti operazioni:

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

   1. Seleziona **Utilizza un ruolo esistente**.

   1. In **Ruolo esistente**, seleziona il tuo ruolo (`LambdaS3Role`).

1. Scegli **Crea funzione**.

**Caricamento del codice della funzione (console)**

1. Nel riquadro **Origine del codice**, scegli **Carica da**.

1. Scegli **File .zip**.

1. Scegli **Carica**.

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

1. Scegli **Save** (Salva).

**Per configurare la memoria e il timeout della funzione (console)**

1. Seleziona la scheda **Configurazione** per la tua funzione.

1. Nel riquadro **Configurazione generale**, scegli **Modifica**.

1. Imposta **Memoria** su 256 MB e **Timeout** su 15 secondi.

1. Scegli **Save** (Salva).

**Per configurare il formato di log (console)**

1. Seleziona la scheda **Configurazione** per la tua funzione.

1. Seleziona **Strumenti di monitoraggio e operazioni**.

1. Nel riquadro **Configurazione della registrazione**, scegli **Modifica**.

1. Per **Configurazione della registrazione**, seleziona **JSON**.

1. Scegli **Save** (Salva).

------
#### [ AWS CLI ]

**Creazione della 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
<a name="file-processing-app-deploy-manual-configure-s3-trigger"></a>

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)](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/recursive-runaway). Ciò può comportare l'addebito di addebiti imprevisti a tuo Account AWS favore.

------
#### [ Console ]

**Configurazione del trigger Amazon S3 (console)**

1. Apri la pagina [Funzioni](https://console.aws.amazon.com/lambda/home#/functions) della console Lambda e scegli la tua funzione (`EncryptPDF`).

1. Selezionare **Add trigger** (Aggiungi trigger).

1. Seleziona **S3**.

1. In **Bucket**, seleziona il tuo bucket di origine.

1. In **Tipi di eventi**, seleziona **Tutti gli eventi di creazione di oggetti**.

1. 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](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/recursive-runaway) in Serverless Land.

1. Scegliere **Aggiungi**.

   Quando crei un trigger utilizzando la console Lambda, Lambda crea automaticamente una [policy basata sulle risorse](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html) per concedere al servizio selezionato l'autorizzazione a richiamare la funzione. 

------
#### [ AWS CLI ]

**Configurazione del trigger Amazon S3 (AWS CLI)**

1. Aggiungi una [policy basata sulle risorse](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html) alla tua funzione che consenta al bucket di sorgenti Amazon S3 di richiamare la tua funzione quando aggiungi un file. Una dichiarazione politica basata sulle risorse fornisce altre Servizi AWS autorizzazioni per richiamare 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 del 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 lo Account AWS crei con lo stesso Amazon Resource Name (ARN).

1. 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" ]
       }
     ]
   }
   ```

1. 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 `put-bucket-notification-configuration` comando e sull'`notification-configuration`opzione, consulta [put-bucket-notification-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-bucket-notification-configuration.html)la *AWS CLI Command* Reference.

------

### Distribuisci le risorse utilizzando AWS SAM
<a name="file-processing-app-deploy-sam"></a>

Prima di iniziare, assicurati che [Docker](https://docs.docker.com/get-docker/) e [la versione più recente di AWS SAMCLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html) siano installati sulla tua macchina di compilazione.

1. Nella directory del progetto, copia e incolla il seguente codice in un file denominato`template.yaml`. Sostituisci i nomi dei bucket segnaposto:
   + [Per il bucket di origine, sostituiscilo `amzn-s3-demo-bucket` con qualsiasi nome conforme alle regole di denominazione dei bucket S3.](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html)
   + 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, devi modificare il modello per rinominare i bucket con nomi univoci a livello globale che soddisfino le regole di denominazione dei bucket [S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html). Questo passaggio viene spiegato ulteriormente in [Distribuisci le risorse utilizzando AWS SAM](#file-processing-app-deploy-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.](lambda-intro-execution-role.md) La [policy gestita da AWS](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-vs-inline.html#aws-managed-policies) `AmazonS3FullAccess` fornisce alla tua funzione le autorizzazioni necessarie per leggere e scrivere oggetti su Amazon S3.

1. 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. La specifica dell'opzione `--use-container` consente di creare la funzione all'interno di un container Docker simile a Lambda. 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 usa 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 contenitore utilizzando la proprietà. [PackageType](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-packagetype)

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

   ```
   sam deploy --guided
   ```

   L'uso del `--guided` flag significa che ti AWS SAM verranno mostrate le istruzioni per guidarti attraverso il 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](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#cfn-concepts-stacks) `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
<a name="file-processing-app-test"></a>

Per testare l'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](testing-guide.md).

### Test manuale dell'app
<a name="file-processing-app-test-manual"></a>

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](https://console.aws.amazon.com/s3/buckets) della console Amazon S3 e scegli il bucket di origine.

   1. Scegli **Carica**.

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

   1. Seleziona **Apri**, quindi **Carica**.

1. 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](https://console.aws.amazon.com/s3/buckets) della console Amazon S3 e scegli il bucket di destinazione.

   1. 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**.

   1. 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 l'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
   ```

1. 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 tua funzione viene eseguita correttamente, vedrai un output 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"
           }
       ]
   }
   ```

1. 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`.

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

------

### Test dell'app con lo script automatico
<a name="file-processing-app-test-auto"></a>

Crea i seguenti file nella directory del tuo 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 ogni file.

#### Script di test automatizzato
<a name="file-processing-app-test-script"></a>

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 sostituiscilo `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 log di CloudWatch Logs più recente della funzione per confermare che quando hai caricato il file di test, la funzione Lambda è stata eseguita e ha segnalato il successo.
+ 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 nel 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](#file-processing-app-test-auto).

#### File di configurazione dello script di test
<a name="file-processing-app-test-config"></a>

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. Assicurati che il `pytest` modulo sia installato nel tuo ambiente locale. È possibile installare `pytest` eseguendo il comando seguente:

   ```
   pip install pytest
   ```

1. Salvate un file PDF denominato `test.pdf` nella directory contenente i `pytest.ini` file `test_pdf_encrypt.py` and.

1. 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
<a name="file-processing-app-next-steps"></a>

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](https://pypi.org/project/pillow/) contengono in genere componenti C o C\$1\$1. Per garantire che il pacchetto di implementazione della funzione sia compatibile con l'ambiente di esecuzione Lambda, è importante utilizzare il binario di distribuzione del codice sorgente corretto.

Quando si distribuiscono le risorse con AWS SAM, è necessario adottare alcune misure aggiuntive per includere la corretta distribuzione dei sorgenti nel pacchetto di distribuzione. Poiché AWS SAM non installerà dipendenze per una piattaforma diversa dalla macchina di compilazione, specificare la corretta distribuzione del codice sorgente (`.whl`file) 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:
+ Usa l'opzione `--use-container` durante l'esecuzione di `sam build`. Quando specifichi questa opzione, AWS SAM scarica un'immagine di base del contenitore compatibile con l'ambiente di esecuzione Lambda e crea il pacchetto di distribuzione della funzione in un contenitore Docker utilizzando quell'immagine. Per ulteriori informazioni, consulta [Creazione di una funzione Lambda all'interno di un container fornito](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-build.html#using-sam-cli-build-options-container).
+ Crea tu stesso il pacchetto di distribuzione.zip della tua funzione utilizzando il file binario di distribuzione sorgente corretto e salva il file.zip nella directory specificata come nel modello. `CodeUri` AWS SAM Per ulteriori informazioni sulla creazione di pacchetti di implementazione .zip per Python utilizzando distribuzioni binarie, consulta [Creazione di un pacchetto di implementazione .zip con dipendenze](python-package.md#python-package-create-dependencies) e [Creazione di un pacchetto di implementazione .zip con librerie native](python-package.md#python-package-native-libraries).

# Creare un'app per eseguire la manutenzione pianificata del database
<a name="scheduled-task-app"></a>

È possibile utilizzare AWS Lambda per sostituire processi pianificati come backup automatici di sistema, conversioni di file e attività di manutenzione. In questo esempio, viene creata un'applicazione serverless che esegue una manutenzione programmata regolare su una tabella DynamoDB eliminando le voci precedenti. L'app utilizza EventBridge Scheduler per richiamare una funzione Lambda su una pianificazione cron. Quando viene richiamata, la funzione interroga la tabella per individuare gli elementi più vecchi di un anno e li elimina. La funzione registra ogni elemento eliminato in Logs. CloudWatch 

Per implementare questo esempio, crea prima una tabella DynamoDB e completala con alcuni dati di test per la funzione da interrogare. Quindi, crea una funzione Python Lambda con un trigger EventBridge Scheduler e un ruolo di esecuzione IAM che dia alla funzione il permesso di leggere ed eliminare gli elementi dalla tua tabella.

![\[\]](http://docs.aws.amazon.com/it_it/lambda/latest/dg/images/ExampleApps/cron_app.png)


**Suggerimento**  
Se non hai familiarità con Lambda, completa il tutorial [Crea la tua prima funzione Lambda](getting-started.md) prima di creare questa app di esempio.

Puoi distribuire la tua app manualmente creando e configurando risorse con. Console di gestione AWS Puoi anche distribuire l'app utilizzando (). AWS Serverless Application Model AWS SAM AWS SAM è uno strumento Infrastructure as Code (IaC). Con IaC, non vengono create risorse manualmente, ma le si definisce in codice e poi le si distribuisce 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)](foundation-iac.md).

## Prerequisiti
<a name="scheduled-task-app-prereqs"></a>

Prima di creare l'app di esempio, assicurati di aver installato gli strumenti e i programmi da riga di comando necessari.
+ **Python**

  Per popolare la tabella DynamoDB creata per testare l'app, questo esempio utilizza uno script Python e un file CSV per scrivere i dati nella tabella. Assicurati che Python versione 3.8 o successiva sia installato sulla tua macchina.
+ **AWS SAM CLI**

  Se desideri creare la tabella DynamoDB e distribuire l'app di esempio AWS SAM utilizzando, devi installare la CLI. AWS SAM Segui le [istruzioni di installazione](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html) nella *Guida per l’utente di AWS SAM *.
+ **AWS CLI**

  Per utilizzare lo script Python fornito per popolare la tabella di test, è necessario aver installato e configurato il AWS CLI. Questo perché lo script utilizza il AWS SDK per Python (Boto3), che richiede l'accesso alle tue credenziali AWS Identity and Access Management (IAM). È inoltre necessario che AWS CLI sia installato per distribuire le risorse utilizzando. AWS SAM Installa la CLI seguendo le [istruzioni di installazione](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) riportate nella *Guida per l'utente di AWS Command Line Interface *.
+ **Docker**

  Per distribuire l'app utilizzando AWS SAM, Docker deve essere installato anche sulla macchina di compilazione. Segui le istruzioni in [Installa Docker Engine sul sito](https://docs.docker.com/engine/install/) Web della documentazione di Docker.

## Download dei file dell'app di esempio
<a name="scheduled-task-app-download"></a>

Per creare il database di esempio e l'app di manutenzione programmata, è necessario creare i seguenti file nella directory del progetto:

**File di database di esempio**
+ `template.yaml`- un AWS SAM modello che puoi usare per creare la tabella DynamoDB
+ `sample_data.csv`: un file CSV contenente dati di esempio da caricare nella tabella
+ `load_sample_data.py`: uno script Python che scrive i dati del file CSV nella tabella

**File dell'app di manutenzione programmata**
+ `lambda_function.py`: il codice della funzione Python per la funzione Lambda che esegue la manutenzione del database
+ `requirements.txt`: un file manifesto che definisce le dipendenze richieste dal codice della funzione Python
+ `template.yaml`- un AWS SAM modello che puoi usare per distribuire l'app

**File di test**
+ `test_app.py`: uno script Python che scansiona la tabella e conferma il corretto funzionamento della funzione emettendo tutti i record più vecchi di un anno

Espandi le seguenti sezioni per visualizzare il codice e per saperne di più sul ruolo di ciascun file nella creazione e nel test dell'app. Per creare i file sul tuo computer locale, copia e incolla il codice seguente.

### AWS SAM modello (tabella DynamoDB di esempio)
<a name="scheduled-task-app-table-yaml"></a>

Copia e incolla il codice seguente in un nuovo file `template.yaml`.

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM Template for DynamoDB Table with Order_number as Partition Key and Date as Sort Key

Resources:
  MyDynamoDBTable:
    Type: AWS::DynamoDB::Table
    DeletionPolicy: Retain
    UpdateReplacePolicy: Retain
    Properties:
      TableName: MyOrderTable
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: Order_number
          AttributeType: S
        - AttributeName: Date
          AttributeType: S
      KeySchema:
        - AttributeName: Order_number
          KeyType: HASH
        - AttributeName: Date
          KeyType: RANGE
      SSESpecification:
        SSEEnabled: true
      GlobalSecondaryIndexes:
        - IndexName: Date-index
          KeySchema:
            - AttributeName: Date
              KeyType: HASH
          Projection:
            ProjectionType: ALL
      PointInTimeRecoverySpecification:
        PointInTimeRecoveryEnabled: true

Outputs:
  TableName:
    Description: DynamoDB Table Name
    Value: !Ref MyDynamoDBTable
  TableArn:
    Description: DynamoDB Table ARN
    Value: !GetAtt MyDynamoDBTable.Arn
```

**Nota**  
AWS SAM i modelli utilizzano una convenzione di denominazione standard di. `template.yaml` In questo esempio, hai due file modello: uno per creare il database di esempio e l'altro per creare l'app stessa. Salvali in sottodirectory separate nella cartella di progetto.

Questo AWS SAM modello definisce la risorsa della tabella DynamoDB che crei per testare la tua app. La tabella utilizza una chiave primaria di `Order_number` con una chiave di ordinamento di `Date`. Affinché la funzione Lambda trovi gli elementi direttamente in base alla data, definiamo anche un [indice secondario globale](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html) denominato `Date-index`.

Per ulteriori informazioni sulla creazione e la configurazione di una tabella DynamoDB tramite la risorsa `AWS::DynamoDB::Table`, consulta [AWS::DynamoDB::Table](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html) nella *Guida per l'utente di AWS CloudFormation *.

### File di dati del database di esempio
<a name="scheduled-task-app-csv-file"></a>

Copia e incolla il codice seguente in un nuovo file `sample_data.csv`.

```
Date,Order_number,CustomerName,ProductID,Quantity,TotalAmount
2023-09-01,ORD001,Alejandro Rosalez,PROD123,2,199.98
2023-09-01,ORD002,Akua Mansa,PROD456,1,49.99
2023-09-02,ORD003,Ana Carolina Silva,PROD789,3,149.97
2023-09-03,ORD004,Arnav Desai,PROD123,1,99.99
2023-10-01,ORD005,Carlos Salazar,PROD456,2,99.98
2023-10-02,ORD006,Diego Ramirez,PROD789,1,49.99
2023-10-03,ORD007,Efua Owusu,PROD123,4,399.96
2023-10-04,ORD008,John Stiles,PROD456,2,99.98
2023-10-05,ORD009,Jorge Souza,PROD789,3,149.97
2023-10-06,ORD010,Kwaku Mensah,PROD123,1,99.99
2023-11-01,ORD011,Li Juan,PROD456,5,249.95
2023-11-02,ORD012,Marcia Oliveria,PROD789,2,99.98
2023-11-03,ORD013,Maria Garcia,PROD123,3,299.97
2023-11-04,ORD014,Martha Rivera,PROD456,1,49.99
2023-11-05,ORD015,Mary Major,PROD789,4,199.96
2023-12-01,ORD016,Mateo Jackson,PROD123,2,199.99
2023-12-02,ORD017,Nikki Wolf,PROD456,3,149.97
2023-12-03,ORD018,Pat Candella,PROD789,1,49.99
2023-12-04,ORD019,Paulo Santos,PROD123,5,499.95
2023-12-05,ORD020,Richard Roe,PROD456,2,99.98
2024-01-01,ORD021,Saanvi Sarkar,PROD789,3,149.97
2024-01-02,ORD022,Shirley Rodriguez,PROD123,1,99.99
2024-01-03,ORD023,Sofia Martinez,PROD456,4,199.96
2024-01-04,ORD024,Terry Whitlock,PROD789,2,99.98
2024-01-05,ORD025,Wang Xiulan,PROD123,3,299.97
```

Questo file contiene alcuni esempi di dati di test con cui compilare la tabella DynamoDB in formato CSV (valori separati da virgola) standard.

### Script Python per caricare dati di esempio
<a name="scheduled-task-app-load-script"></a>

Copia e incolla il codice seguente in un nuovo file `load_sample_data.py`.

```
import boto3
import csv
from decimal import Decimal

# Initialize the DynamoDB client
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('MyOrderTable') 
print("DDB client initialized.")

def load_data_from_csv(filename):
    with open(filename, 'r') as file:
        csv_reader = csv.DictReader(file)
        for row in csv_reader:
            item = {
                'Order_number': row['Order_number'],
                'Date': row['Date'],
                'CustomerName': row['CustomerName'],
                'ProductID': row['ProductID'],
                'Quantity': int(row['Quantity']),
                'TotalAmount': Decimal(str(row['TotalAmount']))
            }
            table.put_item(Item=item)
            print(f"Added item: {item['Order_number']} - {item['Date']}")

if __name__ == "__main__":
    load_data_from_csv('sample_data.csv')
    print("Data loading completed.")
```

Questo script Python utilizza innanzitutto il AWS SDK per Python (Boto3) per creare una connessione alla tabella DynamoDB. Quindi esegue un'iterazione su ogni riga del file CSV di dati di esempio, crea un elemento da quella riga e scrive l'elemento nella tabella DynamoDB utilizzando l'SDK boto3.

### Codice della funzione Python
<a name="scheduled-task-app-function-code"></a>

Copia e incolla il codice seguente in un nuovo file `lambda_function.py`.

```
import boto3
from datetime import datetime, timedelta
from boto3.dynamodb.conditions import Key, Attr
import logging

logger = logging.getLogger()
logger.setLevel("INFO")

def lambda_handler(event, context):
    # Initialize the DynamoDB client
    dynamodb = boto3.resource('dynamodb')
    
    # Specify the table name
    table_name = 'MyOrderTable'
    table = dynamodb.Table(table_name)
    
    # Get today's date
    today = datetime.now()
    
    # Calculate the date one year ago
    one_year_ago = (today - timedelta(days=365)).strftime('%Y-%m-%d')
    
    # Scan the table using a global secondary index
    response = table.scan(
        IndexName='Date-index',
        FilterExpression='#date < :one_year_ago',
        ExpressionAttributeNames={
            '#date': 'Date'
        },
        ExpressionAttributeValues={
            ':one_year_ago': one_year_ago
        }
    )
    
     # Delete old items
    with table.batch_writer() as batch:
        for item in response['Items']:
            Order_number = item['Order_number']
            batch.delete_item(
                Key={
                    'Order_number': Order_number,
                    'Date': item['Date']
                }
            )
            logger.info(f'deleted order number {Order_number}')
    
    # Check if there are more items to scan
    while 'LastEvaluatedKey' in response:
        response = table.scan(
            IndexName='DateIndex',
            FilterExpression='#date < :one_year_ago',
            ExpressionAttributeNames={
                '#date': 'Date'
            },
            ExpressionAttributeValues={
                ':one_year_ago': one_year_ago
            },
            ExclusiveStartKey=response['LastEvaluatedKey']
        )
        
        # Delete old items
        with table.batch_writer() as batch:
            for item in response['Items']:
                batch.delete_item(
                    Key={
                        'Order_number': item['Order_number'],
                        'Date': item['Date']
                    }
                )
    
    return {
        'statusCode': 200,
        'body': 'Cleanup completed successfully'
    }
```

Il codice della funzione Python contiene la [funzione handler](python-handler.md) (`lambda_handler`) che Lambda esegue quando viene invocata la funzione.

Quando la funzione viene richiamata da EventBridge Scheduler, utilizza il AWS SDK per Python (Boto3) per creare una connessione alla tabella DynamoDB su cui deve essere eseguita l'attività di manutenzione pianificata. Quindi utilizza la libreria `datetime` Python per calcolare la data di un anno fa, prima di scansionare la tabella alla ricerca di elementi più vecchi di questo ed eliminarli.

Tieni presente che le risposte delle operazioni di query e scansione di DynamoDB sono limitate a una dimensione massima di 1 MB. Se la risposta è superiore a 1 MB, DynamoDB impagina i dati e restituisce un elemento `LastEvaluatedKey` nella risposta. Per garantire che la nostra funzione elabori tutti i record della tabella, controlliamo la presenza di questa chiave e continuiamo a eseguire scansioni della tabella dall'ultima posizione valutata fino alla scansione dell'intera tabella.

### File manifesto `requirements.txt`
<a name="scheduled-task-app-dependencies"></a>

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

```
boto3
```

Per questo esempio, il codice della funzione ha solo una dipendenza che non fa parte della libreria Python standard: l'SDK for Python (Boto3) che la funzione utilizza per scansionare ed eliminare elementi dalla tabella DynamoDB.

**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](python-package.md#python-package-dependencies).

### AWS SAM modello (app per manutenzione programmata)
<a name="scheduled-task-app-table-yaml"></a>

Copia e incolla il codice seguente in un nuovo file `template.yaml`.

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: SAM Template for Lambda function and EventBridge Scheduler rule

Resources:
  MyLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: ScheduledDBMaintenance
      CodeUri: ./
      Handler: lambda_function.lambda_handler
      Runtime: python3.11
      Architectures:
        - x86_64
      Events:
        ScheduleEvent:
          Type: ScheduleV2
          Properties:
            ScheduleExpression: cron(0 3 1 * ? *)
            Description: Run on the first day of every month at 03:00 AM
      Policies:
        - CloudWatchLogsFullAccess
        - Statement:
            - Effect: Allow
              Action:
                - dynamodb:Scan
                - dynamodb:BatchWriteItem
              Resource: !Sub 'arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/MyOrderTable'

  LambdaLogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub /aws/lambda/${MyLambdaFunction}
      RetentionInDays: 30

Outputs:
  LambdaFunctionName:
    Description: Lambda Function Name
    Value: !Ref MyLambdaFunction
  LambdaFunctionArn:
    Description: Lambda Function ARN
    Value: !GetAtt MyLambdaFunction.Arn
```

**Nota**  
AWS SAM i modelli utilizzano una convenzione di denominazione standard di. `template.yaml` In questo esempio, hai due file modello: uno per creare il database di esempio e l'altro per creare l'app stessa. Salvali in sottodirectory separate nella cartella di progetto.

Questo AWS SAM modello definisce le risorse per la tua app. Definiamo la funzione Lambda utilizzando la risorsa `AWS::Serverless::Function`. La EventBridge pianificazione dello Scheduler e il trigger per richiamare la funzione Lambda vengono creati utilizzando la `Events` proprietà di questa risorsa utilizzando un tipo di. `ScheduleV2` *Per ulteriori informazioni sulla definizione delle EventBridge pianificazioni di Scheduler nei AWS SAM modelli, consulta [ScheduleV2 nella Guida per gli sviluppatori](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-schedulev2.html).AWS Serverless Application Model *

Oltre alla funzione Lambda e alla EventBridge pianificazione Scheduler, definiamo anche un gruppo di CloudWatch log a cui la funzione può inviare i record degli elementi eliminati.

### Script di test
<a name="scheduled-task-app-test-script"></a>

Copia e incolla il codice seguente in un nuovo file `test_app.py`.

```
import boto3
from datetime import datetime, timedelta
import json

# Initialize the DynamoDB client
dynamodb = boto3.resource('dynamodb')

# Specify your table name
table_name = 'YourTableName'
table = dynamodb.Table(table_name)

# Get the current date
current_date = datetime.now()

# Calculate the date one year ago
one_year_ago = current_date - timedelta(days=365)

# Convert the date to string format (assuming the date in DynamoDB is stored as a string)
one_year_ago_str = one_year_ago.strftime('%Y-%m-%d')

# Scan the table
response = table.scan(
    FilterExpression='#date < :one_year_ago',
    ExpressionAttributeNames={
        '#date': 'Date'
    },
    ExpressionAttributeValues={
        ':one_year_ago': one_year_ago_str
    }
)

# Process the results
old_records = response['Items']

# Continue scanning if we have more items (pagination)
while 'LastEvaluatedKey' in response:
    response = table.scan(
        FilterExpression='#date < :one_year_ago',
        ExpressionAttributeNames={
            '#date': 'Date'
        },
        ExpressionAttributeValues={
            ':one_year_ago': one_year_ago_str
        },
        ExclusiveStartKey=response['LastEvaluatedKey']
    )
    old_records.extend(response['Items'])

for record in old_records:
    print(json.dumps(record))

# The total number of old records should be zero.
print(f"Total number of old records: {len(old_records)}")
```

Questo script di test utilizza il AWS SDK per Python (Boto3) per creare una connessione alla tabella DynamoDB ed eseguire la scansione degli elementi più vecchi di un anno. Per confermare se la funzione Lambda è stata eseguita correttamente, alla fine del test, la funzione stampa il numero di record più vecchi di un anno ancora nella tabella. Se la funzione Lambda ha avuto successo, il numero di vecchi record nella tabella dovrebbe essere zero. 

## Creazione e compilazione della tabella DynamoDB di esempio
<a name="scheduled-task-app-create-table"></a>

Per testare la tua app di manutenzione programmata, devi prima creare una tabella DynamoDB e popolarla con alcuni dati di esempio. È possibile creare la tabella manualmente utilizzando o la Console di gestione AWS o AWS SAM. Si consiglia di AWS SAM utilizzarlo per creare e configurare rapidamente la tabella utilizzando alcuni AWS CLI comandi.

------
#### [ Console ]

**Creare la tabella DynamoDB**

1. Aprire la pagina [Tables (Tabelle)](https://console.aws.amazon.com/dynamodbv2/home#tables) della console DynamoDB.

1. Scegliere **Create table (Crea tabella)**.

1. Crea la tabella completando le operazioni seguenti:

   1. In **Dettagli tabella**, per **Nome tabella**, immetti **MyOrderTable**.

   1. Per **Partition key (Chiave di partizione)**, immettere **Order\$1number** e mantenere il tipo di dati impostato come **String (Stringa)**.

   1. Per **Chiave di ordinamento**, immetti **Date** e lascia il tipo come **String**.

   1. Lascia **Impostazioni della tabella** impostato su **Impostazioni predefinite** e scegli **Crea tabella**.

1. Una volta completata la creazione della tabella e lo **stato** è impostato su **Attivo**, crea un indice secondario globale (GSI) procedendo come segue. L'app utilizzerà questo GSI per cercare gli elementi direttamente in base alla data e determinare cosa eliminare.

   1. Scegliete **MyOrderTable**dall'elenco delle tabelle.

   1. Scegli la scheda **Indici**.

   1. **In **Indici secondari globali, scegli Crea indice**.**

   1. In **Dettagli dell'indice**, inserisci **Date** per **Chiave di partizione** e lascia il campo **Tipo di dati** impostato su **Stringa**.

   1. Per **Index name (Nome indice)**, inserisci **Date-index**.

   1. Lascia tutti gli altri parametri impostati sui valori predefiniti, scorri fino alla parte inferiore della pagina e scegli **Crea indice**.

------
#### [ AWS SAM ]

**Creare la tabella DynamoDB**

1. Passa alla cartella in cui è stato salvato il file `template.yaml` per la tabella DynamoDB. Nota che questo esempio utilizza due file `template.yaml`. Assicurati che siano salvati in sottocartelle separate e di trovarti nella cartella corretta contenente il modello per creare la tua tabella DynamoDB.

1. Eseguire il seguente comando seguente.

   ```
   sam build
   ```

   Questo comando raccoglie gli artefatti di compilazione per l'applicazione e li colloca nel formato e nella posizione corretti per l'implementazione.

1. Per creare la risorsa DynamoDB specificata nel file `template.yaml`, eseguire il comando seguente.

   ```
   sam deploy --guided
   ```

   L'uso del `--guided` flag significa che ti AWS SAM verranno mostrate le istruzioni per guidarti nel processo di distribuzione. Per questa implementazione, inserisci un `Stack name` pari a **cron-app-test-db** e accetta i valori predefiniti per tutte le altre opzioni utilizzando Invio.

   Al AWS SAM termine della creazione della risorsa DynamoDB, dovrebbe apparire il seguente messaggio.

   ```
   Successfully created/updated stack - cron-app-test-db in us-west-2
   ```

1. È inoltre possibile confermare che la tabella DynamoDB è stata creata aprendo la pagina [Tabelle](https://console.aws.amazon.com/dynamodbv2/home#tables) della console DynamoDB. Dovresti vedere una tabella denominata `MyOrderTable`.

------

Dopo aver creato la tabella, aggiungi alcuni dati di esempio per testare l'app. Il file CSV `sample_data.csv` scaricato in precedenza contiene una serie di voci di esempio tra cui numeri d'ordine, date e informazioni su clienti e ordini. Usa lo script python `load_sample_data.py` fornito per aggiungere questi dati alla tua tabella.

**Per aggiungere i dati di esempio alla tabella**

1. Passa alla directory contenente i file `sample_data.csv` e `load_sample_data.py`. Se questi file si trovano in directory separate, spostali in modo che vengano salvati nella stessa posizione.

1. Crea un ambiente virtuale Python in cui eseguire lo script mediante il comando seguente. Ti consigliamo di utilizzare un ambiente virtuale perché nel passaggio successivo dovrai installare AWS SDK per Python (Boto3).

   ```
   python -m venv venv
   ```

1. Nell'ambiente virtuale, esegui il comando seguente.

   ```
   source venv/bin/activate
   ```

1. Installa l'SDK per Python (Boto3) nell'ambiente virtuale mediante il comando seguente. Lo script utilizza questa libreria per connettersi alla tabella DynamoDB e aggiungere gli elementi.

   ```
   pip install boto3
   ```

1. Esegui lo script per popolare la tabella mediante il comando seguente.

   ```
   python load_sample_data.py
   ```

   Se lo script viene eseguito correttamente, dovrebbe stampare ogni elemento sulla console man mano che lo carica e riporta `Data loading completed`.

1. Per disattivare l'ambiente virtuale, esegui il comando seguente.

   ```
   deactivate
   ```

1. È possibile verificare che i dati siano stati caricati nella tabella DynamoDB eseguendo le operazioni seguenti:

   1. Apri la pagina [Esplora elementi](https://console.aws.amazon.com/dynamodbv2/home#item-explorer) della console DynamoDB e seleziona la tua tabella (`MyOrderTable`).

   1. Nel riquadro **Elementi restituiti**, dovresti vedere i 25 elementi del file CSV che lo script ha aggiunto alla tabella.

## Creazione dell'app per la manutenzione programmata
<a name="scheduled-task-app-create-app"></a>

È possibile creare e distribuire le risorse per questa app di esempio passo dopo passo utilizzando Console di gestione AWS o utilizzando. AWS SAM In un ambiente di produzione, si consiglia di utilizzare uno strumento Infrustracture-as-Code (IaC), AWS SAM ad esempio per distribuire ripetutamente applicazioni serverless senza utilizzare processi manuali.

Per questo esempio, segui le istruzioni della console per scoprire come configurare ogni AWS risorsa separatamente oppure segui AWS SAM le istruzioni per distribuire rapidamente l'app utilizzando i comandi. AWS CLI 

------
#### [ Console ]

**Per creare la funzione utilizzando Console di gestione AWS**

Innanzitutto, crea una funzione contenente il codice di avvio di base. Quindi, sostituisci questo codice con il codice della tua funzione copiando e incollando il codice direttamente nell'editor di codice Lambda o caricandolo come pacchetto `.zip`. Per questa operazione, si consiglia di copiare e incollare il codice.

1. Aprire la pagina [Funzioni](https://console.aws.amazon.com/lambda/home#/functions) della console Lambda.

1. Selezionare **Create function (Crea funzione)**.

1. Scegli **Author from scratch** (Crea da zero).

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

   1. Nel campo **Function name (Nome funzione)**, immettere `ScheduledDBMaintenance`.

   1. Per **Runtime** scegli l'ultima versione di Python.

   1. In **Architecture** (Architettura), scegli **x86\$164**.

1. Scegli **Crea funzione**.

1. Dopo aver creato la funzione, è possibile configurarla con il codice di funzione fornito.

   1. Nel riquadro **Codice sorgente**, sostituisci il codice Hello world creato da Lambda con il codice della funzione Python dal file `lambda_function.py` salvato in precedenza.

   1. Nella sezione **DEPLOY**, scegli **Implementa** per aggiornare il codice della tua funzione:  
![\[\]](http://docs.aws.amazon.com/it_it/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

**Per configurare la memoria e il timeout della funzione (console)**

1. Seleziona la scheda **Configurazione** per la tua funzione.

1. Nel riquadro **Configurazione generale**, scegli **Modifica**.

1. Imposta **Memoria** su 256 MB e **Timeout** su 15 secondi. Se stai elaborando una tabella di grandi dimensioni con molti record, ad esempio nel caso di un ambiente di produzione, potresti prendere in considerazione l'impostazione di **Timeout** su un numero maggiore. In questo modo la funzione ha più tempo per scansionare e pulire il database.

1. Scegli **Save** (Salva).

**Per configurare il formato di log (console)**

Puoi configurare le funzioni Lambda per generare log in formato testo non strutturato o JSON. È consigliabile utilizzare il formato JSON per i log per agevolare la ricerca e il filtraggio dei dati di log. Per ulteriori informazioni sulle opzioni di configurazione del log Lambda, consulta [Configurazione dei controlli di registrazione avanzati per le funzioni Lambda](monitoring-logs.md#monitoring-cloudwatchlogs-advanced).

1. Seleziona la scheda **Configurazione** per la tua funzione.

1. Seleziona **Strumenti di monitoraggio e operazioni**.

1. Nel riquadro **Configurazione della registrazione**, scegli **Modifica**.

1. Per **Configurazione della registrazione**, seleziona **JSON**.

1. Scegli **Save** (Salva).

**Impostazione delle autorizzazioni IAM**

Per concedere alla funzione le autorizzazioni necessarie per leggere ed eliminare gli elementi di DynamoDB, è necessario aggiungere una policy al [ruolo di esecuzione](lambda-intro-execution-role.md) della funzione che definisca le autorizzazioni necessarie.

1. Apri la scheda **Configurazione**, quindi scegli **Autorizzazioni** dalla barra di navigazione a sinistra.

1. Scegli il nome del ruolo **Ruolo di esecuzione**.

1. Nella console IAM, scegli **Aggiungi autorizzazioni**, quindi **Crea policy in linea**.

1. Utilizza l'editor JSON e inserisci la seguente policy:  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "dynamodb:Scan",
                   "dynamodb:DeleteItem",
                   "dynamodb:BatchWriteItem"
               ],
               "Resource": "arn:aws:dynamodb:*:*:table/MyOrderTable"
           }
       ]
   }
   ```

1. Assegna un nome alla policy **DynamoDBCleanupPolicy**, quindi creala.

**Per configurare EventBridge Scheduler come trigger (console)**

1. Apri la [EventBridge console](https://console.aws.amazon.com/events/home).

1. Nel riquadro di navigazione a sinistra, scegli **Pianificatori** nella sezione **Pianificatore**.

1. Scegli **Crea pianificazione**.

1. Configura le impostazioni del VPC effettuando le seguenti operazioni:

   1. Per **Nome pianificazione**, inserisci un nome per la pianificazione (ad esempio, **DynamoDBCleanupSchedule**).

   1. In **Schema di pianificazione**, scegli **Pianificazione ricorrente**.

   1. Per **Tipo di pianificazione**, lascia l'impostazione predefinita come **Pianificazione basata su CRON**, quindi inserisci i seguenti dettagli di pianificazione:
      + ** **minuti**0**
      + **Ore**: **3**
      + **Giorno del mese**: **1**
      + **Mese**: **\$1**
      + **Giorno della settimana**: **?**
      + **Anno**: **\$1**

      Una volta valutata, questa espressione cron viene eseguita il primo giorno di ogni mese alle 03:00.

   1. Per **Finestra temporale flessibile**, seleziona **Off**.

1. Scegli **Next (Successivo)**.

1. Configura il trigger per la tua funzione Lambda eseguendo le operazioni seguenti:

   1. Nel riquadro **Dettagli della destinazione**, lascia il campo **API di destinazione** impostato su **Destinazioni basate su modelli**, quindi seleziona **Invocazione di AWS Lambda **.

   1. In **Richiama**, seleziona la tua funzione Lambda (`ScheduledDBMaintenance`) dall'elenco a discesa.

   1. Lascia vuoto il campo **Payload** e scegli **Avanti**.

   1. Scorri verso il basso fino a **Autorizzazioni** e seleziona **Crea un nuovo ruolo per questa pianificazione**. Quando crei una nuova EventBridge pianificazione di Scheduler utilizzando la console, EventBridge Scheduler crea una nuova politica con le autorizzazioni necessarie alla pianificazione per richiamare la tua funzione. *Per ulteriori informazioni sulla gestione delle autorizzazioni di pianificazione, consulta Pianificazioni [basate su CRON. nella Guida per l'utente di Scheduler](https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html#cron-based). EventBridge *

   1. Scegli **Next (Successivo)**.

1. Controlla le impostazioni e scegli **Crea pianificazione** per completare la creazione della pianificazione e del trigger Lambda.

------
#### [ AWS SAM ]

**Per distribuire l'app utilizzando AWS SAM**

1. Passa alla cartella in cui è stato salvato il file `template.yaml` per l'app. Nota che questo esempio utilizza due file `template.yaml`. Assicurati che siano salvati in sottocartelle separate e di trovarti nella cartella corretta contenente il modello per creare l'app.

1. Copia i file `lambda_function.py` e `requirements.txt` che hai scaricato in precedenza nella stessa cartella. La posizione del codice specificata nel AWS SAM modello è`./`, ovvero la posizione corrente. AWS SAM cercherà in questa cartella il codice della funzione Lambda quando tenti di distribuire l'app.

1. Eseguire il seguente comando seguente.

   ```
   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. La specifica dell'opzione `--use-container` consente di creare la funzione all'interno di un container Docker simile a Lambda. Lo usiamo qui quindi non è necessario che Python 3.12 sia installato sul computer locale per far funzionare la build.

1. Per creare le risorse Lambda e EventBridge Scheduler specificate nel `template.yaml` file, esegui il comando seguente.

   ```
   sam deploy --guided
   ```

   L'uso del `--guided` flag significa che ti AWS SAM verranno mostrate delle istruzioni per guidarti nel processo di distribuzione. Per questa implementazione, inserisci un `Stack name` pari a **cron-maintenance-app** e accetta i valori predefiniti per tutte le altre opzioni utilizzando Invio.

   Al AWS SAM termine della creazione delle risorse Lambda e EventBridge Scheduler, dovrebbe apparire il seguente messaggio.

   ```
   Successfully created/updated stack - cron-maintenance-app in us-west-2
   ```

1. Puoi inoltre confermare che la funzione Lambda è stata creata aprendo la pagina [Funzioni della console](https://console.aws.amazon.com/lambda/home#/functions) Lambda. Dovresti vedere una funzione denominata. `ScheduledDBMaintenance`

------

## Test dell'app
<a name="scheduled-task-app-test-app"></a>

 Per verificare che la pianificazione attivi correttamente la funzione e che la funzione pulisca correttamente i record dal database, è possibile modificare temporaneamente la pianificazione in modo che venga eseguita una volta in un momento specifico. È quindi possibile eseguire `sam deploy` nuovamente l'operazione per reimpostare il programma di ricorrenza in modo che venga eseguito una volta al mese. 

**Per eseguire l'applicazione utilizzando Console di gestione AWS**

1. Torna alla pagina della console EventBridge Scheduler.

1. **Scegli la tua pianificazione, quindi scegli Modifica.**

1. Nella sezione **Schema di pianificazione**, in **Ricorrenza**, scegli Pianificazione **unica**.

1.  **Imposta il tempo di chiamata a pochi minuti da oggi, rivedi le impostazioni, quindi scegli Salva.** 

 Dopo l'esecuzione della pianificazione e il richiamo della destinazione, esegui `test_app.py` lo script per verificare che la funzione abbia rimosso correttamente tutti i vecchi record dalla tabella DynamoDB. 

**Per verificare che i vecchi record vengano eliminati utilizzando uno script Python**

1.  Nella riga di comando, accedi alla cartella in cui hai salvato`test_app.py`. 

1. Eseguire lo script.

   ```
   python test_app.py
   ```

    Se il test viene superato, viene visualizzato il seguente output. 

   ```
   Total number of old records: 0
   ```

## Fasi successive
<a name="scheduled-task-app-next-steps"></a>

 Ora puoi modificare la EventBridge pianificazione dello Scheduler per soddisfare i requisiti specifici dell'applicazione. EventBridge Scheduler supporta le seguenti espressioni di pianificazione: cron, rate e one-time schedules. 

 *Per ulteriori informazioni sulle espressioni di EventBridge pianificazione di Scheduler, consulta Scheduler [types](https://docs.aws.amazon.com/scheduler/latest/UserGuide/schedule-types.html) nella Scheduler User GuideEventBridge .* [Gestione degli accessi](https://docs.aws.amazon.com/IAM/latest/UserGuide/access.html) nella Guida per l'utente *IAM* 

# Creazione di un sistema di elaborazione degli ordini con Lambda Durable Functions
<a name="order-processing-app"></a>

**Nota**  
ESIGENZA: Aggiungi un diagramma di architettura che mostri API Gateway, il flusso di lavoro Durable Function e i servizi di supporto (DynamoDB,) EventBridge

## Prerequisiti
<a name="order-processing-prerequisites"></a>
+ AWS CLI installato e configurato
+ ESIGENZA: Requisiti specifici per le funzioni durevoli

## Creare i file del codice sorgente
<a name="order-processing-source"></a>

Crea i seguenti file nella directory del tuo progetto:
+ `lambda_function.py`- il codice della funzione
+ `requirements.txt`- manifesto delle dipendenze

### Codice della funzione
<a name="order-processing-function-code"></a>

```
# NEED: Verify correct imports
import boto3
import json

def lambda_handler(event, context):
    # NEED: Verify DurableContext syntax
    durable = context.durable
    
    try:
        # Validate and store order
        order = await durable.step('validate', async () => {
            return validate_order(event['order'])
        })
        
        # Process payment
        # NEED: Verify wait syntax
        await durable.wait(/* wait configuration */)
        
        # Additional steps
        # NEED: Complete implementation
        
    except Exception as e:
        # NEED: Error handling patterns
        raise e

def validate_order(order_data):
    # NEED: Implementation
    pass
```

### File di requisiti
<a name="order-processing-requirements"></a>

```
# NEED: List of required packages
```

## Distribuire l'app
<a name="order-processing-deploy"></a>

### Creare una tabella DynamoDB per gli ordini
<a name="order-processing-dynamodb"></a>

1. Apri la console DynamoDB all'indirizzo [https://console.aws.amazon.com/dynamodb/](https://console.aws.amazon.com/dynamodb/)

1. **Scegli Crea tabella**

1. Per **Nome tabella**, inserisci **Orders**

1. Per la **chiave di partizione, immettere** **orderId**

1. Lascia le altre impostazioni come predefinite

1. Scegli **Crea tabella**

### Creazione della funzione Lambda
<a name="order-processing-lambda"></a>

1. Apri la console Lambda all'indirizzo [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/)

1. Selezionare **Create function (Crea funzione)**.

1. Seleziona l'**autore da zero**

1. Nel campo **Nome funzione**, inserisci **ProcessOrder**.

1. Per **Runtime**, scegli il tuo runtime preferito

1. NECESSITÀ: Aggiungi una configurazione specifica per Durable Functions

1. Selezionare **Create function (Crea funzione)**.

### Crea l'endpoint API Gateway
<a name="order-processing-apigateway"></a>

1. Apri la console API Gateway all'indirizzo [https://console.aws.amazon.com/apigateway/](https://console.aws.amazon.com/apigateway/)

1. Scegli **Crea API**

1. Seleziona **HTTP API**

1. Scegli **Build**

1. Aggiungi un'integrazione con la tua funzione Lambda

1. Configura i percorsi per l'elaborazione degli ordini

1. Distribuzione dell'API

## Eseguire il test dell'app
<a name="order-processing-test"></a>

Invia un ordine di prova:

```
{
    "orderId": "12345",
    "items": [
        {
            "productId": "ABC123",
            "quantity": 1
        }
    ]
}
```

NECESSITÀ: Aggiungi istruzioni di monitoraggio specifiche per Durable Functions

## Fasi successive
<a name="order-processing-next-steps"></a>

### Aggiungi business Logic
<a name="order-processing-business-logic"></a>

Implementa la gestione dell'inventario:

```
async def check_inventory(order):
    # Add inventory check logic
    pass
```

Aggiungi calcoli dei prezzi:

```
async def calculate_total(order):
    # Add pricing logic
    pass
```

### Migliora la gestione degli errori
<a name="order-processing-error-handling"></a>

Aggiungi logica di compensazione:

```
async def reverse_payment(order):
    # Add payment reversal logic
    pass
```

Gestisci gli annullamenti degli ordini:

```
async def cancel_order(order):
    # Add cancellation logic
    pass
```

### Integrazione di sistemi esterni
<a name="order-processing-integrations"></a>

```
async def notify_shipping_provider(order):
    # Add shipping integration
    pass

async def send_customer_notification(order):
    # Add notification logic
    pass
```

### Migliora il monitoraggio
<a name="order-processing-monitoring"></a>
+ Crea CloudWatch dashboard
+ Imposta le metriche per i tempi di elaborazione degli ordini
+ Configura gli avvisi per gli ordini in ritardo