The EC2 service provides API operations for managing the lifecycle of your instances. We will start by looking at how you can terminate your running instances; it is wise to know how to do this before you start launching instances that will incur fees for every hour they run.
The TerminateInstances operation shown in Table 5-10 terminates one or more instances running in your EC2 account. An instance can be terminated multiple times without any ill effects.
Table 5-10. TerminateInstances request parameters
Parameter Name | Value | Required? |
---|---|---|
Action | TerminateInstances | Yes |
InstanceId (Indexed) | The identifiers of one or more instances to terminate | Yes |
Here is an XML document returned by the operation:
<TerminateInstancesResponse xmlns='http://ec2.amazonaws.com/doc/2007-08-29/'> <instancesSet> <item> <instanceId>i-ec43a885</instanceId> <shutdownState> <code>32</code> <name>shutting-down</name> </shutdownState> <previousState> <code>16</code> <name>running</name> </previousState> </item> </instancesSet> </TerminateInstancesResponse>
The response document returned by the operation includes a listing of the instances that were acted upon by the operation with information about the instance’s prior status and its status as a result of the TerminateInstances operation. Each item element in the XML document describes the status of one instance, Table 5-11 lists the contents of this element.
Table 5-11. TerminateInstancesResponseInfoType element
Element Name | Description |
---|---|
instanceId | The identifier of the instance |
shutdownState | The status of the instance after the termination
operation, represented as status name and code values. The instance may have
any of the following status values:
|
previousState | The status of the instance before the termination
operation, represented as status name and code values, like the shutdownState
element |
Example 5-7 defines a method that terminates specific instances based on the identifier values provided. The method returns an array of the terminated instances with information about the previous and current status of each instance.
Example 5-7. Terminate instances: EC2.rb
def terminate_instances(*instance_ids) parameters = build_query_params(API_VERSION, SIGNATURE_VERSION, { 'Action' => 'TerminateInstances', },{ 'InstanceId' => instance_ids, }) response = do_query(HTTP_METHOD, ENDPOINT_URI, parameters) xml_doc = REXML::Document.new(response.body) instances = [] xml_doc.elements.each('//instancesSet/item') do |item| instances << { :id => item.elements['instanceId'].text, :state => item.elements['shutdownState/name'].text, :previous_state => item.elements['previousState/name'].text } end return instances end
Here is an example of how to use the method to terminate an instance:
irb> ec2.terminate_instances('i-ec43a885') => [{:previous_state=>"running", :state=>"shutting-down", :id=>"i-ec43a885"}]
The RunInstances operation shown in Table 5-12 launches one or more instances based on a particular AMI. You can specify the type of instance you wish to run—small, large, or extra large—and you must choose an AMI that is compatible with the instance's underlying 32-bit or 64-bit platform. You can start multiple instances with one request by specifying the minimum and maximum number of instances you wish to run.
When you launch your instances, you specify a number of properties that will determine how that instance behaves in the EC2 environment. You can instruct EC2 to run the instance within specific security groups and associate it with a set of keypair credentials you have created in your account. You can also provide arbitrary context data to the instance, which we will discuss in Instance Data” in Chapter 6. It is important to apply the settings you need at launch time, because you cannot change them afterwards.
Amazon limits most EC2 users to running no more than 20 instances at a time. If 20 instances will not be enough to meet your needs, contact Amazon to arrange for a higher limit.
Table 5-12. RunInstances request parameters
Parameter Name | Value | Required? |
---|---|---|
Action | RunInstances | Yes |
ImageId | The identifier of the AMI the instance will be based on. The AMI must be compatible with the platform of the instance you are launching. | Yes |
MinCount | The minimum number of instances to launch. If the
service cannot launch this number of instances, the operation
will fail with an InsufficientInstanceCapacity
error. | Yes |
MaxCount | The maximum number of instances to launch. The service will try its best to start this many instances but may launch fewer than this number. | Yes |
KeyName | The name of the keypair that will be applied to the instance. If you do not provide this parameter when you launch an AMI that uses key pair authentication to log in, you will not be able to log in to the instance(s) you start. | No |
SecurityGroup (Indexed) | Names of the network security groups the instance will belong to. Once an instance is started, its security group membership cannot be changed. | No |
InstanceType | The type of instance to launch: m1.small , m1.large , or m1.xlarge . If this parameter is not
provided, an m1.small
instance is started (see EC2 Instances” for
a description of the available instance types). | No |
UserData | User-specified data that is made available to the instance. See the section Instance Data” in Chapter 6 for a detailed explanation. | No |
AddressingType | The network addressing scheme the instance will use.
Only one addressing scheme is supported: public. | No |
Here is an XML document returned by the operation:
<RunInstancesResponse xmlns="http://ec2.amazonaws.com/doc/2007-08-29/"> <reservationId>r-a99171c0</reservationId> <ownerId>123456789012</ownerId> <groupSet> <item> <groupId>default</groupId> </item> </groupSet> <instancesSet> <item> <instanceId>i-3495795d</instanceId> <imageId>ami-2bb65342</imageId> <instanceState> <code>0</code> <name>pending</name> </instanceState> <privateDnsName/> <dnsName/> <reason/> <keyName>ec2-private-key</keyName> <amiLaunchIndex>0</amiLaunchIndex> <instanceType>m1.small</instanceType> <launchTime>2007-10-26T04:29:21.000Z</launchTime> </item> </instancesSet> </RunInstancesResponse>
The RunInstances operation will only return a limited amount of information in the response document, because many of the instance’s properties will not become known until the instance has finished launching.
The response document from the operation includes information about the reservation grouping in which the instances were launched, and the reservation itself contains a listing of the launched instances. Table 5-13 outlines the information that is available at the top level of the response document.
Table 5-13. ReservationInfoType element
Element Name | Description |
---|---|
reservationId | The identifier of the reservation in which the instances were started. |
ownerId | The AWS access key credential of the reservation’s owner. |
groupSet | Lists the security groups associated with the running instance. The security group names are listed as multipleitem/groupId elements. |
instancesSet | A listing of the instances started by this reservation, with each instance described by an item element of the RunningInstancesItemType (see dfTable 5-14). |
Table 5-14 gives a description of the information made available about each instance, as contained in the instancesSet/item elements:
Table 5-14. RunningInstancesItemType element
Element Name | Description |
---|---|
instanceId | The identifier of the instance. |
imageId | The identifier of the AMI on which the instance is based. |
instanceState | The current state of the instance, represented as a
named state and a code number. The instance may be:
|
privateDnsName | The private DNS name assigned to the instance to be used within the EC2 network. This element will only have a value when the instance is running. |
dnsName | The public DNS name assigned to the instance to be used from outside the EC2 network. This element will only have a value when the instance is running. |
reason | The reason for the most recent status change. This element is often empty. |
keyName | The keypair name associated with the instance, if any. If the instance does not have an associated keypair, this element will not be present. |
amiLaunchIndex | The launch index, a zero-based offset identifying a particular instance within a reservation group. |
productCodes | Lists the product codes associated with the AMI the instance is based on. If the AMI has no product codes, this element will not be present. Product codes are string values listed as multipleitem/productCode elements inside this element. The presence of a product code indicates that the image is a Paid AMI. |
instanceType | The type of the instance: m1.small , m1.large , or m1.xlarge. |
launchTime | A timestamp specifying when the instance was first launched in ISO 8601 format. |
Example 5-8 defines a method that starts EC2 instances and returns detailed information about the reservation and instances in a hash dictionary. The method has only one mandatory parameter; it specifies the AMI identifier on which the instances will be based. By default, the method launches a single instance.
Example 5-8. Run instances: EC2.rb
def run_instances(image_id, min_count=1, max_count=min_count, options={}) parameters = build_query_params(API_VERSION, SIGNATURE_VERSION, { 'Action' => 'RunInstances', 'ImageId' => image_id, 'MinCount' => min_count, 'MaxCount' => max_count, 'KeyName' => options[:key_name], 'InstanceType' => options[:instance_type], 'UserData' => encode_base64(options[:user_data]), 'AddressingType' => options[:addressing_type] },{ 'SecurityGroup' => options[:security_groups] }) response = do_query(HTTP_METHOD, ENDPOINT_URI, parameters) xml_doc = REXML::Document.new(response.body) return parse_reservation(xml_doc.root) end
Example 5-9 defines a method that parses XML elements of the type RunningInstancesItemType, which contain the details of instance reservations in EC2. A number of EC2 operations include this particular element in their response messages. By factoring the parsing code out into a separate method, we can easily reuse it elsewhere.
Example 5-9. Parse a reservation element: EC2.rb
def parse_reservation(elem) reservation = { :reservation_id => elem.elements['reservationId'].text, :owner_id => elem.elements['ownerId'].text, } group_names = [] elem.elements.each('groupSet/item') do |group| group_names << group.elements['groupId'].text end reservation[:groups] = group_names reservation[:instances] = [] elem.elements.each('instancesSet/item') do |instance| elems = instance.elements item = { :id => elems['instanceId'].text, :image_id => elems['imageId'].text, :state => elems['instanceState/name'].text, :private_dns => elems['privateDnsName'].text, :public_dns => elems['dnsName'].text, :type => elems['instanceType'].text, :launch_time => elems['launchTime'].text } item[:reason] = elems['reason'].text if elems['reason'] item[:key_name] = elems['keyName'].text if elems['keyName'] item[:index] = elems['amiLaunchIndex'].text if elems['amiLaunchIndex'] if elems['productCodes'] item[:product_codes] = [] elems.each('productCodes/item/productCode') do |code| item[:product_codes] << code.text end end reservation[:instances] << item end return reservation end
We can now start an instance based on a public AMI. We will start a single instance based on the “Getting Started” AMI provided by Amazon, which has the identifier ami-2bb65342. We will configure the instance to use the keypair called “ec2-private-key,” which we created earlier, and for which we have the corresponding private key file.
# Set the key_name option to the value 'ec2-private-key' irb> opts = {:key_name => 'ec2-private-key'} # Launch a single instance of the AMI 'ami-2bb65342' irb> instances = ec2.run_instances('ami-2bb65342', 1, 1, opts) {:instances=> [{:state=>"pending", :image_id=>"ami-2bb65342", :public_dns=>nil, :key_name=>"ec2-private-key", :launch_time=>"2007-10-26T07:07:02.000Z", :id=>"i-7641aa1f", :index=>"0", :reason=>nil, :type=>"m1.small", :private_dns=>nil}], :owner_id=>"123456789012", :groups=>["default"], :reservation_id=>"r-04a44b6d"}
The instance will take a little while to start and enter the running state. To monitor the status of the instance, we will use the DescribeInstances operation, which we will discuss next.
Once the instance has entered the running
state, and it has had enough time to
boot the operating system and start the Secure Shell daemon service,
we will be able to log in to the instance and take a look around. We
will discuss the login process shortly, in the section Log In to an Instance.”
The DescribeInstances operation outlined in Table 5-15 lists the instances that are currently running in your EC2 account or those that were terminated within the last hour or so. The listing contains detailed information about each of these instances, and it can be filtered to include only the specific instances you are interested in.
Table 5-15. DescribeInstances request parameters
Parameter Name | Value | Required? |
---|---|---|
Action | DescribeInstances | Yes |
InstanceId (Indexed) | A list of instance IDs to filter by. If this parameter is included, only instances with these IDs will be listed. If this parameter is not included, all your instances will be listed. | No |
Here is an XML document returned by the operation:
<DescribeInstancesResponse xmlns='http://ec2.amazonaws.com/doc/2007-08-29/'> <reservationSet> <item> <reservationId>r-77a54a1e</reservationId> <ownerId>123456789012</ownerId> <groupSet> <item> <groupId>default</groupId> </item> </groupSet> <instancesSet> <item> <instanceId>i-ec43a885</instanceId> <imageId>ami-2bb65342</imageId> <instanceState> <code>16</code> <name>running</name> </instanceState> <privateDnsName>domU-12-31-91.z-1.compute-1.internal</privateDnsName> <dnsName>ec2-67-202-5-75.z-1.compute-1.amazonaws.com</dnsName> <reason/> <amiLaunchIndex>0</amiLaunchIndex> <instanceType>m1.small</instanceType> <launchTime>2007-10-26T04:29:21.000Z</launchTime> </item> </instancesSet> </item> </reservationSet> </DescribeInstancesResponse>
The response document includes a listing of the reservations in which the instances were launched, and each reservation includes a listing of the instances that were started within that reservation. These XML data structures were described in detail in the section Starting Instances.”
Example 5-10 defines a method that
lists your running or recently terminated instances. The method takes
advantage of the parse_reservation
method we have already defined.
Example 5-10. Describe instances: EC2.rb
def describe_instances(*instance_ids) parameters = build_query_params(API_VERSION, SIGNATURE_VERSION, { 'Action' => 'DescribeInstances', },{ 'InstanceId' => instance_ids }) response = do_query(HTTP_METHOD, ENDPOINT_URI, parameters) xml_doc = REXML::Document.new(response.body) reservations = [] xml_doc.elements.each('//reservationSet/item') do |elem| reservations << parse_reservation(elem) end return reservations end
Because we recently started an instance, we can perform a listing and check whether that instance has started up.
irb> listing = ec2.describe_instances [{:instances=> [{:state=>"running", :image_id=>"ami-2bb65342", :public_dns=>"ec2-67-202-4-222.z-1.compute-1.amazonaws.com", :key_name=>"ec2-private-key", :launch_time=>"2007-10-26T07:07:02.000Z", :id=>"i-7641aa1f", :index=>"0", :reason=>nil, :type=>"m1.small", :private_dns=>"domU-12-31-36-00-0A-54.z-1.compute-1.internal"}], :owner_id=>"123456789012", :groups=>["default"], :reservation_id=>"r-04a44b6d"}]
We can see from the details returned by the listing that our
instance is now in the running
state, and the public and private DNS names have been assigned. The
instance is running in the default
security group, and it has been associated with our keypair named
“ec2-private-key.” Everything is looking good, so it is time to log
in.