Amazon aren't stupid, and to really realise the full value/potential of their cloud offering you kind of have to design for the proprietary features of their stack, which of course is the whole point - driving you to be locked in as much as they can. Treat them as just a bunch of generic compute boxes in the cloud and you will end up driving your costs up, not to mention often markedly increasing the complexity of your deployment.
We have a lot of clients who say they want to be multi-cloud, they say they're afraid of being locked into AWS or GCE, and in practice nobody except the supermassive companies out there ever actually do move between them. To that end, we pretty much standardized on using the platform-specific options: CloudFormation, Azure Resource Manager, and Google Cloud Deployment Manager.
(There is a small argument to some of the ancillary services that Terraform can wire up, but to be honest I rarely find a compelling reason to put up with Terraform and its lovely habit of fragging my state in order to wire those up declaratively rather than using a little imperative glue within Auster[0] to do it.)
CloudFormation isn't perfect--but it isn't a hand grenade.
People used to ask us when we started Userify (SSH Key management, https://userify.com)... what happens when AWS clones you?
Well.. that was five years ago, and they haven't cloned us yet. But even if they ever did, they have a vested interest in ensuring lock-in to AWS, so they will always choose to make things work with things that only they offer (such as IAM) instead of making it cross-cloud. That makes things a lot more challenging for large enterprises, especially when you're talking about users that may have to log in to servers hosted in multiple clouds. Having multiple sources of truth doesn't work at scale.
Most large organizations are at least on AWS, GCP, and/or Azure already, so I don't really think Userify's SSH key management (or any other cross-cloud tools like ansible/pupet/terraform/etc) are going away anytime soon.
Has that changed since?
When you're starting out, hosted solutions will save you a lot of time. Running your own servers is a high cost and you need a dedicated team. But once you're pulling in that revenue and can afford it, running your own can save you some money and add a lot of flexibility.
If you're starting out, I highly recommend not tightly coupling yourself to a single service (using AMIs or any really specific AWS stuff) but write your provisioning scripts in such a way as you can plug in different services or deploy locally. Things like Terraform + a provisioner (Ansible/Puppet/etc) can make it easy to move your system to another provider or host your own and more easily measure costs.