2024-09-17
Effortless AWS Lambda Deployments
Launch APIs on AWS Lambda in minutes
Written By
Co-Founder
AWS Lambda is a great service for quickly spinning up serverless APIs, but it still takes a lot of work to set up a production-grade deployment even though there’s no servers to manage.
Let's say you want to host a simple CRUD API on Lambda that reads / writes from a Postgres database in a private VPC. Sounds simple right?
Depending on the exact use case, it will take about 5-10 AWS services to build this simple CRUD API. At a minimum, you will need to configure:
- AWS Lambda function
- RDS database
- VPC Subnets
- Roles + Permissions
- CloudWatch logs
A lot of use cases will also require:
- NAT Gateways for public internet access
- ECR Repositories for Docker Lambdas
- Code Build for running CI/CD pipelines
- API Gateway for connecting multiple Lambdas into a single API
- Route53 + SSL certificates for custom domains
Oh and don’t forget that this is just the initial project setup – you still need to configure the CI/CD pipeline that will build and deploy your code changes to your Lambda environment.
After all of that setup, you finally have a production-ready serverless function running on AWS Lambda. Congratulations! You successfully avoided configuring a server by configuring 5+ AWS services instead. I hope you wrote down what you did, because you’ll need to do it again for any other dev / staging / prod environments you have.
Jokes aside, Lambda is a truly great service once you have this all configured and automated. Luckily, LaunchFlow’s new LambdaService can handle all of this setup for you! Here’s all the code it takes to provision a Lambda API with access to an RDS database in a private VPC:
import launchflow as lf
db = lf.aws.RDS("my-database", engine="postgres16", public_access=False)
function = lf.aws.LambdaService("my-api", handler="app.handler")
You can even use the database object directly in your Lambda function code if you’re building your API with Python:
import launchflow as lf
db = lf.aws.RDS("my-database", engine="postgres16", public_access=False)
def handler(event, context):
ip_address = event["requestContext"]["identity"]["sourceIp"]
db.query(f"INSERT INTO logs (ip_address) VALUES ('{ip_address}')")
return {
"statusCode": 200,
"body": f"Hello, {ip_address}!",
}
api = lf.aws.LambdaService(
name="my-api",
handler=handler,
runtime = lf.aws.lambda_service.PythonRuntime(
runtime="python-3.11",
requirements_txt_path="requirements.txt",
),
)
Or maybe you want to have multiple Lambdas that each handle their own API endpoint using API Gateway:
import launchflow as lf
db = lf.aws.RDS("postgres-db", engine="postgres-16", public_access=False)
def read_handler(*args):
db.query(...)
return {...}
def write_handler(*args):
db.query(...)
return {...}
api_gateway = lf.aws.APIGateway("crud-api")
runtime = lf.aws.lambda_service.PythonRuntime(
runtime="python-3.11",
requirements_txt_path="requirements.txt",
)
read_api = lf.aws.LambdaService(
"read-api",
handler=read_handler,
runtime=runtime,
url=api_gateway.url("/", request="GET"),
)
write_api = lf.aws.LambdaService(
"write-api",
handler=write_handler,
runtime=runtime,
url=api_gateway.url("/", request="POST"),
)
Notice how in all of these examples there are no roles, permissions, VPCs, subnets, or any other low-level AWS configuration. LaunchFlow’s Environment abstraction handles all of that for us while still exposing all the customization options we need.
Want to try it out?
Follow the AWS Lambda Get Started Guide to launch an example API on AWS Lambda in minutes.
Check out more AWS Lambda examples in the Get Started Docs.
Need help building your API?
Email me at josh@launchflow.com and I’d be happy to help you build your API on Lambda, ECS Fargate, or any other runtime on AWS or GCP.
Happy launching! 🚀