

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

# Utilizzo AWS Lambda con Amazon RDS
<a name="services-rds"></a>

Puoi collegare una funzione Lambda a un database Amazon Relational Database Service (Amazon RDS) direttamente e attraverso un Server proxy per Amazon RDS. Le connessioni dirette sono utili in scenari semplici, mentre i server proxy sono consigliati per la produzione. Un proxy del database gestisce un pool di connessioni a database condivisi che consente alla funzione di raggiungere elevati livelli di simultaneità senza esaurire le connessioni al database.

Consigliamo di utilizzare il Server proxy per Amazon RDS per le funzioni Lambda che effettuano connessioni brevi e frequenti al database o aprono e chiudono numerose connessioni al database. Per ulteriori informazioni, consulta [Connessione automatica di una funzione Lambda e un'istanza DB](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/lambda-rds-connect.html) nella Guida per gli sviluppatori di Amazon Relational Database Service.

**Suggerimento**  
Per connettere rapidamente una funzione Lambda a un database Amazon RDS, puoi utilizzare la procedura guidata integrata nella console. Per aprire la procedura guidata, esegui queste operazioni:  
Aprire la pagina [Funzioni](https://console.aws.amazon.com/lambda/home#/functions) della console Lambda.
Seleziona la funzione a cui desideri connettere un database.
Nella scheda **Configurazione**, seleziona **Database RDS**.
Scegli **Connessione al database RDS**.
Dopo aver collegato la funzione a un database, scegli **Aggiungi proxy** se desideri creare un proxy.

## Configurazione della funzione per l'utilizzo con le risorse RDS
<a name="rds-configuration"></a>

Nella console Lambda, puoi eseguire il provisioning, e configurare, delle istanze di database Amazon RDS e risorse proxy. Puoi farlo accedendo ai **database RDS** nella scheda **Configurazione**. In alternativa, puoi anche creare e configurare connessioni alle funzioni Lambda nella console Amazon RDS. Quando configuri un'istanza di database RDS da utilizzare con Lambda, tieni presente i seguenti criteri:
+ Per effettuare la connessione a un database, la funzione si deve trovare nello stesso Amazon VPC in cui viene eseguito il database.
+ Puoi utilizzare i database Amazon RDS con motori MySQL, MariaDB, PostgreSQL o Microsoft SQL Server.
+ Puoi anche utilizzare cluster Aurora DB con motori MySQL o PostgreSQL.
+ Devi fornire un segreto di Secrets Manager per l'autenticazione del database.
+ Un ruolo IAM deve fornire l'autorizzazione all'uso del segreto, mentre una policy di attendibilità deve consentire ad Amazon RDS di assumere il ruolo.
+  Il principale IAM che utilizza la console per configurare la risorsa Amazon RDS e connetterla alla tua funzione deve disporre delle seguenti autorizzazioni:

### Policy di autorizzazione di esempio
<a name="rds-lambda-permissions"></a>

**Nota**  
 Le autorizzazioni del server proxy per Amazon RDS sono necessarie solo se configuri un server proxy per Amazon RDS per gestire un pool di connessioni al database. 

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateSecurityGroup",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSubnets",
        "ec2:DescribeVpcs",
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:AuthorizeSecurityGroupEgress",
        "ec2:RevokeSecurityGroupEgress",
        "ec2:CreateNetworkInterface",
        "ec2:DeleteNetworkInterface",
        "ec2:DescribeNetworkInterfaces"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "rds-db:connect",
        "rds:CreateDBProxy",
        "rds:CreateDBInstance",
        "rds:CreateDBSubnetGroup",
        "rds:DescribeDBClusters",
        "rds:DescribeDBInstances",
        "rds:DescribeDBSubnetGroups",
        "rds:DescribeDBProxies",
        "rds:DescribeDBProxyTargets",
        "rds:DescribeDBProxyTargetGroups",
        "rds:RegisterDBProxyTargets",
        "rds:ModifyDBInstance",
        "rds:ModifyDBProxy"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "lambda:CreateFunction",
        "lambda:ListFunctions",
        "lambda:UpdateFunctionConfiguration"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "iam:AttachRolePolicy",
        "iam:CreateRole",
        "iam:CreatePolicy"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetResourcePolicy",
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret",
        "secretsmanager:ListSecretVersionIds",
        "secretsmanager:CreateSecret"
      ],
      "Resource": "*"
    }
  ]
}
```

------

Amazon RDS addebita una tariffa oraria per i proxy in base alla dimensione dell'istanza di database, consulta [Prezzi di Server proxy per RDS](https://aws.amazon.com/rds/proxy/pricing/) per conoscere i dettagli. Per ulteriori informazioni sulle connessioni proxy in generale, consulta [Utilizzo di Server proxy per Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) nella Guida per l'utente di Amazon RDS.

### Requisiti SSL/TLS per le connessioni Amazon RDS
<a name="rds-lambda-certificates"></a>

Per stabilire SSL/TLS connessioni sicure a un'istanza di database Amazon RDS, la funzione Lambda deve verificare l'identità del server di database utilizzando un certificato affidabile. Lambda gestisce questi certificati in modo diverso a seconda del tipo di pacchetto di implementazione:
+ [Archivi di file .zip](configuration-function-zip.md): la gestione dei certificati varia in base al runtime:
  + **Node.js 18 e versioni precedenti**: Lambda include automaticamente certificati CA e certificati RDS.
  + **Node.js 20 e versioni successive**: Lambda non carica più certificati CA aggiuntivi per impostazione predefinita. Impostare la variabile di ambiente `NODE_EXTRA_CA_CERTS` su `/var/runtime/ca-cert.pem`.

  Potrebbero essere necessarie fino a 4 settimane prima che i nuovi Regioni AWS certificati Amazon RDS vengano aggiunti ai runtime gestiti Lambda.
+ Immagini dei [container: le immagini](images-create.md) AWS di base includono solo certificati CA. Se la tua funzione si connette a un'istanza del database Amazon RDS, devi includere i certificati appropriati nell'immagine container. Nel tuo Dockerfile, scarica il [pacchetto di certificati corrispondente al Regione AWS luogo in cui ospiti il](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html#UsingWithRDS.SSL.CertificatesDownload) database. Esempio:

  ```
  RUN curl https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem -o /us-east-1-bundle.pem
  ```

Questo comando scarica il bundle di certificati Amazon RDS e lo salva nel percorso assoluto `/us-east-1-bundle.pem` nella directory principale del container. Quando configuri la connessione del database nel codice della funzione, devi fare riferimento a questo percorso esatto. Esempio:

------
#### [ Node.js ]

La funzione `readFileSync` è necessaria perché i client del database Node.js necessitano del contenuto effettivo del certificato in memoria, non solo del percorso al file del certificato. Senza `readFileSync`, il client interpreta la stringa del percorso come contenuto del certificato, generando un errore di «certificato autofirmato nella catena di certificati».

**Example Configurazione della connessione Node.js per la funzione OCI**  

```
import { readFileSync } from 'fs';

// ...

let connectionConfig = {
    host: process.env.ProxyHostName,
    user: process.env.DBUserName,
    password: token,
    database: process.env.DBName,
    ssl: {
        ca: readFileSync('/us-east-1-bundle.pem') // Load RDS certificate content from file into memory
    }
};
```

------
#### [ Python ]

**Example Configurazione della connessione Python per la funzione OCI**  

```
connection = pymysql.connect(
    host=proxy_host_name,
    user=db_username,
    password=token,
    db=db_name,
    port=port,
    ssl={'ca': '/us-east-1-bundle.pem'}  #Path to the certificate in container
)
```

------
#### [ Java ]

Per le funzioni Java che utilizzano connessioni JDBC, la stringa di connessione deve includere:
+ `useSSL=true`
+ `requireSSL=true`
+ Un parametro `sslCA` che indica la posizione del certificato Amazon RDS nell'immagine container

**Example Stringa di connessione Java per la funzione OCI**  

```
// Define connection string
String connectionString = String.format("jdbc:mysql://%s:%s/%s?useSSL=true&requireSSL=true&sslCA=/us-east-1-bundle.pem", // Path to the certificate in container
        System.getenv("ProxyHostName"),
        System.getenv("Port"),
        System.getenv("DBName"));
```

------
#### [ .NET ]

**Example Stringa di connessione.NET per la connessione MySQL nella funzione OCI**  

```
/// Build the Connection String with the Token 
string connectionString = $"Server={Environment.GetEnvironmentVariable("RDS_ENDPOINT")};" +
                         $"Port={Environment.GetEnvironmentVariable("RDS_PORT")};" +
                         $"Uid={Environment.GetEnvironmentVariable("RDS_USERNAME")};" +
                         $"Pwd={authToken};" +
                         "SslMode=Required;" +
                         "SslCa=/us-east-1-bundle.pem";  // Path to the certificate in container
```

------
#### [ Go ]

Per le funzioni Go che utilizzano connessioni MySQL, carica il certificato Amazon RDS in un pool di certificati e registralo con il driver MySQL. La stringa di connessione deve quindi fare riferimento a questa configurazione utilizzando il parametro `tls`.

**Example Codice Go per la connessione MySQL nella funzione OCI**  

```
import (
    "crypto/tls"
    "crypto/x509"
    "os"
    "github.com/go-sql-driver/mysql"
)

...

// Create certificate pool and register TLS config
rootCertPool := x509.NewCertPool()
pem, err := os.ReadFile("/us-east-1-bundle.pem")  // Path to the certificate in container
if err != nil {
    panic("failed to read certificate file: " + err.Error())
}
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
    panic("failed to append PEM")
}

mysql.RegisterTLSConfig("custom", &tls.Config{
    RootCAs: rootCertPool,
})

dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?allowCleartextPasswords=true&tls=custom",
    dbUser, authenticationToken, dbEndpoint, dbName,
)
```

------
#### [ Ruby ]

**Example Configurazione della connessione Ruby per la funzione OCI**  

```
conn = Mysql2::Client.new(
    host: endpoint,
    username: user,
    password: token,
    port: port,
    database: db_name,
    sslca: '/us-east-1-bundle.pem',  # Path to the certificate in container
    sslverify: true
)
```

------

## Connessione a un database Amazon RDS in una funzione Lambda
<a name="rds-connection"></a>

Gli esempi di codice seguenti mostrano come implementare una funzione Lambda che si connette a un database Amazon RDS. La funzione effettua una semplice richiesta al database e restituisce il risultato.

**Nota**  
Questi esempi di codice sono validi solo per i [pacchetti di implementazione .zip](configuration-function-zip.md). Se stai implementando la funzione utilizzando un'[immagine container,](images-create.md) devi specificare il file del certificato Amazon RDS nel codice della funzione, come spiegato nella [sezione precedente](#oci-certificate).

------
#### [ .NET ]

**SDK per .NET**  
 C'è di più su. GitHub Trova l’esempio completo e scopri come eseguire la configurazione e l’esecuzione nel repository di [Esempi serverless](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connessione a un database Amazon RDS in una funzione Lambda con .NET.  

```
using System.Data;
using System.Text.Json;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;
using MySql.Data.MySqlClient;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace aws_rds;

public class InputModel
{
    public string key1 { get; set; }
    public string key2 { get; set; }
}

public class Function
{
    /// <summary>
    // Handles the Lambda function execution for connecting to RDS using IAM authentication.
    /// </summary>
    /// <param name="input">The input event data passed to the Lambda function</param>
    /// <param name="context">The Lambda execution context that provides runtime information</param>
    /// <returns>A response object containing the execution result</returns>

    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        // Sample Input: {"body": "{\"key1\":\"20\", \"key2\":\"25\"}"}
        var input = JsonSerializer.Deserialize<InputModel>(request.Body);

        /// Obtain authentication token
        var authToken = RDSAuthTokenGenerator.GenerateAuthToken(
            Environment.GetEnvironmentVariable("RDS_ENDPOINT"),
            Convert.ToInt32(Environment.GetEnvironmentVariable("RDS_PORT")),
            Environment.GetEnvironmentVariable("RDS_USERNAME")
        );

        /// Build the Connection String with the Token 
        string connectionString = $"Server={Environment.GetEnvironmentVariable("RDS_ENDPOINT")};" +
                                  $"Port={Environment.GetEnvironmentVariable("RDS_PORT")};" +
                                  $"Uid={Environment.GetEnvironmentVariable("RDS_USERNAME")};" +
                                  $"Pwd={authToken};";


        try
        {
            await using var connection = new MySqlConnection(connectionString);
            await connection.OpenAsync();

            const string sql = "SELECT @param1 + @param2 AS Sum";

            await using var command = new MySqlCommand(sql, connection);
            command.Parameters.AddWithValue("@param1", int.Parse(input.key1 ?? "0"));
            command.Parameters.AddWithValue("@param2", int.Parse(input.key2 ?? "0"));

            await using var reader = await command.ExecuteReaderAsync();
            if (await reader.ReadAsync())
            {
                int result = reader.GetInt32("Sum");

                //Sample Response: {"statusCode":200,"body":"{\"message\":\"The sum is: 45\"}","isBase64Encoded":false}
                return new APIGatewayProxyResponse
                {
                    StatusCode = 200,
                    Body = JsonSerializer.Serialize(new { message = $"The sum is: {result}" })
                };
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }

        return new APIGatewayProxyResponse
        {
            StatusCode = 500,
            Body = JsonSerializer.Serialize(new { error = "Internal server error" })
        };
    }
}
```

------
#### [ Go ]

**SDK per Go V2**  
 C'è dell'altro GitHub. Trova l’esempio completo e scopri come eseguire la configurazione e l’esecuzione nel repository di [Esempi serverless](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connessione a un database Amazon RDS in una funzione Lambda tramite Go.  

```
/*
Golang v2 code here.
*/

package main

import (
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"os"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/feature/rds/auth"
	_ "github.com/go-sql-driver/mysql"
)

type MyEvent struct {
	Name string `json:"name"`
}

func HandleRequest(event *MyEvent) (map[string]interface{}, error) {

	var dbName string = os.Getenv("DatabaseName")
	var dbUser string = os.Getenv("DatabaseUser")
	var dbHost string = os.Getenv("DBHost") // Add hostname without https
	var dbPort int = os.Getenv("Port")      // Add port number
	var dbEndpoint string = fmt.Sprintf("%s:%d", dbHost, dbPort)
	var region string = os.Getenv("AWS_REGION")

	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		panic("configuration error: " + err.Error())
	}

	authenticationToken, err := auth.BuildAuthToken(
		context.TODO(), dbEndpoint, region, dbUser, cfg.Credentials)
	if err != nil {
		panic("failed to create authentication token: " + err.Error())
	}

	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=true&allowCleartextPasswords=true",
		dbUser, authenticationToken, dbEndpoint, dbName,
	)

	db, err := sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}

	defer db.Close()

	var sum int
	err = db.QueryRow("SELECT ?+? AS sum", 3, 2).Scan(&sum)
	if err != nil {
		panic(err)
	}
	s := fmt.Sprint(sum)
	message := fmt.Sprintf("The selected sum is: %s", s)

	messageBytes, err := json.Marshal(message)
	if err != nil {
		return nil, err
	}

	messageString := string(messageBytes)
	return map[string]interface{}{
		"statusCode": 200,
		"headers":    map[string]string{"Content-Type": "application/json"},
		"body":       messageString,
	}, nil
}

func main() {
	lambda.Start(HandleRequest)
}
```

------
#### [ Java ]

**SDK per Java 2.x**  
 C'è dell'altro GitHub. Trova l’esempio completo e scopri come eseguire la configurazione e l’esecuzione nel repository di [Esempi serverless](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connessione a un database Amazon RDS in una funzione Lambda tramite Java.  

```
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.rdsdata.RdsDataClient;
import software.amazon.awssdk.services.rdsdata.model.ExecuteStatementRequest;
import software.amazon.awssdk.services.rdsdata.model.ExecuteStatementResponse;
import software.amazon.awssdk.services.rdsdata.model.Field;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class RdsLambdaHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {

    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();

        try {
            // Obtain auth token
            String token = createAuthToken();

            // Define connection configuration
            String connectionString = String.format("jdbc:mysql://%s:%s/%s?useSSL=true&requireSSL=true",
                    System.getenv("ProxyHostName"),
                    System.getenv("Port"),
                    System.getenv("DBName"));

            // Establish a connection to the database
            try (Connection connection = DriverManager.getConnection(connectionString, System.getenv("DBUserName"), token);
                 PreparedStatement statement = connection.prepareStatement("SELECT ? + ? AS sum")) {

                statement.setInt(1, 3);
                statement.setInt(2, 2);

                try (ResultSet resultSet = statement.executeQuery()) {
                    if (resultSet.next()) {
                        int sum = resultSet.getInt("sum");
                        response.setStatusCode(200);
                        response.setBody("The selected sum is: " + sum);
                    }
                }
            }

        } catch (Exception e) {
            response.setStatusCode(500);
            response.setBody("Error: " + e.getMessage());
        }

        return response;
    }

    private String createAuthToken() {
        // Create RDS Data Service client
        RdsDataClient rdsDataClient = RdsDataClient.builder()
                .region(Region.of(System.getenv("AWS_REGION")))
                .credentialsProvider(DefaultCredentialsProvider.create())
                .build();

        // Define authentication request
        ExecuteStatementRequest request = ExecuteStatementRequest.builder()
                .resourceArn(System.getenv("ProxyHostName"))
                .secretArn(System.getenv("DBUserName"))
                .database(System.getenv("DBName"))
                .sql("SELECT 'RDS IAM Authentication'")
                .build();

        // Execute request and obtain authentication token
        ExecuteStatementResponse response = rdsDataClient.executeStatement(request);
        Field tokenField = response.records().get(0).get(0);

        return tokenField.stringValue();
    }
}
```

------
#### [ JavaScript ]

**SDK per JavaScript (v3)**  
 C'è altro da fare. GitHub Trova l’esempio completo e scopri come eseguire la configurazione e l’esecuzione nel repository di [Esempi serverless](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connessione a un database Amazon RDS in una funzione Lambda utilizzando. JavaScript  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/* 
Node.js code here.
*/
// ES6+ example
import { Signer } from "@aws-sdk/rds-signer";
import mysql from 'mysql2/promise';

async function createAuthToken() {
  // Define connection authentication parameters
  const dbinfo = {

    hostname: process.env.ProxyHostName,
    port: process.env.Port,
    username: process.env.DBUserName,
    region: process.env.AWS_REGION,

  }

  // Create RDS Signer object
  const signer = new Signer(dbinfo);

  // Request authorization token from RDS, specifying the username
  const token = await signer.getAuthToken();
  return token;
}

async function dbOps() {

  // Obtain auth token
  const token = await createAuthToken();
  // Define connection configuration
  let connectionConfig = {
    host: process.env.ProxyHostName,
    user: process.env.DBUserName,
    password: token,
    database: process.env.DBName,
    ssl: 'Amazon RDS'
  }
  // Create the connection to the DB
  const conn = await mysql.createConnection(connectionConfig);
  // Obtain the result of the query
  const [res,] = await conn.execute('select ?+? as sum', [3, 2]);
  return res;

}

export const handler = async (event) => {
  // Execute database flow
  const result = await dbOps();
  // Return result
  return {
    statusCode: 200,
    body: JSON.stringify("The selected sum is: " + result[0].sum)
  }
};
```
Connessione a un database Amazon RDS in una funzione Lambda utilizzando. TypeScript  

```
import { Signer } from "@aws-sdk/rds-signer";
import mysql from 'mysql2/promise';

// RDS settings
// Using '!' (non-null assertion operator) to tell the TypeScript compiler that the DB settings are not null or undefined,
const proxy_host_name = process.env.PROXY_HOST_NAME!
const port = parseInt(process.env.PORT!)
const db_name = process.env.DB_NAME!
const db_user_name = process.env.DB_USER_NAME!
const aws_region = process.env.AWS_REGION!


async function createAuthToken(): Promise<string> {

    // Create RDS Signer object
    const signer = new Signer({
        hostname: proxy_host_name,
        port: port,
        region: aws_region,
        username: db_user_name
    });

    // Request authorization token from RDS, specifying the username
    const token = await signer.getAuthToken();
    return token;
}

async function dbOps(): Promise<mysql.QueryResult | undefined> {
    try {
        // Obtain auth token
        const token = await createAuthToken();
        const conn = await mysql.createConnection({
            host: proxy_host_name,
            user: db_user_name,
            password: token,
            database: db_name,
            ssl: 'Amazon RDS' // Ensure you have the CA bundle for SSL connection
        });
        const [rows, fields] = await conn.execute('SELECT ? + ? AS sum', [3, 2]);
        console.log('result:', rows);
        return rows;
    }
    catch (err) {
        console.log(err);
    }
}

export const lambdaHandler = async (event: any): Promise<{ statusCode: number; body: string }> => {
    // Execute database flow
    const result = await dbOps();

    // Return error is result is undefined
    if (result == undefined)
        return {
            statusCode: 500,
            body: JSON.stringify(`Error with connection to DB host`)
        }

    // Return result
    return {
        statusCode: 200,
        body: JSON.stringify(`The selected sum is: ${result[0].sum}`)
    };
};
```

------
#### [ PHP ]

**SDK per PHP**  
 C'è di più su. GitHub Trova l’esempio completo e scopri come eseguire la configurazione e l’esecuzione nel repository di [Esempi serverless](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connessione a un database Amazon RDS in una funzione Lambda tramite PHP.  

```
<?php
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# using bref/bref and bref/logger for simplicity

use Bref\Context\Context;
use Bref\Event\Handler as StdHandler;
use Bref\Logger\StderrLogger;
use Aws\Rds\AuthTokenGenerator;
use Aws\Credentials\CredentialProvider;

require __DIR__ . '/vendor/autoload.php';

class Handler implements StdHandler
{
    private StderrLogger $logger;
    public function __construct(StderrLogger $logger)
    {
        $this->logger = $logger;
    }


    private function getAuthToken(): string {
        // Define connection authentication parameters
        $dbConnection = [
            'hostname' => getenv('DB_HOSTNAME'),
            'port' => getenv('DB_PORT'),
            'username' => getenv('DB_USERNAME'),
            'region' => getenv('AWS_REGION'),
        ];

        // Create RDS AuthTokenGenerator object
        $generator = new AuthTokenGenerator(CredentialProvider::defaultProvider());

        // Request authorization token from RDS, specifying the username
        return $generator->createToken(
            $dbConnection['hostname'] . ':' . $dbConnection['port'],
            $dbConnection['region'],
            $dbConnection['username']
        );
    }

    private function getQueryResults() {
        // Obtain auth token
        $token = $this->getAuthToken();

        // Define connection configuration
        $connectionConfig = [
            'host' => getenv('DB_HOSTNAME'),
            'user' => getenv('DB_USERNAME'),
            'password' => $token,
            'database' => getenv('DB_NAME'),
        ];

        // Create the connection to the DB
        $conn = new PDO(
            "mysql:host={$connectionConfig['host']};dbname={$connectionConfig['database']}",
            $connectionConfig['user'],
            $connectionConfig['password'],
            [
                PDO::MYSQL_ATTR_SSL_CA => '/path/to/rds-ca-2019-root.pem',
                PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
            ]
        );

        // Obtain the result of the query
        $stmt = $conn->prepare('SELECT ?+? AS sum');
        $stmt->execute([3, 2]);

        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    /**
     * @param mixed $event
     * @param Context $context
     * @return array
     */
    public function handle(mixed $event, Context $context): array
    {
        $this->logger->info("Processing query");

        // Execute database flow
        $result = $this->getQueryResults();

        return [
            'sum' => $result['sum']
        ];
    }
}

$logger = new StderrLogger();
return new Handler($logger);
```

------
#### [ Python ]

**SDK per Python (Boto3)**  
 C'è dell'altro GitHub. Trova l’esempio completo e scopri come eseguire la configurazione e l’esecuzione nel repository di [Esempi serverless](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connessione a un database Amazon RDS in una funzione Lambda tramite Python.  

```
import json
import os
import boto3
import pymysql

# RDS settings
proxy_host_name = os.environ['PROXY_HOST_NAME']
port = int(os.environ['PORT'])
db_name = os.environ['DB_NAME']
db_user_name = os.environ['DB_USER_NAME']
aws_region = os.environ['AWS_REGION']


# Fetch RDS Auth Token
def get_auth_token():
    client = boto3.client('rds')
    token = client.generate_db_auth_token(
        DBHostname=proxy_host_name,
        Port=port
        DBUsername=db_user_name
        Region=aws_region
    )
    return token

def lambda_handler(event, context):
    token = get_auth_token()
    try:
        connection = pymysql.connect(
            host=proxy_host_name,
            user=db_user_name,
            password=token,
            db=db_name,
            port=port,
            ssl={'ca': 'Amazon RDS'}  # Ensure you have the CA bundle for SSL connection
        )
        
        with connection.cursor() as cursor:
            cursor.execute('SELECT %s + %s AS sum', (3, 2))
            result = cursor.fetchone()

        return result
        
    except Exception as e:
        return (f"Error: {str(e)}")  # Return an error message if an exception occurs
```

------
#### [ Ruby ]

**SDK per Ruby**  
 C'è dell'altro GitHub. Trova l’esempio completo e scopri come eseguire la configurazione e l’esecuzione nel repository di [Esempi serverless](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connessione a un database Amazon RDS in una funzione Lambda tramite Ruby.  

```
# Ruby code here.

require 'aws-sdk-rds'
require 'json'
require 'mysql2'

def lambda_handler(event:, context:)
  endpoint = ENV['DBEndpoint'] # Add the endpoint without https"
  port = ENV['Port']           # 3306
  user = ENV['DBUser']
  region = ENV['DBRegion']     # 'us-east-1'
  db_name = ENV['DBName']

  credentials = Aws::Credentials.new(
    ENV['AWS_ACCESS_KEY_ID'],
    ENV['AWS_SECRET_ACCESS_KEY'],
    ENV['AWS_SESSION_TOKEN']
  )
  rds_client = Aws::RDS::AuthTokenGenerator.new(
    region: region, 
    credentials: credentials
  )

  token = rds_client.auth_token(
    endpoint: endpoint+ ':' + port,
    user_name: user,
    region: region
  )

  begin
    conn = Mysql2::Client.new(
      host: endpoint,
      username: user,
      password: token,
      port: port,
      database: db_name,
      sslca: '/var/task/global-bundle.pem', 
      sslverify: true,
      enable_cleartext_plugin: true
    )
    a = 3
    b = 2
    result = conn.query("SELECT #{a} + #{b} AS sum").first['sum']
    puts result
    conn.close
    {
      statusCode: 200,
      body: result.to_json
    }
  rescue => e
    puts "Database connection failed due to #{e}"
  end
end
```

------
#### [ Rust ]

**SDK per Rust**  
 C'è altro da fare. GitHub Trova l’esempio completo e scopri come eseguire la configurazione e l’esecuzione nel repository di [Esempi serverless](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connessione a un database Amazon RDS in una funzione Lambda tramite Rust.  

```
use aws_config::BehaviorVersion;
use aws_credential_types::provider::ProvideCredentials;
use aws_sigv4::{
    http_request::{sign, SignableBody, SignableRequest, SigningSettings},
    sign::v4,
};
use lambda_runtime::{run, service_fn, Error, LambdaEvent};
use serde_json::{json, Value};
use sqlx::postgres::PgConnectOptions;
use std::env;
use std::time::{Duration, SystemTime};

const RDS_CERTS: &[u8] = include_bytes!("global-bundle.pem");

async fn generate_rds_iam_token(
    db_hostname: &str,
    port: u16,
    db_username: &str,
) -> Result<String, Error> {
    let config = aws_config::load_defaults(BehaviorVersion::v2024_03_28()).await;

    let credentials = config
        .credentials_provider()
        .expect("no credentials provider found")
        .provide_credentials()
        .await
        .expect("unable to load credentials");
    let identity = credentials.into();
    let region = config.region().unwrap().to_string();

    let mut signing_settings = SigningSettings::default();
    signing_settings.expires_in = Some(Duration::from_secs(900));
    signing_settings.signature_location = aws_sigv4::http_request::SignatureLocation::QueryParams;

    let signing_params = v4::SigningParams::builder()
        .identity(&identity)
        .region(&region)
        .name("rds-db")
        .time(SystemTime::now())
        .settings(signing_settings)
        .build()?;

    let url = format!(
        "https://{db_hostname}:{port}/?Action=connect&DBUser={db_user}",
        db_hostname = db_hostname,
        port = port,
        db_user = db_username
    );

    let signable_request =
        SignableRequest::new("GET", &url, std::iter::empty(), SignableBody::Bytes(&[]))
            .expect("signable request");

    let (signing_instructions, _signature) =
        sign(signable_request, &signing_params.into())?.into_parts();

    let mut url = url::Url::parse(&url).unwrap();
    for (name, value) in signing_instructions.params() {
        url.query_pairs_mut().append_pair(name, &value);
    }

    let response = url.to_string().split_off("https://".len());

    Ok(response)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    run(service_fn(handler)).await
}

async fn handler(_event: LambdaEvent<Value>) -> Result<Value, Error> {
    let db_host = env::var("DB_HOSTNAME").expect("DB_HOSTNAME must be set");
    let db_port = env::var("DB_PORT")
        .expect("DB_PORT must be set")
        .parse::<u16>()
        .expect("PORT must be a valid number");
    let db_name = env::var("DB_NAME").expect("DB_NAME must be set");
    let db_user_name = env::var("DB_USERNAME").expect("DB_USERNAME must be set");

    let token = generate_rds_iam_token(&db_host, db_port, &db_user_name).await?;

    let opts = PgConnectOptions::new()
        .host(&db_host)
        .port(db_port)
        .username(&db_user_name)
        .password(&token)
        .database(&db_name)
        .ssl_root_cert_from_pem(RDS_CERTS.to_vec())
        .ssl_mode(sqlx::postgres::PgSslMode::Require);

    let pool = sqlx::postgres::PgPoolOptions::new()
        .connect_with(opts)
        .await?;

    let result: i32 = sqlx::query_scalar("SELECT $1 + $2")
        .bind(3)
        .bind(2)
        .fetch_one(&pool)
        .await?;

    println!("Result: {:?}", result);

    Ok(json!({
        "statusCode": 200,
        "content-type": "text/plain",
        "body": format!("The selected sum is: {result}")
    }))
}
```

------

## Elaborazione di notifiche di eventi da Amazon RDS
<a name="rds-events"></a>

Puoi utilizzare Lambda per elaborare le notifiche degli eventi da un database Amazon RDS. Amazon RDS invia le notifiche a un argomento Amazon Simple Notification Service (Amazon SNS), che puoi configurare per richiamare una funzione Lambda. Amazon SNS avvolge il messaggio proveniente da Amazon RDS nel proprio documento evento e lo invia alla tua funzione.

Per ulteriori informazioni sulla configurazione di un database Amazon RDS per l'invio di notifiche, consulta [Utilizzo delle notifiche di eventi di Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html). 

**Example Messaggio Amazon RDS in un evento Amazon SNS**  

```
{
        "Records": [
          {
            "EventVersion": "1.0",
            "EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:rds-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
            "EventSource": "aws:sns",
            "Sns": {
              "SignatureVersion": "1",
              "Timestamp": "2023-01-02T12:45:07.000Z",
              "Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==",
              "SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem",
              "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
              "Message": "{\"Event Source\":\"db-instance\",\"Event Time\":\"2023-01-02 12:45:06.000\",\"Identifier Link\":\"https://console.aws.amazon.com/rds/home?region=eu-west-1#dbinstance:id=dbinstanceid\",\"Source ID\":\"dbinstanceid\",\"Event ID\":\"http://docs.amazonwebservices.com/AmazonRDS/latest/UserGuide/USER_Events.html#RDS-EVENT-0002\",\"Event Message\":\"Finished DB Instance backup\"}",
              "MessageAttributes": {},
              "Type": "Notification",
              "UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&amp;SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
              "TopicArn":"arn:aws:sns:us-east-2:123456789012:sns-lambda",
              "Subject": "RDS Notification Message"
            }
          }
        ]
      }
```

## Completare il tutorial su Lambda e Amazon RDS
<a name="rds-database-samples"></a>
+ [Uso di una funzione Lambda per accedere a un database Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html): seguendo la Guida per l'utente di Amazon RDS, impara come utilizzare una funzione Lambda per scrivere dati su un database Amazon RDS attraverso un Server proxy per Amazon RDS. La funzione Lambda leggerà i record da una coda di Amazon SQS e scriverà nuove voci in una tabella del database ogni volta che verrà aggiunto un messaggio.

# Seleziona un servizio di database per le tue applicazioni basate su Lambda
<a name="ddb-rds-database-decision"></a>

Molte applicazioni serverless devono archiviare e recuperare dati. AWS offre diverse opzioni di database che funzionano con le funzioni Lambda. Due delle scelte più popolari sono Amazon DynamoDB, un servizio di database NoSQL, e Amazon RDS, una soluzione di database relazionale tradizionale. Le sezioni seguenti spiegano le principali differenze tra questi servizi quando vengono utilizzati con Lambda e ti aiutano a selezionare il servizio di database giusto per la tua applicazione serverless.

Per saperne di più sugli altri servizi di database offerti da AWS e per comprenderne i casi d'uso e i compromessi in generale, consulta [Scelta di un AWS](https://docs.aws.amazon.com/decision-guides/latest/databases-on-aws-how-to-choose/databases-on-aws-how-to-choose.html) servizio di database. Tutti i servizi di database AWS sono compatibili con Lambda, ma non tutti possono essere adatti al tuo caso d'uso specifico.

## Quali sono le tue scelte quando selezioni un servizio di database con Lambda?
<a name="w2aad101d101c19b9"></a>

AWS offre diversi servizi di database. Per le applicazioni serverless, due delle scelte più popolari sono DynamoDB e Amazon RDS.
+ **DynamoDB** è un servizio di database NoSQL completamente gestito ottimizzato per le applicazioni serverless. Fornisce una scalabilità ottimale e prestazioni costanti in millisecondi su qualsiasi scala.
+ **Amazon RDS** è un servizio di database relazionale gestito che supporta più motori di database tra cui MySQL e PostgreSQL. Fornisce funzionalità SQL familiari con un'infrastruttura gestita.

## Suggerimenti se conosci già le tue esigenze
<a name="w2aad101d101c19c11"></a>

Se hai già le idee chiare sulle tue esigenze, ecco i nostri suggerimenti di base:

Consigliamo [DynamoDB](with-ddb.md) per applicazioni serverless che richiedono prestazioni costanti a bassa latenza, scalabilità automatica e non richiedono join o transazioni complesse. È particolarmente adatto per applicazioni basate su Lambda grazie alla sua natura serverless.

[Amazon RDS](services-rds.md) è la scelta migliore quando hai bisogno di query SQL complesse, join o se hai applicazioni esistenti che utilizzano database relazionali. Tuttavia, tieni presente che la connessione delle funzioni Lambda ad Amazon RDS richiede una configurazione aggiuntiva e può influire sui tempi di avvio a freddo.

## Aspetti da tenere in considerazione selezioni un servizio di database
<a name="w2aad101d101c19c13"></a>

Quando scegli tra DynamoDB e Amazon RDS per le tue applicazioni Lambda, considera questi fattori:
+ Gestione delle connessioni e avvii a freddo
+ Modelli di accesso ai dati
+ Complessità delle query
+ Requisiti di coerenza dei dati
+ Caratteristiche di scalabilità
+ Modello di costi

Se conosci questi fattori, puoi selezionare l'opzione che soddisfa al meglio le esigenze del caso d'uso specifico.

### Gestione delle connessioni e avvii a freddo
<a name="w2aad101d101c19c13b9b1"></a>
+ DynamoDB utilizza un'API HTTP per tutte le operazioni. Le funzioni Lambda possono effettuare richieste immediate senza mantenere le connessioni, con conseguente miglioramento delle prestazioni di avvio a freddo. Ogni richiesta viene autenticata utilizzando AWS credenziali senza sovraccarico di connessione.
+ Amazon RDS richiede la gestione dei pool di connessioni poiché utilizza connessioni di database tradizionali. Ciò può influire sugli avvii a freddo poiché le nuove istanze Lambda devono stabilire connessioni. Dovrai implementare strategie di pool di connessioni e potenzialmente utilizzare il [Server proxy per Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) per gestire le connessioni in modo efficace. Tieni presente che l'utilizzo del Server proxy per Amazon RDS comporta costi aggiuntivi.

### Modelli di accesso ai dati
<a name="w2aad101d101c19c13b9b3"></a>
+ DynamoDB funziona al meglio con modelli di accesso noti e design a tabella singola. È ideale per applicazioni Lambda che richiedono un accesso coerente a bassa latenza ai dati basato su chiavi primarie o indici secondari.
+ Amazon RDS offre flessibilità per query complesse e modelli di accesso in evoluzione. È più adatto quando le funzioni Lambda devono eseguire query uniche e personalizzate o join complessi su più tabelle.

### Complessità delle query
<a name="w2aad101d101c19c13b9b5"></a>
+ DynamoDB eccelle nelle operazioni semplici basate su chiavi e nei modelli di accesso predefiniti. Le query complesse devono essere progettate sulla base di strutture indicizzate e i join devono essere gestiti nel codice dell'applicazione.
+ Amazon RDS supporta query SQL complesse con join, sottoquery e aggregazioni. Questo può semplificare il codice della funzione Lambda quando sono necessarie operazioni complesse sui dati.

### Requisiti di coerenza dei dati
<a name="w2aad101d101c19c13b9b7"></a>
+ DynamoDB offre opzioni di coerenza sia finali che avanzate, con una forte coerenza disponibile per le letture di singoli elementi. Le transazioni sono supportate ma con alcune limitazioni.
+ Amazon RDS garantisce la conformità completa di atomicità, coerenza, isolamento e durabilità (ACID) e supporto per transazioni complesse. Se le tue funzioni Lambda richiedono transazioni complesse o una forte coerenza tra più record, Amazon RDS potrebbe essere più adatto.

### Caratteristiche di scalabilità
<a name="w2aad101d101c19c13b9b9"></a>
+ DynamoDB si adatta automaticamente al carico di lavoro. È in grado di gestire picchi improvvisi di traffico provenienti da funzioni Lambda senza pre-provisioning. Puoi utilizzare la modalità di capacità su richiesta per pagare solo per ciò che usi, in linea con il modello di scalabilità di Lambda.
+ Amazon RDS ha una capacità fissa in base alla dimensione dell'istanza scelta. Se più funzioni Lambda tentano di connettersi contemporaneamente, potresti superare la quota di connessione. È necessario gestire con attenzione i pool di connessioni e potenzialmente implementare la logica dei tentativi.

### Modello di costi
<a name="w2aad101d101c19c13b9c11"></a>
+ I prezzi di DynamoDB si allineano bene con le applicazioni serverless. Con la capacità su richiesta, paghi solo per le letture e le scritture effettive eseguite dalle tue funzioni Lambda. Non sono previsti addebiti per i tempi di inattività.
+ Amazon RDS addebita i costi per l'istanza in esecuzione indipendentemente dall'utilizzo. Questo può essere meno conveniente per i carichi di lavoro sporadici che possono essere tipici delle applicazioni serverless. Tuttavia, potrebbe essere più economico per carichi di lavoro ad alto throughput con un utilizzo costante.

## Nozioni di base sulle istanze del database da te scelte
<a name="w2aad101d101c19c15"></a>

Ora che hai letto i criteri per scegliere tra DynamoDB and Amazon RDS e le principali differenze tra questi, puoi selezionare l'opzione più adatta alle tue esigenze e utilizzare le seguenti risorse per iniziare a utilizzarla.

------
#### [ DynamoDB ]

**Iniziare a usare DynamoDB con le seguenti risorse**
+ Per un'introduzione al servizio DynamoDB, leggi [Cos'è DynamoDB?](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) nella *Guida per gli sviluppatori di Amazon DynamoDB*.
+ Segui il tutorial [Uso di Lambda con API Gateway](services-apigateway-tutorial.md) per vedere un esempio di utilizzo di una funzione Lambda per eseguire operazioni CRUD su una tabella DynamoDB in risposta a una richiesta API.
+ Leggi [Programming with DynamoDB e AWS SDKs](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.html) la Amazon *DynamoDB Developer Guide per ulteriori informazioni su come accedere a DynamoDB* dall'interno della tua funzione Lambda utilizzando una delle. AWS SDKs

------
#### [ Amazon RDS ]

**Iniziare a usare Amazon RDS con le seguenti risorse**
+ Per un'introduzione al servizio Amazon RDS, leggi [Cos'è Amazon Relational Database Service (Amazon RDS)?](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) nella *Guida per l’utente di Amazon Relational Database Service*.
+ Segui il tutorial [Uso di una funzione Lambda per accedere a un database Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html) nella *Guida per l’utente di Amazon Relational Database Service*.
+ Per ulteriori informazioni sull'uso di Lambda con Amazon RDS, consulta [Utilizzo AWS Lambda con Amazon RDS](services-rds.md).

------