dev-resources.site
for different kinds of informations.
Using RDS Proxy with a .NET Lambda for Efficient Database Connections
Efficient database connection management is critical in serverless architectures like AWS Lambda.Each Lambda invocation opens a new database connection, and under high traffic, this can quickly exceed the database's connection limits, causing performance bottlenecks and resource exhaustion.
Introduction to RDS Proxy
Amazon RDS Proxy, a fully managed AWS service, optimizes database connections for RDS databases. Acting as an intermediary between your application and the database, it pools and reuses connections, significantly improving efficiency and scalability. RDS Proxy supports a wide range of database engines, including:
- MySQL
- PostgreSQL
- MariaDB
- Microsoft SQL Server
- Amazon Aurora (MySQL and PostgreSQL)
For more details including limitations, refer the following User Guide- Amazon RDS Proxy
Setting Up RDS Proxy
- Sign in to the AWS Management Console and navigate to Amazon RDS Console.
- In the navigation pane, choose Proxies and click Create proxy.
- Configure the following settings:
Parameter | Description |
---|---|
Engine family | Determines the database engine family - MySQL, PostgreSQL, MariaDB, Microsoft SQL Server and Amazon Aurora (MySQL and PostgreSQL). |
Proxy identifier | Name of the Proxy |
Idle client connection timeout | Specify how long a client connection can stay idle before the proxy closes it. By default, this is 30 minutes |
Database | List of RDS DB Instances that can be accessed through the proxy |
Connection pool maximum connections | Represents the percentage of the database's maximum concurrent connections that RDS Proxy can use. If there is a single proxy with a RDS Instance, this value can be 100 |
IAM role | Name of the IAM role the proxy will use to access the AWS Secrets Manager secrets |
Secrets Manager secrets | List of Secrets that contains the database credentials for the proxy to access the database. A proxy can have up to 200 associated Secrets Manager secrets |
Client authentication type | Defines the proxy's authentication method for client connections and associated Secrets Manager secrets. |
IAM authentication | Specifies whether the proxy requires, disallows, or allows IAM authentication. Applicable on for RDS for Microsoft SQL Server |
Require Transport Layer Security | Enable this setting to enforce TLS/SSL for all client connections |
For a detailed explanation of the parameters, refer to the article:
Creating an RDS Proxy
- Click on the Create Proxy button to complete the setup.
- Once created, the proxy appears under the Proxies section in the navigation pane.
Use the Endpoint listed in the Proxy Endpoints section as the host in your database connection string instead of the database hostname to leverage RDS Proxy.
Creating a Database User and Adding It to the RDS Proxy
To ensure the RDS Proxy can interact with your database, follow these steps to create a database user, store the credentials, and associate them with the proxy:
- Create a database user with the necessary privileges
CREATE USER 'newuser'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON database.* TO 'newuser'@'%';
FLUSH PRIVILEGES;
- Store the database credentials in AWS Secrets Manager
- Navigate to AWS Secrets Manager in the AWS Management Console.
- Create a new secret containing the database username and password.
- Note the ARN of the secret for use in Lambda.
- Add the secret to the RDS Proxy
- Attach the following policy to the IAM role associated with the RDS Proxy to read the secret:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:REGION:ACCOUNT_ID:secret:<secret-arn>"
}
]
}
Integrating RDS Proxy in the .NET Lambda
There are multiple approaches to integrate RDS proxy into your .NET Lambda function to access an RDS/MySQL database
Database Credentials
This approach lets your Lambda authenticate to the RDS Proxy using the RDS endpoint and credentials from a secret. Follow these steps to use Database Credentials:
- If the database credentials are stored in a secret, attach the following policy to the Lambda Execution Role to read the secret:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:REGION:ACCOUNT_ID:secret:<secret-arn>"
}
]
}
- Update the lambda code to connect to the database using the RDS Proxy endpoint and database credentials
using MySql.Data.MySqlClient;
namespace RDSProxyTest
{
internal class DBConnection
{
public async Task<MySqlConnection> OpenConnectionAsync()
{
var connectionString = new MySqlConnectionStringBuilder
{
Server = "<rds_proxy_endpoint>",
UserID = "<database_user_name>",
Password = "<database_password>",
Database = "<database_name>"
}.ToString();
var connection = new MySqlConnection(connectionString);
await connection.OpenAsync();
return connection;
}
}
}
IAM Authentication
This approach enables your Lambda function to authenticate to the RDS Proxy using short-lived IAM tokens instead of database credentials. Follow these steps to enable and use IAM Authentication:
Attach the following policy to the Lambda Execution Role for the Lambda to access the RDS Proxy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue"
],
"Resource": "arn:aws:secretsmanager:REGION:ACCOUNT_ID:secret:<secret-arn>"
}
]
}
Replace:
Parameter | Description |
---|---|
REGION | Your AWS region (e.g., us-east-1) |
ACCOUNT_ID | AWS Account ID |
RDS_PROXY_IDENTIFIER | The unique identifier for the RDS Proxy . For ex: if the arn of the RDS Proxy is arn:aws:rds:REGION:ACCOUNT_ID:db-proxy:prx-XXXXXXXXXXXXXXXXX, then value of RDS_PROXY_IDENTIFIER is prx-XXXXXXXXXXXXXXXXX |
DB_USERNAME | A database username, configured in one of the secrets attached to the RDS Proxy |
- Update the lambda code to connect to the database using the RDS Proxy endpoint and database credentials
using Amazon;
using Amazon.RDS.Util;
using Amazon.Runtime;
using MySql.Data.MySqlClient;
namespace RDSProxyTest
{
internal class DBConnection
{
private static async Task<string> GenerateAuthTokenAsync(string endpoint, string username, string region)
{
var regionEndpoint = RegionEndpoint.GetBySystemName(region);
// Use default credentials of the Lambda environment
var credentials = FallbackCredentialsFactory.GetCredentials();
// Generate the authentication token
return await RDSAuthTokenGenerator.GenerateAuthTokenAsync(
credentials,
regionEndpoint,
endpoint,
3306,
username
);
}
public async Task<MySqlConnection> OpenConnectionAsync()
{
var token = await GenerateAuthTokenAsync("<rds_proxy_endpoint>", "<database_user_name>", "<aws_region>");
var connectionString = new MySqlConnectionStringBuilder
{
Server = "<rds_proxy_endpoint>",
Database = "<database_name>",
UserID = "<database_user_name>",
Password = token,
SslMode = MySqlSslMode.Required
}.ToString();
var connection = new MySqlConnection(connectionString);
await connection.OpenAsync();
return connection;
}
}
}
Database Credentials versus IAM Authetication
Feature | Database Credentials | IAM Authentication |
---|---|---|
Authentication Method | Uses database username and password | Uses short-lived IAM tokens (15 minutes) generated by AWS for secure authentication. |
Database Support | Works with all databases supported by RDS Proxy. | Supported for Amazon Aurora (MySQL /PostgreSQL), MySQL, PostgreSQL, MariaDB. It is not supported for Amazon RDS for Oracle, Amazon RDS for SQL Server |
Performance Impact | Minimal Overhead | Slightly higher overhead due to the need to generate and validate IAM tokens. |
Featured ones: