Have you ever tried to setup AWS IAM permissions for a user pursuant to the principle of least privilege? Because Amazon's APIs are about as far from friendly as you can get in this respect.
Their docs make it easy to make the mistake of thinking that fine-grained controls are available for most things, but when it comes to really important things like being able to segregate a production and Dev VPC, their APIs basically force you to grant permissions to everything or nothing.
Some examples of things I've hit:
Not being able to restrict a user to only change a specific routing table
Not being able to restrict a user to only change a specific elastic NIC
I'm consistently surprised at what's missing from their API and couldn't disagree more about being happy with it.
These things are possible... but this gets at another aspect of AWS's design in particular.
I do a lot of my AWS work in CloudFormation. When I hit a wall, the answer is pretty much always to stand up an EC2 instance that can speak SNS, grant it larger-than-necessary permissions to my VPC, teach CloudFormation about it as a custom resource type, and have it serve as a proxy for the not-configurable-enough resource, allowing it to assert its own policy and make third-party calls before making the real callback into your VPC [or not.] It's the AWS equivalent of writing a factory method to wrap a badly-written constructor.
To generalize that thought: IAM "users" are made to either be people (e.g. your developers, your ops people), or representative tokens for entire third-party organizations (e.g. a CI bot.) Despite the existence of IAM roles, IAM isn't really made to assert "machine-agent"-granular permissions.
Instead, what you really want is to imagine a third-party service running in the AWS cloud that does exactly what you want. You would grant that third-party's IAM user overly-wide permission to play with your VPC, but trust it to only do what it should, because, obviously, you have a business relationship and it would be dumb of them to abuse it.
As soon as you can see what API needs to exist, you can turn around and become that very same imaginary third-party: make a separate AWS account, stand up an API server in it that takes requests to do what your "clients" want, and then, in turn, make requests to the AWS APIs on their behalf to accomplish those things.
AWS isn't a high-level framework; it's a kit of low-level tools. (This is really what the PaaS vs IaaS distinction implies, I think.) AWS is built assuming that you're willing and able to take their tools and pipe/script them together to build the higher-level components you need. And, since AWS is for web services, that assumption comes in the form of expecting you to be able to pipe, hook, or wrap any of their APIs to/with/in your own API.
The 'fine-grain' of IAM varies considerably depending on which AWS service you're restricting. You can add extra flexibility with 'Conditions', which I'm sure you're aware of, but I think it's a bit of a misrepresentation to paint IAM as being poor quality. AWS is a very complex environment; I can't see how you could have a user-friendly yet fine-grained user control for something that complex. Anything you choose is going to require training in how to use it.
I wouldn't say I'm happy about it, but neither am I unhappy, and neither am I happy about anything in the world of security (also in today's task list is updating https cipher lists... again...). Not even the simplest thing in security is easy. For example, the basic concept of a password is simple, but actually implementing it? Ugh - it involves every layer from backend to frontend to user training (the hardest part - no sticky notes, no friendly phone calls, no passing around in emails...).
Anyway, for those not used to IAM 'Conditions', an example of use. The following allows Packer (an AMI builder) to destroy any EC2 instance, but only if they have the tag 'name' as 'Packer Builder'. Conditions don't work for everything, so they're not a workaround to get fine-grain everywhere, but they do add a lot of flexibility.
Their docs make it easy to make the mistake of thinking that fine-grained controls are available for most things, but when it comes to really important things like being able to segregate a production and Dev VPC, their APIs basically force you to grant permissions to everything or nothing.
Some examples of things I've hit: Not being able to restrict a user to only change a specific routing table Not being able to restrict a user to only change a specific elastic NIC
I'm consistently surprised at what's missing from their API and couldn't disagree more about being happy with it.