Update
Mike Pope has published a nice article about Granting Permission to Launch EC2 Instances with IAM Roles (PassRole Permission) on the AWS Security Blog, which explains the subject matter from an AWS point of view.
Initial Answer
Skaperen's answer is partially correct (+1), but slightly imprecise/misleading as follows (the explanation seems a bit too complex for a comment, hence this separate answer):
To launch an EC2 instance with an IAM role requires administrative access to the IAM facility.
This is correct as such and points towards the underlying problem, but the required administrative permissions are rather limited, so the following conclusion ...
Because IAM roles grant permissions, there is clearly a security issue to be addressed. You would not want IAM roles being a means to allow permission escalation.
... is a bit misleading, insofar the potential security issue can be properly addressed. The subject matter is addressed in Granting Applications that Run on Amazon EC2 Instances Access to AWS Resources:
You can use IAM roles to manage credentials for applications that run
on Amazon EC2 instances. When you use roles, you don't have to
distribute AWS credentials to Amazon EC2 instances. Instead, you can
create a role with the permissions that applications will need when
they run on Amazon EC2 and make calls to other AWS resources. When
developers launch an Amazon EC2 instance, they can specify the role
you created to associate with the instance. Applications that run on
the instance can then use the role credentials to sign requests.
Now, within the use case at hand the mentioned developers [that] launch an Amazon EC2 instance are in fact EC2 instances themselves, which appears to yield the catch 22 security issue Skaperen outlined. That's not really the case though as illustrated by the sample policy in section Permissions Required for Using Roles with Amazon EC2 :
{
"Version": "2012-10-17",
"Statement": [{
"Effect":"Allow",
"Action":"iam:PassRole",
"Resource":"*"
},
{
"Effect":"Allow",
"Action":"iam:ListInstanceProfiles",
"Resource":"*"
},
{
"Effect":"Allow",
"Action":"ec2:*",
"Resource":"*"
}]
}
So iam:PassRole
is in fact the only IAM permission required, and while technically of administrative nature, this isn't that far reaching - of course, the sample policy above would still allow to escalate permissions by means of listing and in turn passing any available role, but this can be prevented by specifying only those roles that are desired/safe to pass for the use case at hand - this is outlined in section Restricting Which Roles Can Be Passed to Amazon EC2 Instances (Using PassRole):
You can use the PassRole permission to prevent users from passing a
role to Amazon EC2 that has more permissions than the user has already
been granted, and then running applications under the elevated
privileges for that role. In the role policy, allow the PassRole
action and specify a resource (such as
arn:aws:iam::111122223333:role/ec2Roles/*) to indicate that only a
specific role or set of roles can be passed to an Amazon EC2 instance.
The respective sample policy illustrates exactly matches the use case at hand, i.e. grants permission to launch an instance with a role by using the Amazon EC2 API:
{
"Version": "2012-10-17",
"Statement": [{
"Effect":"Allow",
"Action":"ec2:RunInstances",
"Resource":"*"
},
{
"Effect":"Allow",
"Action":"iam:PassRole",
"Resource":"arn:aws:iam::123456789012:role/Get-pics"
}]
}
Unfortunately AWS Identity and Access Management (IAM) doesn't fully cover this particular aspect as of today, because Resource-Level Permissions for EC2 and RDS Resources are not yet available for all API actions, see e.g. this note from Amazon Resource Names for Amazon EC2:
Important Currently, not all API actions support individual ARNs; we'll add support for additional API actions and ARNs for additional
Amazon EC2 resources later. For information about which ARNs you can
use with which Amazon EC2 API actions, as well as supported condition
keys for each ARN, see Supported Resources and Conditions for Amazon
EC2 API Actions.
You will find that all ec2:Describe*
actions are indeed absent still from Supported Resources and Conditions for Amazon EC2 API Actions at the time of this writing, which is causing the error you are experiencing.
- See my initial answer to How to restrict a user to a specific instance volume in AWS using IAM policy for an example how to split your IAM policy regarding those parts that do and do not support resource level permissions to avoid this error as such (obviously this wouldn't prevent users to see all of your account though).
See also Granting IAM Users Required Permissions for Amazon EC2 Resources for a concise summary of the above and details on the ARNs and Amazon EC2 condition keys that you can use in an IAM policy statement to grant users permission to create or modify particular Amazon EC2 resources - this page also mentions that AWS will add support for additional actions, ARNs, and condition keys in 2014.
Alternative/Workaround
Depending on the specific scenario, it might be easier to just provision a separate AWS account, which can be integrated with yours IAM policy wise via Cross-Account Access: Sharing Resources Between AWS Accounts and billing wise via Consolidated Billing.
Best Answer
For this to work, you need to explicitly ALLOW the following:
The above JSON policy basically stipulates that the user ONLY has access to the above. They will NOT have access to anything else. That includes ec2 instances, S3, IAM, cloudfront, etc.