

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Menggunakan AWS Lambda dengan Amazon RDS
<a name="services-rds"></a>

Anda dapat menghubungkan fungsi Lambda ke database Amazon Relational Database Service (Amazon RDS) secara langsung dan melalui Amazon RDS Proxy. Koneksi langsung berguna dalam skenario sederhana, dan proxy direkomendasikan untuk produksi. Proksi basis data mengelola kumpulan koneksi basis data bersama yang memungkinkan fungsi Anda mencapai tingkat konkurensi tinggi tanpa menghabiskan koneksi basis data.

Sebaiknya gunakan Amazon RDS Proxy untuk fungsi Lambda yang sering membuat koneksi database pendek, atau membuka dan menutup sejumlah besar koneksi database. Untuk informasi selengkapnya, lihat [Menghubungkan fungsi Lambda dan instans DB secara otomatis](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/lambda-rds-connect.html) di Panduan Pengembang Layanan Amazon Relational Database Service.

**Tip**  
Untuk menghubungkan fungsi Lambda dengan cepat ke database Amazon RDS, Anda dapat menggunakan panduan panduan dalam konsol. Untuk membuka wizard, lakukan hal berikut:  
Buka [halaman Fungsi](https://console.aws.amazon.com/lambda/home#/functions) di konsol Lambda.
Pilih fungsi yang ingin Anda sambungkan ke database.
Pada tab **Konfigurasi**, pilih **database RDS**.
Pilih **Connect to RDS database**.
Setelah menghubungkan fungsi ke database, Anda dapat membuat proxy dengan memilih **Add proxy**.

## Mengkonfigurasi fungsi Anda untuk bekerja dengan sumber daya RDS
<a name="rds-configuration"></a>

Di konsol Lambda, Anda dapat menyediakan, dan mengonfigurasi, instans database Amazon RDS dan sumber daya proxy. **Anda dapat melakukan ini dengan menavigasi ke **database RDS** di bawah tab Konfigurasi.** Atau, Anda juga dapat membuat dan mengonfigurasi koneksi ke fungsi Lambda di konsol Amazon RDS. Saat mengonfigurasi instance database RDS untuk digunakan dengan Lambda, perhatikan kriteria berikut:
+ Untuk terhubung ke database, fungsi Anda harus berada di VPC Amazon yang sama tempat database Anda berjalan.
+ Anda dapat menggunakan database Amazon RDS dengan mesin MySQL, MariaDB, PostgreSQL, atau Microsoft SQL Server.
+ Anda juga dapat menggunakan cluster Aurora DB dengan mesin MySQL atau PostgreSQL.
+ Anda perlu memberikan rahasia Secrets Manager untuk otentikasi database.
+ Peran IAM harus memberikan izin untuk menggunakan rahasia, dan kebijakan kepercayaan harus memungkinkan Amazon RDS untuk mengambil peran tersebut.
+  Prinsipal IAM yang menggunakan konsol untuk mengonfigurasi sumber daya Amazon RDS, dan menghubungkannya ke fungsi Anda harus memiliki izin berikut:

### Contoh kebijakan izin
<a name="rds-lambda-permissions"></a>

**catatan**  
 Anda memerlukan izin Amazon RDS Proxy hanya jika Anda mengonfigurasi Proxy Amazon RDS untuk mengelola kumpulan koneksi database Anda. 

------
#### [ 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 mengenakan tarif per jam untuk proxy berdasarkan ukuran instans database, lihat harga Proxy [RDS](https://aws.amazon.com/rds/proxy/pricing/) untuk detailnya. Untuk informasi selengkapnya tentang koneksi proxy secara umum, lihat [Menggunakan Proxy Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) di Panduan Pengguna Amazon RDS.

### Persyaratan SSL/TLS untuk koneksi Amazon RDS
<a name="rds-lambda-certificates"></a>

Untuk membuat SSL/TLS koneksi aman ke instans database Amazon RDS, fungsi Lambda Anda harus memverifikasi identitas server database menggunakan sertifikat tepercaya. Lambda menangani sertifikat ini secara berbeda tergantung pada jenis paket penerapan Anda:
+ [arsip file.zip](configuration-function-zip.md): Penanganan sertifikat bervariasi menurut runtime:
  + **Node.js 18 dan sebelumnya**: Lambda secara otomatis menyertakan sertifikat CA dan sertifikat RDS.
  + **Node.js 20 dan yang lebih baru**: Lambda tidak lagi memuat sertifikat CA tambahan secara default. Atur `NODE_EXTRA_CA_CERTS` variabel lingkungan ke `/var/runtime/ca-cert.pem`.

  Mungkin diperlukan waktu hingga 4 minggu untuk sertifikat Amazon RDS Wilayah AWS agar baru ditambahkan ke runtime terkelola Lambda.
+ [Gambar kontainer](images-create.md): gambar AWS dasar hanya menyertakan sertifikat CA. Jika fungsi Anda tersambung ke instans database Amazon RDS, Anda harus menyertakan sertifikat yang sesuai dalam image container Anda. Di Dockerfile Anda, unduh [bundel sertifikat yang sesuai dengan Wilayah AWS tempat Anda meng-host database Anda](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html#UsingWithRDS.SSL.CertificatesDownload). Contoh:

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

Perintah ini mengunduh bundel sertifikat Amazon RDS dan menyimpannya di jalur absolut `/us-east-1-bundle.pem` di direktori root container Anda. Saat mengonfigurasi koneksi database dalam kode fungsi Anda, Anda harus mereferensikan jalur yang tepat ini. Contoh:

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

`readFileSync`Fungsi ini diperlukan karena klien database Node.js memerlukan konten sertifikat yang sebenarnya dalam memori, bukan hanya jalur ke file sertifikat. Tanpa`readFileSync`, klien menafsirkan string jalur sebagai konten sertifikat, menghasilkan kesalahan “sertifikat yang ditandatangani sendiri dalam rantai sertifikat”.

**Example Konfigurasi koneksi Node.js untuk fungsi 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 Konfigurasi koneksi Python untuk fungsi 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 ]

Untuk fungsi Java yang menggunakan koneksi JDBC, string koneksi harus mencakup:
+ `useSSL=true`
+ `requireSSL=true`
+ `sslCA`Parameter yang menunjuk ke lokasi sertifikat Amazon RDS dalam gambar kontainer

**Example String koneksi Java untuk fungsi 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 .NET string koneksi untuk koneksi MySQL dalam fungsi 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 ]

Untuk fungsi Go yang menggunakan koneksi MySQL, muat sertifikat Amazon RDS ke dalam kumpulan sertifikat dan daftarkan dengan driver MySQL. String koneksi kemudian harus mereferensikan konfigurasi ini menggunakan `tls` parameter.

**Example Kode Go untuk koneksi MySQL dalam fungsi 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 Konfigurasi koneksi Ruby untuk fungsi 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
)
```

------

## Menghubungkan ke database Amazon RDS dalam fungsi Lambda
<a name="rds-connection"></a>

Contoh kode berikut menunjukkan cara menerapkan fungsi Lambda yang terhubung ke database Amazon RDS. Fungsi membuat permintaan database sederhana dan mengembalikan hasilnya.

**catatan**  
Contoh kode ini hanya berlaku untuk [paket.zip deployment](configuration-function-zip.md). Jika Anda menerapkan fungsi menggunakan [gambar kontainer,](images-create.md) Anda harus menentukan file sertifikat Amazon RDS dalam kode fungsi Anda, seperti yang dijelaskan di bagian [sebelumnya](#oci-certificate).

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

**SDK untuk .NET**  
 Ada lebih banyak tentang GitHub. Temukan contoh lengkapnya dan pelajari cara mengatur dan menjalankannya di repositori [contoh Nirserver](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Menghubungkan ke database Amazon RDS dalam fungsi Lambda menggunakan.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 untuk Go V2**  
 Ada lebih banyak tentang GitHub. Temukan contoh lengkapnya dan pelajari cara mengatur dan menjalankannya di repositori [contoh Nirserver](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Menghubungkan ke database Amazon RDS dalam fungsi Lambda menggunakan 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 untuk Java 2.x**  
 Ada lebih banyak tentang GitHub. Temukan contoh lengkapnya dan pelajari cara mengatur dan menjalankannya di repositori [contoh Nirserver](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Menghubungkan ke database Amazon RDS dalam fungsi Lambda menggunakan 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 untuk JavaScript (v3)**  
 Ada lebih banyak tentang GitHub. Temukan contoh lengkapnya dan pelajari cara mengatur dan menjalankannya di repositori [contoh Nirserver](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Menghubungkan ke database Amazon RDS dalam fungsi Lambda menggunakan. 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)
  }
};
```
Menghubungkan ke database Amazon RDS dalam fungsi Lambda menggunakan. 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 untuk PHP**  
 Ada lebih banyak tentang GitHub. Temukan contoh lengkapnya dan pelajari cara mengatur dan menjalankannya di repositori [contoh Nirserver](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Menghubungkan ke database Amazon RDS dalam fungsi Lambda menggunakan 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 untuk Python (Boto3)**  
 Ada lebih banyak tentang GitHub. Temukan contoh lengkapnya dan pelajari cara mengatur dan menjalankannya di repositori [contoh Nirserver](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Menghubungkan ke database Amazon RDS dalam fungsi Lambda menggunakan 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 untuk Ruby**  
 Ada lebih banyak tentang GitHub. Temukan contoh lengkapnya dan pelajari cara mengatur dan menjalankannya di repositori [contoh Nirserver](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Menghubungkan ke database Amazon RDS dalam fungsi Lambda menggunakan 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 for Rust**  
 Ada lebih banyak tentang GitHub. Temukan contoh lengkapnya dan pelajari cara mengatur dan menjalankannya di repositori [contoh Nirserver](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Menghubungkan ke database Amazon RDS dalam fungsi Lambda menggunakan 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}")
    }))
}
```

------

## Memproses pemberitahuan acara dari Amazon RDS
<a name="rds-events"></a>

Anda dapat menggunakan Lambda untuk memproses pemberitahuan peristiwa dari database Amazon RDS. Amazon RDS mengirimkan pemberitahuan ke topik Amazon Simple Notification Service (Amazon SNS) yang dapat Anda konfigurasikan untuk memanggil fungsi Lambda. Amazon SNS merangkum pesan dari Amazon RDS dalam dokumen kejadiannya sendiri dan mengirimkannya ke fungsi Anda.

Untuk informasi selengkapnya tentang mengonfigurasi database Amazon RDS untuk mengirim notifikasi, lihat Menggunakan pemberitahuan [peristiwa Amazon RDS.](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html) 

**Example Pesan Amazon RDS di kejadian 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"
            }
          }
        ]
      }
```

## Lengkap Lambda dan Amazon RDS tutorial
<a name="rds-database-samples"></a>
+ [Menggunakan fungsi Lambda untuk mengakses database Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html) — Dari Panduan Pengguna Amazon RDS, pelajari cara menggunakan fungsi Lambda untuk menulis data ke database Amazon RDS melalui Proxy Amazon RDS. Fungsi Lambda Anda akan membaca catatan dari antrian Amazon SQS dan menulis item baru ke tabel di database Anda setiap kali pesan ditambahkan.

# Pilih layanan database untuk aplikasi berbasis Lambda
<a name="ddb-rds-database-decision"></a>

Banyak aplikasi tanpa server perlu menyimpan dan mengambil data. AWS menawarkan beberapa opsi database yang bekerja dengan fungsi Lambda. Dua pilihan yang paling populer adalah Amazon DynamoDB, layanan database NoSQL, dan Amazon RDS, solusi database relasional tradisional. Bagian berikut menjelaskan perbedaan utama antara layanan ini saat menggunakannya dengan Lambda dan membantu Anda memilih layanan database yang tepat untuk aplikasi tanpa server Anda.

Untuk mempelajari lebih lanjut tentang layanan database lain yang ditawarkan oleh AWS, dan untuk memahami kasus penggunaan dan pengorbanannya secara lebih umum, lihat [Memilih](https://docs.aws.amazon.com/decision-guides/latest/databases-on-aws-how-to-choose/databases-on-aws-how-to-choose.html) layanan basis data. AWS Semua layanan AWS database kompatibel dengan Lambda, tetapi tidak semuanya cocok untuk kasus penggunaan khusus Anda.

## Apa pilihan Anda saat memilih layanan database dengan Lambda?
<a name="w2aad101d101c19b9"></a>

AWS menawarkan beberapa layanan database. Untuk aplikasi tanpa server, dua pilihan paling populer adalah DynamoDB dan Amazon RDS.
+ **DynamoDB** adalah layanan database NoSQL yang dikelola sepenuhnya yang dioptimalkan untuk aplikasi tanpa server. Ini memberikan penskalaan yang mulus dan kinerja milidetik satu digit yang konsisten pada skala apa pun.
+ **Amazon RDS** adalah layanan database relasional terkelola yang mendukung beberapa mesin database termasuk MySQL dan PostgreSQL. Ini memberikan kemampuan SQL yang akrab dengan infrastruktur terkelola.

## Rekomendasi jika Anda sudah mengetahui kebutuhan Anda
<a name="w2aad101d101c19c11"></a>

Jika Anda sudah jelas tentang kebutuhan Anda, berikut adalah rekomendasi dasar kami:

Kami merekomendasikan [DynamoDB](with-ddb.md) untuk aplikasi tanpa server yang membutuhkan kinerja latensi rendah yang konsisten, penskalaan otomatis, dan tidak memerlukan gabungan atau transaksi yang rumit. Ini sangat cocok untuk aplikasi berbasis Lambda karena sifatnya yang tanpa server.

[Amazon RDS](services-rds.md) adalah pilihan yang lebih baik ketika Anda membutuhkan kueri SQL yang kompleks, bergabung, atau memiliki aplikasi yang ada menggunakan database relasional. Namun, ketahuilah bahwa menghubungkan fungsi Lambda ke Amazon RDS memerlukan konfigurasi tambahan dan dapat memengaruhi waktu mulai yang dingin.

## Apa yang harus dipertimbangkan ketika memilih layanan database
<a name="w2aad101d101c19c13"></a>

Saat memilih antara DynamoDB dan Amazon RDS untuk aplikasi Lambda Anda, pertimbangkan faktor-faktor berikut:
+ Manajemen koneksi dan start dingin
+ Pola akses data
+ Kompleksitas kueri
+ Persyaratan konsistensi data
+ Karakteristik penskalaan
+ Model biaya

Dengan memahami faktor-faktor ini, Anda dapat memilih opsi yang paling sesuai dengan kebutuhan kasus penggunaan khusus Anda.

### Manajemen koneksi dan start dingin
<a name="w2aad101d101c19c13b9b1"></a>
+ DynamoDB menggunakan API HTTP untuk semua operasi. Fungsi Lambda dapat membuat permintaan langsung tanpa mempertahankan koneksi, menghasilkan kinerja start dingin yang lebih baik. Setiap permintaan diautentikasi menggunakan AWS kredensil tanpa overhead koneksi.
+ Amazon RDS memerlukan pengelolaan kumpulan koneksi karena menggunakan koneksi database tradisional. Ini dapat memengaruhi awal dingin karena instance Lambda baru perlu membuat koneksi. Anda harus menerapkan strategi penyatuan koneksi dan berpotensi menggunakan [Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) untuk mengelola koneksi secara efektif. Perhatikan bahwa menggunakan Amazon RDS Proxy menimbulkan biaya tambahan.

### Pola akses data
<a name="w2aad101d101c19c13b9b3"></a>
+ DynamoDB bekerja paling baik dengan pola akses yang dikenal dan desain meja tunggal. Ini ideal untuk aplikasi Lambda yang membutuhkan akses latensi rendah yang konsisten ke data berdasarkan kunci primer atau indeks sekunder.
+ Amazon RDS memberikan fleksibilitas untuk kueri kompleks dan mengubah pola akses. Ini lebih cocok ketika fungsi Lambda Anda perlu melakukan kueri yang unik dan disesuaikan atau gabungan kompleks di beberapa tabel.

### Kompleksitas kueri
<a name="w2aad101d101c19c13b9b5"></a>
+ DynamoDB unggul dalam operasi sederhana berbasis kunci dan pola akses yang telah ditentukan sebelumnya. Kueri kompleks harus dirancang di sekitar struktur indeks, dan gabungan harus ditangani dalam kode aplikasi.
+ Amazon RDS mendukung kueri SQL yang kompleks dengan gabungan, subkueri, dan agregasi. Ini dapat menyederhanakan kode fungsi Lambda Anda ketika operasi data yang kompleks diperlukan.

### Persyaratan konsistensi data
<a name="w2aad101d101c19c13b9b7"></a>
+ DynamoDB menawarkan opsi konsistensi akhir dan kuat, dengan konsistensi yang kuat tersedia untuk pembacaan item tunggal. Transaksi didukung tetapi dengan beberapa batasan.
+ Amazon RDS memberikan kepatuhan atomisitas, konsistensi, isolasi, dan daya tahan (ACID) penuh dan dukungan transaksi yang kompleks. Jika fungsi Lambda Anda memerlukan transaksi yang kompleks atau konsistensi yang kuat di beberapa catatan, Amazon RDS mungkin lebih cocok.

### Karakteristik penskalaan
<a name="w2aad101d101c19c13b9b9"></a>
+ DynamoDB menskalakan secara otomatis dengan beban kerja Anda. Ini dapat menangani lonjakan lalu lintas tiba-tiba dari fungsi Lambda tanpa pra-penyediaan. Anda dapat menggunakan mode kapasitas sesuai permintaan untuk membayar hanya untuk apa yang Anda gunakan, sangat cocok dengan model penskalaan Lambda.
+ Amazon RDS memiliki kapasitas tetap berdasarkan ukuran instans yang Anda pilih. Jika beberapa fungsi Lambda mencoba terhubung secara bersamaan, Anda dapat melebihi kuota koneksi Anda. Anda perlu mengelola kumpulan koneksi dengan hati-hati dan berpotensi menerapkan logika coba lagi.

### Model biaya
<a name="w2aad101d101c19c13b9c11"></a>
+ Harga DynamoDB selaras dengan aplikasi tanpa server. Dengan kapasitas sesuai permintaan, Anda hanya membayar untuk membaca dan menulis aktual yang dilakukan oleh fungsi Lambda Anda. Tidak ada biaya untuk waktu idle.
+ Amazon RDS mengenakan biaya untuk instans yang sedang berjalan terlepas dari penggunaannya. Ini bisa menjadi kurang hemat biaya untuk beban kerja sporadis yang dapat menjadi tipikal dalam aplikasi tanpa server. Namun, mungkin lebih ekonomis untuk beban kerja throughput tinggi dengan penggunaan yang konsisten.

## Memulai dengan layanan database pilihan Anda
<a name="w2aad101d101c19c15"></a>

Sekarang setelah Anda membaca tentang kriteria untuk memilih antara DynamoDB dan Amazon RDS dan perbedaan utama di antara keduanya, Anda dapat memilih opsi yang paling sesuai dengan kebutuhan Anda dan menggunakan sumber daya berikut untuk mulai menggunakannya.

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

**Memulai DynamoDB dengan sumber daya berikut**
+ Untuk pengenalan layanan DynamoDB, baca [Apa](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) itu DynamoDB? di Panduan Pengembang *Amazon DynamoDB*.
+ Ikuti tutorial [Menggunakan Lambda dengan API Gateway](services-apigateway-tutorial.md) untuk melihat contoh penggunaan fungsi Lambda untuk melakukan operasi CRUD pada tabel DynamoDB sebagai respons terhadap permintaan API.
+ Baca [Pemrograman dengan DynamoDB dan AWS SDKs](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.html) di Panduan *Pengembang Amazon DynamoDB untuk mempelajari lebih lanjut tentang cara mengakses DynamoDB* dari dalam fungsi Lambda Anda dengan menggunakan salah satu file. AWS SDKs

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

**Memulai Amazon RDS dengan sumber daya berikut**
+ Untuk pengenalan layanan Amazon RDS, baca [Apa itu Amazon Relational Database Service (Amazon](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) RDS)? dalam *Panduan Pengguna Layanan Amazon Relational Database Service*.
+ Ikuti tutorial [Menggunakan fungsi Lambda untuk mengakses database Amazon RDS di Panduan Pengguna Layanan *Amazon Relational* Database](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html) Service.
+ Pelajari lebih lanjut tentang menggunakan Lambda dengan Amazon RDS dengan membaca. [Menggunakan AWS Lambda dengan Amazon RDS](services-rds.md)

------