Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Unused EC2 Reserved Instances

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: High (not acceptable risk)
Rule ID: EC2-054

Ensure that all purchased Amazon EC2 Reserved Instances (RI) have corresponding instances running within the same AWS account or within any linked AWS accounts available in an AWS Organization (if you are using one). A corresponding instance is an Amazon EC2 instance provisioned based on the existing reservation criteria such as Region, Instance Type, Tenancy, and Platform (OS).

This rule can help you with the following compliance standards:

  • APRA
  • MAS
  • AWAF

For further details on compliance standards supported by Conformity, see here.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Cost
optimisation

When an Amazon EC2 Reserved Instance is not used (i.e. does not have a running corresponding instance) the investment made is not valorized. For example, if you reserve a c4.large EC2 instance with default tenancy within US East (N. Virginia) region but for some reason you don't provision an instance with the same type and tenancy, in the same region of the same AWS account or in any other linked AWS accounts available within your AWS Organization, the specified Reserved Instance is considered unused and you end up paying for a service that you don't use.


Audit

To determine if you have any unused Amazon EC2 Reserved Instances within your AWS cloud account or AWS Organization, perform the following actions:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon EC2 console at https://console.aws.amazon.com/ec2/.

03 In the navigation panel, under Instances, choose Reserved Instances.

04 Select the Amazon EC2 Reserved Instance (RI) that you want to examine.

05 Choose the Details tab from the console bottom panel and copy the following configuration attributes: Instance Type, Platform, Tenancy, and Availability Zone (if applicable).

06 In the navigation panel, under Instances, choose Instances.

07 Click inside the Filter instances box located under the console top menu, choose Instance type, paste the instance type copied at step no. 5, and press Enter. Repeat this step for the Platform, Tenancy and Availability Zone filters, using the configuration values copied at step no. 5. To return active EC2 instances only, select Instance state and choose running. This filtering technique will help you to determine if there are any Amazon EC2 instance that match the selected reservation criteria, available in the current AWS region. If no Amazon EC2 instances matching your filter criteria are found, the selected reservation does not have an active corresponding instance running in the current AWS region, therefore the verified Amazon EC2 Reserved Instance is not being used.

08 If your AWS account is member of an AWS Organization, access the Instances page available for each linked account, select the same AWS region, and repeat step no. 7 to check for active corresponding Amazon EC2 instances.

09 Repeat steps no. 4 – 8 for each Reserved Instance (RI) available within the current AWS region.

10 Change the AWS cloud region from the console navigation bar and repeat the audit process for other regions.

Using AWS CLI

01 Run describe-instances command (OSX/Linux/UNIX) using custom query filters to list the IDs of the active Amazon EC2 reservations available in the selected AWS region:

aws ec2 describe-reserved-instances
  --region us-east-1
  --filters "Name=state,Values=active"
  --output table
  --query 'ReservedInstances[*].ReservedInstancesId'

02 The command output should return the requested reservation identifiers (IDs):

----------------------------------------
|        ReservedInstancesIds          |
+--------------------------------------+
| abcdabcd-1234-abcd-1234-abcd1234abcd |
| 12341234-abcd-1234-abcd-1234abcd1234 |
----------------------------------------

03 Run describe-reserved-instances command (OSX/Linux/UNIX) using the ID of the active Amazon EC2 reservation that you want to examine as the identifier parameter and custom query filters to describe configuration attributes available for the selected reservation:

aws ec2 describe-reserved-instances
  --region us-east-1
  --reserved-instances-ids abcdabcd-1234-abcd-1234-abcd1234abcd

04 The command output should return the requested configuration attributes. This information will be useful later to search for Amazon EC2 instances that match the purchase criteria:

{
	"ReservedInstances": [
		{
			"ReservedInstancesId": "abcdabcd-1234-abcd-1234-abcd1234abcd",
			"OfferingType": "No Upfront",
			"AvailabilityZone": "us-east-1b",
			"End": "2021-03-21T19:43:23.000Z",
			"ProductDescription": "Linux/UNIX (Amazon VPC)",
			"Scope": "Availability Zone",
			"UsagePrice": 0.0,
			"RecurringCharges": [
				{
					"Amount": 0.048,
					"Frequency": "Hourly"
				}
			],
			"OfferingClass": "standard",
			"Start": "2021-03-21T19:43:24.352Z",
			"State": "active",
			"FixedPrice": 0.0,
			"CurrencyCode": "USD",
			"Duration": 31536000,
			"InstanceTenancy": "default",
			"InstanceType": "c4.large",
			"InstanceCount": 1
		}
	]
}

05 Run describe-instances command (OSX/Linux/UNIX) using predefined and custom query filters to list the IDs of the Amazon EC2 instances that match the selected reservation purchase criteria, available in the selected AWS region. Use the configuration information returned at the previous step to configure the describe-instances command filters:

aws ec2 describe-instances
  --region us-east-1
  --filters "Name=instance-type,Values=c4.large" "Name=tenancy,Values=default" "Name=availability-zone,Values=us-east-1b" "Name=instance-state-name,Values=running"
  --query 'Reservations[*].Instances[*].InstanceId[]'

06 The command output should return a table with the requested active instance IDs:

[]

If the describe-instances command output returns an empty array (i.e. []), as shown in the example above, the selected reservation does not have an active corresponding instance running in the selected AWS region, therefore the verified Amazon EC2 Reserved Instance is not being used.

07 If your AWS account is member of an AWS Organization, repeat steps no. 5 and 6 to check for the corresponding Amazon EC2 instance within other AWS member accounts.

08 Repeat steps no. 3 – 7 for each Reserved Instance (RI) available in the selected AWS region.

09 Change the AWS cloud region by updating the --regioncommand parameter value and repeat the remediation process for other regions.

Remediation / Resolution

Case A: Because the Amazon EC2 Standard Reserved Instances can't be canceled, the only way to decommission the unused reservations and reclaim their cost is to sell them to other businesses and organizations on Amazon EC2 Reserved Instance Marketplace. To list eligible reservations for sale on the Reserved Instance Marketplace, perform the following actions:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon EC2 console at https://console.aws.amazon.com/ec2/.

03 In the navigation panel, under Instances, choose Reserved Instances.

04 Select the unused Reserved Instance that you want to sell, choose Actions, and select Sell Reserved Instances.

05 If you list Amazon EC2 Reserved Instances for sale for the first time, you must register to the Reserved Instance Marketplace. Within Sell Your Reserved Instance dialog box, choose Register to initiate the registration wizard.

06 On the Account Information page, provide a name for the seller in the Business Name box, then choose Continue.

07 On the Add Bank Account page, register a bank account as the deposit for your sales by providing your bank account information. Once your bank account information is validated, choose Continue.

08 On the Confirmation page, choose Continue finish the registration wizard.

09 Select the Reserved Instance that you want to sell, choose Actions and Sell Reserved Instances.

10 On the Sell Your Reserved Instance panel, perform the following operations:

  1. Choose Get Started to start listing your unused reservation.
  2. In the Configure Your Reserved Instance Listing section, specify the number of Reserved Instances you would like to sell and the upfront price for each one, and choose Continue.
  3. In the Confirm Your Reserved Instance Listing section, review the Reserved Instance listing details, then choose List Reserved Instances to list your RIs on the Reserved Instance Marketplace. Choose Close to return to the Amazon EC2 console.

11 Repeat steps no. 9 – 10 to list for sale other unused Amazon__EC2 Reserved Instances, that have been purchased within the current AWS cloud account or in any other member accounts linked to your AWS Organization (if applicable).

12 Change the AWS cloud region from the console navigation bar and repeat the remediation process for other regions.

Using AWS CLI

01 Run create-reserved-instances-listing command (OSX/Linux/UNIX) to create a listing for your unused Amazon EC2 Reserved Instance to be sold on the Reserved Instance Marketplace. The following command example creates a listing of $420.00 for an Amazon EC2 Reserved Instance with the ID "abcdabcd-1234-abcd-1234-abcd1234abcd", that has 6 months remaining in the reservation time-frame:

aws ec2 create-reserved-instances-listing
  --region us-east-1
  --reserved-instances-id abcdabcd-1234-abcd-1234-abcd1234abcd
  --instance-count 1
  --price-schedules Term=6,Price=420.00,CurrencyCode="USD"

02 The command output should return the Reserved Instance listing metadata:

{
	"ReservedInstancesListings": [
		{
			"ReservedInstancesId": "abcdabcd-1234-abcd-1234-abcd1234abcd",
			"CreateDate": "2021-03-05T14:15:37.352Z",
			"InstanceCounts": [
				{
					"State": "active",
					"InstanceCount": 1
				}
			],

			...


			"PriceSchedules": [
				{
					"Term": 6,
					"Price": 420.00,
					"CurrencyCode": "USD",
					"Active": "true"
				}
			],
			"Tags": [],
			"Status": "fulfilled",
			"ClientToken": "abcd1234-abcd-1234-abcd-1234abcd1234"
		}
	]
}

03 Repeat steps no. 1 and 2 to create sale listings for other unused Amazon__EC2 Reserved Instances that have been purchased in the selected AWS account or within any other member accounts linked to your AWS Organization (if applicable).

04 Change the AWS cloud region by updating the --region command parameter value and repeat the remediation process for other regions.

Case B: Provision corresponding Amazon EC2 instances for the unused Reserved Instances (RIs). To launch Amazon EC2 instances that match the RIs purchase criteria, perform the following actions:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon EC2 console at https://console.aws.amazon.com/ec2/.

03 In the navigation panel, under Instances, choose Instances.

04 On the Instances listing page, choose Launch instances and perform the following operations:

  1. For Step 1: Choose an Amazon Machine Image (AMI), choose**an AMI provided by AWS, AWS Marketplace, or select one of your own AMIs. The chosen image must use the same OS platform as the unused Reserved Instance.
  2. For Step 2: Choose an Instance Type, select the required instance type (must match the instance type used by the unused reservation). Choose Next: Configure Instance Details to continue the setup process.
  3. For Step 3: Configure Instance Details, configure the instance network, tenancy, identity management, behavior, and metadata settings. The new instance configuration must match the unused reservation configuration. Choose Next: Add Storage to continue the setup process.
  4. For Step 4: Add Storage, configure the storage device settings. Choose Next: Add Tags to set up the instance tags.
  5. For Step 5: Add Tags, use the Add tag button to create and apply user-defined tags to the new EC2 instance. You can track compute cost and other criteria by tagging your instance. Choose Configure Security Groupto continue the setup process.
  6. For Step 6: Configure Security Group, choose Select an existing security group and select the security group(s) associated with the source Amazon EC2 instance. Choose Review and Launch to continue.
  7. For Step 7: Review Instance Launch, review your EC2 instance configuration details, then choose Launch.
  8. In the Select an existing key pair or create a new key pair configuration box, select Choose an existing key pair and use a secure key pair. Select the I acknowledge that I have access to the selected private key file (<key-name>.pem), and that without this file, I won't be able to log into my instance checkbox for confirmation, then choose Launch Instances to launch your new Amazon EC2 instance.
  9. Choose View Instances to return to the Instances page.

05 Repeat step no. 4 to provision corresponding Amazon EC2 instances for other unused Reserved Instances purchased within the current AWS region or within any other member accounts linked to your AWS Organization (if applicable).

06 Change the AWS cloud region from the console navigation bar and repeat the remediation process for other regions.

Using AWS CLI

01 Execute run-instances command (OSX/Linux/UNIX) to create a new Amazon EC2 instance for the unused Reserved Instance (RI). The new instance configuration must match the unused reservation configuration:

aws ec2 run-instances
  --region us-east-1
  --image-id ami-0abcdabcdabcdabcd
  --count 1
  --instance-type c4.large
  --key-name conformity
  --security-group-ids sg-01234abcd1234abcd
  --placement Tenancy=default

02 The command output should return the configuration metadata for the newly created Amazon EC2 instance:

{
	"Groups": [],
	"Instances": [
		{
			"AmiLaunchIndex": 0,
			"ImageId": "ami-0abcdabcdabcdabcd",
			"InstanceId": "i-01234123412341234",
			"InstanceType": "c4.large",
			"KeyName": "conformity.aws",
			"LaunchTime": "2021-03-22T17:29:43+00:00",
			"Monitoring": {
				"State": "disabled"
			},
			"Placement": {
				"AvailabilityZone": "us-east-1b",
				"GroupName": "",
				"Tenancy": "default"
			},
			"PrivateDnsName": "ip-10-0-0-5.ec2.internal",
			"PrivateIpAddress": "10.0.0.5",
			"ProductCodes": [],
			"PublicDnsName": "",
			"State": {
				"Code": 0,
				"Name": "pending"
			},
			"StateTransitionReason": "",
			"SubnetId": "subnet-abcdabcd",
			"VpcId": "vpc-1234abcd",
			"Architecture": "x86_64",
			"BlockDeviceMappings": [],
			"EbsOptimized": false,
			"EnaSupport": true,
			"Hypervisor": "xen",
			"IamInstanceProfile": {
				"Arn": "arn:aws:iam::123456789012:instance-profile/ec2-manager-role",
				"Id": "ABCDABCDABCDABCDABCD"
			},
			"NetworkInterfaces": [
				{
					"Attachment": {
						"AttachTime": "2021-03-22T17:29:43+00:00",
						"AttachmentId": "eni-attach-0abcd1234abcd1234",
						"DeleteOnTermination": true,
						"DeviceIndex": 0,
						"Status": "attaching",
						"NetworkCardIndex": 0
					},
					"Description": "",
					"Groups": [
						{
							"GroupName": "cc-prod-security-group",
							"GroupId": "sg-01234abcd1234abcd"
						}
					],
					"Ipv6Addresses": [],
					"MacAddress": "06:00:c7:12:51:99",
					"NetworkInterfaceId": "eni-0abcd1234abcd1234",
					"OwnerId": "123456789012",
					"PrivateDnsName": "ip-10-0-0-5.ec2.internal",
					"PrivateIpAddress": "10.0.0.5",
					"PrivateIpAddresses": [
						{
							"Primary": true,
							"PrivateDnsName": "ip-10-0-0-5.ec2.internal",
							"PrivateIpAddress": "10.0.0.5"
						}
					],
					"SourceDestCheck": true,
					"Status": "in-use",
					"SubnetId": "subnet-abcdabcd",
					"VpcId": "vpc-1234abcd",
					"InterfaceType": "interface"
				}
			],
			"RootDeviceName": "/dev/xvda",
			"RootDeviceType": "ebs",
			"SecurityGroups": [
				{
					"GroupName": "cc-prod-security-group",
					"GroupId": "sg-01234abcd1234abcd"
				}
			],
			"SourceDestCheck": true,
			"StateReason": {
				"Code": "pending",
				"Message": "pending"
			},
			"VirtualizationType": "hvm",
		"HibernationOptions": {
				"Configured": true
			},
			"CpuOptions": {
				"CoreCount": 1,
				"ThreadsPerCore": 1
			},
			"CapacityReservationSpecification": {
				"CapacityReservationPreference": "open"
			},
			"MetadataOptions": {
				"State": "pending",
				"HttpTokens": "optional",
				"HttpPutResponseHopLimit": 1,
				"HttpEndpoint": "enabled"
			},
			"EnclaveOptions": {
				"Enabled": false
			}
		}
	],
	"OwnerId": "123456789012",
	"ReservationId": "r-0abcd1234abcd1234"
}

03 Repeat steps no. 1 and 2 to provision corresponding Amazon EC2 instances for other unused Reserved Instances purchased in the selected AWS region or within any other member accounts linked to your AWS Organization (if applicable).

04 Change the AWS cloud region by updating the --region command parameter value and repeat the remediation process for other regions.

References

Publication date Mar 7, 2017