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:
- In the IAM console, Create a role named lambda-vpc-role with permissions AWSLambdaVPCAccessExecutionRole.
- 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:
- 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:
- 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-*
- In VPC console / Route Tables, create a new route table with a default route pointing to my new NAT gateway, nat-*
- In VPC console / Subnets, create a new private subnet associated with the new route table whose default route points to the NAT gateway.
- 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?