AWS IAM EC2 policy limited to originating instance - amazon-web-services

I'm working on a setup where I need to terminate AWS instances because of inactivity (i.e. nothing new in web-server access logs since a period of time). Those instances are testing instances and are created automatically by CI/CD software.
I would like those instances to identify themselves that they become abandoned and terminate themselves. I want to assign a generic iam-role to each of them that will only allow the instance the termination of itself and not the peer instances.
So far I've been here:
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ExamplePolicies_EC2.html
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_variables.html#policy-vars-wheretouse
https://www.reddit.com/r/aws/comments/4gglxk/iam_policy_to_allow_ec2_instance_to_only_query/
https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_iam_mfa-selfmanage.html
And figured out that there are 2 variables available in policies:
ec2-instance-id
ec2:SourceInstanceARN
I came up with few variations of my role policy but none of them work:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:TerminateInstances",
"Resource": "*",
"Condition": {
"ArnEquals": {
"ec2:SourceInstanceARN": "arn:aws:ec2:*:*:instance/${ec2-instance-id}"
}
}
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:TerminateInstances",
"Resource": "arn:aws:ec2:*:*:instance/${ec2-instance-id}"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:TerminateInstances",
"Resource": "${ec2:SourceInstanceARN}"
}
]
}
Is it actually possible to achieve the desired behavior, i.e. to only allow instance to perform specific operation on itself (e.g. Termination)?
UPDATE:
I do know that I can work with tags, that is what I'm doing meanwhile, but that means that all tagged instances can terminate their peers. That is a bit too loose restriction, I'd like to really limit it to the instance it
AWS IAM: Allow EC2 instance to stop itself
IAM policy to allow EC2 instance API access only to modify itself

You were close with your condition. The trick is to compare instance ARN with ec2:sourceInstanceARN:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"ec2:DeleteTags",
"ec2:DescribeTags",
"ec2:CreateTags",
"ec2:TerminateInstances",
"ec2:StopInstances"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ARN": "${ec2:SourceInstanceARN}"
}
}
}
]
}
Clearly for testing purposes I allowed my instances with this policy to tag and stop themselves.

Since the "aws:ARN" condition no longer works, I have found the following approach to work for instances launched with an IAM role:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Allow instance to modify itself",
"Effect": "Allow",
"Action": [
"ec2:DeleteTags",
"ec2:CreateTags"
],
"Resource": "*",
"Condition": {
"StringLike": {
"aws:userid": "*:${ec2:InstanceID}"
}
}
}
]
}

Related

aws runInstance resources denied explicitly allow all resources

I am having a painful bug, when I use the Iam visual editor to create a role to run the instance, if I create two policies, the first when I allow all resources implicitly:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::*:role/*"
}
]
}
however, if I specify the resources I explicitly allow all resources, I get this policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"iam:PassRole",
"ec2:RunInstances"
],
"Resource": [
"arn:aws:ec2:*:*:subnet/*",
"arn:aws:ec2:*::snapshot/*",
"arn:aws:ec2:*:*:launch-template/*",
"arn:aws:ec2:*:*:security-group/*",
"arn:aws:ec2:*:*:placement-group/*",
"arn:aws:ec2:*:*:network-interface/*",
"arn:aws:ec2:*:*:capacity-reservation/*",
"arn:aws:ec2:*:*:key-pair/*",
"arn:aws:ec2:*:*:instance/*",
"arn:aws:elastic-inference:*:*:elastic-inference-accelerator/*",
"arn:aws:ec2:*:*:elastic-gpu/*",
"arn:aws:ec2:*:*:volume/*",
"arn:aws:ec2:*::image/*",
"arn:aws:iam::*:role/*"
]
}
]
}
when I simulate runInstance in the EC2-Classic-InstanceStore the first policy in the IAM policy simulator passes, however the second one doesn't. is there a resource that aws hasn't listed in its IAM visual editor? see attached pics for results:

Grant access for IAM policy to specific AWS Lightsail resources using tags

I'm trying to create an IAM policy so that the user can access Lightsail but only have access to specified instances. Ideally it would use tags so it's easy to maintain, but specifying individual instances would be fine.
I've tried various things, but they either make all instances disappear for the user (when logged in as the user to the web console), or leave all instances visible.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "lightsail:*",
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Deny",
"Action": "lightsail:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/wordpress": "true"
}
}
}
]
}
And
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "FullAccess",
"Effect": "Allow",
"Action": ["lightsail:*"],
"Resource": ["*"]
},
{
"Sid": "DenyInstance",
"Action": ["lightsail:*"],
"Effect": "Deny",
"Resource": ["arn:aws:lightsail:us-east-1:861111111111:Instance/11111111-1b1b-1b1b-1b1b-11bb11bb1b1b"]
}
]
}

AWS IAM - Deny certain EC2 actions based on resource tags?

I'm trying to construct an IAM policy that allows any EC2 action if the resource has a specific resource tag (Development), but deny if the tag is a different value (Production). Here's what I have so far.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:Describe*",
"Resource": "*"
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"ForAllValues:StringEquals": {
"ec2:ResourceTag/Environment": "Development"
}
}
},
{
"Sid": "VisualEditor2",
"Effect": "Deny",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"ForAnyValue:StringEquals": {
"ec2:ResourceTag/Environment": "Production"
}
}
}
]}
I have an AMI with the resource tag "Environment" and value "Production", yet I am still allowed to deregister it without an issue. What am I doing wrong?
Regards
[Updated: 2021-10]
It seems to be the case that ec2:DeregisterImage now supports both aws:ResourceTag/${TagKey} and ec2:ResourceTag/${TagKey}.
[Original: 2019-02]
The ec2:DeregisterImage action does not currently support ec2:ResourceTag/${TagKey}.
See Actions Defined for EC2 which provides a list of conditions supported on EC2 actions.

IAM policy to restrict users to instances in a specific VPC

I am trying to make a IAM policy to restrict user access to all the instances in a specific VPC. Following policy I made but not working.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1450441260778",
"Action": "ec2:*",
"Effect": "Allow",
"Resource": "arn:aws:ec2:region:Account_num:vpc/vpc-id"
}
]
}
I have filled the corresponding account_num and vpc-id in the policy.
You want to restrict the user access and you have used the allow attribute which will give permission to access the instance . Is that the desired behavior ?
If you really want to restrict try "Effect": "Deny" in same policy .
However if you want to give access to certain users here's how you can do it .
The following below policy works for me well in that case. I use it for the developers to restrict the access to start stop the instances . You can add as many permissions as you want in the second block .
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:DescribeInstances*",
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances*",
"ec2:StopInstances*"
],
"Resource": "arn:aws:ec2:ap-southeast-1:ACCOUNT_ID:instance/i-32ds2a29"
}
]
}
ap-southeast-1 is the region for my case .
To control an instance in a specific vpc you can simply use its id .There is no separate arn for vpc+instance_id instead you can use arn:aws:ec2:region:account-id:instance/instance-id as arn refer this .
Similarly you can use the same policy to restrict the users in specific vpc by using arn:aws:ec2:region:account-id:vpc/vpc-id as arn, adding Action ec2:* and deny in effect .
There are certain permissions that cant be applied to a specific resource. These permissions will show an error when you check the policy in IAM.
In order to restrict a user to a specific VPC and allow all EC2 actions, the following policy can help you in achieving that:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "NonResourceBasedReadOnlyPermissions",
"Action": [
"ec2:Describe*",
"ec2:CreateKeyPair",
"ec2:CreateSecurityGroup",
"iam:GetInstanceProfiles",
"iam:ListInstanceProfiles"
],
"Effect": "Allow",
"Resource": "*"
},
{
"Sid": "IAMPassroleToInstance",
"Action": [
"iam:PassRole"
],
"Effect": "Allow",
"Resource": "arn:aws:iam::123456789012:role/VPCLockDown"
},
{
"Sid": "AllowInstanceActions",
"Effect": "Allow",
"Action": [
"ec2:RebootInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"ec2:StartInstances",
"ec2:AttachVolume",
"ec2:DetachVolume"
],
"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/*",
"Condition": {
"StringEquals": {
"ec2:InstanceProfile": "arn:aws:iam::123456789012:instance-profile/VPCLockDown"
}
}
},
{
"Sid": "EC2RunInstances",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/*",
"Condition": {
"StringEquals": {
"ec2:InstanceProfile": "arn:aws:iam::123456789012:instance-profile/VPCLockDown"
}
}
},
{
"Sid": "EC2RunInstancesSubnet",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:us-east-1:123456789012:subnet/*",
"Condition": {
"StringEquals": {
"ec2:vpc": "arn:aws:ec2:us-east-1:123456789012:vpc/vpc-7bcd371e"
}
}
},
{
"Sid": "RemainingRunInstancePermissions",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:us-east-1:123456789012:volume/*",
"arn:aws:ec2:us-east-1::image/*",
"arn:aws:ec2:us-east-1::snapshot/*",
"arn:aws:ec2:us-east-1:123456789012:network-interface/*",
"arn:aws:ec2:us-east-1:123456789012:key-pair/*",
"arn:aws:ec2:us-east-1:123456789012:security-group/*"
]
},
{
"Sid": "EC2VpcNonresourceSpecificActions",
"Effect": "Allow",
"Action": [
"ec2:DeleteNetworkAcl",
"ec2:DeleteNetworkAclEntry",
"ec2:DeleteRoute",
"ec2:DeleteRouteTable",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:DeleteSecurityGroup"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:vpc": "arn:aws:ec2:us-east-1:123456789012:vpc/vpc-7bcd371e"
}
}
}
]
}
In order to understand in detail what each statements are doing, I would recommend reading this blog from AWS. This policy, allows the user to:
Sign in to the AWS Management Console and go to the Amazon EC2 console.
Launch an EC2 instance as long as they:
Specify a subnet in the proper VPC.
Specify the allowed instance profiles.
Start/stop/reboot/terminate/attach volume/detach volume on an instance as long as they:
Specify an instance launched with the proper instance profiles.
Delete security groups, routes, route tables, network ACLs, and ACL entries as well as authorize and revoke security group ingress and egress rules, as long as they are in the proper VPC.

AWS IAM Access Management

I know that you can set up an IAM policy to restrict access to services. However, is it possible to set up a policy to allow access to a part of a service.
E.g. I am two EC2 instances. I need to create two users such that they have an access to the AWS console, but only to one EC2 instance each.
Yes you can do this with Resource-Level Permissions for EC2
The structure of the resource is stated in the documentation as follows:
arn:aws:[service]:[region]:[account]:resourceType/resourcePath
Here is how you would structure the IAM policies for each user:
User 1
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/InstanceIdOne"
}
]
}
User 2
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "arn:aws:ec2:us-east-1:123456789012:instance/InstanceIdTwo"
}
]
}
Policy without access to EC2:DescribeInstance will not work. You need to allow DescribeInstances access on all resources and manage additional access like modify, delete to specific instances depending on what the need is.
In short, allow all basic operations like Describe Tags, Instances, NetworkACLs, Images etc to all users and allow specific destructive actions like Modify and Delete to select user.
List of EC2 actions for your reference here
http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_Operations.html
So you have 2 options-
Create one policy like below and attach the same policy to both users
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ec2:*Describe*",
"Resource":"*",
},
{
"Effect": "Allow",
"Action": [
"ec2:*Modify*",
"ec2:*Delete*"
],
"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:user/**user-name-1**" },
"Resource": "arn:aws:ec2:us-east-1:AWS-account-ID:instance/**InstanceIdOne**"
},
{
"Effect": "Allow",
"Action": [
"ec2:*Modify*",
"ec2:*Delete*"
],
"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:user/**user-name-2**" },
"Resource": "arn:aws:ec2:us-east-1:AWS-account-ID:instance/**InstanceIdTwo**"
}
]}
Create 2 different policies. Example for one below
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "ec2:*Describe*",
"Resource":"*",
},
{
"Effect": "Allow",
"Action": [
"ec2:*Modify*",
"ec2:*Delete*"
],
"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:user/**user-name-1**" },
"Resource": "arn:aws:ec2:us-east-1:AWS-account-ID:instance/**InstanceIdOne**"
}
]}