

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Utilisation AWS Lambda avec Amazon RDS
<a name="services-rds"></a>

Vous pouvez connecter une fonction Lambda à une base de données Amazon Relational Database Service (Amazon RDS) directement via un proxy Amazon RDS. Les connexions directes sont utiles dans les scénarios simples, et les proxys sont recommandés pour la production. Un proxy de base de données gère un groupe de connexions partagées à la base de données qui permet à votre fonction d’atteindre des niveaux de simultanéité élevés sans épuiser les connexions de base de données.

Nous recommandons d’utiliser Proxy Amazon RDS pour les fonctions Lambda qui effectuent fréquemment de brèves connexions à la base de données, ou qui ouvrent et ferment un grand nombre de connexions à la base de données. Pour de plus amples informations, veuillez consulter la rubrique [Automatically connecting a Lambda function and a DB instance](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/lambda-rds-connect.html) du Guide du développeur Amazon Relational Database Service.

**Astuce**  
Pour connecter rapidement une fonction Lambda à une base de données Amazon RDS, vous pouvez utiliser l’assistant guidé intégré à la console. Procédez comme suit pour ouvrir l’assistant :  
Ouvrez la [page Functions](https://console.aws.amazon.com/lambda/home#/functions) (Fonctions) de la console Lambda.
Sélectionnez la fonction à laquelle vous souhaitez connecter une base de données.
Dans l’onglet **Configuration**, sélectionnez **Bases de données RDS**.
Choisissez **Se connecter à la base de données RDS**.
Après avoir connecté votre fonction à une base de données, vous pouvez créer un proxy en choisissant **Ajouter un proxy**.

## Configuration de votre fonction pour qu’elle fonctionne avec les ressources RDS
<a name="rds-configuration"></a>

Dans la console Lambda, vous pouvez allouer et configurer des instances de base de données et des ressources de proxy Amazon RDS. Vous pouvez le faire en accédant aux **Bases de données RDS** sous l’onglet **Configuration**. Vous pouvez également créer et configurer des connexions aux fonctions Lambda dans la console Amazon RDS. Lorsque vous configurez une instance de base de données RDS à utiliser avec Lambda, tenez compte des critères suivants :
+ Pour se connecter à une base de données, votre fonction doit résider dans le même Amazon VPC où votre base de données s’exécute.
+ Vous pouvez utiliser les bases de données Amazon RDS avec les moteurs MySQL, MariaDB, PostgreSQL ou Microsoft SQL Server.
+ Vous pouvez également utiliser des clusters de base de données Aurora avec des moteurs MySQL ou PostgreSQL.
+ Vous devez fournir un secret Secrets Manager pour l’authentification de la base de données.
+ Un rôle IAM doit autoriser l’utilisation du secret et une stratégie d’approbation doit autoriser Amazon RDS à endosser le rôle.
+  Le principal IAM qui utilise la console pour configurer la ressource Amazon RDS et la connecter à votre fonction doit disposer des autorisations suivantes :

### Exemple de politique d’autorisations
<a name="rds-lambda-permissions"></a>

**Note**  
 Vous n’avez besoin des autorisations de Proxy Amazon RDS que si vous configurez un Proxy Amazon RDS pour gérer un pool de connexions à votre base de données. 

------
#### [ 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 facture un tarif horaire pour les proxys en fonction de la taille de l’instance de base de données. Consultez la [tarification des proxys RDS](https://aws.amazon.com/rds/proxy/pricing/) pour plus de détails. Pour plus d’informations sur les connexions de proxy en général, consultez [Utilisation de Proxy Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) dans le Guide de l’utilisateur Amazon RDS.

### Exigences SSL/TLS pour les connexions Amazon RDS
<a name="rds-lambda-certificates"></a>

Pour établir des SSL/TLS connexions sécurisées à une instance de base de données Amazon RDS, votre fonction Lambda doit vérifier l'identité du serveur de base de données à l'aide d'un certificat sécurisé. Lambda gère ces certificats différemment selon le type de package de déploiement :
+ [Archives .zip](configuration-function-zip.md) : la gestion des certificats varie en fonction de l’environnement d’exécution :
  + **Node.js 18 et versions antérieures** : Lambda inclut automatiquement les certificats CA et RDS.
  + **Node.js 20 et versions ultérieures** : Lambda ne charge plus de certificats CA supplémentaires par défaut. Définissez la variable d'environnement `NODE_EXTRA_CA_CERTS` sur `/var/runtime/ca-cert.pem`.

  L'ajout de nouveaux certificats Amazon RDS aux environnements d'exécution gérés par Lambda peut Régions AWS prendre jusqu'à 4 semaines.
+ [Images de conteneur](images-create.md) : les images AWS de base incluent uniquement les certificats CA. Si votre fonction se connecte à une instance de base de données Amazon RDS, vous devez inclure les certificats appropriés dans votre image de conteneur. Dans votre Dockerfile, téléchargez le [bundle de certificats correspondant à l' Région AWS endroit où vous hébergez votre](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html#UsingWithRDS.SSL.CertificatesDownload) base de données. Exemple :

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

Cette commande télécharge le bundle de certificats Amazon RDS et l’enregistre sur le chemin absolu `/us-east-1-bundle.pem` dans le répertoire racine de votre conteneur. Lorsque vous configurez la connexion à la base de données dans le code de votre fonction, vous devez référencer ce chemin exact. Exemple :

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

La fonction `readFileSync` est requise, car les clients de base de données Node.js ont besoin du contenu réel du certificat en mémoire, et pas seulement du chemin d’accès au fichier de certificat. Sans `readFileSync`, le client interprète la chaîne de chemin comme le contenu du certificat, ce qui entraîne une erreur « certificat autosigné dans la chaîne de certificats ».

**Example Configuration de la connexion pour la fonction OCI Node.js**  

```
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 Configuration de la connexion pour la fonction OCI Python**  

```
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 ]

Pour les fonctions Java utilisant des connexions JDBC, la chaîne de connexion doit inclure :
+ `useSSL=true`
+ `requireSSL=true`
+ Paramètre `sslCA` indiquant l’emplacement du certificat Amazon RDS dans l’image de conteneur

**Example Chaîne de connexion pour la fonction OCI Java**  

```
// 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 Chaîne de connexion pour la connexion MySQL dans la fonction OCI .NET**  

```
/// 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 ]

Pour les fonctions Go utilisant des connexions MySQL, chargez le certificat Amazon RDS dans un groupe de certificats et enregistrez-le avec le pilote MySQL. La chaîne de connexion doit ensuite référencer cette configuration à l’aide du paramètre `tls`.

**Example Code Go pour la connexion MySQL dans la fonction 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 Configuration de connexion Ruby pour la fonction 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
)
```

------

## Connexion à une base de données Amazon RDS dans une fonction Lambda
<a name="rds-connection"></a>

L’exemple de code suivant illustre comment implémenter une fonction Lambda qui se connecte à une base de données Amazon RDS. La fonction effectue une simple requête de base de données et renvoie le résultat.

**Note**  
Ces exemples de code ne sont valides que pour les [packages de déploiement .zip](configuration-function-zip.md). Si vous déployez votre fonction à l’aide d’une [image de conteneur](images-create.md), vous devez spécifier le fichier de certificat Amazon RDS dans le code de votre fonction, comme expliqué dans la [section précédente](#oci-certificate).

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

**SDK pour .NET**  
 Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’[exemples sans serveur](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connexion à une base de données Amazon RDS dans une fonction Lambda à l’aide de .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 ]

**Kit SDK pour Go V2**  
 Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’[exemples sans serveur](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connexion à une base de données Amazon RDS dans une fonction Lambda à l’aide de 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 pour Java 2.x**  
 Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’[exemples sans serveur](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connexion à une base de données Amazon RDS dans une fonction Lambda à l’aide de 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 pour JavaScript (v3)**  
 Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’[exemples sans serveur](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connexion à une base de données Amazon RDS dans une fonction Lambda à l'aide de. 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)
  }
};
```
Connexion à une base de données Amazon RDS dans une fonction Lambda à l'aide de. 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 ]

**Kit SDK pour PHP**  
 Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’[exemples sans serveur](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connexion à une base de données Amazon RDS dans une fonction Lambda à l’aide de 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 ]

**Kit SDK for Python (Boto3)**  
 Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’[exemples sans serveur](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connexion à une base de données Amazon RDS dans une fonction Lambda à l’aide de 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 ]

**Kit SDK pour Ruby**  
 Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’[exemples sans serveur](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connexion à une base de données Amazon RDS dans une fonction Lambda à l’aide de 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 pour Rust**  
 Il y en a plus à ce sujet GitHub. Trouvez l’exemple complet et découvrez comment le configurer et l’exécuter dans le référentiel d’[exemples sans serveur](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Connexion à une base de données Amazon RDS dans une fonction Lambda à l’aide de 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}")
    }))
}
```

------

## Traitement des notifications d’événements provenant d’Amazon RDS
<a name="rds-events"></a>

Vous pouvez utiliser Lambda pour traiter les notifications d’événements d’une base de données Amazon RDS. Amazon RDS envoie des notifications à une rubrique Amazon Simple Notification Service (Amazon SNS) que vous pouvez configurer pour invoquer une fonction Lambda. Amazon SNS enveloppe le message d’Amazon RDS dans son propre document d’événement, et l’envoie à votre fonction.

Pour plus d’informations sur la configuration d’une base de données Amazon RDS pour envoyer des notifications, consultez [Utilisation des notifications d’événements Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html). 

**Example Message Amazon RDS dans un événement 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"
            }
          }
        ]
      }
```

## Tutoriel complet Lambda et Amazon RDS
<a name="rds-database-samples"></a>
+ [Utilisation d’une fonction Lambda pour accéder à une base de données Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html) — Dans le Guide de l’utilisateur Amazon RDS, découvrez comment utiliser une fonction Lambda pour écrire des données dans une base de données Amazon RDS via Proxy Amazon RDS. Votre fonction Lambda lira les enregistrements d’une file d’attente Amazon SQS et écrira de nouveaux éléments dans une table de votre base de données chaque fois qu’un message sera ajouté.

# Sélectionner un service de base de données pour vos applications basées sur Lambda
<a name="ddb-rds-database-decision"></a>

De nombreuses applications sans serveur ont besoin de stocker et de récupérer des données. AWS propose plusieurs options de base de données qui fonctionnent avec les fonctions Lambda. Les deux options les plus populaires sont Amazon DynamoDB, un service de base de données NoSQL, et Amazon RDS, une solution de base de données relationnelle traditionnelle. Les sections suivantes expliquent les principales différences entre ces services lorsque vous les utilisez avec Lambda, et vous aident à sélectionner le service de base de données adapté à votre application sans serveur.

Pour en savoir plus sur les autres services de base de données proposés par AWS, et pour comprendre leurs cas d'utilisation et leurs inconvénients de manière plus générale, voir [Choisir un service de AWS base de données](https://docs.aws.amazon.com/decision-guides/latest/databases-on-aws-how-to-choose/databases-on-aws-how-to-choose.html). Tous les services de base de données AWS sont compatibles avec Lambda, mais ils ne sont pas nécessairement tous adaptés à votre cas d’utilisation particulier.

## Quelles sont les options proposées lors de la sélection d’un service de base de données avec Lambda ?
<a name="w2aad101d101c19b9"></a>

AWS propose plusieurs services de base de données. Pour les applications sans serveur, DynamoDB et Amazon RDS sont deux des options les plus populaires.
+ **DynamoDB** est un service de base de données NoSQL entièrement géré, optimisé pour les applications sans serveur. Il offre une mise à l’échelle transparente et des performances constantes de l’ordre de quelques millisecondes à n’importe quelle échelle.
+ **Amazon RDS** est un service de base de données relationnelle géré qui prend en charge plusieurs moteurs de base de données, dont MySQL et PostgreSQL. Il fournit les fonctionnalités familières de SQL avec une infrastructure gérée.

## Recommandations si vous connaissez déjà vos besoins
<a name="w2aad101d101c19c11"></a>

Si vous connaissez déjà bien vos besoins, voici nos recommandations de base :

Nous recommandons [DynamoDB](with-ddb.md) pour les applications sans serveur qui ont besoin de performances constantes à faible latence et d’une mise à l’échelle automatique, et qui ne nécessitent pas de jointures ou de transactions complexes. Cette solution est particulièrement adaptée aux applications basées sur Lambda en raison de sa nature sans serveur.

[Amazon RDS](services-rds.md) est un meilleur choix lorsque vous avez besoin de requêtes SQL complexes, de jointures ou si vous avez des applications existantes utilisant des bases de données relationnelles. Sachez toutefois que la connexion des fonctions Lambda à Amazon RDS nécessite une configuration supplémentaire et peut avoir un impact sur les temps de démarrage à froid.

## Éléments à prendre en compte lors de la sélection d’un service de base de données
<a name="w2aad101d101c19c13"></a>

Lorsque vous choisissez entre DynamoDB et Amazon RDS pour vos applications Lambda, tenez compte des facteurs suivants :
+ Gestion des connexions et démarrages à froid
+ Modèles d’accès aux données
+ Complexité des requêtes
+ Exigences de cohérence des données
+ Caractéristiques de mise à l’échelle
+ Modèle de coût

La compréhension de ces facteurs vous permettra de choisir l’option qui répond le mieux aux besoins de votre cas d’utilisation.

### Gestion des connexions et démarrages à froid
<a name="w2aad101d101c19c13b9b1"></a>
+ DynamoDB utilise une API HTTP pour toutes les opérations. Les fonctions Lambda peuvent effectuer des requêtes immédiatement sans maintenir de connexion, ce qui améliore les performances de démarrage à froid. Chaque demande est authentifiée à l'aide AWS d'informations d'identification sans surcoût de connexion.
+ Amazon RDS nécessite de gérer des groupes de connexions, car il utilise des connexions de base de données traditionnelles. Cela peut affecter les démarrages à froid, car les nouvelles instances Lambda doivent établir des connexions. Vous devrez mettre en œuvre des stratégies de regroupement de connexions et éventuellement utiliser le [Proxy Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) pour gérer efficacement les connexions. Notez que l’utilisation du Proxy Amazon RDS entraîne des coûts supplémentaires.

### Modèles d’accès aux données
<a name="w2aad101d101c19c13b9b3"></a>
+ DynamoDB fonctionne mieux avec les modèles d’accès connus et les modèles à table unique. Il est idéal pour les applications Lambda qui ont besoin d’un accès constant à faible latence aux données sur la base de clés primaires ou d’index secondaires.
+ Amazon RDS offre de la flexibilité pour les requêtes complexes et les modèles d’accès changeants. Il est mieux adapté lorsque vos fonctions Lambda doivent effectuer des requêtes uniques et personnalisées, ou des jointures complexes sur plusieurs tables.

### Complexité des requêtes
<a name="w2aad101d101c19c13b9b5"></a>
+ DynamoDB excelle dans les opérations simples basées sur les clés et dans les modèles d’accès prédéfinis. Les requêtes complexes doivent être conçues autour de structures d’index, et les jointures doivent être gérées dans le code de l’application.
+ Amazon RDS prend en charge les requêtes SQL complexes avec des jointures, des sous-requêtes et des agrégations. Cela peut simplifier le code de votre fonction Lambda lorsque des opérations de données complexes sont nécessaires.

### Exigences de cohérence des données
<a name="w2aad101d101c19c13b9b7"></a>
+ DynamoDB propose à la fois des options de cohérence finale et de cohérence forte, la cohérence forte étant disponible pour les lectures d’un seul élément. Les transactions sont prises en charge, mais avec certaines restrictions.
+ Amazon RDS offre une conformité totale en matière d’atomicité, de cohérence, d’isolation et de durabilité (ACID) et une prise en charge des transactions complexes. Si vos fonctions Lambda nécessitent des transactions complexes ou une cohérence forte entre plusieurs enregistrements, Amazon RDS pourrait être plus adapté.

### Caractéristiques de mise à l’échelle
<a name="w2aad101d101c19c13b9b9"></a>
+ DynamoDB s’adapte automatiquement à votre charge de travail. Il peut gérer les pics de trafic soudains provenant des fonctions Lambda sans pré-approvisionnement. Vous pouvez utiliser le mode de capacité à la demande pour ne payer que ce que vous utilisez, ce qui correspond parfaitement au modèle de mise à l’échelle de Lambda.
+ Amazon RDS dispose d’une capacité fixe en fonction de la taille d’instance que vous choisissez. Si plusieurs fonctions Lambda tentent de se connecter simultanément, vous risquez de dépasser votre quota de connexions. Vous devez gérer avec soin les groupes de connexions et éventuellement implémenter une logique de nouvelle tentative.

### Modèle de coût
<a name="w2aad101d101c19c13b9c11"></a>
+ La tarification de DynamoDB est parfaitement adaptée aux applications sans serveur. Avec une capacité à la demande, vous ne payez que pour les lectures et écritures réellement utilisées par vos fonctions Lambda. Le temps d’inactivité n’est pas facturé.
+ Amazon RDS facture l’instance en cours d’exécution, quelle que soit son utilisation. Cela peut être moins rentable pour les charges de travail sporadiques, qui sont courantes dans les applications sans serveur. Toutefois, cela peut s’avérer plus économique pour les charges de travail à haut débit avec une utilisation constante.

## Commencer avec le service de base de données que vous avez choisi
<a name="w2aad101d101c19c15"></a>

Maintenant que vous avez pris connaissance des critères de sélection entre DynamoDB et Amazon RDS et des principales différences entre les deux, vous pouvez sélectionner l’option qui répond le mieux à vos besoins et utiliser les ressources suivantes pour commencer à l’utiliser.

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

**Mise en route avec DynamoDB grâce aux ressources suivantes**
+ Pour une présentation du service DynamoDB, consultez [Qu’est-ce que DynamoDB ?](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) dans le *Guide du développeur Amazon DynamoDB*
+ Suivez le didacticiel [Utilisation de Lambda avec API Gateway](services-apigateway-tutorial.md) pour découvrir un exemple d’utilisation d’une fonction Lambda pour effectuer des opérations CRUD sur une table DynamoDB en réponse à une demande d’API.
+ Lisez [Programming with DynamoDB et AWS SDKs](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.html) le manuel du *développeur Amazon DynamoDB pour en savoir plus sur la façon d'accéder à DynamoDB* depuis votre fonction Lambda en utilisant l'un des. AWS SDKs

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

**Mise en route avec Amazon RDS grâce aux ressources suivantes**
+ Pour une présentation du service Amazon RDS, consultez l’article [Qu’est-ce que Amazon Relational Database Service (Amazon RDS) ?](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) dans le *Guide de l’utilisateur Amazon Relational Database Service*.
+ Suivez le didacticiel [Utilisation d’une fonction Lambda pour accéder à une base de données Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html) dans le *Guide de l’utilisateur Amazon Relational Database Service*.
+ Pour en savoir plus sur l’utilisation de Lambda avec Amazon RDS, consultez [Utilisation AWS Lambda avec Amazon RDS](services-rds.md).

------