Launch HN: SST (YC W21) – A live development environment for AWS Lambda
SST is a framework for building serverless apps on AWS. It includes a local development environment that allows you to make changes and test your Lambda functions live. It does this by opening a WebSocket connection to your AWS account, streaming any Lambda function invocations, running them locally, and passing back the results. This allows you to work on your functions, without mocking any AWS resources, or having to redeploy them every time, to test your changes. Here's a 30s video of it in action — https://www.youtube.com/watch?v=hnTSTm5n11g
For some background, serverless is an execution model where you send a cloud provider (AWS in this case), a piece of code (called a Lambda function). The cloud provider is responsible for executing it and scaling it to respond to the traffic. While you are billed for the exact number of milliseconds of execution.
Back in 2016, we were really excited to discover serverless and the idea that you could just focus on your code. So we wrote a guide to show people how to build full-stack serverless applications — https://serverless-stack.com/#guide. But we noticed that most of our readers had a really hard time testing and debugging their Lambda functions. There are two main approaches to local Lambda development:
1) Locally mock all the services that your Lambda function uses. For example, if your Lambda functions are invoked by an API endpoint, you'll run a local server mocking the API endpoint that invokes the local version of your Lambda function. This idea can be extended to services like SQS (queues), SNS (message bus), etc. However, if your Lambda functions are invoked as a part of a workflow that involves multiple services, you quickly end up going down the path of having to mock a large number of these services. Effectively running a mocked local version of AWS. There are services that use this approach (like LocalStack), but in practice they end up being slow and incomplete.
2) Redeploy your changes to test them. This is where we, and most of our readers eventually end up. You'll make a change to a Lambda function, deploy that specific function, trigger your workflow, and wait for CloudWatch logs to see your debug messages. Deploying a Lambda function can take 5-10s and it can take another couple of seconds for the logs to show up. This process is really slow and it also requires you to keep track of the functions that've been affected by your changes.
We talked to a bunch of people in the community about their local development setup and most of them were not happy with what they had. One of the teams we spoke to mentioned that they had toyed with the idea of using something like ngrok (or tunneling) to proxy the Lambda function invocations to their local machine. And that got us thinking about how we could build that idea into a development environment that automatically did that for you.
So we created SST. The `sst start` command deploys a small _debug_ stack (a WebSocket API and DynamoDB table) to your AWS account. It then deploys your serverless app and replaces the Lambda functions in it, with a _stub_ Lambda function. Finally, it fires up a local WebSocket client and connects to the _debug_ stack. Now, when a Lambda function in your app is invoked, it'll call the WebSocket API, which then streams the request to your local WebSocket client. That'll run the local version of the Lambda function, send the result back through the WebSocket API, and the _stub_ Lambda function will respond with the results.
This approach has a few advantages. You can make changes to your Lambda functions and test them ...
91 comments
[ 3.1 ms ] story [ 170 ms ] threadReally excited about this and it has been a LONG time coming.
It’s a cool business though - selling shovels.
SST is open source and runs on your AWS account. We don't charge you for it and it's most likely going to be within the free tier on AWS.
If you can do this reliably, and pass corporate venting, you easily have a product worth millions.
On the other hand, if this gets popular Amazon can easily just clone the product and integrate it directly. You'll know it's a good idea then.
Edit : MIT ! Awesome, thanks for the donation to The Open source community. If I ever use this in a real project I'll go ahead and donate a few bucks.
But the way this works locally (for Node) is that you do an npm install just as you would and it executes your application locally. The packaging part comes into play when deploying these functions to AWS. And I agree that portion even for Node isn't bullet proof. It's something we want to do a better job of.
But when you `sst deploy` it, we'll package your functions. To do this we use esbuild (https://esbuild.github.io), it's like Webpack but 10x faster. It'll generated a single js file that should be fairly small and you shouldn't have to use Layers.
However, this isn't bullet proof. There are some dependencies that are not compatible with esbuild/webpack, and you'll end up having to zip them up as a directory. That's something we are going to work to improve in the future.
Very developer-friendly founders as well, being ever helpful over Slack and more.
Highly recommended!
We have a separate service that's a CI/CD pipeline for serverless apps. We use a SaaS model there — https://seed.run. It supports SST out of the box. But it also supports Serverless Framework, the other popular option out there.
There's Apache Openwhisk and OpenFass which are all open standards for serverless.
I've personally gone back and forth on the idea of purely local vs cloud based development. And fwiw, SST strikes a very interesting balance between the two. You get the feel of a local environment, while still connecting to every cloud resource.
https://seed.run
This deploys it to AWS first, and when a function gets invoked remotely, streams that request to your local machine where it'll execute that function and send the results back to AWS. You basically get to test and develop against your real infrastructure.
But I do feel your pain, building a CI/CD for serverless is quite annoying and is a big waste of time for startups. I would not recommend it.
And quite frankly serverless as an ecosystem needs to be improved before it can compete with app engine, when it comes to developer experience. We care a great deal about it and that's what we are working on.
SST on the other hand, deploys your app and when a deployed Lambda function gets invoked remotely, it'll stream that request to your local machine, execute it, and send the results back to AWS. So you get the advantage of working against real infrastructure while still making changes locally.
The video helps a illustrate it a little better — https://www.youtube.com/watch?v=hnTSTm5n11g
I use that model and it's pretty good. I can output local log lines and see them on the console.
To fix this SST will deploy your entire stack, and let you trigger the workflow live. So you can hit the endpoint just as your frontend would, or trigger the entire SNS workflow. Except all the Lambda function invocations will be streamed to your local machine and the responses will be sent back.
This approach allows you to get the best of both worlds. The speed on an `sls invoke local`, without having to mock anything.
But I have to deploy stub functions and have a different deployment model for prod. :) So there are definitely tradeoffs.
I like this idea and will certainly try it out!
What I was really hoping for is someone who could figure out a way to launch a terminal in Lambda so that I can modify my functions in place and view the logs in place, and then when I'm done, save my work to git, like I used to be able to do when I had a fleet of servers and could just log onto one of them in prod and muck around with logs (and yes I know this is a bad idea but it's also how things get done quickly).
While this doesn't quite do the edit in place and I wouldn't recommend running this for prod with live traffic; we use it to run some scripts against prod. You get an environment where you can make changes quickly as opposed to having to deploy your function to run them.
Have you considered extracting the lambda portion into a lambda extension so that you can deploy this as part of any cdk/cloudformation stack or standalone lambda and toggle on/off local debugging based on some registration in dynamo (e.g. store a predicate applied to the event and proxy to local if the predicate evaluates true)? This would allow something like this to be hugely useful in mitigating outages.
I didn't catch it in the repo yet but I'd you're proxying local AWS calls through the lambda to allow quickly catching IAM and security group/routing issues, that would be incredible.
Happy to help with this stuff and will definitely be a user!
I hadn't thought of using something like this for mitigating outages. Do you mind elaborating on that a bit more?
Currently there isn't a simple way to switch off the debug mode. So if `sst start` deploys the Lambda with the debug mode, `sst deploy` will disable it by putting the original Lambda back. But your idea of switching it on and off should work!
For the IAM portion, we are don't use the IAM credentials of the local machine while executing the Lambda. We use the credentials of the original Lambda. This allows for testing against the right credentials.
Appreciate the feedback! If you've have any questions or are curious about the internals, I'd love to hear from you jay@anoma.ly
Being able to debug in situ would be fairly incredible in a complex application.
None of that is meant to take away at all from what you've built. What you have here is really awesome and I'm excited to use it.
Appreciate the feedback!
Wonderful tooling, I've been enjoying it quite a bit. Keep it up! I'm excited to see the feature set grow.
After having struggled with all the confusing serverless related content out there, the docs are a big point of emphasis for the project.
Currently we do APIs, queues, cron jobs, and pub/sub. We won't force people to use these but we'll be adding support for more serverless use cases as we go along.
For example, if your Lambda function publishes to a SNS topic that invokes another Lambda function. You can only test this locally my mocking the inputs for the first one, testing that. And repeating it for the second one.
With SST, it deploys this stack to AWS. So when you trigger this workflow, both the Lambda functions get invoked on your local machine. You don't need to mock anything. It is as if they were invoked live.