Providing internet connectivity to the instance launched inside the Private Subnet using NAT Gateway

Ankush Chavan
7 min readJul 17, 2020
Image Credit: https://www.getcoitservices.com/why_use_nat_gateway/index.html

In this article, we will discuss how to provide internet connectivity to the instance running inside the private subnet using NAT Gateway and considering all of the security measures. This project has the following key points:

  1. Deploying a WordPress site in a Public Subnet
  2. Deploying a MySQL database in a Private Subnet
  3. Attaching NAT Gateway to the Private Subnet so that Private Subnet can have internet connectivity.
  4. Login into the Private Subnet using the Bastion Host.

Let’s start the project by writing a Terraform code in a nat.tf file.

  • Configuring AWS:

Specifying the provider we are going to use(in my case AWS), default region, and the profile. The profile contains all of the credentials to log in to the AWS.

Crating new Profile: Run the following command and follow the steps.

$ aws configure --profile ankush
  • Creating Private EC2 Key-Pair:

Above code will create a private EC2 Key-Pair named Terraform_vpc

  • Creating a VPC:

Creating a VPC with the CIDR block length 192.168.0.0/16

  • Creating Subnet:

Now, we will create two subnets in a VPC named my-vpc. Out of these two subnets, one subnet is a public subnet and another is a private subnet. The public subnet have access to the internet where the private subnet is isolated.

Let’s create a public subnet named my-subnet1

In this public subnet, we will launch the WordPress site.

Now, create private subnet named my-subnet2

In this private subnet, we will launch the MySQL database.

  • Creating an Internet Gateway and Route table:

Until now, we had set up labs(Subnet) for our WordPress site. For providing Internet connectivity inside public subnet we required to create an Internet Gateway. So, let’s create Internet Gateway inside the my-vpc.

The above code will create an Internet Gateway named my-internet-gateway.

After that create a Route Table and associate this Route table with the public subnet(my-subnet1).

Now, the Route Table named my-route-table is created.

Associate this route table with the public subnet.

  • Creating NAT Gateway for providing a network to the Private Subnet:

The very first step in the processing of creating NAT Gateway is that we required to create an EIP(Elastic IP). Afterward, we will attach this Elastic IP to the NAT Gateway.

Now, create a NAT Gateway and allocate the Elastic IP to it. Also, we will provide a subnet where this NAT Gateway should be required to create. As we required NAT Gateway to provide internet connectivity and the Public subnet has internet connectivity, we will create a NAT Gateway in the Public subnet.

As the NAT Gateway is created, we will create a Route Table and update the gateway.

To provide internet connectivity to the Private subnet(my-subnet2), we will associate this route with the private subnet.

Finally, the complete lab for launching a WordPress site is set up successfully.

  • Creating Security Groups for WordPress and MySQL Instances:

Security Group for WordPress Instance:

As we know, WordPress works on port 80 by default. So, we will allow inbound traffic from port 80. Also, for management purposes, we required to login inside the instance. So, we will allow port 22 for SSH.

Security Group for MySQL instance:

As we are running MySQL instance in a private subnet, we required that MySQL can only be accessed by the WordPress instance. So, we will only allow the inbound traffic from port 3306 on which MySQL works by default.

Security Group for Bashing host:

For the management purpose, sometimes we required to login inside the instance running in the private subnet. To login inside this instance running inside the private subnet, we required the bastion host. Because in the firewall(security group) of the instance running inside a private subnet, we haven’t allowed SSH protocol.

Whenever we SSH into the instance running inside a private subnet, if we are using the allowHttp security group then this security group(allowBashing) will allow the request.

Launching MySQL Instance:

The WordPress required MySQL database to be set up first. So, we will launch a MySQL instance first.

Launching WordPress Instance:

Finally, we will launch the WordPress Instance and this will successfully launch the WordPress site.

Finally, the Terraform code for launching the WordPress site using public and private subnet in the same VPC is completed.

Run the Terraform Code:

Step 1: Initializing the modules

$ terraform init

Step 2: Validating the Terraform code

$ terraform validate

Step 3: Run the Terraform code

$ terraform apply --auto-approve

Step 4: Check if the NAT Gateway is created, WordPress and MySQL instances are launched successfully by login into the AWS Console.

NAT Gateway is created
WordPress and MySQL instances are launched

As we can see in the above image, the WordPress instance has public IP allocated. So, WordPress can be accessed from the public world using public IP.

But, the MySQL instance doesn’t have any public IP assigned. So, there is no way we can access the MySQL instance from the public world.

Step 5: Accessing the WordPress Site

Now, open the public IP of the WordPress instance form the browser.

WordPress site is launched

The WordPress site is launched successfully and can be accessed by using the public IP of the WordPress instance.

  • Logging into the MySQL instance(instance inside Private Subnet) using Bastion host:

Our MySQL instance is running inside the private subnet and we had allowed the access only form the source who used the allowHttp security group. So, if we try to login to the MySQL instance from outside world, we will fail.

Trying to access MySQL instance from public world

So, to login to the MySQL instance, we will require to launch a new MySQL instance in a Public Subnet and attach the allowHttp security group to this instance. Now, this instance will serve as a Bastion Host. Because by using this instance we will log in to the MySQL instance running inside Private Subnet.

For login, we will require a security key. So, we will upload the .pem file of the security key associated with the MySQL instance running inside the Private Subent.

Upload the .pem file of a security key to the Bastion Host:

upload .pem file of the security key to the Bashing host using WinSCP program

First, we will log in to the Bastion Host.

Now, we will try to login to the MySQL instance from the Bastion host.

Log in to the MySQL instance from the Bastion Host

And, we had successfully logged in to the MySQL instance from the Bastion Host.

That's it for this article.

If you liked this article, please applaud it.

You can also follow me on Twitter at @cankush625 or find me on LinkedIn.

--

--