SCP Enforce Tags on resource creation fail

2

Hello, I started a project that aims to prevent the creation of certain resources if they do not have certain Tags. Following this documentation "https://aws.amazon.com/pt/blogs/mt/implement-aws-resource-tagging-strategy-using-aws-tag-policies-and-service-control-policies-scps/" I successfully replicated the "ec2:runinstance" action using only one Tag, but when I added a second Tag to the policy, the "ec2:runinstance" action happens with the presence of only one of the two Tags I defined.

With a few more tests you can prevent the action by creating two SCP policies, one policy for each Tag, so only when the two Tags I defined are present the resource is created, the big problem now is that the maximum number of SCP policies that I can apply to the Organization is 5 per account, and in the project there would be a total of 6 Tags.

What I need is to concatenate these two JSON policies into one that works, but all the SCP "Conditions" I've tried either block everything or release the action with the presence of just one Tag.

Is there a condition that validates all Tags present and then denies the action, or is what I'm trying impossible at the moment?

I tried with these other conditions, but without success, I didn't find where I could be going wrong.

ForAllValues:StringEquals

StringEqualsIfExists

StringNotEqualsIfExists

StringNotEquals

{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "DenyCreateOperationSCP1",
			"Effect": "Deny",
			"Action": [
				"ec2:RunInstances"
			],
			"Resource": [
				"arn:aws:ec2:*:*:instance/*"
			],
			"Condition": {
				"Null": {
					"aws:RequestTag/Customer": "true",
					"aws:RequestTag/Name": "true"
				}
			}
		},
		{
			"Sid": "DenyDeleteTag1",
			"Effect": "Deny",
			"Action": [
				"ec2:DeleteTags"
		],
			"Resource": [
				"arn:aws:ec2:*:*:instance/*"
		],
			"Condition": {
				"Null": {
					"aws:RequestTag/Customer": "true",
					"aws:RequestTag/Name": "true"
				}
			}
		}
	]
}
4 Answers
2
Accepted Answer

Hi There, I tried the same SCP policy mentioned in the blog and it works as expected with both tags in the policy. Did you attach the policy to the account/OU. so you can create 1 policy document with all 6 tags for "ec2:RunInstances" and another policy for "ec2:DeleteTags".

If number of policies are concern then you can put all in single document as mentioned in the blog.

https://aws.amazon.com/pt/blogs/mt/implement-aws-resource-tagging-strategy-using-aws-tag-policies-and-service-control-policies-scps/

Editing the answer to add policy Hi This is how I have put one policy. you need to create another policy for deny delete tags.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyEC2CreationSCP1",
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*",
        "arn:aws:ec2:*:*:volume/*"
      ],
      "Condition": {
        "Null": {
          "aws:RequestTag/cost": "true"
        }
      }
    },
    {
      "Sid": " DenyEC2CreationSCP2",
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*",
        "arn:aws:ec2:*:*:volume/*"
      ],
      "Condition": {
        "Null": {
          "aws:RequestTag/team": "true"
        }
      }
    },
    {
      "Sid": " DenyEC2CreationSCP3",
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*",
        "arn:aws:ec2:*:*:volume/*"
      ],
      "Condition": {
        "Null": {
          "aws:RequestTag/name": "true"
        }
      }
    }
  ]
}
AWS
answered 3 months ago
profile picture
EXPERT
reviewed a month ago
1

Hi, thanks for the reply. Yes the policy works partially, but if you try to create a new EC2 only 1 Tag is mandatory, if any of the defined Tags is present the action will be executed. The condition I am looking for is that I must have all the Tags defined for the action to be executed, if a single Tag is missing the action must be blocked.

Yes, I attached the policy to the account.

I just tested again with separate policies, this time I made the code simpler and the result was that the "ec2:RunInstance" action was executed with the presence of just one of the 3 Tags I stipulated.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyCreateOperationSCP1",
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*"
      ],
      "Condition": {
        "Null": {
          "aws:RequestTag/Automation": "true",
          "aws:RequestTag/Customer": "true",
          "aws:RequestTag/Name": "true"
        }
      }
    }
  ]
}
profile picture
answered 3 months ago
  • Hi This is how I have put the policy. Please try and let me know.

    { "Version": "2012-10-17", "Statement": [ { "Sid": "DenyEC2CreationSCP1", "Effect": "Deny", "Action": [ "ec2:RunInstances" ], "Resource": [ "arn:aws:ec2:::instance/", "arn:aws:ec2:::volume/" ], "Condition": { "Null": { "aws:RequestTag/cost": "true" } } }, { "Sid": "DenyEC2CreationSCP2", "Effect": "Deny", "Action": [ "ec2:RunInstances" ], "Resource": [ "arn:aws:ec2:::instance/", "arn:aws:ec2:::volume/" ], "Condition": { "Null": { "aws:RequestTag/customer": "true" } } }, { "Sid": "DenyEC2CreationSCP3", "Effect": "Deny", "Action": [ "ec2:RunInstances" ], "Resource": [ "arn:aws:ec2:::instance/", "arn:aws:ec2:::volume/" ], "Condition": { "Null": { "aws:RequestTag/name": "true" } } } ] }

1

Sorry for the delay, I created a separate policy to Deny Tags and still encountered problems deleting Tags that are not defined in the policy. In the example I mentioned previously, I made it clear that only the Customer and Name Tags should have the "ec2:DeleteTags" action denied, but any other Tag present in the resource is also denied.

In any case, this is not a critical problem for the solution I was looking for, thank you very much for your time and commitment Jhalak Modi, it helped me a lot.

For anyone that could be looking for something like this, this is my final policy. It prevents the creation of several resources if the 3 tags (Automation, Customer and Name) are not present, there are still some additional tests to confirm that all services behave well with this policy, but it worked perfectly for my needs.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenySCP1",
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances",
        "iam:CreateRole",
        "iam:CreateUser",
        "iam:CreateAccessKey",
        "iam:CreateGroup",
        "iam:CreatePolicy",
        "iam:CreatePolicyVersion",
        "logs:CreateLogDelivery",
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:CreateExportTask",
        "elasticloadbalancing:CreateLoadBalancer",
        "lambda:CreateFunction",
        "acm:RequestCertificate",
        "rds:CreateDBCluster",
        "rds:CreateDBInstance",
        "rds:CreateGlobalCluster",
        "sns:CreateTopic",
        "sqs:CreateQueue",
        "secretsmanager:CreateSecret"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*",
        "arn:aws:iam:*:*:user/*",
        "arn:aws:iam:*:*:role/*",
        "arn:aws:iam:*:*:group/*",
        "arn:aws:iam:*:*:policy/*",
        "arn:aws:logs:*:*:log-group:*",
        "arn:aws:elasticloadbalancing:*:*:loadbalancer/*",
        "arn:aws:lambda:*:*:function:*",
        "arn:aws:acm:*:*:*",
        "arn:aws:rds:*:*:cluster:*",
        "arn:aws:rds:*:*:db:*",
        "arn:aws:rds:*:*:global-cluster:*",
        "arn:aws:sns:*:*:*",
        "arn:aws:sqs:*:*:*",
        "arn:aws:secretsmanager:*:*:secret:*"
      ],
      "Condition": {
        "Null": {
          "aws:RequestTag/Automation": "true"
        }
      }
    },
    {
      "Sid": "DenySCP2",
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances",
        "iam:CreateRole",
        "iam:CreateUser",
        "iam:CreateAccessKey",
        "iam:CreateGroup",
        "iam:CreatePolicy",
        "iam:CreatePolicyVersion",
        "logs:CreateLogDelivery",
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:CreateExportTask",
        "elasticloadbalancing:CreateLoadBalancer",
        "lambda:CreateFunction",
        "acm:RequestCertificate",
        "rds:CreateDBCluster",
        "rds:CreateDBInstance",
        "rds:CreateGlobalCluster",
        "sns:CreateTopic",
        "sqs:CreateQueue",
        "secretsmanager:CreateSecret"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*",
        "arn:aws:iam:*:*:user/*",
        "arn:aws:iam:*:*:role/*",
        "arn:aws:iam:*:*:group/*",
        "arn:aws:iam:*:*:policy/*",
        "arn:aws:logs:*:*:log-group:*",
        "arn:aws:elasticloadbalancing:*:*:loadbalancer/*",
        "arn:aws:lambda:*:*:function:*",
        "arn:aws:acm:*:*:*",
        "arn:aws:rds:*:*:cluster:*",
        "arn:aws:rds:*:*:db:*",
        "arn:aws:rds:*:*:global-cluster:*",
        "arn:aws:sns:*:*:*",
        "arn:aws:sqs:*:*:*",
        "arn:aws:secretsmanager:*:*:secret:*"
      ],
      "Condition": {
        "Null": {
          "aws:RequestTag/Name": "true"
        }
      }
    },
    {
      "Sid": "DenySCP3",
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances",
        "iam:CreateRole",
        "iam:CreateUser",
        "iam:CreateAccessKey",
        "iam:CreateGroup",
        "iam:CreatePolicy",
        "iam:CreatePolicyVersion",
        "logs:CreateLogDelivery",
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:CreateExportTask",
        "elasticloadbalancing:CreateLoadBalancer",
        "lambda:CreateFunction",
        "acm:RequestCertificate",
        "rds:CreateDBCluster",
        "rds:CreateDBInstance",
        "rds:CreateGlobalCluster",
        "sns:CreateTopic",
        "sqs:CreateQueue",
        "secretsmanager:CreateSecret"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*",
        "arn:aws:iam:*:*:user/*",
        "arn:aws:iam:*:*:role/*",
        "arn:aws:iam:*:*:group/*",
        "arn:aws:iam:*:*:policy/*",
        "arn:aws:logs:*:*:log-group:*",
        "arn:aws:elasticloadbalancing:*:*:loadbalancer/*",
        "arn:aws:lambda:*:*:function:*",
        "arn:aws:acm:*:*:*",
        "arn:aws:rds:*:*:cluster:*",
        "arn:aws:rds:*:*:db:*",
        "arn:aws:rds:*:*:global-cluster:*",
        "arn:aws:sns:*:*:*",
        "arn:aws:sqs:*:*:*",
        "arn:aws:secretsmanager:*:*:secret:*"
      ],
      "Condition": {
        "Null": {
          "aws:RequestTag/Customer": "true"
        }
      }
    }
  ]
}
profile picture
answered 3 months ago
  • Soo cool that you have the right policy working according to your org standards.

1

Great, that works perfectly. I needed to create two policies for TagEnforce and two for DenyTagDelete because there are several tags on several resources, but they worked as expected. Thank you very much for the support.

There was just another unresolved issue, the part of the code that prevents the deletion of Tags does not only work for the specified Tags, if I create a new Tag in a EC2 that already exists, for example, the deletion of this new Tag is also denied.

Let's consider this codes:

I tryed this way

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowDeleteTagsExceptSpecificTags",
      "Effect": "Deny",
      "Action": "ec2:DeleteTags",
      "Resource": "arn:aws:ec2:*:*:instance/*",
      "Condition": {
        "Null": {
          "aws:RequestTag/Customer": "true",
          "aws:RequestTag/Name": "true"
        }
      }
    }
  ]
}

and this way

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowDeleteTagsExceptSpecificTags",
      "Effect": "Deny",
      "Action": "ec2:DeleteTags",
      "Resource": "arn:aws:ec2:*:*:instance/*",
      "Condition": {
        "Null": {
          "aws:RequestTag/Customer": "true"
        }
      },
{
      "Sid": "AllowDeleteTagsExceptSpecificTags",
      "Effect": "Deny",
      "Action": "ec2:DeleteTags",
      "Resource": "arn:aws:ec2:*:*:instance/*",
      "Condition": {
        "Null": {
          "aws:RequestTag/Name": "true"
        }
      }
    }
  ]
}

I also tried with other conditions but without success

profile picture
answered 3 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions