It's not typical (because most people don't know about it), but API Gateway can integrate directly with many AWS services without the need to put AWS Lambda in between.
If you find yourself writing many Lambdas just to do simple transforms and piping around data, it's always a good idea to check if the two services can directly talk to each other first.
The mapping template language(?) is frustrating to do anything in though. Its documentation is somewhat hidden / distributed, especially any special variables / util functions, and suffers from limitations like the foreach operator being limited to 1000 iterations. Unless you're literally returning entire database objects (unprocessed, including all the type info) or something similar, it's pretty limited.
I started to have a look but that first diagram arrows everywhere, does no one do simple any more?
It does look like what a normal web app would do in say PHP or Django. Is there really an advantage to splitting it into microservices and putting it in AWS Lambda over a load balancer and extra instances when needed? A normal app would have those services split into classes / modules and would run on the same machine (the aysnc tasks being an exception). I imagine my approach would need a lot less ops and coordination between the parts.
Not sure yet I like how aws does this but I started to think that serverless and microservices are about state after all. It is about ephemeral apps that hold only the bare minutes state. For instance you don’t need user management as identity is better when decoupled into another service. A lot of it sounds like Unix philosophy as in one good tool for one job. HashiCorp YouTube videos explain a lot of those ideas quite nicely. In this world stuff like aws lambda makes sense. However you can build your own lambda and deploy as a container service. So again not exactly sure if aws is doing things right, but the concepts make sense. Apps as functions.
That was my conclusion after getting all excited about serverless initially. I was seeing lower latency, no coldstart concerns, and easier log access/ability to debug just by going back to having a server. Plus having your entire deploy be completely governed by a gigantic YAML file that no one's ever bothered to fully (or even properly) document gets old very fast. So I'm back to using servers.
There are a few advantages. Not worrying about maintaining and securing underlying infrastructure is huge. Not worrying about load balancing logic is helpful. Having isolated blast radius of application failures is nice. Overprovisioning can be a real problem depending on the underlying machines.
And then when you get into the surrounding services and features you really start to feel the benefits. Want to have canary deployments? Want to have a queue of failed events? Want to start piping data into a data lake for future analytics? Need to introduce a decoupling message queue in front of an expensive operation? All of it is almost turnkey.
In my experience, when a single engineering team owns the entire service, a single web app >>> cluster of microservices.
The advantage to splitting up systems is when multiple teams own part of the service and do not want to be dependent on each other for testing and deploying and signing off on features.
Although given the amount of time I spent this week to be able to send a string from my microservice to a partner teams' microservice and get a different string back, I'm not feeling microservice love today...
I wish articles like these would include sections about how their developers dev / test / promote through different environments. Only seeing how a production system is structured is less than half the battle and can mask true complications of going serverless.
Deploying serverless code through the cycle is no different conceptually than deploying regular code. In our case we deploy Cloudformation templates that reference the same Lambda package in S3 across accounts. Rolling back is redeploying the old template v
Typically you spin up a dev stack with the same cloudformation templates, so you get an exactly prod parallel environment (with parameters for things like DDB dev table names)
chiming in here to agree with the other replies - one of the big benefits of serverless for us is that every environment is a "complete" environment, using an identical architecture to prod and no mocking or sharing of services. And costs maybe $50/mo/dev, most of which is a NAT gateway.
If you do test, you really can only test each unit in isolation - testing the kind of setup in the article is just too hard and the tooling for doing automated tests on that kind of thing is not very mature. There is stuff like localstack/samstack/etc but I haven't seen anyone really use it as part of a workable test strategy for serverless AWS.
Consider what happens outside of serverlessland: when people have 15+ microservices each of which needs a different docker container and different data store. Do they tend to do whole-system testing of it? No, in my experience people tend mumble something about "contracts" and test individual bits in isolation.
This is on top of the open secret which is: it's very, very hard to predict what the ongoing costs of a serverless solution will be. Most of the services are priced by usage but the units are small (seconds, minutes, etc) and the sums are too (eg $0.000452 per hour of xyz). Post-project bill shock is a considerable problem.
Source: worked at an AWS partner consultancy on many cloud "architectures" similar to the article.
Actually using cloud formation, it’s really easy to do integration testing. Often times server less can be cheaper because the systems only pay for what they use. High tps is expensive on server less, but low tps is dirt cheap. Source is I work at aws
Serverless covers 2 scenarios very well: when you have volume so low, that you don't want to pay for reserved capacity: if nobody is using the stuff, you pay next to nothing.
And also if there is a lot of load, it's very very easy to scale it to cover very high demand.
These reference architectures always look less like anything a sane person would come up with than an opportunity to cram every possible cloud service into a solution and jack the price of hosting a simple web app up into the thousands of dollars a month.
Actually when I saw the diagram at the top of the article I thought "Yup, that looks almost exactly like the architecture of the last project I worked on", as it uses all those AWS services in roughly the same arrangement.
That's not to say I disagree with your comment though...
Too much marketing, not enough content. Glossing over the dumpster fire of Cognito is enough for me to not trust the rest of the content.
There is so much custom code to essentially fling data between services. I imagine only a small percent of the code and dev time is spent on business logic. These Rube Goldberg machines are my least favourite part of AWS, especially when dealing with at-least-once delivery.
Cognito has an awful API and worse documentation. It's also super limited in terms of how user metadata is represented, is hard to query efficiently for users meeting certain criteria, and produces super cryptic errors when integrations aren't set up correctly. As a whole the Cognito product feels like some weird bolted-on POC that AWS decided to charge money for. Compare that to a real _product_ like Auth0 and it just falls to pieces.
If the appeal is about free usage under 40k monthly active users, you probably don't need an external complex managed auth solution in the first place.
Try finding a cognito user from a cognito identity, you can't.
Visit the amplify-js and amplify-cli github repos and search for cognito issues.
Try using the cognito console, it is a litter box of warning messages and exceptions. Try connecting Cognito and Pinpoint if you are in Europe, 2 years and it still doesn't work, but no indication.
See its cloudformation configuration and how many field changes cause a Replace. Yes, replace Cognito and goodbye users.
Until recently user names were case sensitive, and they didn't have basic account enumeration protections.
Its UX is exactly how DynamoDB can do damage to a product.
I recently built a new app on AWS and Lambda. I really wanted to use Cognito to keep everything in AWS. I fought with getting it working for a day or so before giving up and trying out Auth0. I was up and running with Auth0 in a couple hours. I found the Cognito documentation to be insufficient for my needs. Others may have better experiences.
No, I was not aware of that Firebase functionality as I have never used it. Interesting. Yes, it would be ideal if I could just let another layer do all of the authentication and authorization. That would have worked for the bits of code that use the database. I still would need a way to use the authentication token for things like the Stripe integration.
Right, rather than managing your own server with a known interface and familiar commands, you get the pleasure of managing everything through a single bloated configuration file typically with very poor documentation.
I wonder what the difference between managed serverless and having an EC2 instance w/ Firecracker loaded up on it would be.
I've used Lambda and I fear maintenance burdens due to the underlying environments migrating; they'll keep the runtime for a running function for you but if it's old I don't think you can update that without having to upgrade runtimes.
Also you get billed in 50ms increments at minimum, and so beyond that there's little incentive to make a function faster / a lot of incentive to stuff more logic into a function and make it less composable.
I think I'd rather define an AMI w/ Firecracker using Packer, and stand up a box with Terraform, and write logs to CloudWatch, and have a much more predictable billing cycle / greater control.
If your load is within a reasonably small range, Lambda is quite expensive on a per-computation basis. But, if your load varies wildly (and especially unpredictably), you can spend less time worrying about that than on a build-similar on EC2 solution.
I'm using Lambda@Edge for static site auth, so I just need to pass some HTTP headers, and it still seems a bit overkill. I really like the ability to integrate with a CDN, I don't think I want to move away from that to something like nginx that could fall over and be more expensive, but being billed for every signin I do is a bit nerve-wracking. Maybe it's just new and I don't have enough experience with it yet.
> I've used Lambda and I fear maintenance burdens due to the underlying environments migrating; they'll keep the runtime for a running function for you but if it's old I don't think you can update that without having to upgrade runtimes.
AWS supports runtimes as long as there are upstream support security updates available [1]. If there are no security updates anymore, it's a good idea anyway to update to a newer version. If course you don't have to do that if you host it on your own, but it's a good idea nevertheless.
Also mind that most of the runtimes AWS deprecated already are old NodeJS versions. That's apparently because NodeJS only offers 30 months of support for their LTS versions [2]. So choosing a language which offers longer support (for example Python which offers 5 years of support [3]), might be a better choice if you don't want to update your software regularly.
Also you could still provide your own runtime, which wouldn't be deprecated at all via custom runtimes [4].
> Also you get billed in 50ms increments at minimum, and so beyond that there's little incentive to make a function faster / a lot of incentive to stuff more logic into a function and make it less composable.
You get billed in 100ms increments [5]. While I'd like to see smaller increments as well, I encountered more money thrown out of the window by overprovisioning memory (and therefore CPU) for AWS Lambda functions, than you could possibly save by optimizing for billable duration.
Hmm, you make some good points w.r.t. the custom runtime. I do kind of wish that AWS would maintain its own LTS releases of things like node.js, but I guess it's difficult to say whether that would require source mutation from the user.
I do wish there were more examples of Lambda functions, like a marketplace of some sort. I'm using NodeJS only because certain tutorials offer examples in node.js (like static site authentication): https://douglasduhaime.com/posts/s3-lambda-auth.html
I actually logged into CloudWatch just to see that point on 50ms vs. 100ms and yeah you're right, it's 100 not 50. I'm pretty new to Lambda, and wonder whether the billing insights dashboard will give me the breakdown b/w duration and memory.
If you want to figure out if you overprovisioned memory for your AWS Lambda functions: There is a pretty handy pre-defined query in CloudWatch Insights for that.
That sounds like more of a maintenance nightmare. Why go through the hassle instead of just using Docker/Fargate with either ECS or EKS? If you don’t want to use Lambda?
I've only used Docker w/ ECS and EC2 task definitions, but creating and draining instances is pretty time-consuming and I'm guessing not responsive enough for serverless-specific workloads. If you use Packer and lock down your AMI and atomically update it, I don't see maintenance as being that big of a hassle, but I don't have too much experience in this regards and I value optionality to a high degree. I guess this would also depend on how many microVMs you might be able to reliably stick on an EC2 instance.
Rolling your own firecracker solution would put the control in your hands, but then aren't you limited to .metal EC2 instances (with all the cost increases that come with it)?
Firecracker uses KVM to implement virtualization to launch containers inside "micro" VMs. As far as I know, Amazon only gives you virtualization extension access on bare metal instances.
In my case I see people skipping over things they don’t know when estimating like traffic and actual resource deployment and crap like “yeah Jenkins will be fine in a container”.
Always assumptions, missing info and costs and poor understanding of it because it’s so damn complicated understanding cost. Consider traffic costing across several regions and you can regularly just piss $20k away from a small architectural decision made wrong.
Estimating costs is Actually so difficult that it has almost entirely replaced the old role of license management under the lie that renting your shit monthly makes that concern go away.
I think for most places and most workloads, the state of the art in cost estimation is “figure out the fixed costs, see that they’re reasonable, then launch and keep an eye on the first few bills to hope all the bandwidth and other “surcharge type” costs aren’t deal-breakers...”
This doesn’t work when the cloud marketing associates this as a “cost of doing business”
Which causes revenue chasing and profit hunting to “stay alive”.
Not to mention the massive startup credits issued which ensure complete and utter lock-in for the entirety of your business’s existence (successful or not).
Most companies don’t audit their cloud costs and the ones that do simply consider it the “cost of doing business” and move on.
This is a terrible practice that is being pushed by the cloud vendors. It’s gotten to the point where now cloud advocates are calling AWS and others an “operating system” your business needs to perform and fulfill its vision.
My company has given a hard push of lowering costs by 20% across all business lines and auditing our cloud usage has been very very shocking.
I am sure as the effects of the pandemic continue, more and more companies are going to realize the same thing.
It is sad. I will say that many years ago I was stuck on the cloud bandwagon, but today if you asked me how a new business should set up their infra, I would advocate for on-prem or leasing bare metal from some provider.
Just a simple way to provision and snapshot VMs is what 99% of businesses actually need. This is what most businesses have always needed. Many are still using this exact same technology today without any problems.
The entire system is described by a few cloudformation templates that you maintain in source control. Plus the actual application code running in the lambdas, these frameworks are super-thin.
Unless something changes in gulp, gulp packages, OS, your codebase, disk write speed or network latency...
Or was your comment sarcastic and I didn't get it? Whenever I tried to run the same gulp tasks on a different machine, it almost never worked first-try.
The immediate thought looking at that diagram is that while on first glance serverless runtimes seem to promise that you don't have to care about the details, turns out you really do have to care a lot about the details!
You're not really relieving yourself of concerns by using serverless runtimes, just shifting them around. Sure, you don't have to care about managing state at the leaves, but you very definitely do now have to come up with a way to hold state globally with ephemeral/stateless leaves, and it turns out that's... a really hard problem with a really complex solution space.
Not to be overly dismissive or say that one way is better than the other, it definitely depends on the usecase and probably the underlying business model of the usecase. Just to point out that when it comes to engineering abstractions, there really isn't any free lunch. It's all tradeoffs.
How is that any different than a typical web server? Hopefully you don’t maintain state on your web server either. This isn’t a new concept. Even in the early 2000s when I was maintaining two web servers behind a physical load balancer we knew to maintain session state separately from the web server.
I hate to be “that guy”. But “the cloud” is no more than someone else managing servers and services at varying levels of abstraction.
I have no idea why some people hear AWS/Azure and they act as if the same architectural principles that have always applied still apply, just on a more granular scale in the case of “Serverless”.
More of a rant about the person who complains about not being able to maintain state at a tier that you never maintain state at in even a traditional architecture.
It’s nice to see the serverless movement and its applications. However the fact every (public) cloud provider does it differently is killing it (incompatible logic/interfaces). Right now, serverless is merely shifting complexity of apps to cloud services. Cloud services with a lot more logic (lines of code) that does a million other things than what your application needs. That oftens means much more (uncovered) bugs. In order to have better control and predictability there has to be standards and minimizing depth of code.
I’m convinced serverless is the next after containers; but only if it becomes a standard that can encapsulate services in building blocks that you can easily connect with each other and very predictably behavior. We are not there yet, hopefully soon.
The only think that you need to make your code work with Lambda is a function that takes in an event body and a Lambda context. If you are following standard architectural best practices, your lambda entry point should just be validating your event, mapping it to your business domain and remapping the result. You should treat your lambda event just like you would an action in your controller in most MVC frameworks aka “skinny controllers”.
This is a standard “onion architecture” with “ports and adapters”.
Sound development principles don’t get thrown out of the window just because you “move to the cloud”.
How do you mange cost, then? If you host your container on a DigitalOcean VPS, you can just spin one up in a few clicks and you have a consistent, predictable pricing. Who would be the target audience using "serverless" over spinning up a few virtual or dedicated servers? I haven't heard of any company that needed to instantly scale from 1k to 1m users overnight.
I hate the "serverless" term, but I think people just use "serverless" for platforms where you can write some code and it will be automatically deployed, hosted and scaled on their server(s). So instead of "serverless" it's more like pre-configured managed server clusters running where you can only run restricted code/functions.
I personally don't understand who the target audience is, as small apps/companies very rarely (if ever) need to scale and large enterprise companies are probably better off hiring a sys admin and getting their own dedicated servers, which would lead to a lot more flexibility, performance and reduced costs.
That looks really complicated to me. What's the advantage of setting up a system like that over a typical server, i.e. with most of that stuff handled by one server, writing code to coordinate between a few external things (like maybe auth0 and a DB)?
A better separation of concerns. I only have to worry about my function with lambda. With a server, I have to worry about everything that could go wrong with an OS, like new security exploits.
Take that concept a step further, and I don't want to worry about my functions. I want to focus on the one place of expertise I do best and build on standard implementations of validation and data transformation.
For the core functionality the only part you touch is the code in the lambdas. Everything comes out of the box if you use a framework like Serverless or SAM. (The step functions, batches, identity, and async pieces you have to configure separately).
The number of OSs you patch or upgrade over the course of running this for a few years is... zero. And the time and effort to scale up, run failover tests on your servers, migrate to new hardware ..also zero.
But the servers are just a small part of it. The application services around it make it possible to build enterprise grade scalable services with low ops overhead really fast.
That sounds really appealing. I really love the sales pitch for serverless stuff. I think I've probably just been exposed to a lot of really advanced ways of setting it up for a big project. It seems complex.
This looks so expensive! I've been going in the same path (with centige.com, WIP) but then I stopped and refactored some stuff:
- I had lots of lambdas written in TS. Things were going out of hands. So I refactored them into three lambdas only. A large one that has a switch statement to execute the correct function, and two other ones for some quite long-running processes.
- The big lambda was executed too many times. Moving it to an actual server would cost me way less. So I did. Plus I could add more security features that would need AWS API Gateway if I chose to stick with lambdas, which is too expensive.
- Initially I used Amplify. And while recently its bundle size has been reduced substantially, it's still big (see https://bundlephobia.com/result?p=aws-amplify@3.0.12). In my case, I only needed the Auth package, which is 50kb (https://bundlephobia.com/result?p=@aws-amplify/auth@3.2.7). However, my options were quite limited and I found myself changing things around to make my app compatible with the way AWS Cognito worked[1] (used by Amplify Auth). I ended up removing it and handling authentication on my own.
A better stack for a serverless app would be Vercel for deploying the app (it's cheap, it has SSL, and it has automatic deployments) and either lambdas or a server, depending on your needs, for handling backend stuff.
Also, use something like aws4fetch instead of the actual SDK if you can. It will save your visitors some kilobytes :)
---
[1]: Email/password auth with Cognito is not the best thing out there. So I wanted to add Google Sign In. At the same time, I wanted to use DynamoDB's row-level access (similar to Firebase's write rules, but more limited). My plan didn't go too well, as I needed the user's Id (provided by Google) when writing to DDB. But Cognito wasn't returning the Id... I spent a couple of days on it, then I figured that I'm just wasting my time.
I used Lambdas as our core logic processor for 4 years. We cared about every failure and the core motivation was it's scaling ability as our traffic was bursty and would scale 1000x on random days.
Lambda -- Serverless in general -- is fantastic when your application has any amount of downtime (on the order of 10 seconds). If there is even the briefest moment your system can be turned off, you'll save dramatically over a traditional server model.
This is actually a decent use case for it. I should have been more nuanced in my response.
I have seen more then one project fail when they use lamdas to serve apis. This is because of the cold start problem, but also because lambda does have scaling issues unless you work around them. By scaling I mean greater then 1000 tps.
All of the services performed within lambdas SLA but failed to meet the requirements that the project had.
The solution was always to wrap whatever function it called in a traditional app and deploy it using a contanerized solution where response times dramatically improved and services became more reliable.
The idea behind lambda is good, but it can't beat more traditional stacks at the moment. One could argue that most projects don't have these requirements, and I would agree, but the marketing behind lambda doesn't make that clear.
I did this a few years back. What happens is clients just don't have the budget unless they are onboard. They really don't like tech. Think about when you first started work on a computer. You're afraid you're going to break it and are just learning how to type on a keyboard.
My focus now is device to device and offline first. My diagram then is that last Asynchronous Task block on the right along with your S3 webhosting. Data is only on the app and my servers are now like bots. If they see a client with data they like, they extract it and perform all types of tasks on it. My focus is on what is good data for my servers to pick up and for my apps to transfer device to device.
When your business API is one get data and one post data I find 100% serverless passable.
I'm starting to accrue a list of projects that started out looking like that, with product owners swearing blind that was the sum total of all they could want, but ended up becoming much more complex. Then you get into the pain of sequential lambda cold starts, etc and before you know it everyone thinks you're in too deep to turn around and the pain just won't go away.
Just one more AWS service and all our problems will be solved...
I just fell on the post today. I am the one who wrote the article... I'm a bit terrified by the comments haha. But that's a way to learn and improve stuff.
Thanks for your support in the middle of this.
To answer your question: our dev environment is iso to staging and production with AWS accounts for each developer. The cost is close to 0. Deploying and testing a code change takes seconds. Deploying and testing a config change however is still a little bit longer for sure...
I read the entire article, and my first thought is... why? Why go through all that complexity? How much money does this actually save over writing a regular server to prompt favoring this approach? Wouldn't this have a similar cost as a regular server if you get regular activity, minus all the complexity? What happens when your lambdas get DDoSed, do you get overcharged?
“ Q: How can I address or prevent API threats or abuse?
API Gateway supports throttling settings for each method or route in your APIs. You can set a standard rate limit and a burst rate limit per second for each method in your REST APIs and each route in WebSocket APIs. Further, API Gateway automatically protects your backend systems from distributed denial-of-service (DDoS) attacks, whether attacked with counterfeit requests (Layer 7) or SYN floods (Layer 3).”
As developers we have done a poor job of managing complexity. Largely a result of schedule pressure that leads over time to code bases that have modules that reach deep into the internals of other modules. The consequence is a complex codebase that slows down development.
So I believe serverless/micro services is a way to enforce those boundaries in such a way that a junior developer or schedule pressure won’t allow us to cheat and reach into the internals of another module to get a feature shipped in time. You simply can’t do that when code is running on a different server. So this additional complexity forces separation of concerns that can’t be cheated by schedule pressure or shortcuts.
Of course the downside to this is we have to now manage a different kind of complexity.
As developers I wish we pushed back and simply built our monoliths as a set of independent npm packages, jars, or whatever your language supports. Doing this enforces clear separation of interfaces / dependency management. If we did that then the complexity of debugging and supporting the architecture presented, which strikes me as several orders of magnitude more complex, would be avoided and instead we simply manage at our code level.
At a past job, we hired some people out of Amazon to work on our cloud services. They rewrote large portions of it using AWS serverless tools.
Cost was a big concern for us. Strangely enough, the AWS experts insisted it would be impossible to estimate the cost of the serverless architecture until we deployed it at scale and tried it out. Is this still the case, or has it become easier to estimate costs during development?
In our case, costs did go up significantly after the serverless rewrite, but they also added additional functionality and complexity that made a 1:1 cost comparison impossible.
Serverless was interesting, but if I was involved in another backend project I would want to understand the cost better before diving into the deep end with all of these intertwined services.
The cost become a politically sensitive, and ultimately secretive, topic after it became clear that the costs were growing.
I was less involved with that team over time. I got the impression that serverless was quick and easy for the simple server-side operations that could be mapped easily to AWS' serverless building blocks. Of course, this is where they started and showed initial promise.
It broke down as they started taking more complicated server-side functions and forcing them into serverless style. It felt like a square peg / round hole situation that ballooned in complexity just to make it serverless.
If I did it again, I'd have the teams start with the most complicated server-side functions instead of picking the low hanging fruit first.
And, of course, be open to using regular old servers where it made sense to do so. AWS Serverless provided a lot of internal political ammunition because the cloud team could show up in a meeting with complicated diagrams exactly like what you see in this article, whereas previously we just showed single blocks for servers and another block for databases. The complexity did a great job of convincing execs that the AWS experts knew what they were doing, but then of course they were committed to going with the serverless options.
> Think you're ever going to be able to migrate that app to anything other than AWS?
Obviously, no, we did not expect to migrate our AWS Serverless backend to something other than AWS.
Avoiding vendor lock in makes sense in few, select circumstances.
Avoiding vendor lock in for the sake of avoid vendor lock in leads to over engineered services that take longer to deliver because people are going out of their way to avoid using vendor-specific tools.
In all of my time as an engineering manager, the number of times that avoiding vendor lock in has solved more problems than it caused is still zero.
Use the best tools available at your disposal to get the job done. Cross the vendor-changing bridge if (and only if) it becomes a requirement.
I think you might be thinking it is a binary choice. Educated decisions can be made to decide if a particular item is worth the lock in or not. For example auto scaling groups in AWS are much faster to set up and maintain than vendor neutral choices. But leaving asg is pretty much the same amount of work as setting up auto scaling anyway. Switching out has cost but not that much. Something like cognito... that’s almost impossible to leave. But more importantly it’s the AWS “glue” between these services that is truly impossible to leave.
I have seen two businesses fail under the weight of AWS billing and be unable to get out from underneath it before they ran out of funding. It’s definitely not something to look at lightly.
And how many companies are successful either because they started on AWS until they found product market fit and they were capitalized well enough to migrate off (Dropbox) or are successfully running their entire business at scale on AWS (Netflix).
How many companies fail because they run out funding - period?
Congratulations, you found two examples out of the millions of companies that exist in this world, both with astronomically greater funding and scale than anyone you or I are likely to work on. Yet people continue to obsess about these unicorns and assume the choices they've had to make are clearly the right choices for everyone.
The greatest problem with modern devops is peoples delusional ideas over the scale upon which they're really operating and where they're really going to start feeling the pinch. I've come across way too many tinpot "we're netflix!" setups that crumble under their own unmanageability as soon as they have budget and staff taken away from them for a couple of quarters.
So you are claiming that there are only two companies that have successfully run a business on AWS?
The reason for managed cloud is the same reason for using any other vendor. To let you focus on your core competencies that give you a competitive advantage. Do you also think companies shouldn’t use Github, Microsoft, Workday, Oracle, SalesForce, Atlassian, etc.?
Do you know how much infrastructure you can buy for the fully allocated code of one employee?
Maybe they know something that you don’t know...
Seeing that even Amazon admits that only 5% of Enterprise workloads are on any cloud provider, who is arguing that it is always the right choice?
I command a higher than (local) market salary for an individual contributor in no small part because of my expertise when it comes to AWS, but I’m the first person to tell someone who asks me for advice when it doesn’t make sense to bother with the complexity and cost of a cloud provider and just use a colo, VPS, or just use AWS Lightsail (AWS’s answer to companies like Linode).
> In all of my time as an engineering manager, the number of times that avoiding vendor lock in has solved more problems than it caused is still zero.
How long have you stuck around to find out? Never had to undertake a massive task to migrate an existing system that's closely bound to its legacy platform? Because that's the other side of the coin.
I also highly suspect that number is not zero, you're just not counting the obvious decisions people make every day that avoid lock-in because they seem like common sense. But I suspect you're not building everything using ColdFusion, though, or doing your version control through Perforce...
> Use the best tools available at your disposal to get the job done.
Behind this phrase lies the fallacy that there is any such thing as "the best tool" and the implication that anyone doing anything different is a clear idiot. In reality, everyone uses "the best tool", it's just they have different metrics by which they measure it.
I used AWS for a recent personal project. Lambda was not the right approach for me and primarily due to cost. I had an idea of how long a request takes to process (ball park estimate) and the expected throughout (requests per second). From that I knew that at minimum, I would be paying $x a month, and as the execution time of my code goes up or I get a spike in my traffic volume, it would only increase from there.
If you’re at scale, AWS Lambda blows up real quick.
That’s why you use Lambda+APIGW with proxy integration where you can use your standard frameworks like Express, Django, Flask, ASP.NET MVC and your can easily move from lambda without any code changes.
You’re not “locked in” to Lambda. When you see that lambda isn’t the answer you deploy the code to a server or Docker just by making a few changes to your deployment pipeline.
If you use the standard APIGW solution where it routes to your various lambdas, you would have to rewrite code.
Sorry but maybe you misunderstood my post. I never said anything about “lock in”. I could easily estimate ballpark minimum costs in front. There’s absolutely no reason to continue using Lambda at that point.
Lock in or no lock in, there’s also a cost of writing the deployment scripts and setting up your development vs. production Lambda stack. And if you are using Lambda, you’re going to end up making various decisions to keep your costs low. For example, I was working with a JVM stock. Spring is too heavy, and even Guice has some execution cost. So on Lambda, I would use Dagger... a decision made purely because I’m operating on Lambda.
Building an architecture on Lambda requires certain decisions to be made up front. Saying that you can just lift and shift later on is very simplistic and will be costly depending on what you’ve already done on Lambda.
I would always say estimate your costs first and think about the long term picture about your request rates, patterns (spikes), and growth rates.
Setting up your lambda deployment scripts is setting your CodeUri value in CF to match the output directory of your build and running CloudFormation package and deploy.
Changing your deployment to use Docker/Fargate is creating your Docker container by copying from the same output directory to your container in your Docker file, pushing your container to ECR, and running a separate CloudFormation deploy to deploy to Docker.
I’ve deployed to both simultaneously.
There are no decisions to be made up front. You create your standard Node/Express (for example) service and add four lines of code. Lambda uses one entry point and Docker or your VM uses the other.
It’s simplistic because it is simple. Java is never a good choice for Lambda.
>Setting up your lambda deployment scripts is setting your CodeUri value in CF to match the output directory of your build and running CloudFormation package and deploy.
What about writing CF to begin with for all your Lambda functions and setting up all their permissions to work alongside whatever other resources you have?
>Changing your deployment to use Docker/Fargate is creating your Docker container by copying from the same output directory to your container in your Docker file, pushing your container to ECR, and running a separate CloudFormation deploy to deploy to Docker.
Nobody said anything about Docker or Fargate. This has nothing to do with the topic. My problems had no need for using Docker. Do you randomly pick a tool kit and just hope it works out? I suspect you're not really working at scale and costs aren't a concern.
>I’ve deployed to both simultaneously.
Great job. We are all proud of you I guess, but this is not how engineering works, especially when you're building at scale.
>It’s simplistic because it is simple. Java is never a good choice for Lambda.
It's actually not simplistic. Software engineering is about being able to make tradeoffs. Not everything is a CRUD/web application. It's funny you keep going back to Node/Express as your examples. Have you looked into Express and what dependencies it has, or do you just randomly pick the new framework of the week? I don't mean this as an attack, but I'm more than slightly annoyed that you keep referring to Node and Express, when that has nothing to do with the problems I'm trying to solve.
The funny thing is you've written out all these lengthy posts but never stopped to ask about whatever constraints the system has. You started with the solution and are basically now looking at one of my constraints (JVM ecosystem) and are saying it's not a good choice.
In the real world, we often don't have the ability to randomly swap out a language. There's enough properly tested code that already exists or a massive code base that entire teams are supporting. They're not going to drop that just so they can go pick up a shiny new framework or product offering. LOL.
What about writing CF to begin with for all your Lambda functions and setting up all their permissions to work alongside whatever other resources you have?
There are no “all of your lambda functions” with the proxy integration. You write your standard Node/Express, C#/WebAPI, Python/Flask API as you normally would and add two or three lines of code that translates the lambda event to the form your framework expects. I’ve seen similar proxy handlers for PHP, and Ruby. I am sure there is one for Java.
As far as setting up your permissions, you would have to create the same roles regardless and attach them to your EC2 instance or Fargate definition.
Just make sure your build artifacts end up in the path specified by the CodeUri and change your runtime to match your language. I’ve used this same template for JS, C#, and Python.
Nobody said anything about Docker or Fargate. This has nothing to do with the topic. My problems had no need for using Docker. Do you randomly pick a tool kit and just hope it works out? I suspect you're not really working at scale and costs aren't a concern.
You’re using your standard framework that you would usually use. You can use whatever deployment pipeline just as easily to deploy to EC2 with no code changes.
Great job. We are all proud of you I guess, but this is not how engineering works, especially when you're building at scale.
Actually it is. Since you are using a standard framework choose whatever deployment target you want....
Have you looked into Express and what dependencies it has, or do you just randomly pick the new framework of the week? I don't mean this as an attack, but I'm more than slightly annoyed that you keep referring to Node and Express, when that has nothing to do with the problems I'm trying to solve.
I also mentioned C# and Python. But as far as Java/Spring. Here you go.
The funny thing is you've written out all these lengthy posts but never stopped to ask about whatever constraints the system has. You started with the solution and are basically now looking at one of my constraints (JVM ecosystem) and are saying it's not a good choice.
I’ve also just posted a Java solution. The constraints of Lambda are well known and separate from Java - 15 minute runtime, limited CPU/Memory options and a 512MB limit of local TMP storage.
In the real world, we often don't have the ability to randomly swap out a language. There's enough properly tested code that already exists or a massive code base that entire teams are supporting. They're not going to drop that just so they can go pick up a shiny new framework or product offering. LOL.
My suggestion didn’t require “switching out the language”. Proxy integration works with every supported language - including Java. It also works with languages like PHP that are not supported via custom runtimes and third party open source solutions.
This solution is entirely wrong and doesn’t work for the problem I was trying to solve. You seem to believe every problem is a web application or a web API of some kind. The proxy doesn’t make sense in my use case, and for the simple reason that it’s cost prohibitive alone, I would pass.
Feel free to keep writing more paragraphs. You’re trying to solve problems that don’t exist.
It seems like you start from solutions and hope that the problem will fit. Lambda seems to be your hammer and you write as if everything is a nail.
It seems like you start from solutions and hope that the problem will fit. Lambda seems to be your hammer and you write as if everything is a nail.
So lambda seems to be the solution and my “hammer” even though I mentioned both EC2 and ECS? Is there another method of running custom software on AWS that I’m not aware of besides those three - Docker (ECS/EKS), Lambda, and EC2?
Sure, if you want to inflate developer costs. Isn't a huge portion of the cloud argument that people are expensive, infra is cheap so who cares if you spend a lot on AWS as long as you have fewer sysadmins? If you suddenly care how much you're spending on infrastructure but, apparently, don't care how much you spend on developers to work within such a convoluted system, why not exit the cloud at that point?
Everything is convoluted if you don’t know what you are doing.For instance, I find the entire modern front end development ecosystem a royal clusterf*&$ but people are using it effectively everyday.
193 comments
[ 3.2 ms ] story [ 240 ms ] threadIf you find yourself writing many Lambdas just to do simple transforms and piping around data, it's always a good idea to check if the two services can directly talk to each other first.
The docs for most services are really bad. I wasn't fond of learning VTL for AGW either :/
It does look like what a normal web app would do in say PHP or Django. Is there really an advantage to splitting it into microservices and putting it in AWS Lambda over a load balancer and extra instances when needed? A normal app would have those services split into classes / modules and would run on the same machine (the aysnc tasks being an exception). I imagine my approach would need a lot less ops and coordination between the parts.
And then when you get into the surrounding services and features you really start to feel the benefits. Want to have canary deployments? Want to have a queue of failed events? Want to start piping data into a data lake for future analytics? Need to introduce a decoupling message queue in front of an expensive operation? All of it is almost turnkey.
The advantage to splitting up systems is when multiple teams own part of the service and do not want to be dependent on each other for testing and deploying and signing off on features.
Although given the amount of time I spent this week to be able to send a string from my microservice to a partner teams' microservice and get a different string back, I'm not feeling microservice love today...
If you do test, you really can only test each unit in isolation - testing the kind of setup in the article is just too hard and the tooling for doing automated tests on that kind of thing is not very mature. There is stuff like localstack/samstack/etc but I haven't seen anyone really use it as part of a workable test strategy for serverless AWS.
Consider what happens outside of serverlessland: when people have 15+ microservices each of which needs a different docker container and different data store. Do they tend to do whole-system testing of it? No, in my experience people tend mumble something about "contracts" and test individual bits in isolation.
This is on top of the open secret which is: it's very, very hard to predict what the ongoing costs of a serverless solution will be. Most of the services are priced by usage but the units are small (seconds, minutes, etc) and the sums are too (eg $0.000452 per hour of xyz). Post-project bill shock is a considerable problem.
Source: worked at an AWS partner consultancy on many cloud "architectures" similar to the article.
Does it look like an unmaintanable untestable mess?
Serverless covers 2 scenarios very well: when you have volume so low, that you don't want to pay for reserved capacity: if nobody is using the stuff, you pay next to nothing.
And also if there is a lot of load, it's very very easy to scale it to cover very high demand.
Don't get me wrong, I absolutely love AWS SAM, but I believe testing serverless applications locally is still an unsolved problem.
That's not to say I disagree with your comment though...
There is so much custom code to essentially fling data between services. I imagine only a small percent of the code and dev time is spent on business logic. These Rube Goldberg machines are my least favourite part of AWS, especially when dealing with at-least-once delivery.
What's wrong with it?
If the appeal is about free usage under 40k monthly active users, you probably don't need an external complex managed auth solution in the first place.
Visit the amplify-js and amplify-cli github repos and search for cognito issues.
Try using the cognito console, it is a litter box of warning messages and exceptions. Try connecting Cognito and Pinpoint if you are in Europe, 2 years and it still doesn't work, but no indication.
See its cloudformation configuration and how many field changes cause a Replace. Yes, replace Cognito and goodbye users.
Until recently user names were case sensitive, and they didn't have basic account enumeration protections.
Its UX is exactly how DynamoDB can do damage to a product.
I understand the wish to keep everything in AWS.
Especially after I read many times thaz Auth0 is pretty expensive. Is this true?
I would have preferred to keep everything in AWS just to make it easier to use one set of credentials (IAM) to manage permissions.
That's when I figured that I'm not gaining anything by using Cognito.
I've used Lambda and I fear maintenance burdens due to the underlying environments migrating; they'll keep the runtime for a running function for you but if it's old I don't think you can update that without having to upgrade runtimes.
Also you get billed in 50ms increments at minimum, and so beyond that there's little incentive to make a function faster / a lot of incentive to stuff more logic into a function and make it less composable.
I think I'd rather define an AMI w/ Firecracker using Packer, and stand up a box with Terraform, and write logs to CloudWatch, and have a much more predictable billing cycle / greater control.
AWS supports runtimes as long as there are upstream support security updates available [1]. If there are no security updates anymore, it's a good idea anyway to update to a newer version. If course you don't have to do that if you host it on your own, but it's a good idea nevertheless.
Also mind that most of the runtimes AWS deprecated already are old NodeJS versions. That's apparently because NodeJS only offers 30 months of support for their LTS versions [2]. So choosing a language which offers longer support (for example Python which offers 5 years of support [3]), might be a better choice if you don't want to update your software regularly.
Also you could still provide your own runtime, which wouldn't be deprecated at all via custom runtimes [4].
> Also you get billed in 50ms increments at minimum, and so beyond that there's little incentive to make a function faster / a lot of incentive to stuff more logic into a function and make it less composable.
You get billed in 100ms increments [5]. While I'd like to see smaller increments as well, I encountered more money thrown out of the window by overprovisioning memory (and therefore CPU) for AWS Lambda functions, than you could possibly save by optimizing for billable duration.
[1]: https://docs.aws.amazon.com/lambda/latest/dg/runtime-support...
[2]: https://nodejs.org/en/about/releases/
[3]: https://devguide.python.org/#status-of-python-branches
[4]: https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom...
[5]: https://aws.amazon.com/lambda/pricing/
I do wish there were more examples of Lambda functions, like a marketplace of some sort. I'm using NodeJS only because certain tutorials offer examples in node.js (like static site authentication): https://douglasduhaime.com/posts/s3-lambda-auth.html
I actually logged into CloudWatch just to see that point on 50ms vs. 100ms and yeah you're right, it's 100 not 50. I'm pretty new to Lambda, and wonder whether the billing insights dashboard will give me the breakdown b/w duration and memory.
Thanks!
It’s quite sad how effective cloud marketing penetrated the dev community.
The claim is that getting out of the regular instance-and-EBS-volume architecture avoids cost.
The question being whether "avoids cost" meant Amazon, or your business.
Always assumptions, missing info and costs and poor understanding of it because it’s so damn complicated understanding cost. Consider traffic costing across several regions and you can regularly just piss $20k away from a small architectural decision made wrong.
Estimating costs is Actually so difficult that it has almost entirely replaced the old role of license management under the lie that renting your shit monthly makes that concern go away.
"The difference between theory and practice is greater in practice than in theory."--Herb Sutter in C++ Users Journal some decades ago.
Which causes revenue chasing and profit hunting to “stay alive”.
Not to mention the massive startup credits issued which ensure complete and utter lock-in for the entirety of your business’s existence (successful or not).
This is a terrible practice that is being pushed by the cloud vendors. It’s gotten to the point where now cloud advocates are calling AWS and others an “operating system” your business needs to perform and fulfill its vision.
My company has given a hard push of lowering costs by 20% across all business lines and auditing our cloud usage has been very very shocking.
I am sure as the effects of the pandemic continue, more and more companies are going to realize the same thing.
Just a simple way to provision and snapshot VMs is what 99% of businesses actually need. This is what most businesses have always needed. Many are still using this exact same technology today without any problems.
Or was your comment sarcastic and I didn't get it? Whenever I tried to run the same gulp tasks on a different machine, it almost never worked first-try.
You're not really relieving yourself of concerns by using serverless runtimes, just shifting them around. Sure, you don't have to care about managing state at the leaves, but you very definitely do now have to come up with a way to hold state globally with ephemeral/stateless leaves, and it turns out that's... a really hard problem with a really complex solution space.
Not to be overly dismissive or say that one way is better than the other, it definitely depends on the usecase and probably the underlying business model of the usecase. Just to point out that when it comes to engineering abstractions, there really isn't any free lunch. It's all tradeoffs.
I have no idea why some people hear AWS/Azure and they act as if the same architectural principles that have always applied still apply, just on a more granular scale in the case of “Serverless”.
> and they act as if the same architectural principles that have always applied still apply,
They do still apply...
More of a rant about the person who complains about not being able to maintain state at a tier that you never maintain state at in even a traditional architecture.
I’m convinced serverless is the next after containers; but only if it becomes a standard that can encapsulate services in building blocks that you can easily connect with each other and very predictably behavior. We are not there yet, hopefully soon.
This is a standard “onion architecture” with “ports and adapters”.
Sound development principles don’t get thrown out of the window just because you “move to the cloud”.
I personally don't understand who the target audience is, as small apps/companies very rarely (if ever) need to scale and large enterprise companies are probably better off hiring a sys admin and getting their own dedicated servers, which would lead to a lot more flexibility, performance and reduced costs.
Take that concept a step further, and I don't want to worry about my functions. I want to focus on the one place of expertise I do best and build on standard implementations of validation and data transformation.
The number of OSs you patch or upgrade over the course of running this for a few years is... zero. And the time and effort to scale up, run failover tests on your servers, migrate to new hardware ..also zero.
But the servers are just a small part of it. The application services around it make it possible to build enterprise grade scalable services with low ops overhead really fast.
- I had lots of lambdas written in TS. Things were going out of hands. So I refactored them into three lambdas only. A large one that has a switch statement to execute the correct function, and two other ones for some quite long-running processes.
- The big lambda was executed too many times. Moving it to an actual server would cost me way less. So I did. Plus I could add more security features that would need AWS API Gateway if I chose to stick with lambdas, which is too expensive.
- Initially I used Amplify. And while recently its bundle size has been reduced substantially, it's still big (see https://bundlephobia.com/result?p=aws-amplify@3.0.12). In my case, I only needed the Auth package, which is 50kb (https://bundlephobia.com/result?p=@aws-amplify/auth@3.2.7). However, my options were quite limited and I found myself changing things around to make my app compatible with the way AWS Cognito worked[1] (used by Amplify Auth). I ended up removing it and handling authentication on my own.
A better stack for a serverless app would be Vercel for deploying the app (it's cheap, it has SSL, and it has automatic deployments) and either lambdas or a server, depending on your needs, for handling backend stuff.
Also, use something like aws4fetch instead of the actual SDK if you can. It will save your visitors some kilobytes :)
---
[1]: Email/password auth with Cognito is not the best thing out there. So I wanted to add Google Sign In. At the same time, I wanted to use DynamoDB's row-level access (similar to Firebase's write rules, but more limited). My plan didn't go too well, as I needed the user's Id (provided by Google) when writing to DDB. But Cognito wasn't returning the Id... I spent a couple of days on it, then I figured that I'm just wasting my time.
I've re-platformed so many projects these past few years because of these issues.
I wish more would take that to heart instead of marketing for Amazon.
Lambda -- Serverless in general -- is fantastic when your application has any amount of downtime (on the order of 10 seconds). If there is even the briefest moment your system can be turned off, you'll save dramatically over a traditional server model.
I have seen more then one project fail when they use lamdas to serve apis. This is because of the cold start problem, but also because lambda does have scaling issues unless you work around them. By scaling I mean greater then 1000 tps.
All of the services performed within lambdas SLA but failed to meet the requirements that the project had.
The solution was always to wrap whatever function it called in a traditional app and deploy it using a contanerized solution where response times dramatically improved and services became more reliable.
The idea behind lambda is good, but it can't beat more traditional stacks at the moment. One could argue that most projects don't have these requirements, and I would agree, but the marketing behind lambda doesn't make that clear.
My focus now is device to device and offline first. My diagram then is that last Asynchronous Task block on the right along with your S3 webhosting. Data is only on the app and my servers are now like bots. If they see a client with data they like, they extract it and perform all types of tasks on it. My focus is on what is good data for my servers to pick up and for my apps to transfer device to device.
I'm starting to accrue a list of projects that started out looking like that, with product owners swearing blind that was the sum total of all they could want, but ended up becoming much more complex. Then you get into the pain of sequential lambda cold starts, etc and before you know it everyone thinks you're in too deep to turn around and the pain just won't go away.
Just one more AWS service and all our problems will be solved...
What does your dev/sandbox environment look like? Are you using localstack?
Thanks for your support in the middle of this.
To answer your question: our dev environment is iso to staging and production with AWS accounts for each developer. The cost is close to 0. Deploying and testing a code change takes seconds. Deploying and testing a config change however is still a little bit longer for sure...
“ Q: How can I address or prevent API threats or abuse?
API Gateway supports throttling settings for each method or route in your APIs. You can set a standard rate limit and a burst rate limit per second for each method in your REST APIs and each route in WebSocket APIs. Further, API Gateway automatically protects your backend systems from distributed denial-of-service (DDoS) attacks, whether attacked with counterfeit requests (Layer 7) or SYN floods (Layer 3).”
So I believe serverless/micro services is a way to enforce those boundaries in such a way that a junior developer or schedule pressure won’t allow us to cheat and reach into the internals of another module to get a feature shipped in time. You simply can’t do that when code is running on a different server. So this additional complexity forces separation of concerns that can’t be cheated by schedule pressure or shortcuts.
Of course the downside to this is we have to now manage a different kind of complexity.
As developers I wish we pushed back and simply built our monoliths as a set of independent npm packages, jars, or whatever your language supports. Doing this enforces clear separation of interfaces / dependency management. If we did that then the complexity of debugging and supporting the architecture presented, which strikes me as several orders of magnitude more complex, would be avoided and instead we simply manage at our code level.
Cost was a big concern for us. Strangely enough, the AWS experts insisted it would be impossible to estimate the cost of the serverless architecture until we deployed it at scale and tried it out. Is this still the case, or has it become easier to estimate costs during development?
In our case, costs did go up significantly after the serverless rewrite, but they also added additional functionality and complexity that made a 1:1 cost comparison impossible.
Serverless was interesting, but if I was involved in another backend project I would want to understand the cost better before diving into the deep end with all of these intertwined services.
I was less involved with that team over time. I got the impression that serverless was quick and easy for the simple server-side operations that could be mapped easily to AWS' serverless building blocks. Of course, this is where they started and showed initial promise.
It broke down as they started taking more complicated server-side functions and forcing them into serverless style. It felt like a square peg / round hole situation that ballooned in complexity just to make it serverless.
If I did it again, I'd have the teams start with the most complicated server-side functions instead of picking the low hanging fruit first.
And, of course, be open to using regular old servers where it made sense to do so. AWS Serverless provided a lot of internal political ammunition because the cloud team could show up in a meeting with complicated diagrams exactly like what you see in this article, whereas previously we just showed single blocks for servers and another block for databases. The complexity did a great job of convincing execs that the AWS experts knew what they were doing, but then of course they were committed to going with the serverless options.
I think they probably considered you a "sucker". Think you're ever going to be able to migrate that app to anything other than AWS?
Obviously, no, we did not expect to migrate our AWS Serverless backend to something other than AWS.
Avoiding vendor lock in makes sense in few, select circumstances.
Avoiding vendor lock in for the sake of avoid vendor lock in leads to over engineered services that take longer to deliver because people are going out of their way to avoid using vendor-specific tools.
In all of my time as an engineering manager, the number of times that avoiding vendor lock in has solved more problems than it caused is still zero.
Use the best tools available at your disposal to get the job done. Cross the vendor-changing bridge if (and only if) it becomes a requirement.
I have seen two businesses fail under the weight of AWS billing and be unable to get out from underneath it before they ran out of funding. It’s definitely not something to look at lightly.
How many companies fail because they run out funding - period?
Congratulations, you found two examples out of the millions of companies that exist in this world, both with astronomically greater funding and scale than anyone you or I are likely to work on. Yet people continue to obsess about these unicorns and assume the choices they've had to make are clearly the right choices for everyone.
The greatest problem with modern devops is peoples delusional ideas over the scale upon which they're really operating and where they're really going to start feeling the pinch. I've come across way too many tinpot "we're netflix!" setups that crumble under their own unmanageability as soon as they have budget and staff taken away from them for a couple of quarters.
The reason for managed cloud is the same reason for using any other vendor. To let you focus on your core competencies that give you a competitive advantage. Do you also think companies shouldn’t use Github, Microsoft, Workday, Oracle, SalesForce, Atlassian, etc.?
Do you know how much infrastructure you can buy for the fully allocated code of one employee?
Maybe they know something that you don’t know...
Seeing that even Amazon admits that only 5% of Enterprise workloads are on any cloud provider, who is arguing that it is always the right choice?
I command a higher than (local) market salary for an individual contributor in no small part because of my expertise when it comes to AWS, but I’m the first person to tell someone who asks me for advice when it doesn’t make sense to bother with the complexity and cost of a cloud provider and just use a colo, VPS, or just use AWS Lightsail (AWS’s answer to companies like Linode).
$10k does not get you very far with AWS.
How long have you stuck around to find out? Never had to undertake a massive task to migrate an existing system that's closely bound to its legacy platform? Because that's the other side of the coin.
I also highly suspect that number is not zero, you're just not counting the obvious decisions people make every day that avoid lock-in because they seem like common sense. But I suspect you're not building everything using ColdFusion, though, or doing your version control through Perforce...
> Use the best tools available at your disposal to get the job done.
Behind this phrase lies the fallacy that there is any such thing as "the best tool" and the implication that anyone doing anything different is a clear idiot. In reality, everyone uses "the best tool", it's just they have different metrics by which they measure it.
I used AWS for a recent personal project. Lambda was not the right approach for me and primarily due to cost. I had an idea of how long a request takes to process (ball park estimate) and the expected throughout (requests per second). From that I knew that at minimum, I would be paying $x a month, and as the execution time of my code goes up or I get a spike in my traffic volume, it would only increase from there.
If you’re at scale, AWS Lambda blows up real quick.
If you use the standard APIGW solution where it routes to your various lambdas, you would have to rewrite code.
Lock in or no lock in, there’s also a cost of writing the deployment scripts and setting up your development vs. production Lambda stack. And if you are using Lambda, you’re going to end up making various decisions to keep your costs low. For example, I was working with a JVM stock. Spring is too heavy, and even Guice has some execution cost. So on Lambda, I would use Dagger... a decision made purely because I’m operating on Lambda.
Building an architecture on Lambda requires certain decisions to be made up front. Saying that you can just lift and shift later on is very simplistic and will be costly depending on what you’ve already done on Lambda.
I would always say estimate your costs first and think about the long term picture about your request rates, patterns (spikes), and growth rates.
Changing your deployment to use Docker/Fargate is creating your Docker container by copying from the same output directory to your container in your Docker file, pushing your container to ECR, and running a separate CloudFormation deploy to deploy to Docker.
I’ve deployed to both simultaneously.
There are no decisions to be made up front. You create your standard Node/Express (for example) service and add four lines of code. Lambda uses one entry point and Docker or your VM uses the other.
It’s simplistic because it is simple. Java is never a good choice for Lambda.
What about writing CF to begin with for all your Lambda functions and setting up all their permissions to work alongside whatever other resources you have?
>Changing your deployment to use Docker/Fargate is creating your Docker container by copying from the same output directory to your container in your Docker file, pushing your container to ECR, and running a separate CloudFormation deploy to deploy to Docker.
Nobody said anything about Docker or Fargate. This has nothing to do with the topic. My problems had no need for using Docker. Do you randomly pick a tool kit and just hope it works out? I suspect you're not really working at scale and costs aren't a concern.
>I’ve deployed to both simultaneously.
Great job. We are all proud of you I guess, but this is not how engineering works, especially when you're building at scale.
>It’s simplistic because it is simple. Java is never a good choice for Lambda.
It's actually not simplistic. Software engineering is about being able to make tradeoffs. Not everything is a CRUD/web application. It's funny you keep going back to Node/Express as your examples. Have you looked into Express and what dependencies it has, or do you just randomly pick the new framework of the week? I don't mean this as an attack, but I'm more than slightly annoyed that you keep referring to Node and Express, when that has nothing to do with the problems I'm trying to solve.
The funny thing is you've written out all these lengthy posts but never stopped to ask about whatever constraints the system has. You started with the solution and are basically now looking at one of my constraints (JVM ecosystem) and are saying it's not a good choice.
In the real world, we often don't have the ability to randomly swap out a language. There's enough properly tested code that already exists or a massive code base that entire teams are supporting. They're not going to drop that just so they can go pick up a shiny new framework or product offering. LOL.
There are no “all of your lambda functions” with the proxy integration. You write your standard Node/Express, C#/WebAPI, Python/Flask API as you normally would and add two or three lines of code that translates the lambda event to the form your framework expects. I’ve seen similar proxy handlers for PHP, and Ruby. I am sure there is one for Java.
As far as setting up your permissions, you would have to create the same roles regardless and attach them to your EC2 instance or Fargate definition.
But as far the CF template. Here you go:
https://github.com/awslabs/aws-serverless-express/blob/maste...
Just make sure your build artifacts end up in the path specified by the CodeUri and change your runtime to match your language. I’ve used this same template for JS, C#, and Python.
Nobody said anything about Docker or Fargate. This has nothing to do with the topic. My problems had no need for using Docker. Do you randomly pick a tool kit and just hope it works out? I suspect you're not really working at scale and costs aren't a concern.
You’re using your standard framework that you would usually use. You can use whatever deployment pipeline just as easily to deploy to EC2 with no code changes.
Great job. We are all proud of you I guess, but this is not how engineering works, especially when you're building at scale.
Actually it is. Since you are using a standard framework choose whatever deployment target you want....
Have you looked into Express and what dependencies it has, or do you just randomly pick the new framework of the week? I don't mean this as an attack, but I'm more than slightly annoyed that you keep referring to Node and Express, when that has nothing to do with the problems I'm trying to solve.
I also mentioned C# and Python. But as far as Java/Spring. Here you go.
https://github.com/awslabs/aws-serverless-java-container/wik...
The funny thing is you've written out all these lengthy posts but never stopped to ask about whatever constraints the system has. You started with the solution and are basically now looking at one of my constraints (JVM ecosystem) and are saying it's not a good choice.
I’ve also just posted a Java solution. The constraints of Lambda are well known and separate from Java - 15 minute runtime, limited CPU/Memory options and a 512MB limit of local TMP storage.
In the real world, we often don't have the ability to randomly swap out a language. There's enough properly tested code that already exists or a massive code base that entire teams are supporting. They're not going to drop that just so they can go pick up a shiny new framework or product offering. LOL.
My suggestion didn’t require “switching out the language”. Proxy integration works with every supported language - including Java. It also works with languages like PHP that are not supported via custom runtimes and third party open source solutions.
Feel free to keep writing more paragraphs. You’re trying to solve problems that don’t exist.
It seems like you start from solutions and hope that the problem will fit. Lambda seems to be your hammer and you write as if everything is a nail.
Good luck!
So lambda seems to be the solution and my “hammer” even though I mentioned both EC2 and ECS? Is there another method of running custom software on AWS that I’m not aware of besides those three - Docker (ECS/EKS), Lambda, and EC2?
Sure, if you want to inflate developer costs. Isn't a huge portion of the cloud argument that people are expensive, infra is cheap so who cares if you spend a lot on AWS as long as you have fewer sysadmins? If you suddenly care how much you're spending on infrastructure but, apparently, don't care how much you spend on developers to work within such a convoluted system, why not exit the cloud at that point?