I want an IAM policy that allows an EC2 instance to modify it's own name tag. It should not have permission to modify the tags of any other instance.
It is my understanding that this should work. However it does not, I get an error message stating I don't have permission to add the tag.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowTaggingSelf",
"Effect": "Allow",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*",
"Condition": {
"StringEquals": {
"ec2:SourceInstanceARN": "${aws:SourceARN}"
},
"ForAllValues:StringEquals": {
"aws:TagKeys": [
"Name"
]
}
}
}
]
}
If I remove the condition, it works
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowTaggingSelf",
"Effect": "Allow",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "*"
}
]
}
But this is to permissive, I don't want any instance to be able to edit tags of any other instance. What is wrong with my condition?
As far as I'm aware, EC2 doesn't provide a direct way to reference 'self' in IAM policies. The most reliable approach is to either dynamically generate the policy with the specific instance ID, or have your application code retrieve its own instance ID from the metadata service and only tag itself.
This IAM policy that would enable an instance to tag itself if you combine it with application-level checking:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowDescribeInstances",
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*"
},
{
"Sid": "AllowTaggingInstances",
"Effect": "Allow",
"Action": [
"ec2:CreateTags",
"ec2:DeleteTags"
],
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {
"ForAllValues:StringEquals": {
"aws:TagKeys": ["Name"]
}
}
}
]
}
Then in your application code:
1. Get instance ID from metadata: curl http://169.254.169.254/latest/meta-data/instance-id
2. Only call CreateTags/DeleteTags on that specific instance ID
The policy restricts tag operations to only the "Name" tag on any instance, and your application logic ensures it only targets itself.