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...