AWS SDK for JavaでEC2のインスタンスを上げたり落としたり取得したり


覚書です。
あまりサンプルコードを探せなかったので、書きました。

# 前提環境

* Java7
* AWS SDK for Java 1.6.11

# AWS SDK for JavaでEC2のインスタンスを上げたり落としたり取得したり

面倒臭かったのでJunitとして書いています。


```java:EC2SampleTest.java
package com.amazonaws.samples;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
import com.amazonaws.regions.Region;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.ec2.AmazonEC2;
import com.amazonaws.services.ec2.AmazonEC2Client;
import com.amazonaws.services.ec2.model.DescribeInstanceStatusRequest;
import com.amazonaws.services.ec2.model.DescribeInstanceStatusResult;
import com.amazonaws.services.ec2.model.DescribeInstancesRequest;
import com.amazonaws.services.ec2.model.DescribeInstancesResult;
import com.amazonaws.services.ec2.model.Filter;
import com.amazonaws.services.ec2.model.Instance;
import com.amazonaws.services.ec2.model.InstanceStateName;
import com.amazonaws.services.ec2.model.InstanceStatus;
import com.amazonaws.services.ec2.model.InstanceType;
import com.amazonaws.services.ec2.model.Reservation;
import com.amazonaws.services.ec2.model.RunInstancesRequest;
import com.amazonaws.services.ec2.model.RunInstancesResult;
import com.amazonaws.services.ec2.model.TerminateInstancesRequest;

public class EC2SampleTest {

	
	/** EC2クライアント */
	AmazonEC2 ec2;
	
	/**
	 * EC2クライアントをpropertiesファイルから作成します。
	 */
	@Before
	public void setupEC2Client() {
		ec2 = new AmazonEC2Client(new ClasspathPropertiesFileCredentialsProvider());		
		ec2.setRegion(Region.getRegion(Regions.AP_NORTHEAST_1));
		System.out.println("client has been setup");
	}
	
	/**
	 * テスト実行後起動中のすべてのEC2インスタンスを削除します
	 */
	@After
	public void terminateEC2Instance() {		
		DescribeInstancesResult describeInstances = ec2.describeInstances(
				new DescribeInstancesRequest()
						.withFilters(
								new Filter()
								.withName("instance-state-name")
								.withValues(
										InstanceStateName.Running.toString()
								)
						)
				);
		
		List<String> instances = new ArrayList<String>();
		
		for (Reservation res : describeInstances.getReservations()) {
			for (Instance i : res.getInstances()) {
				if(InstanceStateName.Running.toString().equals(i.getState().getName())) {
					instances.add(i.getInstanceId());
				}
			}
		}
		System.out.println(instances);
		
		if(!instances.isEmpty()) ec2.terminateInstances(new TerminateInstancesRequest(instances));
	}
	
	/**
	 * 新しいEC2インスタンスをAMIからt1microに作成します。
	 * @throws Exception
	 */
	@Test
	public void createNewEC2Instance() throws Exception {

		//EC2インスタンスの設定
		RunInstancesRequest request = new RunInstancesRequest()			
			.withImageId("ami-0d13700c") //amazon-linux 64bit
			.withMaxCount(1)
			.withMinCount(1)
			.withSecurityGroups("default")
			.withKeyName("demo-key")
			.withInstanceType(InstanceType.T1Micro);
		
		//インスタンスの作成リクエストを発行
		RunInstancesResult result = ec2.runInstances(request);
		
		//作成したインスタンスIDを取得
		List<String> list = new ArrayList<String>();
		for(Instance instance : result.getReservation().getInstances()) {
			list.add(instance.getInstanceId());
		}
		
		System.out.println(list);
		
		boolean pending = true;
		
		//作成したインスタンスのStateがrunningになるまで待機
		while(pending) {
			DescribeInstancesResult dir = ec2.describeInstances(new DescribeInstancesRequest().withInstanceIds(list));
			
			List<Reservation> reservations = dir.getReservations();
			
			for (Reservation reservation : reservations) {
				List<Instance> instances = reservation.getInstances();
				
				for (Instance instance : instances) {
					System.out.println(instance.getState());
					
					if(InstanceStateName.Running.toString().equalsIgnoreCase(instance.getState().getName())) {
						pending = false;
					}
				}
			}
			
			Thread.sleep(1000);
		}	
		
		//状態を再取得
		DescribeInstanceStatusResult instanceStatuses = ec2.describeInstanceStatus(new DescribeInstanceStatusRequest().withInstanceIds(list));
		
		List<InstanceStatus> statuses = instanceStatuses.getInstanceStatuses();
		
		//ステータスがrunningになっているかassert
		for (InstanceStatus instanceStatus : statuses) {
			System.out.println(String.format("%s %s", instanceStatus.getInstanceId(), instanceStatus.getInstanceState()));
			assertThat(instanceStatus.getInstanceState().getName(), equalTo(InstanceStateName.Running.toString()));
		}
	}
}

```

EC2Clientに渡している`ClasspathPropertiesFileCredentialsProvider`はclasspathルートにおいてある`AwsCredentials.properties`から、apiの認証に必要な`AWS Access Key ID`と`Secret Access Key`を設定しています。

```properties:AwsCredentials.properties
# Fill in your AWS Access Key ID and Secret Access Key
# http://aws.amazon.com/security-credentials
accessKey= Your AWS Access Key ID
secretKey= Your Secret Access Key

```


もっとスッキリ書きたい…