AWS SCP for EC2 type - amazon-web-services

I want to allow users only to create t2.micro/small/medium for development and allow them to use only spot instances. Have created IAM policy to restrict type/size of instances. In addition I want to put restriction on "on-demand" instances (team MUST opt for spot instances only). What is the cleaner way of achieving it?

allow full access with the account
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "limitedSize",
"Effect": "Deny",
"Action": [
"ec2:RunInstances",
"cloudwatch:DescribeAlarms"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*"
],
"Condition": {
"ForAnyValue:StringNotLike": {
"ec2:InstanceType": [
"t3.*",
"t2.*"
]
}
}
}
]
}

Try AWS Service Catalog.. that is the exact service which can help u here.

Use the ec2:InstanceMarketType condition key in your IAM policy.
Example (untested):
{
"Version": "2012-10-17",
"Statement": {
"Effect": "Allow",
"Action": "*",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:InstanceMarketType": "spot"
}
}
}
}
References:
Condition Keys for EC2
EC2 Condition Key Example
Another SO Question

Related

PermissonSet vs IAM policy - different behavior

If I apply below policy to IAM role, it works fine and lets user create ec2 instances as long as they provide Project tag. But if I apply it as PermissionSet, it prevents users from creating ec2 instance even though they specified Project tag.
Here is the how the policy looks like:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyEC2CreationWithoutProjectTag",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*:*:instance/*"
],
"Condition": {
"StringNotEquals": {
"aws:RequestTag/Project": "*"
}
}
}
]
}
What am I missing here?

Enforce Encryption on SNS creation by SCP

I would like to create an SCP to enforce encryption on SNS creation. I am creating the below policy but it has not worked.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Deny",
"Action": [
"sns:CreateTopic"
],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"attributes:KmsMasterKeyId": "alias/aws/sns"
}
}
}
]
}
I'm not sure where did you find attributes:KmsMasterKeyId condition key, but based on AWS docs, sns:CreateTopic does not support such a condition.

restrict aws iam user to a specific region (eu-west-1)

I'm trying to create a policy in which the user exam can access only to the region eu-west-1.
I tried to find a solution but didn't found the right one.
the policy looks something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "user_arn",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]
}
but it does not seem to work no matter what I do.
what is the best way to do so that the user can do whatever he wants but only in this region?
found a solution
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]
}
This should work as well, however you are granting full access to EC2 limited to one region. In the example below you "deny" any ec2 action outside the region or regions defined below, however you are not granting any privileges (they should be assigned in a separate policy or use an Allow statement. Normally this is used as an SCP in AWS organizations,a and you jusy deny action "*", to force all users to create resources only in the designated regions, and deny any API action in regions not authorized.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": "eu-west-1"
}
}
}
]

AWS IAM EC2 policy limited to originating instance

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}"
}
}
}
]
}

how to limit instance launch by instance type in AWS using IAM service

I am using the policy to limit RunIstances only to a specific instance types and a specific region. When I run the launch wizard or simulation under a test user I am getting "implicitly denied" error.
Here is the policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:us-east-1::instance/*"
],
"Condition": {
"StringEquals": {
"ec2:InstanceType": [
"t1.micro",
"m1.small"
]
}
}
},
{
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:us-east-1::image/ami-*",
"arn:aws:ec2:us-east-1::subnet/*",
"arn:aws:ec2:us-east-1::network-interface/*",
"arn:aws:ec2:us-east-1::volume/*",
"arn:aws:ec2:us-east-1::key-pair/*",
"arn:aws:ec2:us-east-1::security-group/*"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ec2:CreateSecurityGroup",
"ec2:DeleteSecurityGroup",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:CreateKeyPair"
],
"Resource": [
"*"
]
}
]
}
could somebody point to the issue?
In your resource blocks, insert an asterisk between the two ":" in the arn lines, to specify all accounts, or replace it with your account number.
"arn:aws:ec2:us-east-1:*:instance/*"
"arn:aws:ec2:us-east-1:*:image/ami-*",
"arn:aws:ec2:us-east-1:*:subnet/*",
"arn:aws:ec2:us-east-1:*:network-interface/*",
"arn:aws:ec2:us-east-1:*:volume/*",
"arn:aws:ec2:us-east-1:*:key-pair/*",
"arn:aws:ec2:us-east-1:*:security-group/*"
Please see the IAM policy generator tool. Your code does not look like the right syntax.
First, Allow all actions in EC2. Next, Deny specific actions in EC2.
Example to Allow all actions in EC2:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"NotAction": "ec2:*",
"Resource": "*"
}
]
}
Example to Deny creating resources in specific regions:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyTheseActions",
"Effect": "Deny",
"Action": [
"ec2:RunInstances",
"ec2:StartInstances"
],
"Resource": "arn:aws:ec2:us-west-1",
"Resource": "arn:aws:ec2:us-east-1",
"Resource": "arn:aws:ec2:eu-west-1",
"Resource": "arn:aws:ec2:sa-east-1",
"Resource": "arn:aws:ec2:ap-northeast-1",
"Resource": "arn:aws:ec2:ap-southeast-1",
"Resource": "arn:aws:ec2:ap-southeast-2"
}
]
}
Currently the easier way to control access to AWS regions, EC2 and RDS Instances sizes and types would probably be using IAM policies with the Condition (Optional) policy element – lets you specify conditions for when a policy is in effect.
We'll setup an AWS IAM Policy using a Condition statement, which will allow full AWS EC2 and RDS services, strictly for the 3 more cost effective -> AWS regions which are:
us-east-1 (North Virginia, USA)
us-east-2 (Ohio, USA)
us-west-2 (Oregon, USA)
All other regions will not be allowed, this policy also sets up a conditional access control for starting both EC2 and RDS instances. Instead of specifying all of the possible type/class instances to run, we use Deny effect in the statement, which allows for a short and simple policy limiting by instances sizes (micro, small, medium and large). This has the further effect of preventing any other policies from overriding the block.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "MultiServiceFullAccessCustom",
"Effect": "Allow",
"Action": [
"ec2:*",
"rds:*"
],
"Resource": [
"*"
],
"Condition": {
"StringEquals": {
"aws:RequestedRegion": [
"us-east-1",
"us-east-2",
"us-west-2"
]
}
}
},
{
"Sid": "Ec2RunInstanceCustomSize",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*:*:instance/*"
],
"Condition": {
"ForAnyValue:StringNotLike": {
"ec2:InstanceType": [
"*.nano",
"*.micro",
"*.small",
"*.medium",
"*.large"
]
}
}
},
{
"Sid": "RdsFullAccessCustomSize",
"Effect": "Deny",
"Action": [
"rds:CreateDBInstance",
"rds:CreateDBCluster"
],
"Resource": [
"arn:aws:rds:*:*:db:*"
],
"Condition": {
"ForAnyValue:StringNotLike": {
"rds:DatabaseClass": [
"*.micro",
"*.small",
"*.medium",
"*.large"
]
}
}
}
]
}
What does this policy not protect us from?
This does not impose limits on the size of instances deployed though other services - most importantly, through an auto-scaling group or EKS.
We are not limiting in any way the total number of instances spun up by a given user. The normal limits help here, but there isn't a way to determine how many instances are currently running through just policy.
We're not capping costs, just adding some protections. If you want to set alerts for cost overruns or spikes, you need to look into the Billing controls.
terraform-aws-cost-billing-alarm
terraform-aws-cost-budget
terraform-aws-lambda-nuke
terraform-aws-lambda-scheduler-stop-start
We do not require any Multi Factor Authentication (MFA) for the role switch. The assumption is that users logging in are already using some form of second factor for authentication. This is mostly due to the increased complexity around using the CLI with MFA, and the fact that the role change is only to allow an override, not to enable an elevation to another security domain. You might want to add the feature; it is not difficult to add, and can bring reasonable protections.
We are only looking at instance startup, but you may consider who can shutdown or terminate instances, as that may result in downtime or data loss.
Reference links
https://blog.vizuri.com/limiting-allowed-aws-instance-type-with-iam-policy
https://blyx.com/2016/03/24/how-to-restrict-by-regions-and-instance-types-in-aws-with-iam/
https://aws.amazon.com/blogs/security/easier-way-to-control-access-to-aws-regions-using-iam-policies/
https://medium.com/faun/100-days-of-devops-day-10-restricting-user-to-launch-only-t2-instance-509aaaec5aa2
https://aws.amazon.com/blogs/security/back-to-school-understanding-the-iam-policy-grammar/