AWS Lambda – Best practices
cloudncode.blog
cloudncode.blog
No mention of Lambda best practices like:
- Using CloudFormation
- IAM policies
- Managing config
- How to handle databases and connection pools
Instead we get a logging suggestion that while interesting (I too prefer ElasticSearch to CloudWatch logs) is definitely not Lambda best practice.
And suggestion about choosing the right timeout (which is not necessarily helpful since the default timeout is 3 seconds so the best practice could be... "Leave the default alone unless you have a really good reason to raise it")
As far as the logging piece goes, if you are to use ElasticSearch I would strongly recommend putting the logs in CloudWatch logs first then using something like Logstash with a CloudWatch logs source to populate it into Elasticsearch as to not add another network dependency to your Lambda function.
Just like everyday conversation. I can speak without anonymity. But I would hate for someone to go look at some of the things I said 20 years ago.
a) most people will never put in that effort to search my history and
b) I trust that I will be able to find a proper excuse/response to anyone who would "attack me with my written history"
https://www.amazon.co.uk/Building-Serverless-Architectures-C...
But SAM is certainly a valid option if you are OK with vendor lock in. (which many people are)
I have tried kappa (Python) and node-lambda (Node.js), and serverless works better than both of them, is more frequently updated (Lambda and API Gateway themselves change frequently), supports more languages (I have used it with Java, Python and Node.js) and has a much larger, more active community.
The API gateway support is pretty simple and solid, and they also allow you to use cloud formation rules directly so it is very flexible.
So if you don't rely on the cross-provider features Serverless offers I suggest to take a look at CloudFormation + SAM instead.
Related: https://aws.amazon.com/blogs/compute/container-reuse-in-lamb...
It's the same approach as autoscaling VMs, but at a function level.
It should help with overhead, but not always. There's benefits to partial solutions sometimes, if you can avoid the side effects.
With creative use of deletion policy you can do pretty well.
CloudFormation is pretty terrible about managing changes on DynamoDb databases, though.
Sure, you can make lambda IP subnets in your VPC, assign your lambda to a subnet, give it a security group, and then you can easily setup your security group rules for your lambdas to connect. It's quite snazzy! Until you realize that cold startup times for your lambda normally are around a second, and when you have it running in your VPC, it takes 5 more seconds for it to make the VPC network interface. If you're using lambdas to make a REST API, this turns an occasional slight slowdown to a complete show stopper for your users.
There doesn't appear to be any good solution to this right now. You can host your Lambda outside the VPC, but then you essentially need to open your MySQL security group to the world (or every AWS Subnet, which is about the same thing). You can make a request to your Lambda function every 15 minutes, which is a terrible hack but works, except when you start approaching 50+ lambda functions you have to make heartbeat requests to every 15 minutes.
The issue is somewhat mitigated if, instead of leaning towards the natural inclination to make a separate Lambda function for each possible API request, you group API requests together, or use one Lambda function for your entire need. If your service is small in scope anyway, it won't particularly affect performance, and there will be less likelihood the lambda will go dormant/less functions you need to make heartbeat requests to. Serverless Framework has a good overview of the coding pattern options: https://serverless.com/blog/serverless-architecture-code-pat...
And yes, if you just jump straight from traditional server architectures straight to Lambda functions and Dynamodb NoSQL, you don't need VPC connections to connect to Database servers. But some of us change architecture paradigms one step at a time, Amazon!
I have a variety of web application APIs running on webservers in a VPC, with an RDS MySQL instance for backing. I'm interested in writing our new development using Lambda, but I'm still using MySQL as the database backend for now, and I still need to interact with existing APIs in the VPC. Perhaps someday I will have moved all those other applications to Lambda as well, and perhaps someday I will port all of our database functionality to DynamoDB, but I don't think that should be required in order to just get started with Lambda.
If I was writing everything from scratch, maybe I'd go full serverless. But I'm not in that case, and I'm also not in a case where MySQL won't "scale" for me at all (I wish I had that problem). If Lambda's not for me, any Amazon engineer can feel free to tell me so, but given their marketing, I did not think this was the case. They offered Lambda VPC for a reason, even though it doesn't work very well currently.
A while ago (pre proxy), it was nearly impossible to send back 302 redirects cleanly.
With LAMBDA_PROXY, it's not clear that you can actually return binary data through the Api Gateway. There's the undocumented isBase64Encoded parameter, but as far as I can tell, it's ignored. It doesn't trigger an error, but it doesn't decode base64 either.
Just this week I'm working on moving a static html site + a couple of dynamic urls over. I can work around the binary issue, but serving images is a solved problem in the rest of the world.
- When dealing with uploads have an API call to get a pre-signed S3 upload URL
- When dealing with downloads using HATEOAS and/or the Location header to send the client to S3 to grab the actual file.
It requires some client-side designing around eventual consistency but it works well and is very scalable.
The value is that it does deploy, the route-mapping, config management, and also allows you to 'keep-warm' if you want to keep the backend responsive even after zero/low traffic.
My hope is that best practices are going to continue being distilled into these deployment/wrapper frameworks.
> AWS Lambda itself isn't very good, for reasons that are specific to Lambda
- Format all logs in json. This allows you to use the json path filtering option on CW.
- Add function version & tag to the log lines. CW doesn't allow you to filter based on version.
- Don't expect CW log querying to work all the time.
- Output runtime stats to CW metrics.
edit: formatting
This is a vague statement that's not really based on evidence, and I'm not sure why using Postgres, for example, is going to be so much worse for most use cases than these NoSQL solutions.
Side note, is that just startup time for a single lambda `node`? Won't you be running >>1 node and not really care about startup time for any single node?
So if you're low, continuous traffic, it'll happen once and you won't really care. If you're high traffic, occasionally different instances will get started up, will also need their node network interface, and also take 6+ seconds. And if you're low traffic but not continuous, if there's a pause for more than around 15 minutes (entirely depends on how much demand there is for lambda and how rapidly they clean up old containers), for the next request you get you'll have to cold start again.
If anyone has any research, thoughts, or comments on this side of Lambda, I'd love to learn more
We've been experimenting with a lot of best practices around serverless development with StdLib [1]. Everything from versioning, project and team management, to authentication and billing. Basically --- we acknowledged that a lot of these aspects were surprisingly difficult and created a "git-esque" workflow for serverless function management ("lib up" to deploy, "lib get" to retrieve a current version of a function, etc.) - would love your feedback if you have time.
(Disclaimer: Founder.)
Your configuration and your code both live together, and can be stored in git together. You can create separate environments -- dev, staging, production, etc -- and deploy to them separately.
There aren't great options for testing in Lambda right now, and for the most part the advice I've seen is to make testable libraries, and then hook them into lambda.
I really wish that there was an always update flag on the cloudformation property to resolve this.
Is there any framework for handling routing and deployments?
What I mean is, is there ane xisting solution where I can make JS files to routes, and have those routes and js files be loaded into Lambda and configure the API end point; so that if I need to make an update to the lambda function i can just update the file (and re run the framework)
There will be niche use cases for Lambda but Serverless(TM) is just another passing buzzword. It won't see wide adoption unless the cold startup and costs are significantly lowered than current solutions.