Introduction
One of the most popular services available on Amazon Web Services is EC2, which stands for Elastic Compute Cloud. EC2 makes it easy for developers and users to create and manage cloud-hosted virtual machines, also known as EC2 instances.
EC2 provides a web interface which makes it easy to spin up and work with VM instances, including configuration, authentication, connection, maintenance, storage, scaling, and more.
In addition to creating and working with the EC2 service through the web interface, AWS provides SDK's that allow VM operations to be performed directly from code.
In this article, we'll discuss using the Java SDK and API to create an EC2 instance, start and stop the instance, reboot it, back it up into an image, and restoring it from the backup.
Setup AWS Credentials for the Java SDK
Let's start by learning how to create a set of AWS credentials, which are required to access AWS and make API calls through the SDK. The easiest way to do this is to log into the AWS console and create a new IAM (Identity and Access Management) role.
Follow these steps to do this:
-
Log into the AWS Console.
-
Click on the Services menu in the top left of the screen, search for IAM, and click on the dropdown option that appears.
- Under the Security Status heading, expand the Create individual IAM users option and click the Manage Users button.
-
Click the Add user button.
-
Enter the user name for your new IAM user and check the box for Programmatic access.
-
Click the Next: Permissions button and then select Attach existing policies directly.
-
Type EC2 into the search box and in the results, check the box for AmazonEC2FullAccess.
-
Click the Next: Tags button, then click the Next: Review button.
-
Review the IAM user configuration and click the Create user button.
-
You'll be taken to a confirmation page, where you can copy out the Access key ID and Secret access key which are the credentials you'll use to access the AWS API through the Java SDK.
By default, the SDK will look up for the credentials in the Default credential profile file, which is a file typically located at ~/.aws/credentials
on your local machine. You'll need to create this file yourself and add the IAM credentials into it.
To configure this yourself, create the new file ~/.aws/credentials
and add the following contents, replacing the access key and secret key with the values from your newly created IAM user in the AWS console:
aws_access_key_id = YOUR_ACCESS_KEY_ID
aws_secret_access_key = YOUR_SECRET_ACCESS_KEY
Create a default region file for the AWS SDK to use by adding a new file called ~/.aws/config
with the following contents (you can replace the region with one closer to where your users live for optimal performance):
region = US_WEST_2
The local environment should now be configured for the AWS Java SDK to authenticate successfully.
Installing the SDK with Maven
If you're using Maven, add the following dependency to include the AWS Java SDK:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-ec2</artifactId>
<version>${version}</version>
</dependency>
Or, if you're using Gradle:
compile group: 'com.amazonaws', name: 'aws-java-sdk', version: '${version}'
Now, instead of just the EC2 dependency, you could use aws-java-sdk
, which is the entire SDK. There's a lot of dependencies in the entire SDK - 219, to be exact, so if you're only using EC2, there's no need to download them all.
Creating an EC2 Instance
The AWS Java SDK for EC2 provides several classes that can be used to create a new instance. These are located in the software.amazon.awssdk
library. These classes are:
- Region: Represents an AWS hosting region to perform the SDK operations in.
- Ec2Client: Used to set up and configure a client to connect to AWS EC2 over web services.
- InstanceType: Represents a VM instance type/size such as
T2.MICRO
. - RunInstancesRequest: Represents a web request for creating EC2 instances.
- RunInstancesResponse: Represents a web response from the AWS EC2 service after instance creation.
Let's see how we can use these to create an EC2 instance:
Region region = Region.US_WEST_2;
String amiId = "ami-0e34e7b9ca0ace12d";
Ec2Client ec2 = Ec2Client.builder()
.region(region)
.build();
RunInstancesRequest runRequest = RunInstancesRequest.builder()
.imageId(amiId)
.instanceType(InstanceType.T1_MICRO)
.maxCount(1)
.minCount(1)
.build();
RunInstancesResponse response = ec2.runInstances(runRequest);
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
Here, we set up a Region
to a region close to the end-users for optimal performance. If a Region
is not programmatically specified, the default region from the ~/.aws/config
is used.
Then, we've specified our AMI in a String. This is a unique identifier for the machine image we're using and can be obtained in the AWS Console.
With those two in place, we've instantiated an Ec2Client
object and set the region. After that, using the RunInstancesRequest
class, we've populated the information for a request.
The request is sent via the runInstances()
method and the response is packed in a RunInstancesResponse
instance.
After this, the instance can be seen in the AWS Console:
Let's now manipulate the instance we created, beginning with starting and stopping it.
Starting and Stopping an Instance
Building upon the classes used in the previous example, and in the same fashion, to send requests for starting and stopping of an instance, we have:
- StartInstancesRequest: Represents a web request for starting EC2 instances.
- StopInstancesRequest: Represents a web request for stopping EC2 instances.
Let's see how we can use these two classes to start and stop an EC2 instance:
Region region = Region.US_WEST_2;
String instanceId = "i-025dea8c69e83bb61";
Ec2Client ec2 = Ec2Client.builder()
.region(region)
.build();
StartInstancesRequest request = StartInstancesRequest.builder()
.instanceIds(instanceId)
.build();
ec2.startInstances(request);
StopInstancesRequest request = StopInstancesRequest.builder()
.instanceIds(instanceId)
.build();
ec2.stopInstances(request);
We've set the Region
and made note of our instance ID. Then, we've built an Ec2Client
, like last time.
Finally, we've formulated a StartInstancesRequest
with the instance ID and sent it via the startInstances()
method.
The StopInstancesRequest
is built the exact same way and is sent via the stopInstances()
method.
After starting or stopping an EC2 instance in this way, the new state of the instance should be visible in the AWS EC2 console.
For convenience, both the stopping and starting actions can be performed in a single reboot request.
Rebooting an Instance
In the same fashion, we're introduced to the RebootInstancesRequest
class:
- RebootInstancesRequest: Represents a web request for starting EC2 instances.
Let's see how we can construct a request to reboot an instance:
Region region = Region.US_WEST_2;
String instanceId = "i-025dea8c69e83bb61";
Ec2Client ec2 = Ec2Client.builder()
.region(region)
.build();
RebootInstancesRequest request = RebootInstancesRequest.builder()
.instanceIds(instanceId)
.build();
ec2.rebootInstances(request);
We've set the Region
and instanceId
and constructed an Ec2Client
.
Using the builder()
method of the RebootInstancesRequest
, we build a request with just the instanceId
.
The request is sent via the rebootInstances()
method, after which, the instance is rebooted.
Next, we'll look into automating the common task of backing up an existing EC2 instance to an AMI. We'll also discuss how to restore the image to a new EC2 instance.
Back up an Instance to an AMI (Amazon Machine Image)
As with the previous tasks, this one is taken care of with a request as well. To construct requests for backing up instances to images, we've got:
- CreateImageRequest: Represents a web request for creating a new AMI.
Let's see how we can use the CreateImageRequest
class to back up an image based on an existing instance:
Region region = Region.US_WEST_2;
String instanceId = "i-025dea8c69e83bb61";
Ec2Client ec2 = Ec2Client.builder()
.region(region)
.build();
CreateImageRequest request = CreateImageRequest.builder()
.instanceId(instanceId)
.name("newimage")
.build();
ec2.createImage(request);
After creating a new AMI from an existing EC2 instance in this way, the new AMI will be visible in the IMAGES > AMIs link on the right sidebar of the EC2 console.
Restore an Instance from an AMI
Luckily, restoring this AMI to create a new instance is very easy since we already learned how to create a new EC2 instance in the first example of this article.
All we need to do is replace the string amiId
(which we originally found from the desired AMI in the AWS console) with the AMI ID from the new custom AMI that we created:
Region region = Region.US_WEST_2;
String amiId = "created_ami";
Ec2Client ec2 = Ec2Client.builder()
.region(region)
.build();
RunInstancesRequest runRequest = RunInstancesRequest.builder()
.imageId(amiId)
.instanceType(InstanceType.T1_MICRO)
.maxCount(1)
.minCount(1)
.build();
RunInstancesResponse response = ec2.runInstances(runRequest);
This will allow us to use our custom AMI as a template for creating the new EC2 instance instead of the out-of-the-box AWS AMI from their marketplace.
Conclusion
In this article, we discussed how to set up and configure the AWS SDK for Java, specifically for the EC2 service.
We covered the setup of credentials for AWS SDK authentication and adding required dependencies using Maven. We also detailed the Java code for some common EC2 operations such as creating a new instance, stopping/starting the instance, rebooting the instance, and backing up/restoring the instance from an AMI.
About the Author
This article was written by Jacob Stopak, a software developer and consultant with a passion for helping others improve their lives through code. Jacob is the author of the Baby Bitcoin Guidebook for Developers, a book that dives into Bitcoin's code to help curious developers understand how Bitcoin works under the hood.