So you may be wondering why I'm creating this tutorial, when I already have a setup in Azure (see blog entry here)? Well to keep things simple, I have been studying the AWS Solutions Architect certification for a while now, but ever since my organization decided to put more emphasis on getting Azure up and running as an option for our customers, I put my AWS studies on the back burner.

I have come to the realization that I have been postponing this certification for so long that I'm starting to forget what I covered in the past. While the new year is young, it's time to put a solid effort and setup a lab environment on AWS that mirrors my Azure lab. Oh and also get my AWS Solution Architect Associate certification in February!

Truth be told, the inspiration for the bastion host setup actually came from AWS themselves in this article. If you've read my previous blog post, where I set up a bastion/jump host in Azure, the main reason as to why I'm using one is security. Ssh to my app server is restricted to the internal network; ssh access from a public IP is denied on my application servers. Only my bastion also known as jump host is allowed to have ssh access from a public IP.


Once again I have exposed port 22 to the public only on the bastion host. The standard web port (80) is open on the app server only. To do any tasks on the app server a management user needs to ssh to the bastion host and from there ssh to the app server. And like my example on Azure, to fully secure the bastion host it's highly recommended to use a VPN connection when connecting to the bastion host. However for this lab environment, we don't need to set one up.

Creating a VPC

To start this demo we'll create a completely new VPC. Mine will be named pafable-demo with a CIDR block of, leave the tenancy to default.  

Now jump down to subnets and let's create a subnet on the new VPC. If you've read my previous blog post, I'm not a fan of wasting IP so I went with a /24 subnet which gives us 256 addresses to play with (251 for AWS). I used CIDR block for my subnet and named it pafable-demo-sub.

After you have created the subnet, please create an internet gateway. Mine will be named pafable-demo-igw. This step is rather quick, as soon as the internet gateway is ready, select it and attach it to a your new VPC.

Then jump down to route tables and select the route table created for your new VPC. In here, create a route to the internet using the newly created internet gateway. A destination of and the target should be the new internet gateway. Save this route for now, we'll return to it later. This route will allow the app server to reach out to the internet.


Now comes the interesting part, peering is the magic that will allow both VPC's (default and pafable-demo) to communicate with each other. Go to Peering Connections and click on the blue button for "Create Peering Connection". Give your peering connection a name, mine is named default-to-pafable-demo, this is important so that I know exactly which VPCs are connected by this peering connection. I then set my new VPC ( pafable-demo ) as the requester and my default VPC as the accepter. After you have created the peering connection, do not forget to accept the connection!

Jump back into the Route Tables and let's edit the routes to allow traffic between the VPCs. As it stands, both VPCs don't know how to reach each other. Select the default VPC and then Edit Routes. In here, I'll create a route that says in order to get to the network use the peering connection. Likewise for my pafable-demo VPC, I'll create a route in order to reach the use the peering connection.

Creating the Bastion Host

For my example, I will be deploying the bastion host in the North Virginia region. I will be using Amazon Linux 2 AMI with a t2.micro instance type. Also I'll keep everything default on the bastion host. Default VPC, subnet and storage.

What will change is the security group setting. I will create a new security group with only ssh (port 22) allowed. Create a key pair and save it to your machine.

Creating App Host

The app host will be deployed in the same region as the bastion (N. Virginia). I will also be using Amazon Linux 2 AMI with a t2.micro instance type. However I will deploy this on the new VPC (pafable-demo). Step through the instance configuration and select the defaults until you get to the security group configuration.

In the security group page allow ssh to connect from the bastion server only. My bastion server's private IP is Along with ssh, add an entry for http to the public.

Once your two EC2 instances are up and running, ssh to the bastion server. To get to the app server you'll need the key pair on the bastion server. This is not an ideal situation and should never be used in a live production environment! However since this is a demo, I'll upload it to my bastion host. If you can connect to the app server, then you have successfully setup a bastion host to connect to an app server!


There was a lot in here to read so here is quick breakdown of what I just did to create a bastion host.

  1. Create a new VPC (pafable-demo)
  2. Create a new subnet in pafable-demo
  3. Create a new internet gateway in pafable-demo
  4. Setup a peering connection between the default VPC and pafable-demo
  5. Create routes in the default VPC's subnet to pafable-demo's subnet
  6. Create  a bastion host in the default VPC
  7. Create an app server on pafable-demo
  8. On the bastion server edit the security group so that it allows ssh from public
  9. On the app server edit the security group so that bastion host can ssh to it