Launch, Stop, and Terminate AWS EC2 Instances with Node.js

When provisioning and decommissioning Amazon servers in the cloud, we can use the console or we can use code. We’re programmers, right? Well let’s follow DevOps principles and embrace our coding capabilities to deploy AWS EC2 infrastructure in a scalable way.

Let’s build!

Table of Contents:

Assumptions before jumping in:

OK, now that we are all set to start building, let’s get to it!

Install the AWS SDK

npm install aws-sdk

That was easy! Onward and upward, now the cool parts!

Launching an AWS EC2 Instance

First let’s launch an EC2 instance. Here is the full block of code that will get you there!

// load the SDK for JavaScript
const AWS = require('aws-sdk');

// set the region
AWS.config.update({region:'us-west-2'});

// create an ec2 object
const ec2 = new AWS.EC2({apiVersion: '2016-11-15'});

// setup instance params
const params = {
  ImageId: 'ami-#####',
  InstanceType: 't2.micro',
  KeyName: 'My-Key-Pair',
  MinCount: 1,
  MaxCount: 1,
  SubnetId: 'subnet-#####',
  TagSpecifications: [
    {
      ResourceType: "instance",
      Tags: [
        {
          Key: "Name",
          Value: "Node SDK EC2 Creation"
        }
      ]
    }
  ]
};

ec2.runInstances(params, function(err, data) {
  if (err) {
    console.log(err, err.stack); // an error occurred
  } else {
    console.log(data);           // successful response
  }  
});

OK, let’s take a moment to break down some of what we are doing. I will cut the code into chunks and explain each section. Starting from the top…

// load the SDK for JavaScript
const AWS = require('aws-sdk');

// set the region
AWS.config.update({region:'us-west-2'});

// create an ec2 object
const ec2 = new AWS.EC2({apiVersion: '2016-11-15'});

First is the setup. What we initially do is load the amazon sdk i.e. aws-sdk. Next we set our region. As you probably know, there is a wide array of AWS regions. I chose the west coast (Oregon), but there are numerous regions you can choose from. We also create a new ec2 service object which we utilize later in the code. Cool? Cool!

Next we setup the instance parameters. This is information specific to our EC2 instance(s).

Note: The ImageId and SubnetId are placeholders. These values are the ones you obtained from here and here.

// setup instance params
const params = {
  ImageId: 'ami-#####',
  InstanceType: 't2.micro',
  KeyName: 'My-Key-Pair',
  MinCount: 1,
  MaxCount: 1,
  SubnetId: 'subnet-#####',
  TagSpecifications: [
    {
      ResourceType: "instance",
      Tags: [
        {
          Key: "Name",
          Value: "Node SDK EC2 Creation"
        }
      ]
    }
  ]
};

There are a few things I’d like to point out here. First is the ImageId, this is a unique identifier that is particular to the region that you can obtain from AWS, which specifies the server instance you want to use. Second is the InstanceType. As we are targeting “free-tier” this is set to t2.micro.

Note: be sure to check your region and setup to ensure you are using free-tier. Do not send your bills here!

The KeyName is the key pair you have setup.

MinCount is the minimum number of instances to launch, while MaxCount is (yup, you guessed it) the maximum number of servers to launch. Both of these must be set to 1 or greater. For more details, go here.

I am also setting the ID of the subnet to launch the instance into.

You will notice I added the TagSpecifications to set a tag, which lets me know I created this instance via code. I find this helpful when checking that my code worked!

Finally, I deploy the instance by calling runInstances with the specified params and pass in a callback function to handle the response.

ec2.runInstances(params, function(err, data) {
  if (err) {
    console.log(err, err.stack); // an error occurred
  } else {
    console.log(data);           // successful response
  }  
});

Do note that you can also utilize promises as well instead of callbacks, as seen here. My examples follow the standard callback syntax utilized in the AWS API documentation.

Now that all the details are outlined, let’s launch! Type the following in the command line to run the example:

node ec2-launch-instances.js

This will output a lot of information from the creation of this instance. To continue on and stop (then terminate) this instance, be sure to grab the InstanceId of the EC2 server we just created!

Stopping an AWS EC2 Instance

Great, so we created an instance, now what? Well, one thing we can do is stop said instance (or instances). As you can see, most of the code is similar to deploying an instance.

// load the SDK for JavaScript
const AWS = require('aws-sdk');

// set the region
AWS.config.update({region:'us-west-2'});

// create an ec2 object
const ec2 = new AWS.EC2({apiVersion: '2016-11-15'});

// setup instance params
const params = {
  InstanceIds: [
    'i-#####'    
  ]
};

ec2.stopInstances(params, function(err, data) {
  if (err) {
    console.log(err, err.stack); // an error occurred
  } else {
    console.log(data);           // successful response
  }  
});

The key difference (outside of the call to stopInstances) is the params object, which takes an array of InstanceIds to stop. So, to stop the instance we started, we must add the InstanceId into the params object.

Once you have entered the instance id, type the following to stop the instance:

node ec2-stop-instances.js

Boom, instance stopped!

Terminating an AWS EC2 Instance

So, we stopped the instance, we are done, right? Well, not quite. Launching an instance provisions our server, but the server is still there when stopped. To fully decommission, we need to terminate the instance.

// load the SDK for JavaScript
const AWS = require('aws-sdk');

// set the region
AWS.config.update({region:'us-west-2'});

// create an ec2 object
const ec2 = new AWS.EC2({apiVersion: '2016-11-15'});

// setup params
const params = {
  InstanceIds: [
    'i-#####'    
  ]
};

ec2.terminateInstances(params, function(err, data) {
  if (err) {
    console.log(err, err.stack); // an error occurred
  } else {
    console.log(data);           // successful response
  }  
});

As you can see, most of this code is pretty similar to our previous examples and astute readers are already figuring ways to refactor the code to make it more maintainable, economic, and efficient.

Similar to when we stop the instance, we add the target instance id to the params object.

Once we are ready to terminate, we type the following:

node ec2-terminate-instances.js

And just like that, we have destroyed our instance.

Conclusion

In this article, we have utilized Node.js to create, stop, and terminate Amazon EC2 instances. We are now that much closer to automating the deployment of our servers, versioning our infrastructure, embracing DevOps principles, and leveraging IAC to scale and accelerate our organization. Ain’t no stopping us, let’s keep pushing!

Check out the additional resources below and happy coding!

Additional Resources

Updated: