Preventing higher costs on EC2
Teresa N. Fontanella De Santis
Posted on March 15, 2022
In this post we will discuss an example of how to prevent running unwanted expensive EC2 instances.
Situation
We currently have several AWS accounts with consolidated billing in one AWS account using AWS Organizations. Hundreds of users are using those AWS Accounts daily to complete their daily work.
Issue
We want to prevent all users to launch expensive EC2 instances with higher prices (like the GPU Accelerated instances types), to do not have a heart attack when looking at the bill in the following month. We can use IAM custom policies to define those conditions, but the restriction must be applied also in those who had full administration access.
Solution
We can take advantage of AWS Organizations and create Service Control Policies (or SCPs) to define IAM guardrails. These policies will help us to define a set of Denied actions on an AWS Account, no matter IAM user's permissions. Additionally, this won’t required any additional cost. The following steps can be run on a CloudShell terminal.
-
Enable organization Secure Control Policies (SCPs).
rootId=$(aws organizations list-roots | jq .Roots[].Id | sed 's/"//g') aws organizations enable-policy-type --root-id $rootId --policy-type SERVICE_CONTROL_POLICY`
-
Create SCP to restrict expensive instance types.
Save a SCP policy in a json file and create the policy. Then, obtain the policyId to be used in next step.
cat > scp_ec2_policy.json <<'END' { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Deny", "Action": "ec2:RunInstances", "Resource": "*", "Condition": { "StringLike": { "ec2:InstanceType": "p*.*" } } } ] } END policyName="DenyEC2InstanceTypes" description="Denies launch of expensive EC2 instances" file="file://scp_ec2_policy.json" policy=$(aws organizations create-policy --content $file --name $policyName --type SERVICE_CONTROL_POLICY --description "$description") policyId=$(echo $policy | jq ".Policy.PolicySummary.Id" | sed 's/"//g')
-
Attach it on AWS Account on AWS Organizations.
Apply the following command per each AWS Account invited into the AWS Organization, except the management account. Replace<aws_account_id>
by AWS Account's ID.
aws organizations attach-policy --policy-id $policyId --target-id <aws_account_id>
Finally, when trying to launch a new EC2 instance with p3 instance type, we'll get an error no matter we have EC2 Full Access. This is great to prevent unexpected costs for launching expensive EC2 instances!
Posted on March 15, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.