Introducing Apex – Serverless Architecture with AWS Lambda
medium.com
medium.com
That may improve over time. But even more than that "serverless" is misleading. True, you don't have to personally manage the servers that are running your code, but that means that your operations team is actually inside Amazon. They have economies of scale, but that means they also don't always notice when one of their servers isn't performing up to par. More than once we've had to ask our support reps to get Lambda instances behind the scene restarted. At that point I start to wonder what the point is at all.
I would second what meddlepal said in a sibling comment about tooling and documentation. Everything is a little undercooked. I can see something like Apex being hugely useful here.
Given the current pricing it does seem hard to imagine large-scale systems running entirely on Lambda. But I imagine that will change.
I completely agree with TJ that we are headed for a new paradigm in server-side computing that looks a lot more like Lambda than Docker or Chef. We're racing towards a much higher level of abstraction. It's too early to tell if it will be an AWS product that emerges as the dominant platform for this new paradigm, or if a new player becomes dominant.
I'm pretty sure they have another post coming in the near future too.
I am impressed by how fast they built their platform given the size of their dev team. We (I'm a course author there, not developer) also use Lambda for custom slack bots too.
everything is versioned (so different api endpoints for staging, prod and development can talk to different versions of the lambda function), which is a big plus.
the api gateway stack is highly opinionated, as in it's good for JSON data parsed using Java on the back end (API gateway uses velocity). our strategy is to use it as a nodejs backend, so there was a lot of magic involved in the setup. it's not well documented and it discovering things like "$input.json('$') means entire body" is not easy. also we wanted to return errors as HTTP codes, not just in the JSON message body.
the setup initially was horrible and magic, but it's luckily automatable. I got it working well so that a single lambda function can receive calls from multiple api paths (so we can deploy an entire API at once, and manage dependencies simply), and that all the environment configuration is in the api gateway, not lambda (so a single function can be invoked with production/staging/development environment parameters).
it took me a while to figure out exactly how to pass things up and down the stack, and we ended up building something similar to apex (but significantly simpler due to a limited use case). a single command-line request packs up everything, uploads lambda, creates and configures the API gateway functions, manages versions and permissions, so it's relatively easy to create a new JS function tied to a URL in the API gateway now. It kind of looks like sinatra. we might end up opensourcing that if I get a chance to clean it up.
They only allow a certain fixed execution time and 500 mb of temp space, max. And they won't raise these limits.
During testing I noticed that frequently I would have the same contents of empirical storage (/tmp) -- i.e. i'd be running on the same host.
I have a sneaking suspicion that the entire purpose of lambda is to resell capacity on hosts that aren't busy -- but could be -- thus the low CPU time limits and storage spaces. I'm sure someone would not notice 500 MB or 5 minutes of CPU time vampired on their less busy, not monitored hosts from time to time. And if the real user does need the capacity, they can just kill the process, which had happened many times in my testing (process would be killed or die for no reason).
Sounds great and amazing in theory, but execution is horrible and unusable except as a toy.
That's interesting about the random kills, I'll keep an eye out for that, good to know. Interesting theory though haha, wouldn't surprise me too much.
Lambda has a lot of strengths, and it gives you solid primitives like immutable versions, version aliases/pointers and stateless functions.
The problem I had was that it didn't give me any more than that. Here are just a few of the things we had figure out and then build ourselves:
1. The development workflow. How can I get a REPL workflow going that doesn't make me go crazy.
2. Deploys and Rollbacks. How can we safely deploy and rollback, especially in cases where you have the same lambda function in multiple regions and each region is at a different published version (because the version number is monotonically incrementing)
3. Permissions and Policies. The broad strokes are clear. But you want your S3 bucket or SNS topic to trigger lambda? Get ready to spend an hour trying to figure out what you've done wrong and what's missing from the vague directions. Hope you get that REPL flow solid first.
In the end, we built several scripts (create_build, publish_version, promote_to_prod, etc) and we use these directly during development and from a Fabric-based deploy script. When I have time I plan to release this tooling open-source.
If I had to do it all over again, I wouldn't. And I wouldn't use Apex (at least not yet). I would just use a t2.small instances with a simple worker.
But I will never support anything that locks me into a particular vendor.
There are many reasons, from geopolitical to economic, that any open source infrastructure effort should be vendor neutral.
Anyway what is novel this year at AWS becomes industry standard and commoditized later.
Maybe TJ could correct any inaccuracies here:
It sounds very much like the Node.js shim used for local testing or other languages could be enhanced to listen to a TCP port rather than use stdin/stdout.
At which point, instead of just using the shim for local testing, you could deploy Apex + Shim to any VM and port. No more lock in.
Off topic: if you're reading this, Vlad my boy, I will think about sending you an email at some point. Because we all know how you love emails.
API gateway has a fixed timeout of 10 seconds that you can't currently extend. Should be fine for most use cases, but something to be aware of if you have any functions that will take longer.
Lambda functions cannot return binary data.
I've just finished prototyping a A/B testing backend running over Lambda / API Gateway. I think I bumped into some of the rough edges others are mentioning.
What troubled me the most however is how difficult it is to share / open-source the code for such a project. There are no environment variable support, so to configure things you have to embed them in code. No way to easily package something that users can just run a few simple commands and get up and running (I think having an AWS CLI + keys already set up is a pretty hefty upfront requirement). So you end up with a huge readme or a blog post just to explain how to set up all the moving parts. A small mistake anywhere along the process and this thing isn't working any more...
I hope tools like Apex can also solve this use-case. Something akin to the heroku / digitalocean button would be truly awesome.
Built for: Triggering events when something happens within AWS Not built for: Replacing all of your servers
I once knew a guy who was very into Oracle and wanted to server up HTML from stored procedures. This strikes me as that line of thinking.
In fact quite a popular thing for client-server app's where the server was built in PL/SQL, and some clients just needed reports.
I agree, AWS Lambda is a hammer. Just like everyone in enterprise software jumped at J2EE and Enterprise Java Beans back in early 2000's, and "did it wrong", I expect the same to happen here.
I just wish I know of a decent Open Source project doing similar things in a super-light-weight fashion - ideally in Python.
PHP isn't integrated with the AWS stack, but you could drop a terabyte of code on a 256mb VM and it would all run when called. Scales down really well, which is great for housing little one off scripts to receive web hooks at minimum cost, utility servers, etc. It's not sexy, but very effective.
I'd imagine you could do the same type of thing with Python in a CGI mode or something along those lines, but most other languages purposed for web stuff tend to need to load a lot of libraries at runtime to operate that way.
Deleted comment