All Products
Search
Document Center

Function Compute:Accessing ApsaraDB RDS for MySQL

Last Updated:Jun 21, 2026

In Function Compute, execution instances are stateless. You can use a database to persist structured data and share state. By accessing a cloud database from Function Compute, you can perform operations such as data queries and insertions. This topic uses a Python function as an example to describe how to access an ApsaraDB RDS for MySQL instance from within the same VPC or across different VPCs and regions.

Prerequisites

Procedure

Step 1: Configure the database whitelist

Scenario 1: Same VPC

If you access a database in the same VPC, ensure that the database instance and the function are in the same region. We recommend that you create the database instance in a zone that Function Compute supports. For more information, see Zones that Function Compute supports. If your database instance is not in a supported zone, you can create a vSwitch in the same zone as your function and specify its ID in the function's VPC configuration. Because vSwitches in the same VPC can communicate with each other over the private network, your function can use this vSwitch to access resources in other zones of the VPC. For more information, see What do I do if I receive the 'vSwitch is in unsupported zone' error?.

  1. Log on to the Function Compute console and create a Python web function. On the function details page, select the Configuration tab, and then click Modify in the Advanced Settings section. In the Advanced Settings panel, find the Network section, enable VPC access for the function, and configure the destination VPC resources.

    Note

    Make sure that the VPC configured for the function is the same as the VPC to which the database instance is bound.

    You can configure the VPC, vSwitch, and security group. We recommend that you deploy vSwitches in two or more zones to take full advantage of the multi-zone disaster recovery capabilities of Function Compute, which enhances the high availability of your service. The supported zones in the current region are cn-hangzhou-h, i, j, k, f, g, and b.

  2. On the function details page, go to the Configuration tab. In the Network section, obtain the CIDR block of the vSwitch configured for the function.

  3. Add the vSwitch CIDR block that you obtained in the previous step to the database access whitelist.

    Important

    We recommend that you authorize function access by using an IP address whitelist instead of a security group. Using a security group may cause intermittent connection failures, which can affect your service.

    1. Go to the RDS instance list, select a region, and then click the target instance ID.

    2. In the navigation pane on the left, click Whitelist and SecGroup.

      On the Whitelist Settings page, you can view the current IP whitelist mode.

      Note

      Older instances may operate in high-security mode. All new instances use the standard whitelist mode.

    3. To the right of the default group, click Modify. In the Edit Whitelist dialog box, add the IPv4 CIDR block of the vSwitch that you obtained in step 2 to the whitelist, and then click OK.

    After the configuration is complete, the function can access the RDS database through its internal endpoint.

Scenario 2: Across VPCs or regions

VPCs and regions are logically isolated. By default, you cannot access a database across VPCs or regions. To enable this, configure a static public IP address for your function. The system creates a public NAT gateway in the function's VPC, which allows the function to access the database over the internet by using the public IP address.

  1. Log on to the Function Compute console. In the navigation pane on the left, click Functions. Select a region, and then create a function as prompted.

  2. On the function details page, click the Configuration tab. In the Advanced Settings section, click Modify. In the Advanced Settings panel, find the Network section. To activate the static public IP, enable Static Public IP Address and disable Allow Default NIC to Access Internet. Then, click Deploy.

  3. On the function details page, go to the Configuration tab. In the Network section, obtain the Elastic IP Address configured for the function.

  4. Add the Elastic IP Address that you obtained in the previous step to the database access whitelist.

    Important

    We recommend that you authorize function access by using an IP address whitelist instead of a security group. Using a security group may cause intermittent connection failures, which can affect your service.

    1. Go to the RDS instance list, select a region, and then click the target instance ID.

    2. In the navigation pane on the left, click Whitelist and SecGroup.

      On the Whitelist Settings page, you can view the current IP whitelist mode.

      Note

      Older instances may operate in high-security mode. All new instances use the standard whitelist mode.

    3. To the right of the default group, click Modify. In the Edit Whitelist dialog box, add the static public IP address that you obtained in step 3 to the whitelist, and then click OK.

      A whitelist can contain specific IP addresses, such as 192.168.0.1, and CIDR blocks, such as 192.168.0.0/24. Separate multiple entries with commas. Note: Setting the whitelist to 0.0.0.0/0 allows access from the public internet, while setting it to 127.0.0.1 blocks all external access. The new whitelist takes effect in about one minute.

    After the configuration is complete, the function can access the RDS database through its public endpoint.

Step 2: Access RDS from your function

  1. Log on to the Function Compute console. In the function list, find the target function. On its details page, click the Code tab and enter the following sample code in the editor.

    from flask import Flask, jsonify
    import pymysql
    import os
    from datetime import datetime
    import logging
    app = Flask(__name__)
    # Global variable to store the singleton MySQL connection
    _mysql_connection = None
    # Create a database connection (singleton pattern)
    def getConnection():
        global _mysql_connection
        try:
            # If the connection exists and is active, return it.
            if _mysql_connection is not None:
                try:
                    # Test if the connection is valid with a simple query.
                    with _mysql_connection.cursor() as cursor:
                        cursor.execute("SELECT 1")  # A simple query to test the connection status
                        result = cursor.fetchone()
                        if result and result[0] == 1:
                            return _mysql_connection
                except pymysql.OperationalError:
                    # If the connection is broken, reset it.
                    _mysql_connection = None
            # If the connection does not exist or is broken, create a new one.
            _mysql_connection = pymysql.connect(
                host=os.environ['MYSQL_HOST'],
                port=int(os.environ['MYSQL_PORT']),
                user=os.environ['MYSQL_USER'],
                password=os.environ['MYSQL_PASSWORD'],
                db=os.environ['MYSQL_DBNAME']
            )
            return _mysql_connection
        except Exception as e:
            logging.error(f"Error occurred during database connection: {e}")
            raise
    @app.route('/', defaults={'path': ''})
    @app.route('/<path:path>', methods=['GET', 'POST', 'PUT', 'DELETE'])
    def hello_world(path):
        conn = getConnection()
        try:
            with conn.cursor() as cursor:
                # Query all records from the users table. You must change 'users' to your actual table name.
                sql = "SELECT * FROM users"
                cursor.execute(sql)
                result = cursor.fetchall()
                columns = [desc[0] for desc in cursor.description]  # Get the list of column names
                # Convert the query result to a list of dictionaries
                users = []
                for row in result:
                    user = {}
                    for idx, column_name in enumerate(columns):
                        value = row[idx]
                        if isinstance(value, datetime):  # Handle datetime fields
                            user[column_name] = value.strftime('%Y-%m-%d %H:%M:%S')
                        else:
                            user[column_name] = value
                    users.append(user)
                if users:
                    # Return the JSON response with all users
                    return jsonify(users), 200
                else:
                    # If no users are found, return a 404 error
                    return jsonify({'error': 'No users found'}), 404
        except Exception as e:
            logging.error(f"Error occurred during database operation: {e}")
            return jsonify({'error': 'Database error'}), 500
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=9000)
    
  2. On the Function Details page, select the Configuration tab, find Advanced Settings, and click Modify on its right. In the Advanced Settings panel, find the Environment Variables section, configure the following environment variables, and then click Deploy.

    Parameter

    Value

    Description

    MYSQL_HOST

    rm-bp19u8e76ae****.mysql.rds.aliyuncs.com

    The endpoint of the RDS instance.

    • If you are accessing an RDS database in the same VPC, set this environment variable to the internal endpoint of the database.

    • If you are accessing an RDS database across different VPCs or regions, set this environment variable to the public endpoint of the database.

    In the RDS instance list, click the ID of the target RDS instance. In the navigation pane on the left, click Database Connection. On the Database Connection page, you can obtain the internal or public endpoint of the database.

    MYSQL_DBNAME

    db_test

    The name of the database created in the RDS instance.

    MYSQL_PASSWORD

    *****

    The database password.

    MYSQL_PORT

    3306

    The private port of the database instance.

    MYSQL_USER

    dms_user_****

    The name of the account created in the RDS instance.

  3. On the function details page, click the Code tab, and then click Test Function. After the function executes successfully, check the returned result to confirm that the query completed.

    The returned JSON data contains user records with fields such as id, username, email, password_hash, created_at, and updated_at.

More information

  • For more examples of accessing an ApsaraDB RDS for MySQL database, see Function Compute Python accessing MySQL database.

  • If you cannot access your database, troubleshoot the issue based on its symptoms. For more information, see Common causes of database access failures.

  • ApsaraDB RDS supports the MySQL, SQL Server, PostgreSQL, and MariaDB database engines. For more information, see Introduction to ApsaraDB RDS.

  • To use the Serverless Devs command-line tool to create a function and access an ApsaraDB RDS for MySQL database, follow these steps.

    Click here to view the Serverless Devs procedure

    1. Install Serverless Devs and Docker, and configure your credentials. For more information, see Quick start.

    2. Create a code directory named mycode, and prepare the s.yaml file and the app.py code file. An example of the s.yaml file is provided below. For the sample code, see the code provided in Step 2: Access RDS from your function.

      The following s.yaml example is for accessing an RDS database in the same VPC. If you need to access a database across different VPCs or regions, see Scenario 2: Across VPCs or regions.

      # ------------------------------------
      #   Official documentation: https://manual.serverless-devs.com/user-guide/aliyun/#fc3
      #   Tips: https://manual.serverless-devs.com/user-guide/tips/
      #   If you have questions, join the DingTalk group: 33947367
      # ------------------------------------
      edition: 3.0.0
      name: hello-world-app
      access: "default"
      vars: # Global variables
        region: "cn-hangzhou"  # If you are accessing an RDS database in the same VPC, make sure the function is deployed in the same region as the RDS database.
      resources:
        hello_world:
          component: fc3 
          actions:       
            pre-${regex('deploy|local')}: 
              - component: fc3 build 
          props:
            region: ${vars.region}              
            functionName: "start-python-0t1m"
            runtime: custom.debian10
            description: 'hello world by serverless devs'
            timeout: 10
            memorySize: 512
            cpu: 0.5
            diskSize: 512
            code: ./code
            customRuntimeConfig:
              port: 9000
              command:
                - python3
                - app.py
            internetAccess: true
            vpcConfig:
             vpcId: vpc-bp1dxqii29fpkc8pw**** # The ID of the VPC where the database instance is located.
             securityGroupId: sg-bp12ly2ie92ixrfc**** # The security group ID.
             vSwitchIds: 
              - vsw-bp1ty76ijntee9z83**** # Make sure that the CIDR block of this vSwitch is added to the database instance's access whitelist.
            environmentVariables:
              PYTHONPATH: /code/python
              PATH: /code/python/bin:/var/fc/lang/python3.10/bin:/usr/local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin
              MYSQL_HOST: rm-bp1j1y7657640z5****.mysql.rds.aliyuncs.com  # The internal endpoint of the database instance.
              MYSQL_PORT: "3306"  # The private port of the database instance.
              MYSQL_USER: dms_user_****  # The account for the database in the instance.
              MYSQL_PASSWORD: ****   # The password for the database account.
              MYSQL_DBNAME: db_test  # The name of the database created in the instance.
    3. Run the following command to build the project.

      sudo s build --use-docker
    4. Run the following command to deploy the project.

      sudo s deploy -y
    5. Run the following command to invoke the function.

      Note

      Make sure that the vSwitch CIDR block or Elastic IP Address configured for the function is added to the database instance's access whitelist. For more information, see Step 1.

      sudo s invoke -e "{}"