AWS EC2 Exercise: Set up an EC2 Instance with the Command Line

Bradley Goldsmith
Strategio
Published in
9 min readDec 23, 2022

In this blog, I will explain how to create an AWS EC2 instance and access it via SSH entirely using the command line.

Background

Virtual Machines (VMs) are incredible tools that allow us to set up an isolated, customized computer for whatever purpose we desire — running a web server, setting up a development environment, or simply trying out other operating systems.

Why use EC2? With an Amazon Web Services (AWS) account, you can use their Elastic Compute Cloud (EC2) service to create virtual machines on Amazon’s servers, without needing to make any investment in hardware. That’s a huge advantage, especially if you are an Enterprise that uses a lot of computing resources.

Why use the command line? AWS provides a nice GUI for using cloud services, but it requires your attention. You need to click through menus and type in information to get the resource you need. The Command Line Interface (CLI) allows you to do everything you can do in the AWS Console with powerful bash commands. If you find yourself doing a particular process repeatedly (like spinning up an EC2 instance), you can write a bash script that automates the process, saving you a lot of potential time. Understanding the CLI is essential to this.

Prerequisites

  • An AWS account.
  • EC2 basics — it is best for you to have launched an EC2 from the AWS Management Console before.
  • Familiarity with Linux command line basics.
  • A terminal with the AWS Command Line Interface is installed and configured to your account.

Overview

Before we dive in, let’s go over what we will need to accomplish:

  • Create a key pair for our EC2 instance. This is needed for the Secure Shell (SSH) protocol.
  • Create a security group with ingress rules for SSH.
  • Query AWS for information: our VPC id, subnet id, and the desired AMI id.
  • Launch the instance. We will use the information we queried AWS for to make sure we set it up properly.
  • SSH into the instance. We can use the key we created in step one.
  • Terminate the instance and clean up our work.

Note that when running the commands, any parameter value in brackets <> should be changed to a value that makes sense for you.

Things can get a little confusing in the shell interface, so I recommend having two windows open: one terminal and one empty text file. The terminal is where we will run our commands and read the output. Use the empty text file to store important information that is outputted to the terminal, such as resource IDs, resource names, and IP addresses. And please note that at any time you can open up the AWS Management console and see how the changes you make through the CLI are reflected in the console’s GUI.

  1. Make a key pair with the ‘create-key-pair’ command.

EC2 has the ability to easily create RSA or ED25519 key pairs. Navigate to a directory where you would like to store your key pair, and run the following command (Note that anything in brackets <> you should change to a value that makes sense for you, e.g., the — — key-name property).

aws ec2 create-key-pair \
--key-name <medium-post-pk> \
--key-type rsa \
--key-format pem \
--query "KeyMaterial" \
--output text > <medium-post-pk>.pem
  • — — key-name: name for your public key. The public and private keys can have different names, but for ease of use, give them the same name.
  • — — output text > my-medium-key-pair.pem: this tells the shell to redirect its output to a file named “my-medium-kp.pem”. This file stores the private key.

See the AWS EC2 user guide for more information on this command.

2. Get your VPC ID by querying AWS with the ‘describe-vpcs’ command. (optional)

EC2 instances are launched inside Virtual Private Clouds. You will need to tell AWS EC2 where you are launching your EC2 using the VPC’s id.

Run the “describe-vpcs” command with these parameters to query AWS about which VPCs exist under your profile. Specify the profile you are using (here I am using my Admin profile) and the region you are working in (I use us-east-1). You will use the profile and region values again in this tutorial, so be consistent from here on!

aws ec2 describe-vpcs \
--profile <Administrator> \
--region <us-east-1>

This will output a JSON object to the terminal with the result of the query. Copy down the value for “VpcId” for the desired VPC. Note that if you do not specify a VPC when launching an instance (later on), your account’s default VPC will be used.

Example output

3. Create a security group with the‘create-security-group’ command. (optional)

We will need to specify a security group for our EC2 instance. In particular, we want to create and configure a security group to allow SSH access to the virtual machines in the group. The name and description are up to you. You can skip this step and the following if you already have a security group (you will just need its sg-id).

aws ec2 create-security-group \
--group-name <MediumGuideSG> \
--description "<security group for medium ec2 tutorial>" \
--vpc-id <use the vpc id from the step 2> \
--region us-east-1 \
--profile Administrator

This will output a JSON object representing the group to the shell. Copy the value for“GroupId”.

4. Create an ingress rule for the Security Group to allow SSH traffic with the ‘authorize-security-group-ingress’ command. (optional)

We need to configure our newly created Security Group to allow clients to SSH traffic on port 22. If this is mysterious to you, you can read more about the SSH network protocol, but you don’t need to know anything to continue with this guide.

It is easy to configure a security group in such a way with the CLI. Run the following command:

aws ec2 authorize-security-group-ingress \
--group-id <sg id> \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0 \
--region us-east-1 \
--profile Administrator

The result of this command is a JSON object of the newly created rule.

Note the values for the — —protocol, — —port, and — —cidr flags. These values configure the SG to allow SSH traffic from anywhere on port 22 of any EC2 instance in that SG.

Example result of authorize-security-group

5. Get your Subnet’s ID by querying AWS with the ‘describe-subnets’ command. (optional)

An EC2 instance is launched inside of a subnet in a Virtual Private Cloud. You will need to tell AWS EC2 where you are launching your EC2 in that cloud using a subnet id. For our purposes, this subnet must be public. If you do not specify a subnet when launching an instance (later on), AWS will choose one of your account’s default VPC subnets.

Use the following command to query AWS for a list of all of the Administrator profile’s subnets in the us-east-1 availability zone and region, filtered so that it shows only subnets that are in your VPC:

aws ec2 describe-subnets \
--filters "Name=vpc-id,Values=<your VPC id>" \
--region us-east-1 \
--profile Administrator

Look through the query result for a public subnet that fits your needs, and copy it down. The subnet must be public (i.e., needs to be routable to an Internet Gateway) so that we can access our EC2 instance via SSH over the internet. Press ‘q’ to quit the JSON view at any time.

On my own machine, I used one of the default subnets, which are public. Your query result may look different from mine, and you must confirm that your subnet is public.

6. Determine the ID of the AMI you want to use.

When we launch the instance, we will need to specify an Amazon Machine Image (AMI) as the template for the EC2 instance by giving an AMI ID. Recall that an image in this context is a virtualized machine state. I will be using the Amazon Linux machine image whose ID is ami-0b0dcb5067f052a63. I recommend you use the same.

There are multiple ways to determine the AMI ID of your desired AMI. The simplest would be to open the AWS Management Console, navigate to the EC2 service‘s launch wizard, and copy down the ID of what you want from the menu.

Simply select the machine you want and copy down the string starting with “ami-”.

But in the spirit of this guide, I should tell you how you could obtain an AMI ID from the command line. You can query AWS for these AMI IDs by running the describe-images ec2 command. Read about the command here, and try it yourself. A sample query might look like the following:

aws ec2 describe-images \
--owners amazon \
--filters "Name=name,Values=amzn2-ami-hvm-2.0.????????.?-x86_64-gp2" "Name=st\
ate,Values=available" \
--query "reverse(sort_by(Images, &CreationDate))[:1].imageID" \
--output text \
--region us-east-1 \
--profile Administrator

7. Choose an instance type.

Just as the AMI describes the software and OS of an EC2 instance, the Instance Type describes the hardware — the number of processors, RAM, and memory for the machine. EC2 requires us to specify an instance type. I will use the free t2.micro instance type, which has 1 CPU and 1 GiB memory.

Read up on all the different instance types here. Select one that fulfills your needs, and be mindful of the different pricing rates. All we need to run our command is the instance type’s name.

8. Launch your instance with the ‘run-instances’ command.

Now it’s finally time to put it all together and launch our instance! Make sure you have your:

  • Instance type
  • AMI ID
  • Subnet ID
  • Security Group ID
  • Public/private key pair (specifically, its name)

Then run the following command, replacing the fields with your own data.

aws ec2 run-instances \
--image-id <ami-0b0dcb5067f052a63> \
--count 1 \
--instance-type t2.micro \
--key-name <webserver-kp> \
--security-group-id <sg id> \
--subnet-id <subnet id> \
--region us-east-1 \
--profile Administrator

This will result in a JSON object describing all of your current EC2 instances. Note that the status for the just-launched instance is “pending”.

Shell output after running aws ec2 run-instances command. Note the instance is currently “pending” and not yet “running”.

Note the InstanceId. This is the id of the new instance you just launched. Save this ID somewhere safe for use in the next steps.

9. Confirm your instance is running with the ‘describe-instances’ command.

Wait a little while for the instance to begin running — a couple of minutes at most. You can confirm that the instance is running by querying AWS with the following command:

aws ec2 describe-instances \
--instance-ids <Instance ID from step 8> \
--region us-east-1 \
--profile Administrator

The state should now say “running.” Notice also that the instance now has a public DNS name and public IP address, which it did not when it was in the “pending” state.

10. Connect to the instance with SSH.

Now that our instance is running, it’s time to access it via SSH!

Navigate to the directory where you stored the .pem file in step 1. We need to run the SSH command from that folder.

Go back to step 9 and grab either the public DNS name or the public IP address, which will be used to formulate the SSH request. I decided to formulate the request as an ec2-user, though you may change that as well.

ssh -i <keyname> ec2-user@<PUBLIC IP ADDRESS OR PUBLIC DNS NAME>

In my particular case, the command looks like this:

ssh -i webserver-kp.pem ec2-user@ec2-3-93-247-91.compute-1.amazonaws.com

Press enter, and you should now be in your EC2 instance’s shell! Welcome to your virtual machine!

If SSH raises an error about the key pair, make sure that the .pem file has the proper permissions set on it. Run the following command to set permissions:

chmod 400 <keyname.pem>

11. Terminate the instance with ‘terminate-instance’ and tear it all down.

Now it’s time to tear it all down. Run the following command to terminate your instance and delete it. Use the following command:

aws ec2 terminate-instances \
--instance-ids <instance id> \
--region us-east-1
--profile Administrator

This will return a (wait for it) JSON object detailing which instances are being terminated and their statuses (they go from running to shutting down, and then to terminating). You can confirm that everything was cleaned up properly by rerunning the describe-instances command or by logging in to the AWS Management Console and checking that the instance was deleted.

--

--