- Knowledge Base
- Amazon Web Services
- AWS Identity and Access Management (IAM)
- Amazon EC2 Purchase Restriction
Ensure that only dedicated IAM users have the capability to purchase Amazon EC2 Reserved Instances and/or Savings Plans within your AWS cloud account in order to address internal compliance requirements and prevent unexpected charges on your AWS bill. Prior to running this conformity rule, the name(s) of the IAM user(s) allowed to purchase EC2 Reserved Instances and/or Savings Plans, must be configured in the conformity rule settings, on the Trend Cloud One™ – Conformity console.
This rule can help you work with the AWS Well-Architected Framework.
optimisation
Purchasing Amazon EC2 Reserved Instances (RIs) and Savings Plans result in bigger financial commitments. Therefore, to keep compute costs under control, you might want to control who can make such purchases within your AWS cloud account.
Audit
To check for unintended IAM users that have permissions to purchase Amazon EC2 Reserved Instances and/or Savings Plans, perform the following operations:
Using AWS Console
01 Sign in to your Trend Cloud One™ – Conformity account, access Amazon EC2 Purchase Restriction conformity rule settings and identify the name(s) of the IAM user(s) allowed to purchase Amazon EC2 Reserved Instances and/or Savings Plans in your AWS account.
02 Sign in to the AWS Management Console.
03 Navigate to Amazon IAM console at https://console.aws.amazon.com/iam/.
04 In the navigation panel, under Access management, choose Users.
05 Click on the name of the IAM user that you want to examine.
06 Select the Permissions tab and click on the Expand button (right arrow icon) available next to each IAM policy attached, to show the IAM policy document in JSON format.
07 Inside the policy document box, search for the "Action" policy element that contains "ec2:PurchaseReservedInstancesOffering" or "savingsplans:CreateSavingsPlan" or both, in combination with "Effect" set to "Allow", as shown in the example below:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:PurchaseReservedInstancesOffering", "savingsplans:CreateSavingsPlan" ], "Resource": "*" } ] }
If the verified IAM user has permissions to purchase Amazon EC2 Reserved Instances and/or Savings Plans, and the user name is not listed in the conformity rule settings identified at step no. 1, the selected AWS IAM user should not be able to make purchases, therefore the associated identity-based policies are not compliant.
08 Repeat steps no. 5 – 7 for each Amazon IAM user created within your AWS cloud account.
Using AWS CLI
01 Sign in to your Trend Cloud One™ – Conformity account, access Amazon EC2 Purchase Restriction conformity rule settings and identify the name(s) of the IAM user(s) allowed to purchase Amazon EC2 Reserved Instances and/or Savings Plans in your AWS account.
02 Run list-users command (OSX/Linux/UNIX) using custom query filters to list the names of all IAM users available within your AWS account:
aws iam list-users --output table --query 'Users[*].UserName'
03 The command output should return a table with the requested IAM user identifiers:
----------------------- | ListUsers | +---------------------+ | cc-project5-admin | | cc-rds-db-manager | +---------------------+
04 Run list-attached-user-policies command (OSX/Linux/UNIX) using the name of the Amazon IAM user that you want to examine as identifier parameter and custom filtering to list the Amazon Resource Names (ARNs) of the IAM managed policies currently attached to the selected user:
aws iam list-attached-user-policies --user-name cc-project5-admin --query 'AttachedPolicies[*].PolicyArn'
05 The command output should return the ARNs of the managed policies attached to the specified IAM user:
[ "arn:aws:iam::123456789012:policy/cc-ec2-compute-access", "arn:aws:iam::123456789012:policy/cc-rds-service-access" ]
06 Run get-policy-version command (OSX/Linux/UNIX) using the ARN of the IAM policy that you want to examine as identifier parameter and custom query filters to describe the policy document in JSON format. Repeat this step for each managed policy attached to the specified IAM user:
aws iam get-policy-version --policy-arn arn:aws:iam::123456789012:policy/cc-ec2-compute-access --version-id v1 --query 'PolicyVersion.Document'
07 The command output should return the requested IAM policy document:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:Describe*", "elasticloadbalancing:Describe*", "autoscaling:Describe*", "cloudwatch:Describe*", "cloudwatch:ListMetrics", "cloudwatch:GetMetricStatistics", "ec2:PurchaseReservedInstancesOffering", "savingsplans:CreateSavingsPlan" ], "Resource": "*" } ] }
08 Run list-user-policies command (OSX/Linux/UNIX) using the name of the Amazon IAM user that you want to examine as identifier parameter and custom filtering to list the names of the inline policies embedded within the selected IAM user:
aws iam list-user-policies --user-name cc-project5-admin --query 'PolicyNames'
09 The command output should return the names of the inline policies embedded in the specified IAM user:
[ "cc-inline-ec2-policy", "cc-custom-api-access" ]
10 Run get-user-policy command (OSX/Linux/UNIX) using the name of the inline policy that you want to examine as identifier parameter, returned at the previous step, to describe the IAM policy document in JSON format. Repeat this step for each inline policy attached to the specified IAM user:
aws iam get-user-policy --user-name cc-project5-admin --policy-name cc-inline-ec2-policy --query 'PolicyDocument'
11 The command output should return the requested AWS IAM policy document:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:PurchaseReservedInstancesOffering", "savingsplans:CreateSavingsPlan" ], "Resource": "*" } ] }
Search the policy documents returned by the get-policy-version command output at step no. 6 and the get-user-policy command output at step no. 10 for the "Action" policy element that contains "ec2:PurchaseReservedInstancesOffering" or "savingsplans:CreateSavingsPlan" or both, in combination with "Effect": "Allow". If the verified IAM user has permissions to purchase Amazon EC2 Reserved Instances and/or Savings Plans, and the user name is not listed in the conformity rule settings identified at step no. 1, the selected AWS IAM user should not be able to make purchases, therefore the associated identity-based policies are not compliant.
12 Repeat steps no. 3 – 10 for each unintended AWS IAM user available within your AWS cloud account.
Remediation / Resolution
To prevent unintended AWS IAM users from purchasing Amazon EC2 Reserved Instances and/or Savings Plans within your AWS cloud account, perform the following operations:
Using AWS CloudFormation
01 CloudFormation template (JSON):
{ "AWSTemplateFormatVersion": "2010-09-09", "Resources": { "IAMUser": { "Type": "AWS::IAM::User", "Properties": { "UserName": "cc-ec2-instance-developer" } }, "IAMUserPolicy": { "Type": "AWS::IAM::Policy", "Properties": { "PolicyName": "full-access-policy", "PolicyDocument": { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:Describe*", "elasticloadbalancing:Describe*", "autoscaling:Describe*", "cloudwatch:Describe*", "cloudwatch:ListMetrics", "cloudwatch:GetMetricStatistics", "ec2:PurchaseReservedInstancesOffering", "savingsplans:CreateSavingsPlan" ], "Resource": "*" } ] }, "Users": [ { "Ref": "IAMUser" } ] } } } }
02 CloudFormation template (YAML):
AWSTemplateFormatVersion: '2010-09-09' Resources: IAMUser: Type: AWS::IAM::User Properties: UserName: cc-ec2-instance-developer IAMUserPolicy: Type: AWS::IAM::Policy Properties: PolicyName: full-access-policy PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - ec2:Describe* - elasticloadbalancing:Describe* - autoscaling:Describe* - cloudwatch:Describe* - cloudwatch:ListMetrics - cloudwatch:GetMetricStatistics - ec2:PurchaseReservedInstancesOffering - savingsplans:CreateSavingsPlan Resource: '*' Users: - !Ref 'IAMUser'
Using Terraform (AWS Provider)
01 Terraform configuration file (.tf):
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } } required_version = ">= 0.14.9" } provider "aws" { profile = "default" region = "us-east-1" } resource "aws_iam_user" "iam-user" { name = "cc-ec2-instance-developer" } resource "aws_iam_policy" "iam-policy" { name = "ec2-access-policy" policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:Describe*", "elasticloadbalancing:Describe*", "autoscaling:Describe*", "cloudwatch:Describe*", "cloudwatch:ListMetrics", "cloudwatch:GetMetricStatistics", "ec2:PurchaseReservedInstancesOffering", "savingsplans:CreateSavingsPlan" ], "Resource": "*" } ] } EOF } resource "aws_iam_policy_attachment" "iam-user-attachment" { name = "iam-user-attachment" users = [aws_iam_user.iam-user.name] policy_arn = aws_iam_policy.iam-policy.arn }
Using AWS Console
01 Sign in to the AWS Management Console.
02 Navigate to Amazon IAM console at https://console.aws.amazon.com/iam/.
03 In the navigation panel, under Access management, choose Users.
04 Click on the name of the unintended IAM user that you want to reconfigure (see Audit section part I to identify the non-compliant user).
05 Select the Permissions tab, expand the panel with the policy that you want to update, then choose Edit policy.
06 On the Edit <policy-name>
configuration page, perform the following actions:
- Select the JSON tab and remove the following lines: "ec2:PurchaseReservedInstancesOffering" and "savingsplans:CreateSavingsPlan" from the "Action" element value. This will remove the user capability to purchase Amazon EC2 Reserved Instances and Savings Plans.
- Choose Review policy to review the modified policy.
- Choose Save changes to apply the permission changes.
07 Repeat steps no. 5 and 6 for each non-compliant identity-based policy attached to the selected IAM user.
08 Repeat steps no. 4 – 7 for each unintended AWS IAM user available within your AWS cloud account.
Using AWS CLI
01 Modify the non-compliant identity-based policy (see Audit section part II to identify the right policy) and remove the following lines: "ec2:PurchaseReservedInstancesOffering" and "savingsplans:CreateSavingsPlan" from the "Action" element value (highlighted). This will remove the user capability to purchase Amazon EC2 Reserved Instances and Savings Plans. Save the modified IAM policy document to a JSON file named compliant-user-policy.json:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "ec2:Describe*", "elasticloadbalancing:Describe*", "autoscaling:Describe*", "cloudwatch:Describe*", "cloudwatch:ListMetrics", "cloudwatch:GetMetricStatistics", "ec2:PurchaseReservedInstancesOffering", "savingsplans:CreateSavingsPlan" ], "Resource": "*" } ] }
02 Run create-policy-version command (OSX/Linux/UNIX) to update the non-compliant customer-managed policy attached to the specified AWS IAM user using the policy document modified at the previous step:
aws iam create-policy-version --policy-arn arn:aws:iam::123456789012:policy/cc-ec2-compute-access --set-as-default --policy-document file://compliant-user-policy.json
03 The command output should return the metadata for the new policy version:
{ "PolicyVersion": { "VersionId": "v2", "IsDefaultVersion": true, "CreateDate": "2021-02-04T16:00:00+00:00" } }
04 Run put-user-policy command (OSX/Linux/UNIX) to update the non-compliant inline policy embedded in the specified AWS IAM user using the policy document modified at step no. 1 (the command does not produce an output):
aws iam put-user-policy --user-name cc-project5-admin --policy-name cc-inline-ec2-policy --policy-document file://compliant-user-policy.json
05 Repeat steps no. 1 – 4 for each unintended AWS IAM user available in your AWS cloud account.
References
- AWS Documentation
- AWS Identity and Access Management (IAM) FAQs
- Policies and permissions in IAM
- AWS Billing policy examples
- AWS Command Line Interface (CLI) Documentation
- iam
- list-users
- list-attached-user-policies
- get-policy-version
- list-user-policies
- get-user-policy
- create-policy-version
- put-user-policy