Serverless dev practices questions
Hi guys,
So after spending some time exploring serverless practices (Lambda in particular), a few questions popped into my mind which i’d love to get some more experienced views. The development guidelines seem to be quite straightforward for some simple stuff to do and the given sample code demonstrate it nicely. Yet - what happens when the overall application isn’t as simple and requires more than 15 lines of code? Building the design and logic of the app shouldn’t be that hard, yet making sure that it actually works is what worries me more…
What are the given practices to test, debug, troubleshoot and iterate with the code i write in Lambda? The best i came up with is traces and log collection (most common), wrappers for the code in Lambda to collect more metrics and SAM local which should allow you to run stuff locally (but then, how to simulate the real context and the flow of the app)... are these really enough to test code in Lambda? Are there any other options around? Are there any other outstanding issues in developing for for Lambda?
29 comments
[ 3.1 ms ] story [ 74.5 ms ] threadThis would also maintain as loose as possible coupling to the Lambda ecosystem, making porting easy -- I'm in Java-land, so that probably means Dropwizard. I'm not there yet, but I'm planning to maintain a parallel Dropwizard wrapper, to make local dev easy.
Works great.
The lambda function gets the request, looks at the url and routes based on that
I don't actually use the AWS HTTP API gateway. I control the front end entirely so my UI just talks direct to lambda. It's very simple - instead of futzing around implementing REST API mapping layers I just connect all my front end functions to a single lambda function and specify in the params the name of the python function I want to run. Super easy.
Even if you wanted to use API gateway you could still map all the end points to one single application and dispatch based on the route/URL.
I can make a solid recommendation to anyone use lambda .... seriously consider using Cognito for your user management.
There's no reason why you couldn't have tens of thousands of functions in the same function, in fact probably a good idea.
Can you please expand on that recommendation? I tried and found it profoundly opaque, and eventually gave up in favour of auth0. I specifically wanted to use the hosted login/sign-up forms.
It lays out the architecture fairly well and how Cognito ties into it. Still very fiddly, and doesn't give any indication on how to use their hosted forms (which are a bit of a mystery to me as well).
Since it's still on point with the OP's question, I'll ask: What has your experience been with auth0? It's another service I have considered.
The thing I spend the most time on was "user_metadata" and "app_metadata", two JSON blobs on each user, RW and RO respectively. In order to read those at all from your application, you have to define a custom "rule" (arbitrary Javascript that wraps responses). The reason for this is something about standards and name-spacing, but I couldn't really follow the argument, and it's seems like this is something that very confusing to a lot of users.
[0]: https://stackoverflow.com/questions/45828654/aws-cognito-use...
Between the startup time (importing that much Python takes a few seconds, fine for a long running server, not good per-request), and all the dev-ops/infrastructure automation to get it all working correctly in dev/prod, I just think it would be more effort than it's worth, compared to running in "normally" on a cluster of VMs or dedicated machines.
The python project defines a wsgi application (which is a python function meeting the wsgi spec), and Zappa runs the function on Lambda.
I wonder how large Zappa sites have gotten.
Personally, I've found it tough to test full integrations where I'm depending on cron jobs, work queues and notifications. I felt like I was writing an awful lot of code just to be able to fake all these integration points, which meant that in reality there was a lot of behavior that wasn't really being tested.
- We use the Serverless framework
- Monorepo with multiple (micro) services
- Each service exposes Lambda for particular functions (e.g. Articles service exposes GetArticle, CreateArticle, etc..)
- No business logic is being shared between services, only libraries
- Three environments, Dev, Stage, Production (and every developer can also deploy its own)
- Tests are invoking the Lambda handlers directly and are mocking responses from other Lambda calls. We use Localstack to stub AWS services, such as S3 and DynamoDB.
Still, a lot to learn of course, but so far everything is working great for us.
Security wise, everything is private except one Lambda that exposes a GraphQL server and is being forwarded to the public net through API Gateway. We will implement subnets and security groups very soon.
https://azure.microsoft.com/en-us/pricing/details/functions/
[1] https://claudiajs.com/
I'm not sure how AWS Lambda handles the charging of network latency (or failure) case of downstream external service dependencies but that is one of our biggest problems. ie pull/scrape architecture. The push portion (ie events) of our architecture is an obvious fit but that is already taken care of quite nicely.
We interact with hundreds of web services (REST APIS, SOAP, etc) that are actually external from us.
Its unclear if or how Amazon charges you for a slow external service (I would imagine its particularly bad if the code is blocking IO) or if that is even possible. I do know spawning a whole bunch of servers to connect to a single REST API endpoint is damn slow.
I have feeling Lambda for our case is probably not a good one? Obviously for data processing I can see it but that is not a challenge we have.
In an ideal world our downstream (or I guess it could be called upstream...) dependencies would contact us but... that sadly isn't the case particularly for adhoc stuff.
Don't look at your function as an app, it's an function and the best functions do a single thing. The definition of a single thing depends on the scale of view you're taking. But that may help you to realize your functions shouldn't be very complex and possibly small enough to test more easily.
However, that results in increased system complexity as you start adding SNS topics, SQS queues, DynamoDB tables, and all sorts of event triggers. Something I've adopted is using draw.io (others use Lucid Chart) to draw out the system logic. Maybe this helps?
https://www.draw.io/ https://www.lucidchart.com/
Maybe this makes the confusion worse?
30 questions to ask a serverless fanboy http://www.iheavy.com/2017/03/13/30-questions-to-ask-a-serve....
Then we use Apigee a127 Node project to invoke the lambda's. This is where authentication is done (we use Auth0 JWT/Bearer tokens). The Apigee a127 project invokes the lambda and handles routing. We looked at serverless but didn't want to use API Gateway since we already had apigee. We plan to look at SAM next but so far haven't need it. We have a few grunt scripts that we can use for running the lambda locally so far not a big deal.
For logging we use an AWS ElasticSearch cluster and Kibana.
So far we haven't run into any big issues with lambda, we see better response times when there is a constant load on the system, I guess that helps w/ keeping the lambda's warm. Even cold start isn't a big issue b/c the $$$ saved is well worth it.
Automate EVERYTHING. You will quickly get a bunch of lambda's and you need a way to keep them all updated, manual SUCKS.