0
votes

I am using the serverless framework to try and have my lambda function throw some records into an 'always on' Aurora RDS instance. So far I've been met with connect timeouts when using the mysql npm package and trying to connect to the RDS instance.

Here is what I've checked\tried:

  • put the lambda function in the VPC in serverless.yml
  • included the 3 subnets associated with that VPC in the yml
  • specified the security group in the servless.yml
  • checked that there is an aurora routing rule in that service group that allowed access to the service group itself
  • added ec2 elastic interface iam role statements

serverless.yml:

service: myrds

provider:
  name: aws
  runtime: nodejs10.x
  stage: ${opt:stage, 'dev'}
  region: ${opt:region, 'us-east-2'}
  iamRoleStatements:
    - Effect: "Allow"
      Action: 
        - "ec2:CreateNetworkInterface"
        - "ec2:DescribeNetworkInterfaces"
        - "ec2:DeleteNetworkInterface"
      Resource: "*"
  - Effect: "Allow"
      Action:
        - "sqs:SendMessage"
        - "sqs:GetQueueUrl"
        - "sqs:ListQueues"
      Resource:
        Fn::GetAtt: 
          - RDSQueue
          - Arn 
    - Effect: "Allow"
      Action:
        - "sqs:SendMessage"
        - "sqs:GetQueueUrl"
        - "sqs:ListQueues"
      Resource:
        Fn::GetAtt: 
          - DeadLetterQueue
          - Arn 
 functions:
   consumer:
    handler: handler.consumer
    timeout: 20
    vpc:
    securityGroupIds:
      - sg-123456
    subnetIds:
      - subnet-11111
      - subnet-22222
      - subnet-33333
    events:
      - sqs:
          arn:
            Fn::GetAtt:
              - RDSQueue
              - Arn
    environment:
      NODE_ENV: ${opt:stage, 'dev'}
  resources:
    Resources:
      RDSQueue:
        Type: 'AWS::SQS::Queue'
        Properties:
          QueueName: "RDSQueue-${opt:stage, 'dev'}"
          RedrivePolicy:
            deadLetterTargetArn:
              "Fn::GetAtt":
                - DeadLetterQueue
                - Arn
            maxReceiveCount: 3
      DeadLetterQueue:
        Type: 'AWS::SQS::Queue'
        Properties:
          QueueName: "DeadLetterQueue-${opt:stage, 'dev'}"

What am I missing here? It's connect timing out when it is triggered from the SQS queue.

1
Have you given lambda permission to access Aurora? - Juned Ahsan
@JunedAhsan I didn't see any specific iamrolestatements for aurora, assuming that's what you mean. I was looking in the SDK and under RDS I didn't see anything that was applicable for simple connect and query. Is that what you mean or are you talking about something else? - Ryan
where is the database connection config in your yml? - Juned Ahsan
Do the subnets have a routing table entry that point to an Internet Gateway? - Joey Kilpatrick
@JunedAhsan it's defined in a .js file, not in the yml - Ryan

1 Answers

0
votes

The typical configuration when connecting from an AWS Lambda function to an Amazon RDS database is:

  • Lambda function connected to the private subnets in the VPC
  • A Security Group on the Lambda function (Lambda-SG) with all Outbound access permitted
  • A Security Group on the RDS database (RDS-SG) with an Inbound rule allowing traffic on the appropriate port (eg 3306) from Lambda-SG

That is, RDS-SG specifically references Lambda-SG in the inbound rule.

If the Lambda function also needs to connect to the Internet, then there will need to be a NAT Gateway in the public subnet of the VPC.