The following steps will explain designing a policy to prevent actions on specific resources.
The example below shows how to create a Deny policy to prevent TerminateInstance of specific EC2 instances using Tags associated with those instances. Additionally, the policy will include a Deny for the DeleteTag action. Using IAM users, this policy will prevent specific users from taking steps to terminate specific instances. This approach requires the inability to delete tags on these resources to be a part of the overall tagging strategy within AWS.
Create a tagging model to determine if an EC2 instance will require elevated access to terminate the instance. This elevated access will be realized by not having the following policy attached to their IAM user.
Create an IAM Policy with a Deny applied to the ec2:TerminateInstance action. Specify all Resources. Lastly, specify the condition using the ec2:ResourceTag string.
Additionally, using the Deny effect for the ec2:CreateTags and ec2:DeleteTags will prevent those with this policy from deleting "privileged" infrastructure.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "ec2:TerminateInstances",
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:ResourceTag/PrivilegedTerminate": "Yes"
}
}
},
{
"Effect" : "Deny",
"Action" :
[
"ec2:DeleteTags"
],
"Resource" : "*"
}
]
}
Attaching this policy to an existing Role will prevent that role from being able to delete the tagged resources. Since an express Deny always supersedes an Allow, this will prevent any user, even those in the AdministratorAccess group, from terminating the tagged instances nor deleting the associated tags while still allowing them to add additional tags for other business needs.
Attach this policy to a group the currently logged on IAM user.
Launch an EC2 instance and add the key/value pair PrivilegedTerminate/Yes tag to the instance.
First, attempt to delete the tag. If the policy is working correctly, a similar error should appear upon saving as seen here:
Locate the freshly created instance and attempt to terminate it. Assuming the tags were correctly populated, the following error should be seen upon clicking Yes, Terminate:
While this is a specific use case, hopefully this will provide some inspiration and sufficiently explain the functionality.