In Function Compute, you can use a function to call ApsaraDB RDS for MySQL API operations to perform operations such as insert and query on an ApsaraDB RDS for MySQL instance. In normal cases, instance status is not shared among different execution environments in Function Compute. You can persist structured data in a database to share instance status. This topic describes how to use Funcraft to deploy a function to access an ApsaraDB RDS for MySQL database.

Prerequisites

  1. You have created a virtual private cloud (VPC) and a VSwitch.

    The VSwitch must belong to a zone supported by Function Compute. For more information about the zones supported by Function Compute, see VPC access.

  2. Create an ApsaraDB RDS for MySQL instance

    You have created a database instance in same VPC as Function Compute. You do not need to create the VSwitch in the same zone as Function Compute. VSwitches under the same VPC can communicate with each other even when they are in different zones.

  3. Configure an IP address whitelist for an ApsaraDB RDS for MySQL instance

    If you want to use IP address whitelists to control access to databases, you must enter the internal Classless Inter-Domain Routing (CIDR) blocks of the virtual private clouds (VPCs) or vSwitches in the IP Addresses field.

    You can log on to the VPC console to obtain the internal CIDR block on the details page of the VPC or vSwitch that you want to use to access the database.

  4. Create a security group

    You have configured the security group to allow outbound traffic from the internal CIDR block and port of the database.

Write code for a function

The following section describes how to use Funcraft to write a function that accesses a database. The sample code is written in Python 3.

  1. On the local machine, create a directory to store code and dependent modules. In the directory, create the template.yml file. In this example, the /tmp/code/template.yml file is created and contains the following content:
    ROSTemplateFormatVersion: '2015-09-01'
    Transform: 'Aliyun::Serverless-2018-04-03'
    Resources:
      service:
        Type: 'Aliyun::Serverless::Service'
        Properties:
          Description: This is MYSQL service
          Policies:
            - AliyunECSNetworkInterfaceManagementAccess
          VpcConfig:
            VpcId: vpc-XXXX
            VSwitchIds:
              - vsw-XXX
            SecurityGroupId: sg-XXXX
          InternetAccess: true
        function:
          Type: 'Aliyun::Serverless::Function'
          Properties:
            Initializer: 'index.initializer'
            Handler: 'index.handler'
            Runtime: python3
            Timeout: 10
            MemorySize: 128
            CodeUri: './'

    The following list describes the main parameters:

    • A service named service is declared.
      • Policies: grants Function Compute permission to manage elastic network interfaces (ENIs) attached to Elastic Compute Service (ECS) instances. Function Compute can then access resources in the VPC.
      • VpcConfig: binds the VPC to the service. You must replace the following values with the information for your VPC.
        • VpcId: the ID of the VPC.
        • VSwitchId: the ID of the VSwitch.
        • SecurityGroupId: the ID of the security group.
    • A function named function is declared.
      • Initializer: the initializer function. For more information, see Initializer function.
      • Handler: the function handler. For more information, see Function entry point.
      • Runtime: the runtime environment of the function.
      • CodeUri: the directory where the code package is located.

        When you deploy the function, Funcraft packages and uploads the items in the directory specified by the CodeUri parameter.

  2. In the directory that contains the template.yml file, create the Funfile file. In this example, the new file contains the following sample content:
    RUNTIME python3
    RUN fun-install pip install PyMySQL
  3. Run the fun install command to install dependencies.
    fun install                 
    When the code editor shows the following content, the dependencies have been installed.
    Install Success
  4. In the directory that contains the template.yml file, create a Python file. In this example, the /tmp/code/index.py file is created and contains the following sample content:
    # -*- coding: utf-8 -*-
    import logging
    import pymysql
    import os,sys
    
    logger = logging.getLogger()
    
    def getConnection():
      try:
        conn = pymysql.connect(
          host = os.environ['MYSQL_HOST'],       // Replace the value with the internal endpoint of your ApsaraDB RDS for MySQL database.
          port = int(os.environ['MYSQL_PORT']),  // Replace the value with the port number of your database.
          user = os.environ['MYSQL_USER'],       // Replace the value with the username of your database.
          passwd = os.environ['MYSQL_PASSWORD'], // Replace the value with the password used to log on to the database.
          db = os.environ['MYSQL_DBNAME'],       // Replace the value with the name of your database.
          connect_timeout = 5)
        return conn
      except Exception as e:
        logger.error(e)
        logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
        sys.exit()
    
    def conditionallyCreateUsersTable():
      try:
        conn = getConnection()
        with conn.cursor() as cursor:
          sql = """CREATE TABLE IF NOT EXISTS users (
            id        VARCHAR(64) NOT NULL,
            name    VARCHAR(128) NOT NULL,
            PRIMARY KEY(id))"""
          cursor.execute(sql)
        conn.commit()
      finally: 
        conn.close()
    
    def initializer(context): 
      conditionallyCreateUsersTable()
    
    
    def handler(event, context): 
      try: 
        conn = getConnection()
        with conn.cursor() as cursor: 
          sql = "REPLACE INTO users (id, name) VALUES(%s, %s)"
          cursor.execute(sql, ('2', 'wan'))
          cursor.execute("SELECT * FROM users")
          result = cursor.fetchone()
          logger.info(result)
          return result
      finally:
        conn.close()
      except Exception as e:
        logger.error(e)
        logger.error("ERROR: Unexpected error: Could not connect to MySql instance.")
        sys.exit()
    
    def conditionallyCreateUsersTable():
      try:
        conn = getConnection()
        with conn.cursor() as cursor:
          sql = """CREATE TABLE IF NOT EXISTS users (
            id        VARCHAR(64) NOT NULL,
            name    VARCHAR(128) NOT NULL,
            PRIMARY KEY(id))"""
          cursor.execute(sql)
        conn.commit()
      finally:
        conn.close()
    
    def initializer(context):
      conditionallyCreateUsersTable()
    
    
    def handler(event, context):
      try:
        conn = getConnection()
        with conn.cursor() as cursor:
          sql = "REPLACE INTO users (id, name) VALUES(%s, %s)"
          cursor.execute(sql, ('2', 'wan'))
          cursor.execute("SELECT * FROM users")
          result = cursor.fetchone()
          logger.info(result)
          return result
      finally:
        conn.close()
  5. Run the following command to deploy the function to Function Compute by using Funcraft:
    fun deploy                   
    When the code editor shows the following content, the function has been deployed.
            function <function-name> deploy success
    service <service-name> deploy success

    After the deployment is complete, log on to the and click Service/Function. On the page that appears, you can see the newly deployed service and function.

Debug the function

After the function is deployed, you can debug it in the Function Compute console.

  1. Log on to the Function Compute console.
  2. In the top navigation bar, select a region.
  3. In the left-side navigation pane, click Services and Functions.
  4. In the Services pane, click the service that you require. On the Functions tab, click the name of the function that you require.
  5. On the page that appears, click the Code tab. On the Code tab, click Invoke.
    After the execution is complete, you can view the execution results and logs. log

References

Examples on how to access ApsaraDB RDS for MySQL databases from Function Compute