AWS Service Control Policy (SCP) With Examples
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In the last blog post, we have discussed AWS Organization policy.
https://cloudaffaire.com/what-is-aws-organization-policy/
In this blog post, we will discuss AWS Service Control Policy (SCP) with examples. Service Control Policy (SCP) is similar to IAM permissions policies except that they don’t grant any permissions. Instead, SCPs specify the maximum permissions for an organization, organizational unit (OU), or account. When you attach an SCP to your organization root or an OU, the SCP limits permissions for entities in member accounts.
Elements Of Service Control Policy (SCP):
Service Control Policy (SCP) policy syntax is very much similar to IAM permission policy or any other resource-based policy and is written in JSON. Below are the elements of a service control policy.
- Version: Specifies the language syntax rules to use for processing the policy.
- Statement: Serves as the container for policy elements. You can have multiple statements in SCPs.
- Statement ID (Sid): (Optional) Provides a friendly name for the statement.
- Effect: Defines whether the SCP statement allows or denies access to the IAM users and roles in an account.
- Action: Specifies AWS service and actions that the SCP allows or denies.
- NotAction: Specifies AWS service and actions that are exempt from the SCP. Used instead of the Action element.
- Resource: Specifies the AWS resources that the SCP applies to.
- Condition: Specifies conditions for when the statement is in effect.
Example Service Control Policy:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
{ "Version": "2012-10-17", "Statement": [{ "Sid": "RequireMicroInstanceType", "Effect": "Deny", "Action": "ec2:RunInstances", "Resource": [ "arn:aws:ec2:*:*:instance/*" ], "Condition": { "StringNotEquals": { "ec2:InstanceType": "t2.micro" } } }] } |
The above example scp policy restrict anyone from creating any EC2 instance of any other type than “t2.micro”.
Next, we are going to discuss how to manage AWS organization scp policy using API.
Prerequisite:
AWS Organization created with multiple OU and member accounts. You can refer below blog post to create the organization. This blog is a continuation from below blog post.
https://cloudaffaire.com/how-to-manage-aws-organization-using-api/
How To Enable Service Control Policy (SCP) In AWS Organization Using AWS CLI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
## Get your Root OU ID ROOT_OU_ID=$(aws organizations list-roots \ --profile management | jq -r .Roots[0].Id) && echo $ROOT_OU_ID ## Enable Service Control Policy (SCP) aws organizations enable-policy-type \ --root-id $ROOT_OU_ID \ --policy-type SERVICE_CONTROL_POLICY \ --profile management ## List all SCP policies in your organization aws organizations list-policies \ --filter SERVICE_CONTROL_POLICY \ --profile management ## Observe default SCP FullAWSAccess has been ## created as we have enabled the SCP policy ## View default (FullAWSAccess) SCP policy details FULLAWSACCESS_POLICY_ID=$(aws organizations list-policies \ --filter SERVICE_CONTROL_POLICY \ --profile management | jq -r .Policies[0].Id ) && aws organizations describe-policy \ --policy-id $FULLAWSACCESS_POLICY_ID \ --profile management ## View where the default (FullAWSAccess) SCP policy is applied aws organizations list-targets-for-policy \ --policy-id $FULLAWSACCESS_POLICY_ID \ --profile management ## Observe, the default (FullAWSAccess) SCP is applied to ## every OU and account as its currently attached to root |
How To Create A New SCP Policy Using AWS CLI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
## Create a new tag policy file cat < { "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": [ "ec2:CreateSubnet" ], "Resource": "*" } ] } EOF ## Create a new SCP policy aws organizations create-policy \ --content file://foundation_policy.json \ --name EnforceSubnetCreation \ --type SERVICE_CONTROL_POLICY \ --description "Deny subnet creation" \ --profile management |
How To Attach An SCP To An Organizational Unit Using AWS CLI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
## Get "Foundation" OU id FOUNDATION_OU_ID=$(aws organizations list-children -\ -child-type ORGANIZATIONAL_UNIT \ --parent-id $ROOT_OU_ID \ --profile management | jq -r .Children[0].Id) && echo $FOUNDATION_OU_ID ## Attach the SCP policy to the "Foundation" OU DENYSUBNETPOLICY=$(aws organizations list-policies \ --filter SERVICE_CONTROL_POLICY \ --profile management | jq -r .Policies[1].Id ) && aws organizations attach-policy \ --policy-id $DENYSUBNETPOLICY \ --target-id $FOUNDATION_OU_ID \ --profile management ## View where the SCP policy is applied aws organizations list-targets-for-policy \ --policy-id $DENYSUBNETPOLICY \ --profile management |
Now, if we try to create a new subnet in the accounts under “Foundation” OU, you will get an error.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
## Create a VPC AWS_VPC_ID=$(aws ec2 create-vpc \ --cidr-block 10.0.0.0/16 \ --query 'Vpc.{VpcId:VpcId}' \ --output text \ --region ap-south-1 \ --profile member1) ## Try to create a subnet AWS_SUBNET_ID=$(aws ec2 create-subnet \ --vpc-id $AWS_VPC_ID --cidr-block 10.0.1.0/24 \ --availability-zone ap-south-1a --query 'Subnet.{SubnetId:SubnetId}' \ --output text \ --region ap-south-1 \ --profile member1) ## You will get an error due to the above SCP ## Delete the vpc aws ec2 delete-vpc \ --vpc-id $AWS_VPC_ID \ --region ap-south-1 \ --profile member1 |
Next, let us explain SCP policy inheritance with an example. This time we are going to create a new SCP to deny VPC creation and apply it to “Regulatory” OU.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
## Create a new tag policy file cat < { "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": [ "ec2:CreateInternetGateway" ], "Resource": "*" } ] } EOF ## Create a new SCP policy aws organizations create-policy \ --content file://regulatory_policy.json \ --name EnforceInternetGatewayCreation \ --type SERVICE_CONTROL_POLICY \ --description "Deny internet gateway creation" \ --profile management ## Get "Regulatory" OU id REGULATORY_OU_ID=$(aws organizations list-children -\ -child-type ORGANIZATIONAL_UNIT \ --parent-id $FOUNDATION_OU_ID \ --profile management | jq -r .Children[0].Id) && echo $REGULATORY_OU_ID ## Attach the SCP policy to the "Foundation" OU DENYIGWPOLICY=$(aws organizations list-policies \ --filter SERVICE_CONTROL_POLICY \ --profile management \ --query 'Policies[?Name == `EnforceInternetGatewayCreation`].Id' | jq -r .[0] ) && aws organizations attach-policy \ --policy-id $DENYIGWPOLICY \ --target-id $REGULATORY_OU_ID \ --profile management ## View where the SCP policy is applied aws organizations list-targets-for-policy \ --policy-id $DENYIGWPOLICY \ --profile management |
Next, try to create internet gateway in an account inside Regulatory OU.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
## Create a VPC in member2 account (under Regulatory OU) AWS_VPC_ID=$(aws ec2 create-vpc \ --cidr-block 10.0.0.0/16 \ --query 'Vpc.{VpcId:VpcId}' \ --output text \ --region ap-south-1 \ --profile member2) ## Try to create an internet gateway in member2 account (under Regulatory OU) AWS_INTERNET_GATEWAY_ID=$(aws ec2 create-internet-gateway \ --query 'InternetGateway.{InternetGatewayId:InternetGatewayId}' \ --output text \ --region ap-south-1 \ --profile member2) ## Error ## Try to create an internet gateway in member1 account (under Foundation OU) AWS_INTERNET_GATEWAY_ID=$(aws ec2 create-internet-gateway \ --query 'InternetGateway.{InternetGatewayId:InternetGatewayId}' \ --output text \ --region ap-south-1 \ --profile member1) ## Success ## Try to create a subnet in member2 account (under Regulatory OU) AWS_SUBNET_ID=$(aws ec2 create-subnet \ --vpc-id $AWS_VPC_ID --cidr-block 10.0.1.0/24 \ --availability-zone ap-south-1a --query 'Subnet.{SubnetId:SubnetId}' \ --output text \ --region ap-south-1 \ --profile member2) ## Error ## Though SCP EnforceSubnetCreation is not directly applied to ## Regulatory OU, but it was inherited from Foundation OU ## Delete the InternetGateway aws ec2 delete-internet-gateway \ --internet-gateway-id $AWS_INTERNET_GATEWAY_ID \ --region ap-south-1 \ --profile member1 ## Delete the vpc aws ec2 delete-vpc \ --vpc-id $AWS_VPC_ID \ --region ap-south-1 \ --profile member2 |
How To Update An SCP Policy Using AWS CLI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
## Update the SCP policy definition cat < { "Version": "2012-10-17", "Statement": [ { "Effect": "Deny", "Action": [ "ec2:CreateSubnet", "ec2:ModifySubnetAttribute" ], "Resource": "*" } ] } EOF ## Update SCP Policy aws organizations update-policy \ --policy-id $DENYSUBNETPOLICY \ --content file://foundation_policy.json \ --profile management |
How To Detach An SCP Policy From An Organizational Unit Using AWS CLI
1 2 3 4 5 6 7 8 9 10 11 |
## Detach EnforceInternetGatewayCreation policy from Regulatory OU aws organizations detach-policy \ --policy-id $DENYIGWPOLICY \ --target-id $REGULATORY_OU_ID \ --profile management ## Detach EnforceSubnetCreation policy from Foundation OU Using AWS CLI aws organizations detach-policy \ --policy-id $DENYSUBNETPOLICY \ --target-id $FOUNDATION_OU_ID \ --profile management |
How To Delete An SCP Policy Using AWS CLI
1 2 3 4 5 6 7 8 9 |
## Delete EnforceInternetGatewayCreation SCP policy aws organizations delete-policy \ --policy-id $DENYIGWPOLICY \ --profile management ## Delete EnforceSubnetCreation SCP policy aws organizations delete-policy \ --policy-id $DENYSUBNETPOLICY \ --profile management |
Hope you have enjoyed this article. To know more about AWS organization, please refer below official documentation
https://docs.aws.amazon.com/organizations/index.html