My general experience with crafting IAM policies is very reminiscent of SELinux, in that it's very difficult to work agnostically while adhering to a principle of least privilege. Especially given that this kind of task is often done by admin/ops people, one typically can't know in advance everything that the app might need to be able to access in order to work correctly. The process of discovering this is: try runni…
aws-cdk is their infra-as-code product and it's extremely valuable for iam alone.
You can say things like: my_lambda.grantRead(s3_bucket)
And it figures out the least privileges necessary to make all of that work.
Plus it's real code, not some annoying DSL, which means you can easily abstract other iam permissions out. I have a fairly tight lambda policy that I reuse in all sorts of places, and it's as easy to use as the above snippet.