February 13, 2016

AWS – VPCs & Subnets, routing tables, and Internet Gateways

In order for an instance to have internet access, you will need the following:


You can find all my latest posts on medium.
  • An internet gateway attached to your vpc
  • The internet gateways is associate by an entry in your route table. Note, your VPC can have multiple route tables.
  • This route table must be attached to your subnet, which consequently makes your subnet into a public subnet.
  • The subnet’s attached network acl, must have the appropriate inbound/outbound firewall rules in place to allow the desired traffic through
  • your instance must have a public or Elastic IP address
  • ensure your security groups and network ACLs allows the relevant traffic to go through
  • setting inside instances are correct, e.g.:
    • firewalld is configured
    • network service is running
    • services are running and listening on ports.



First off, a vpc is a way to group your resources. These resources can be in different AZ. Hence a vpc isn’t attached to particular AZ.

Your AWS accounts comes with pre-created vpc, called “default”:

However in order to create a new vpc, you need to provide the following info:

The description in the cidr block is:

For my example, let’s say I create a vpc with the following details:


  • Name tag:  cb1
  • CIDR block:
  • Tenancy: default  (the only other option in the dropdown list is “dedicated”)

In this scenario, according t  the full range of ip address available is:

I.e., the subnet mask of 16, locked down the first to parts “10.0”.

After we have created the vpc, we can view it’s details:






Now we can attach 1 or more subnets to this VPC. To create a new subnet, you need to provide the following info:

Also here’s the help info for the CIDR block field:


Notice here that a subnet is associated to a particular AZ, and must also belong to an existing VPC. So in my case I created a subnet with the following details:

  • Name tag: public-subnet
  • VPC: cb1
  • Availability Zone: us-east-1a
  • CIDR block:

Here the subnet’s CIDR range must fall within the VPC, wider CIDR range. In this instance, the range for the cb1’s range is So the subnet’s mask of falls within this range as shown here:


After creating this subnet, we now have:

Any EC2 instance that is connected to this subnet, will have an internal ip address which ranges between


Now let’s create another subnet for this vpc, which is also in the same AZ. This time with the following details:

The ip range for this subnet works out to be:

This ip range again falls within the vpc range.

After creating this subnet we now end up with:


Notice that both subnets inherited the vpc’s  “route table”.

Note, each newly created route table comes prelisted with a default route, referred to as the local route. This local route has an IP range that covers the entire vpc IP range. This is what makes it possible for each EC2 instance in your VPC to automatically be able to communicate with each other.

In order make  a subnet into public subnet (i.e. be able to receive outside traffic), it needs to be connected to a route table, which in turn is attached to an  “internet gateway”:

This gateway is attached to the default VPC’s subnet’s routing table.


Source: Amazon

Now by default, when you create a new vpc,  a “main” (default) route table also get’s created with the following rule:

This is an example for a vpc with cidr block of This routing table automatically get’s assigned to any subnets that you create inside this vpc. This route allows routing of traffic from instance in one subnet to reach an instance in another subnet.




Now let’s create an internet gateway, to create a gateway, you just need to provide a name for the internet gateway:


Now we have ended up with:




Note, we already have an internet gateway, which by default is attached to the default vpc.

Next we need to attach our new gateway to our new vpc:


Now we end up with:


Note: A vpc is can only have up to 1 internet gateway attached to it at any one time.

Now we need to link our Interneet Gateway to our new vpc’s route table. Here’s how to create a route table:

As you can see, we simply have to give the route table a name and specify which vpc it belongs to. However we don’t need to do any of this because a route table was automatically created at the time of the vpc creation. I just allocated a name “cb1-route-table” to this route table:

This route table was automatically created at the time of the vpc’s creation. This route table was also automatically attached to both public-subnet, and private-subnet, at the time of both subnet’s creation.

Now we need to add a route to our route table that specifies that all data is allowed to go in/out via our new internet gateway:


So that we end up with:



However since both of our net subnets (private-subnet and public-subnets) are using the same route table:

It means that both subnets are public subnets, whereas we wanted “private-subnet” to be a private subnet (which can only recieve traffic from internal resources, e.g. from an ELB).

Before we make “private-subnet” private, we’ll first create the following:

  • EC2 instance, ensure that this instance is part of this new vpc
  • An ELB


Follow this guide to create an EC2 instance, also make sure to create the in our new vpc.

When creating the ELB, you need to attach it to our new vpc:

Note: I also opened up the http+https firewalls because my ec2 is going to act as a web server. We then sroll further down and only  attach  the public-subnet.

In the next section we select all the what ec2 instances that we want to send data traffic to:

{need to add a screenshot}









Also as part creating the elb, you have to specify which ec2 instance the elb should be attached to, i.e. send traffic to.

After you have created the elb, your elb has a url to access it with:

Which is connected to our instance:



At this point, you should be able to access your ec2 via it’s ip address:


Or the elb’s url:










At this point, you should be able to access your ec2 via it’s ip address:

Or the elb’s url:

Both of this is working because our ec2 instance is attached to the public via the elb, and via the subnet, private-subnet, which is still attached to a route table that is connected to an internet gateway.

We now want to close off direct access to our ec2 instance (i.e. ip based access), so that it can only be accessible via the ELB’s url. To do this we need to first create a new route table that isn’t attache to an internet gateway:

Now let’s confirm that our route table isn’t attached to an internet gateway:

Note, the public route table looks like this:

Now let’s switch our private-subnet to use this new private route-table:

So now we have:

Now when we try to access via ip address we get:

But it still works via the elb’s url: