Search code examples
aws-lambdaamazon-rdsserverless-frameworkamazon-vpcaws-serverless

Create an RDS instance available to Lambda functions in Serverless Framework


I have a AWS Lambda application deployed via Serverless Framework. It needs a database, the CloudFormation for which I include in serverless.yaml's resources section.

With minimal knowledge of VPCs, subnets, and security groups, my goal is the following:

  1. Create/update a MySQL RDS instance with the serverless deploys.
  2. The functions in the Lambda application should be able to access the database.
  3. The database should be accessible publicly with a password, so I can connect with MySQL tools like Sequel Ace from my computer.

What I've tried so far:

I've attempted this with the below serverless configuration. It creates the database but it doesn't fulfill #2 and #3.

I've also tried setting provider.vpc.securityGroupIds and provider.vpc.subnetIds in serverless.yaml to the same ones the RDS instance uses, to no avail.

serverless.yaml

(the relevant sections)

service: myapp

provider:
    name: aws
    runtime: provided.al2
    lambdaHashingVersion: 20201221

functions:
    console:
        handler: bin/console
        timeout: 120 # in seconds
        layers:
            - ${bref:layer.php-80} # PHP
            - ${bref:layer.console} # The "console" layer

resources:
    Resources:
        # RDS instance
        ProductDatabase:
            Type: AWS::RDS::DBInstance
            Properties:
                AllocatedStorage: 5
                DBInstanceClass: db.t3.micro
                DBName: myapp
                Engine: mysql
                EngineVersion: 8.0.25
                MasterUsername: myappuser
                MasterUserPassword: redacted
                PubliclyAccessible: true

Solution

  • There is a good article here that explains the steps you need.

    In order for your Lambda to have access to your AWS resources it needs to be inside the same VPC, and its execution role needs to have the appropriate permissions through IAM Roles/Groups.

    You also want to avoid having your RDS open to the world, so you should be creating all of this inside a VPC. You can attach your lambda function to the VPC, then allow access to the RDS only to the VPC subnets via a security group.

    That will get you steps 1 and 2 of your requirements.

    In this same security group you can allow access to the external IP address of your computer to get step 3. You can configure this through the CLI so if you don't have a static IP it only takes a second to add. PowerShell example below:

    Grant-EC2SecurityGroupIngress -GroupId "sg-xxxxxxxxxx" -IpPermission @(123.123.123.123/32)