Get details of processes running in MySQL RDS using Lambda

In this post, we’ll see how we can fetch list of processes running in MySQL RDS instance with the help of Lambda function. At the end of this post, we’ll also see an interesting use case of this setup.

Pre- requisite: 1 MySQL RDS database instance running in private subnet(You can create a db subnet group with private subnets of a VPC and launch RDS instance with that db subnet group).I’ve setup my RDS instance with default security group, however you can specify any other security group also.

Step 1: Create an IAM policy with following permissions:

{
"Version": "2012–10–17",
"Statement": [{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:DescribeNetworkInterfaces",
"ec2:CreateNetworkInterface",
"ec2:DeleteNetworkInterface"
],
"Resource": "*"
}]
}

Step 2: Create a role for lambda with this policy along with AWSLambdaBasicExecutionPolicy attached to that role.

Step 3: Create Lambda function with python 3.7 runtime and 1 minute timeout. Use the Lambda role we created earlier for this function.

Now setup the VPC configuration for this Lambda function because it needs to connect to RDS instance which is running in private subnets.

I’ve selected same subnets and security groups as that of my RDS instance. If you select a different VPC and subnet groups, make sure they are configured to connect with RDS VPC and subnet. Also make sure security group of RDS allows access on port 3306 to Lambda’s security group.

Step 4: Now we need to create code for our Lambda function. You can follow https://medium.com/@manivannan_data/import-custom-python-packages-on-aws-lambda-function-5fbac36b40f8 to set up python virtual environment.I’ve executed following commands to set up my virtualenv.

sudo pip install virtualenv
cd $HOME
virtualenv -p /usr/bin/python3.7 rds
source rds/bin/activate
pip3 install pymysql

Step 5: For Step 3 given at https://medium.com/@manivannan_data/import-custom-python-packages-on-aws-lambda-function-5fbac36b40f8, use code given at https://raw.githubusercontent.com/vinycoolguy2015/awslambda/master/rds.py

import pymysql
import logging
import sys
import json

def lambda_handler(event, context):
logger = logging.getLogger()
logger.setLevel(logging.INFO)

try:
conn = pymysql.connect("<rds_hostname>", user="<rds_user>", passwd="<rds_password>", db="<rds_db_name>", connect_timeout=5)
except pymysql.MySQLError as e:
logger.error("ERROR: Unexpected error: Could not connect to MySQL instance.")
logger.error(e)
sys.exit()

logger.info("SUCCESS: Connection to RDS MySQL instance succeeded")

with conn.cursor() as cur:
query_statement = "show processlist"
cur.execute(query_statement)
result = cur.fetchall()
logger.info("Result: " + json.dumps(result, indent=

In the connection string, replace your RDS hostname/credentials and database name. Here we are hardcoding these values in code, but you can also use secret manager to retrieve the credentials.

Step 6: Create a zip package following step 5 given at https://medium.com/@manivannan_data/import-custom-python-packages-on-aws-lambda-function-5fbac36b40f8

Step 7: Go to Lambda console and upload the zip package as source code. Now if you execute this Lambda function, you’ll get all the process running on MySQL server.

Use Case: Now when we have our Lambda function ready, we can create a CloudWatch alarm based on RDS CPU/Memory utilisation and can configure that alarm to trigger this Lambda. This way whenever there is a CPU/Memory spike, you’ll get what all processes were running at that point of time.

Experienced Cloud Consultant with a knack of automation. Linkedin profile: https://www.linkedin.com/in/vinayakpandeyit/