LocalStack tries, but IMO it's not great.
LocalStack tries, but IMO it's not great.
I think things like the AWS SAM or LocalStack do a decent job at this. But, maybe more importantly, it requires a shift in developer thinking. Screw local development; yeah, I'll invoke locally during prototyping, but once the essential structure is done I'm going to deploy it and test directly on AWS.
I don't find the feedback cycle due to deployment time to be a blocker. SAM can deploy a function in 10 seconds. Its not an instant code reload, its not ideal, but its also not context-breaking like a 2 minute deploy would be (to be fair, SAM is capable of 1+ minute deploys, but that's usually only when you're adding new AWS resources like new buckets or event invocation rules, not when you're just changing the function code).
It's easy. But if that's too much for you, the serverless framework has some nice plugins for all of it.
This enables you to, with a little more effort, swap out the Interface Adapter part with, say, a CLI. Or, if you ever want to get off lambda, its a bit easier as well.
Mocking out dependencies, like S3 buckets, isn't worth it during a prototype/MVP. As time goes on, sure, go for it. But early on, just use AWS. Don't use localstack or any of the other various tools that try to replicate AWS. They're all going to get it wrong, hopefully in obvious ways, but usually in subtle ways that'll crash production, and you're just creating more work for yourself. Just use AWS. Just use AWS. Just use AWS.
Then, everything is once more tested using AWS. I stay away from replicating AWS services locally.
It greatly simplifies refactoring and overhauling the core itself, as well as trying out new approaches.
And local development when you've opted to use systems like Cognito are well beyond its scope, unless someone has something very clever that I haven't seen.
From a lot of experience doing this on AWS and on other clouds, I have learned that it is better to use systems that you can operate, and then use hosted versions where applicable. RDS is great, but it's great mostly because you can run PostgreSQL locally and inspect its brain. DynamoDB, SQS, etc. tend to be untrustworthy and should be avoided unless you have a bulletproof story for local testing (and none of the fake implementations are bulletproof).
(I actually have an answer for local dev with Cognito because my current employer already had Cognito when I showed up, but it amounts to "have configurable signing keys and sign your own JWT in dev".)
Our local tests' leaky abstractions don't care about anything happening upstream. They only care about testing our core "agnostic" logic.
(Also, getting a bit further away from that, I find API Gateway kinda shifty and I dislike that it's so hard to run something like NestJS inside of Serverless. Doable, there are examples, but it kinda sucks.)
Are you saying you need an environment to test in that is 100% disconnected from the internet? Given the interconnectedness of APIs in 2019, that seems like making things harder than necessary.
For personal projects, having to futz with Pulumi--and, I should note, Pulumi is the one I like--just to write some code on top of a web server just really sucks. Iterating on a heckin' cloud template just to be able to write some code sucks. Waiting (and as somebody who works on devops projects primarily at work, I am very familiar with how long one waits) destroys motivation to work on anything, both at the start of a session and in the middle--like, blowing away all those dependencies when I need to reset takes way longer than `docker-compose down && docker-compose up`. I am also incredibly cheap for personal projects, because I cannot rationalize spending money on something I'm not certain I'm going to ship, and so I can't adequately ensure that AWS is not going to start dinging my credit card for resources.
This post talks about how our team experienced much of what’s in this thread and what we built to solve it: https://www.stackery.io/blog/how-do-we-setup-a-proper-server...
VS Code folks seem to be pretty excited about our plugin https://marketplace.visualstudio.com/items?itemName=stackery...
We’d love to have you give it a try and let us know how it works for you.
The problem that I have, and it is probably intractable is 1) I don't want to manage developers YOLOing dev stuff around at work and having a gigantic bill show up because a developer randomed something expensive and didn't know/didn't care to monitor it, and 2) I don't want to deal with the expense or the slowness (of deploys and redeploys, and that includes the AWS resources--ever gone "ugh, I need to burn this down and start fresh" on a dev environment in AWS? it takes forever) of using AWS for development on personal projects.
Visual tools: If you are proficient at writing CFN templates or have found another tool to do that, cool. FWIW, our customers tell us they find the visualization useful when onboarding other engineers onto a project and then when they have a split screen between the template and the visualization to see how the CFN template is built.
Yoloing Developers: Heh. I'm stealing that phrase. But seriously, this is a common concern and a reason why managing accounts and namespacing for dev/test/staging/prod environments is a big deal. (plug - we do that too) At AWS dev managers get daily reports on the cost of each developer's accounts. While serverless tends to be much cheaper for dev environments than containers or EC2 instances, there are indeed ways to run costs up.
Deploying and redeploying: That's precisely why our CLI enables development against live cloud resources. When you use stackery local invoke, it assumes the function’s IAM role and fetches the function’s env var values. This enables rapid, and accurate, local function development. On the infrastructure side, it's common for our users to make up to 5 or more changes to their architecture in a day. The more you can do with the building blocks, the less code you need.
Thanks for taking a look.
This is acutely top-of-mind for me because I used to run a devops consultancy and I currently head devops, including release management, for a startup built heavily on AWS Lambda. I am doing my level best to reduce the loop as much as I can for the dev team.
It's still way, way slower than control-S. And always will be.
I test the lambda body locally with a single command. Only upload a new zip when you hit the release candidate stage and that's not frequent enough for the few seconds it takes to upload to lambda to be a problem.
And an API.
And a website.
And a CDN.
And...
And if you get as far as CloudFormation I just have one word of advice. Run!
It's ugly. It has a TON of powerful functionality that the documentation dives into way too early for most people. It has some weird behavior, especially when you get into networking or stateful resources. It's not perfect. But it gets the job done.
CF's limitations are in part due to the fact that AWS services are all independent entities and the interoperability services have tremendous difficulty getting other service teams to do their part.
The CloudTrail team, for instance, went to great lengths to furnish documentation for other teams to configure their API logging; I know our team fucked it up repeatedly because it was always an afterthought.
You can see in CF that some resources are basically useless, and are plainly provided by CF so that the service owner could check a box. Read "Updating DB Instances" here[1] and then look at all the properties that require replacement.
CF's design reflects this reality. It does not try to understand how services interact or what objects are. Rather, a "resource" knows how to set up and teardown and a few other operations.
If you manage resources exclusively through CF, it can handle most simple use cases. Which is the other limit of CF: by design, they're trying to keep their core invariants simple.
For instance, CF offers no mechanism to stage deploys. As an example, the popular Serverless tool has to initially construct a stack with just an S3 bucket, and then issue an update to that to include your actual stack.
Internally, we proposed doing staged deploys (because wound up hacking them together) and they weren't interested. And I think that's because they would rather keep the API simple even if it means users move away from CF; possibly a consequence of a loss leader business model.
So, yes, CF does get the job done at first, but you will eventually find yourself outgrowing it.
[1]: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGui...