Let's say you have a bug or SQL injection in a web app (or choose any server): the user running the web app and/or database now has access to your AWS account.
Instance profiles are available to every user and process on the server for the life of the server.
Layering multiple least-privilege roles is impossible: you can't assign multiple IAM roles to an instance.
You can't separate what process receives access to those credentials.
The old-school way of embedding credentials in a config file and make it readable only by root and/or a specific user account on the system is currently the best solution. Better, but more challenging at scale, are SE-Linux, AppArmor, etc.
You can assign multiple IAM roles to an instance profile, which is what is associated with an instance.
See e.g. [0]; you can add IAM roles to instance profiles without destroying the instance.
[0] https://docs.aws.amazon.com/cli/latest/reference/iam/add-rol...
Perhaps there is some contradiction in the IAM docs, but I couldn't find that reference. This seems to indicate that only one role can be assigned to an instance profile:
"Note that only one role can be assigned to an Amazon EC2 at a time, and all applications on the instance share the same role and permissions." (first paragraph, last sentence)
http://docs.aws.amazon.com/IAM/latest/UserGuide/roles-usingr...