Clean up your Spot Instances
To avoid unnecessary costs, it's important that you terminate any instances that were started from Spot Instance requests; simply canceling Spot Instance requests will not terminate your instances, which means that you'll continue to be charged for them. The following snippet shows you how to terminate an instance after you obtain the instance identifier for an active Spot Instance.
The example at the end of this topic (p. 128) shows this snippet in use.
//
// Method to terminate a Spot Instance
private static async Task TerminateSpotInstance(
IAmazonEC2 ec2Client, string requestId) {
var describeRequest = new DescribeSpotInstanceRequestsRequest();
describeRequest.SpotInstanceRequestIds.Add(requestId);
// Retrieve the Spot Instance request to check for running instances.
DescribeSpotInstanceRequestsResponse describeResponse =
await ec2Client.DescribeSpotInstanceRequestsAsync(describeRequest);
// If there are any running instances, terminate them if( (describeResponse.SpotInstanceRequests[0].Status.Code == "request-canceled-and-instance-running")
|| (describeResponse.SpotInstanceRequests[0].State == SpotInstanceState.Active)) {
TerminateInstancesResponse response =
await ec2Client.TerminateInstancesAsync(new TerminateInstancesRequest{
InstanceIds = new List<string>(){
describeResponse.SpotInstanceRequests[0].InstanceId } });
foreach (InstanceStateChange item in response.TerminatingInstances) {
Console.WriteLine($"\n Terminated instance: {item.InstanceId}");
Console.WriteLine($" Instance state: {item.CurrentState.Name}\n");
} } }
Complete code
The following code example calls the methods described earlier to create and cancel a Spot Instance request and terminate a Spot Instance.
SDK references
NuGet packages:• AWSSDK.EC2
Programming elements:
• Namespace Amazon.EC2 Class AmazonEC2Client
Amazon EC2
Class InstanceType
• Namespace Amazon.EC2.Model
Class CancelSpotInstanceRequestsRequest Class DescribeSpotInstanceRequestsRequest Class DescribeSpotInstanceRequestsResponse Class InstanceStateChange
Class LaunchSpecification
Class RequestSpotInstancesRequest Class RequestSpotInstancesResponse Class SpotInstanceRequest
Class TerminateInstancesRequest Class TerminateInstancesResponse
The code
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using Amazon.EC2;
using Amazon.EC2.Model;
namespace EC2SpotInstanceRequests { class Program
{
static async Task Main(string[] args) {
// Some default values.
// These could be made into command-line arguments instead.
var instanceType = InstanceType.T1Micro;
string securityGroupName = "default";
string spotPrice = "0.003";
int instanceCount = 1;
// Parse the command line arguments
if((args.Length != 1) || (!args[0].StartsWith("ami-"))) {
Console.WriteLine("\nUsage: EC2SpotInstanceRequests ami");
Console.WriteLine(" ami: the Amazon Machine Image to use for the Spot Instances.");
return;
}
// Create the Amazon EC2 client.
var ec2Client = new AmazonEC2Client();
// Create the Spot Instance request and record its ID Console.WriteLine("\nCreating spot instance request...");
var req = await CreateSpotInstanceRequest(
Amazon EC2
ec2Client, args[0], securityGroupName, instanceType, spotPrice, instanceCount);
string requestId = req.SpotInstanceRequestId;
// Wait for an EC2 Spot Instance to become active Console.WriteLine(
$"Waiting for Spot Instance request with ID {requestId} to become active...");
int wait = 1;
var requestInfo = await GetSpotInstanceRequestInfo(ec2Client, requestId);
if(requestInfo.Status.Code == "fulfilled") {
Console.WriteLine($"\nSpot Instance request {requestId} " + $"has been fulfilled by instance {requestInfo.InstanceId}.\n");
TimeSpan span = DateTime.Now.Subtract(start);
Console.WriteLine($"That took {span.TotalMilliseconds} milliseconds");
// Perform actions here as needed.
// For this example, simply wait for the user to hit a key.
// That gives them a chance to look at the EC2 console to see // the running instance if they want to.
Console.WriteLine("Press any key to start the cleanup...");
Console.ReadKey(true);
// Cancel the request.
// Do this first to make sure that the request can't be re-fulfilled // once the Spot Instance has been terminated.
Console.WriteLine("Canceling Spot Instance request...");
await CancelSpotInstanceRequest(ec2Client, requestId);
// Terminate the Spot Instance that's running.
Console.WriteLine("Terminating the running Spot Instance...");
await TerminateSpotInstance(ec2Client, requestId);
Console.WriteLine("Done. Press any key to exit...");
Console.ReadKey(true);
}
//
// Method to create a Spot Instance request
private static async Task<SpotInstanceRequest> CreateSpotInstanceRequest(
IAmazonEC2 ec2Client, string amiId, string securityGroupName, InstanceType instanceType, string spotPrice, int instanceCount) {
var launchSpecification = new LaunchSpecification{
ImageId = amiId,
InstanceType = instanceType };
launchSpecification.SecurityGroups.Add(securityGroupName);
var request = new RequestSpotInstancesRequest{
SpotPrice = spotPrice,
InstanceCount = instanceCount,
Amazon EC2
LaunchSpecification = launchSpecification };
RequestSpotInstancesResponse result =
await ec2Client.RequestSpotInstancesAsync(request);
return result.SpotInstanceRequests[0];
}
//
// Method to get information about a Spot Instance request, including the status, // instance ID, etc.
// It gets the information for a specific request (as opposed to all requests).
private static async Task<SpotInstanceRequest> GetSpotInstanceRequestInfo(
IAmazonEC2 ec2Client, string requestId) {
var describeRequest = new DescribeSpotInstanceRequestsRequest();
describeRequest.SpotInstanceRequestIds.Add(requestId);
DescribeSpotInstanceRequestsResponse describeResponse =
await ec2Client.DescribeSpotInstanceRequestsAsync(describeRequest);
return describeResponse.SpotInstanceRequests[0];
}
//
// Method to cancel a Spot Instance request
private static async Task CancelSpotInstanceRequest(
IAmazonEC2 ec2Client, string requestId) {
var cancelRequest = new CancelSpotInstanceRequestsRequest();
cancelRequest.SpotInstanceRequestIds.Add(requestId);
await ec2Client.CancelSpotInstanceRequestsAsync(cancelRequest);
}
//
// Method to terminate a Spot Instance
private static async Task TerminateSpotInstance(
IAmazonEC2 ec2Client, string requestId) {
var describeRequest = new DescribeSpotInstanceRequestsRequest();
describeRequest.SpotInstanceRequestIds.Add(requestId);
// Retrieve the Spot Instance request to check for running instances.
DescribeSpotInstanceRequestsResponse describeResponse =
await ec2Client.DescribeSpotInstanceRequestsAsync(describeRequest);
// If there are any running instances, terminate them if( (describeResponse.SpotInstanceRequests[0].Status.Code == "request-canceled-and-instance-running")
|| (describeResponse.SpotInstanceRequests[0].State == SpotInstanceState.Active)) {
TerminateInstancesResponse response =
await ec2Client.TerminateInstancesAsync(new TerminateInstancesRequest{
InstanceIds = new List<string>(){
describeResponse.SpotInstanceRequests[0].InstanceId } });
foreach (InstanceStateChange item in response.TerminatingInstances) {
Console.WriteLine($"\n Terminated instance: {item.InstanceId}");
Console.WriteLine($" Instance state: {item.CurrentState.Name}\n");
} } } }
IAM
}
Additional considerations
• After you run the tutorial, it's a good idea to sign in to the Amazon EC2 console to verify that the Spot Instance request has been canceled and that the Spot Instance has been terminated.
Accessing AWS Identity and Access Management (IAM) with the AWS SDK for .NET
The AWS SDK for .NET supports AWS Identity and Access Management, which is a web service that enables AWS customers to manage users and user permissions in AWS.
An AWS Identity and Access Management (IAM) user is an entity that you create in AWS. The entity represents a person or application that interacts with AWS. For more information about IAM users, see IAM Users and IAM and STS Limits in the IAM User Guide.
You grant permissions to a user by creating a IAM policy. The policy contains a policy document that lists the actions that a user can perform and the resources those actions can affect. For more information about IAM policies, see Policies and Permissions in the IAM User Guide.
APIs
The AWS SDK for .NET provides APIs for IAM clients. The APIs enable you to work with IAM features such as users, roles, and access keys.
This section contains a small number of examples that show you the patterns you can follow when working with these APIs. To view the full set of APIs, see the AWS SDK for .NET API Reference (and scroll to "Amazon.IdentityManagement").
This section also contains an example (p. 149) that shows you how to attach an IAM role to Amazon EC2 instances to make managing credentials easier.
The IAM APIs are provided by the AWSSDK.IdentityManagement NuGet package.
Prerequisites
Before you begin, be sure you have set up your environment (p. 14). Also review the information in Setting up your project (p. 16) and SDK features (p. 48).
Topics
Topics