I am trying to set up some restriction on the type of instances that people can launch. I have the following policy
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:us-east-1:123:key-pair/CI",
"arn:aws:ec2:us-east-1:123:instance/*",
"arn:aws:ec2:us-east-1:123:image/ami-*",
"arn:aws:ec2:us-east-1:123:subnet/*",
"arn:aws:ec2:us-east-1:123:network-interface/*",
"arn:aws:ec2:us-east-1:123:volume/*",
"arn:aws:ec2:us-east-1:123:security-group/sg-a363xxxx"
]
},
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": [
"*"
],
"Condition": {
"StringNotEquals": {
"ec2:InstanceType": "m4.4xlarge"
}
}
}
]
The first part of the statement works fine, but I am trying to add the Deny piece.
{
"DryRun": true,
"ImageId": "ami-5f709f34",
"KeyName": "FE-CI",
"SecurityGroupIds": [
"sg-a363bada"
],
"UserData": "",
"InstanceType": "m4.4xlarge",
"SubnetId": "subnet-xxxxx",
"EbsOptimized":false}
when adding the Condition statement everything gets denied. Here is the decoded authorization message.
{
"DecodedMessage": " {\"allowed\":false,\"explicitDeny\":true,\"matchedStatements\":{\"items\":[{\"statementId\":\"\",\"effect\":\"DENY\",\"principals\":{\"items\":[]},\"principalGroups\":{\"items\":[{\"value\":\"xxx\"}]},\"actions\":{\"items\":[{\"value\":\"ec2:RunInstances\"}]},\"resources\":{\"items\":[{\"value\":\"*\"}]},\"conditions\":{\"items\":[{\"key\":\"ec2:InstanceType\",\"values\":{\"items\":[{\"value\":\"m4.4xlarge\"}]}}]}}]},\"failures\":{\"items\":[]},\"context\":{\"principal\":{\"id\":\"xxx\",\"name\":\"jellin-test\",\"arn\":\"arn:aws:iam::xxx:user/jellin-test\"},\"action\":\"ec2:RunInstances\",\"resource\":\"arn:aws:ec2:us-east-1:xxx:key-pair/FE-CI\",\"conditions\":{\"items\":[{\"key\":\"ec2:Region\",\"values\":{\"items\":[{\"value\":\"us-east-1\"}]}}]}}}"
}
I am not seeing anything obviously wrong here. My understanding is that the first statement should pass and the second one will only deny if the InstanceType is not m4.4xlarge
The StringNotEquals key needs to be changed to StringNotEqualsIfExists. There is a good explanation of why this happens here.
Related
I have a tag enforcement scp that deny ec2 creation without CodeDomaine Tag except for AWS Backup service:
"Statement": [
{
"Sid": "DenyEC2CreationSCP1",
"Effect": "Deny",
"Action": [
"ec2:RunInstances"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"Null": {
"aws:RequestTag/CodeDomaine": "true"
},
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:sts::*:assumed-role/AWSBackupDefaultServiceRole/AWSBackup-AWSBackupDefaultServiceRole"
]
}
}
},
I want to allow AWS backup service to restore when needed but i get this error:
DecodedMessage": "{\"allowed\":false,\"explicitDeny\":true,\"matchedStatements\":{\"items\":[{\"statementId\":\"DenyEC2CreationSCP1\",\"effect\":\"DENY\",\"principals\":{\"items\":[{\"value\":\"AROAY56UJVB4...\"}]},\"principalGroups\":{\"items\":[]},\"actions\":{\"items\":[{\"value\":\"ec2:RunInstances\"}]},\"resources\":{\"items\":[{\"value\":\"arn:aws:ec2:*:*:instance/*\"},{\"value\":\"arn:aws:ec2:*:*:volume/*\"}]},\"conditions\":{\"items\":[{\"key\":\"aws:PrincipalArn\",\"values\":{\"items\":[{\"value\":\"arn:aws:sts::*:assumed-role/AWSBackupDefaultServiceRole/*\"}]}},{\"key\":\"aws:RequestTag/CodeDomaine\",\"values\":{\"items\":[{\"value\":\"true\"}]}}]}}]},\"failures\":{\"items\":[]},\"context\":{\"principal\":{\"id\":\"AROAY56UJ...:AWSBackup-AWSBackupDefaultServiceRole\",\"arn\":\"arn:aws:sts::<accountID>:assumed-role/AWSBackupDefaultServiceRole/AWSBackup-AWSBackupDefaultServiceRole\"},\"action\":\"ec2:RunInstances\",\"resource\":\"arn:aws:ec2:eu-west-3:<accountID>:instance/*\",\"conditions\":{\"items\":[{\"key\":\"ec2:InstanceMarketType\",\"values\":{\"items\":[{\"value\":\"on-demand\"}]}},{\"key\":\"aws:Resource\",\"values\":{\"items\":[{\"value\":\"instance/*\"}]}},{\"key\":\"aws:Account\",\"values\":{\"items\":[{\"value\":\"<accountID>\"}]}},{\"key\":\"ec2:AvailabilityZone\",\"values\":{\"items\":[{\"value\":\"eu-west-3b\"}]}},{\"key\":\"ec2:ebsOptimized\",\"values\":{\"items\":[{\"value\":\"false\"}]}},{\"key\":\"ec2:IsLaunchTemplateResource\",\"values\":{\"items\":[{\"value\":\"false\"}]}},{\"key\":\"ec2:InstanceType\",\"values\":{\"items\":[{\"value\":\"t2.medium\"}]}},{\"key\":\"ec2:RootDeviceType\",\"values\":{\"items\":[{\"value\":\"ebs\"}]}},{\"key\":\"ec2:InstanceProfile\",\"values\":{\"items\":[{\"value\":\"arn:aws:iam::<accountID>:instance-profile/autodesk-dev\"}]}},{\"key\":\"aws:Region\",\"values\":{\"items\":[{\"value\":\"eu-west-3\"}]}},{\"key\":\"aws:Service\",\"values\":{\"items\":[{\"value\":\"ec2\"}]}},{\"key\":\"ec2:InstanceID\",\"values\":{\"items\":[{\"value\":\"*\"}]}},{\"key\":\"aws:Type\",\"values\":{\"items\":[{\"value\":\"instance\"}]}},{\"key\":\"ec2:Tenancy\",\"values\":{\"items\":[{\"value\":\"default\"}]}},{\"key\":\"ec2:Region\",\"values\":{\"items\":[{\"value\":\"eu-west-3\"}]}},{\"key\":\"aws:ARN\",\"values\":{\"items\":[{\"value\":\"arn:aws:ec2:eu-west-3:<accountID>:instance/*\"}]}}]}}}"
}
I tried many solutions to adjust the SCP conditions but no way!!
thanks
Resolved !
have to specify the role RNA and not the session RNA (ex : arn:aws:iam::*:role/OrganizationAdminRole)
"Statement": [
{
"Sid": "DenyEC2CreationSCP1",
"Effect": "Deny",
"Action": [
"ec2:RunInstances"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"Null": {
"aws:RequestTag/CodeDomaine": "true"
},
"StringNotLike": {
"aws:PrincipalArn": [
"arn:aws:iam::*:role/service-role/AWSBackupDefaultServiceRole"
]
}
}
},
im trying to create an aws iam role policy resource on terraform but i got the following error message: MalformedPolicyDocument: The policy failed legacy parsing
Already tried to parse on json formatters and things like that and the json policy looks fine so idk what im missing, thanks for the help!
policy = <<POLICY
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Resource": [
"*"
],
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
]
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterface",
"ec2:DescribeDhcpOptions",
"ec2:DescribeNetworkInterfaces",
"ec2:DeleteNetworkInterface",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:DescribeVpcs"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"ec2:CreateNetworkInterfacePermission"
],
"Resource": [
"arn:aws:ec2:${var.REGION}:network-interface/*"
],
"Condition": {
"StringEquals": {
"ec2:Subnet": [
"${element(aws_subnet.private.*.id, 0)}",
"${element(aws_subnet.private.*.id, 1)}"
],
"ec2:AuthorizedService": "codebuild.amazonaws.com"
}
}
},
{
"Effect": "Allow",
"Action": [
"s3:*"
],
"Resource": [
"${aws_s3_bucket.codebuild.arn}",
"${aws_s3_bucket.codebuild.arn}/*"
]
}
]
}
POLICY
I haven't seen the error before, but Googling tells me the JSON parser/processor AWS is using for IAM policies seems very picky. I.e. Version has to come before Statement, etc.
In your particular case based on a comment I found I guess it might be about white space around your value.
The comment says:
Additionally, you cannot have an space before the initial "{".
Thus in Terraform what you might need is a trimspace around the whole value:
policy = trimspace(<<POLICY
{
"Version": "2012-10-17",
[... redacted for readability]
}
POLICY
)
I have been trying to create a policy that will not allow an ec2 instance to be created unless it has a Project tag. Here is what I have now and all I get is ec2:RunInstances You are not authorized to perform this operation even with I have the tag Project.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RunCloudFormation",
"Effect": "Allow",
"Action": [
"cloudformation:*"
],
"Resource": [
"*"
]
},
{
"Sid": "CreateEC2Instances",
"Effect": "Allow",
"Action": [
"ec2:Describe*",
"ec2:CreateSecurityGroup",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateTags",
"ec2:RunInstances"
],
"Resource": "*"
},
{
"Sid": "LaunchingEC2withAMIsAndTags",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"StringLike": {
"aws:RequestTag/Project": "?*"
}
}
}
]
}
Here is a snippet of my CloudFormation template:
"KeyName": {
"Ref": "KeyName"
},
"Tags": [
{
"Key": "Project",
"Value": "test"
},
{
"Key": "OwnerAdmin",
"Value": "myname"
},
{
"Key": "Name",
"Value": "TESTTags"
}
],
I managed to get the policy simulator to allow the RunInstances action by changing
"Resource": "arn:aws:ec2:*:*:instance/*"
to
"Resource": "*",
You only need to use the resource level permissions if you want to constrain resources used by the instance, such as AMI, subnet, security group, etc.
I tried to provide a policy following the samples here: https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-restrict-access-examples.html
But, I keep getting a warning and it does not work.
These are all I tried so far:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowStartSessionExceptProd",
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": "*",
"Condition": {
"StringNotLike": {
"ssm:resourceTag/environment": [
"prod",
"Prod"
]
}
}
}
]
}
Or
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowStartSessionExceptProd",
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"arn:aws:ec2:*:*:instance": [
"i-myInstanceId1",
"i-myInstanceId2"
]
}
}
}
]
}
Or even I tried to use more resource-based conditions.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowStartSessionExceptProd",
"Effect": "Allow",
"Action": [
"ssm:StartSession"
],
"Resource": "*",
"Condition": {
"StringNotLike": {
"ssm:resourceTag/environment": [
"prod",
"Prod"
],
"arn:aws:ec2:*:*:resourceTag/environment": [
"prod",
"Prod"
],
"ec2:resourceTag/environment": [
"prod",
"Prod"
]
}
}
}
]
}
In general, all I want to do is allow access to start session in SSM on servers which are not prod servers.
My EC2 prod servers all have a tag environment:prod
I get an error message on each condition which doesn't work:
There are no actions in your policy that support this condition key.
Example:
ec2:resourceTag /environment (StringNotLike prod and Prod)
There are no actions in your policy that support this condition key.
I appreciate any help.
From the comments and some investigation, here's the answer:
From the docs, it is pretty easy to notice which actions support what conditions.
Unfortunately the examples provided for Restricting Access are wrong, i.e. there's an error in the documentation that contains the sample code.
A PR might be a good idea so others don't hang on the same thing.
I have created a policy which allows users to do all ec2 actions but restricts user to runinstances and createvolumes and terminate instances only when they pass the given tag key-values pairs with a explicit deny.
ec2 full permissions policy
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*"
}
]
}
ec2 run instance and create volumes explicit deny with conditions.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Deny",
"Action": [
"ec2:RunInstances",
"ec2:CreateVolume"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"ForAllValues:StringNotEquals": {
"aws:TagKeys": "Name",
"aws:RequestTag/Name": "${aws:username}"
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Deny",
"Action": "ec2:CreateTags",
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"ForAllValues:StringNotEquals": {
"aws:RequestTag/Name": "${aws:username}"
},
"StringNotEquals": {
"ec2:CreateAction": "RunInstances",
"aws:TagKeys": "Name"
}
}
},
{
"Sid": "VisualEditor2",
"Effect": "Deny",
"Action": [
"ec2:DeleteVolume",
"ec2:TerminateInstances"
],
"Resource": [
"arn:aws:ec2:*:*:instance/*",
"arn:aws:ec2:*:*:volume/*"
],
"Condition": {
"ForAllValues:StringNotEquals": {
"ec2:ResourceTag/Name": "${aws:username}"
}
}
}
]
}
My requirement is to restrict user to give all ec2 permissions and restrict to runinstances only when pass tag key "Name" and tag value as "their aws user name".
but when this policy is applied to a user, it is restricting them to run only when they pass tagkey "Name", but its not restricting with tagvalue "their aws user name ${aws:username}".
but the same restriction is working properly when the user is trying to terminate instances i.e user is unable to terminate instances with tagkey "Name" and tag value "their aws user name ${aws:username}"
what could be the error in policy, that is allowing user to runinstances with tagkey "Name" and any value for tagValue, even null is also allowing
You can use the below IAM Policy and edit as per your liking. I use this in production and works flawlessly. It will only launch instances if they are tagged with values present in the list.:
Here, Key = Environment, Value = mentioned below
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TheseActionsDontSupportResourceLevelPermissions",
"Effect": "Allow",
"Action": [
"ec2:Describe*"
],
"Resource": "*"
},
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "ec2:RunInstances",
"Resource": [
"arn:aws:ec2:*::image/ami-*",
"arn:aws:ec2:*:ACCOUNT_ID:volume/*",
"arn:aws:ec2:*:ACCOUNT_ID:subnet/*",
"arn:aws:ec2:*:ACCOUNT_ID:network-interface/*",
"arn:aws:ec2:*:ACCOUNT_ID:security-group/*",
"arn:aws:ec2:*:ACCOUNT_ID:key-pair/*"
]
},
{
"Sid": "VisualEditor1",
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:ACCOUNT_ID:instance/*",
"Condition": {
"StringNotLike": {
"aws:RequestTag/Environment": [
"Testing",
"Staging",
"Production",
"Nightly",
"Sandbox",
"LoadTesting"
]
}
}
}
]
}
It is not working because the following block is implementing a logical OR. So, the instance will be launched if any of the condition is met. You have to create a logical AND by separating the condition keys in two different blocks as mentioned here.
"Condition": {
"ForAllValues:StringNotEquals": {
"aws:TagKeys": "Name",
"aws:RequestTag/Name": "${aws:username}"
}
}