2

I have an AWS Lambda function which is being successfully run via a HTTP request to an API Gateway. It returns a JSON response which I can see in my local web browser.

Now I want it to gather data from an Aurora Serverless MySQL database which I have set up. I can access this database from a Cloud 9 environment. I can import my Lambda function into Cloud 9 and choose "run local" and it successfully connects to the database and runs SQL queries.

However, when I run the Lambda function from the API gateway, pymysql.connect fails, throwing an OperationalError with the message "Can't connect to MySQL server on 'testdb.cluster-xxxxx.us-east-1.rds.amazonaws.com".

I have followed Tutorial: Configuring a Lambda Function to Access Amazon RDS in an Amazon VPC and performed these steps:

  1. In the IAM console, Create a role named lambda-vpc-role with permissions AWSLambdaVPCAccessExecutionRole.
  2. In the Lambda console for the function, set Execution Role / Existing Role to lambda-vpc-role

I have read Using Amazon Aurora Serverless which states that "You can access an Aurora Serverless DB cluster from AWS Lambda" and directs me to Configuring a Lambda Function to Access Resources in an Amazon VPC. Following this, I have performed these steps:

  1. In the Lambda console for the function, in the Network box, set the VPC to the VPC in which the Aurora Serverless cluster is running.

That document also states, "When you add VPC configuration to a Lambda function, it can only access resources in that VPC. If a Lambda function needs to access both VPC resources and the public Internet, the VPC needs to have a Network Address Translation (NAT) instance inside the VPC." Therefore I read How can I grant internet access to my VPC Lambda function? and performed these steps:

  1. In VPC console / NAT Gateways, create a new NAT Gateway on an existing public subnet, which is to say one with a route table with a default route pointing to igw-*
  2. In VPC console / Route Tables, create a new route table with a default route pointing to my new NAT gateway, nat-*
  3. In VPC console / Subnets, create a new private subnet associated with the new route table whose default route points to the NAT gateway.
  4. In the Lambda console for the function, in the Network box, set the Subnets to contain only the new private subnet.

I now believe my Lambda function is running within the VPC and I can successfully run it using the API gateway and see its JSON response. However it is still unable to connect to the MySQL database.

What further steps are needed to allow the Lambda function to connect to the database?

Rob Fisher
  • 151
  • 5

1 Answers1

1

The missing step is:

  1. In the VPC console / Security Groups, select the rds-launch-wizard group (the security group created when the Aurora Serverless cluster was created), choose the Inbound Rules tab and click edit. Add a rule. For type, choose MYSQL/Aurora (which selects TCP port 3306). For source, enter the CIDR for the private subnet created in step 6 and which the Lambda function is configured to use.

Because the Lambda function is run on a machine in a different subnet from the database cluster, although it is in the same VPC, the security group still needs to be configured to allow the inbound connection to the database from that source.

I think the question and this answer now provide the full steps to set up a public-facing Lambda function with access to an Aurora Serverless database cluster, but perhaps other answers could improve on these instructions. There may be a more concise way to describe the configuration or a more easily reproducible method, such as by using command line tools instead of the web consoles.

Rob Fisher
  • 151
  • 5