Function Compute accesses Alibaba Cloud Relational Database Service (RDS) through a virtual private cloud (VPC). By placing your function and your RDS instance in the same VPC, you establish a private network path between them without exposing database traffic to the public internet.
Prerequisites
Before you configure access, make sure you have:
An RDS instance and a Function Compute function deployed in the same region
Both the RDS instance and the function configured to use the same VPC
The RDS instance IP address whitelist configured to allow inbound traffic from the function's VPC CIDR block or private IP range
A RAM role or RAM user with permissions to read the database credentials (recommended: store credentials in Alibaba Cloud KMS or environment variables, not hardcoded in function code)
Configure VPC access for your function
To connect your function to RDS, configure the function's network settings to use the VPC where your RDS instance runs.
For step-by-step configuration instructions, see Configure network settings.
After the VPC binding is complete, your function can reach the RDS instance using the instance's private endpoint (intranet connection string), available on the RDS console under Database Connection.
Connect to RDS in your function code
Use the RDS private endpoint and port in your connection string. Store credentials as environment variables to avoid hardcoding sensitive information.
Do not hardcode database passwords in your function code or configuration files. Use environment variables or a secrets management service such as Alibaba Cloud KMS to inject credentials at runtime.
The following examples show how to connect to an RDS MySQL instance from a Function Compute function.
Python
import os
import pymysql
def handler(event, context):
connection = pymysql.connect(
host=os.environ['RDS_HOST'], # RDS private endpoint, e.g. rm-xxxx.mysql.rds.aliyuncs.com
port=int(os.environ['RDS_PORT']), # Default MySQL port: 3306
user=os.environ['RDS_USER'],
password=os.environ['RDS_PASSWORD'],
database=os.environ['RDS_DB_NAME'],
connect_timeout=5
)
try:
with connection.cursor() as cursor:
cursor.execute('SELECT 1')
result = cursor.fetchone()
return str(result)
finally:
connection.close()Java
import com.aliyun.fc.runtime.Context;
import com.aliyun.fc.runtime.StreamRequestHandler;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.io.InputStream;
import java.io.OutputStream;
public class RDSHandler implements StreamRequestHandler {
@Override
public void handleRequest(InputStream input, OutputStream output, Context context) throws Exception {
String host = System.getenv("RDS_HOST");
String port = System.getenv("RDS_PORT");
String user = System.getenv("RDS_USER");
String password = System.getenv("RDS_PASSWORD");
String dbName = System.getenv("RDS_DB_NAME");
String url = String.format("jdbc:mysql://%s:%s/%s", host, port, dbName);
try (Connection conn = DriverManager.getConnection(url, user, password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 1")) {
if (rs.next()) {
output.write(rs.getString(1).getBytes());
}
}
}
}Node.js
const mysql = require('mysql2/promise');
exports.handler = async (event, context) => {
const connection = await mysql.createConnection({
host: process.env.RDS_HOST, // RDS private endpoint
port: parseInt(process.env.RDS_PORT, 10),
user: process.env.RDS_USER,
password: process.env.RDS_PASSWORD,
database: process.env.RDS_DB_NAME,
connectTimeout: 5000
});
try {
const [rows] = await connection.execute('SELECT 1');
return JSON.stringify(rows);
} finally {
await connection.end();
}
};Go
package main
import (
"database/sql"
"fmt"
"os"
_ "github.com/go-sql-driver/mysql"
"github.com/aliyun/fc-runtime-go-sdk/fc"
)
func HandleRequest() (string, error) {
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?timeout=5s",
os.Getenv("RDS_USER"),
os.Getenv("RDS_PASSWORD"),
os.Getenv("RDS_HOST"),
os.Getenv("RDS_PORT"),
os.Getenv("RDS_DB_NAME"),
)
db, err := sql.Open("mysql", dsn)
if err != nil {
return "", err
}
defer db.Close()
var result string
err = db.QueryRow("SELECT 1").Scan(&result)
if err != nil {
return "", err
}
return result, nil
}
func main() {
fc.Start(HandleRequest)
}Set the following environment variables on your function:
| Variable | Description | Example |
|---|---|---|
RDS_HOST | RDS private endpoint (intranet connection string) | rm-xxxx.mysql.rds.aliyuncs.com |
RDS_PORT | Database port | 3306 |
RDS_USER | Database username | appuser |
RDS_PASSWORD | Database password | Set via KMS or secret injection |
RDS_DB_NAME | Target database name | mydb |
Troubleshoot connection issues
| Symptom | Likely cause | Resolution |
|---|---|---|
| Connection timeout | Function and RDS are in different VPCs, or the VPC binding is incomplete | Verify that both resources use the same VPC; re-check the function's network configuration |
| Access denied | Incorrect credentials or missing database user permissions | Confirm the database username and password; grant the user access to the target database |
| IP address whitelist blocks connection | RDS IP address whitelist does not include the function's private IP range | Add the VPC CIDR block to the RDS IP address whitelist |
| Cannot resolve hostname | Function is not bound to the VPC where RDS runs | Complete VPC configuration as described in Configure network settings |