AWS VPC with public subnet, a private subnet, Internet gateway and NAT gateway And Deploy Public WordPress Site With Private MYSQL Database Using Terraform

Nischal Vooda
8 min readJul 16, 2020

--

Things we do here:-

We will do here everything using terraform automation tool:

We have to create a web portal for our company with all the security as much as possible.

So, we use the WordPress software with a dedicated database server.

The database should not be accessible from the outside world for security purposes.

We only need the public WordPress to clients.

So here are the steps for proper understanding!

Steps:

1) Write an Infrastructure as code using Terraform, which automatically creates a VPC.

2) In that VPC we have to create 2 subnets:

a) public subnet [ Accessible for Public World! ]

b) private subnet [ Restricted for Public World! ]

3) Create a public-facing internet gateway to connect our VPC/Network to the internet world and attach this gateway to our VPC.

4) Create a routing table for Internet gateway so that instance can connect to the outside world, update and associate it public subnet.with

5) Launch an ec2 instance that has WordPress setup already having to the security group allowing port 80 at our client can connect to our WordPress site.

Also, attach the key to the instance for further login into it.

6) Launch an ec2 instance that has MYSQL setup already with security group allowing port 3306 in a private subnet so that our WordPress VM can connect with the same.

Also, attach the key with the same.

Note: WordPress instance has to be part of the public subnet so that our client can connect our site.

MySQL instance has to be part of a private subnet so that the outside world can’t connect to it.

introduction:

VPC

VPC is like an office or a private space in which we can set up our labs/subnet for launching instances inside it.

This space looks like real but it is virtual. This space is our means private that is isolated from other spaces/office that’s the reason it is known as VPC- Virtual Private Computing.

SUBNET

IN AWS labs are known as Subnet. In VPC there are subnets. These subnets have a router, DHCP server that is connected switch .when we launch any instance inside subnet it will attach to switch and DHCP is the one who assigns IP to this instance.

There may be many subnet inside VPC. These subnet having connectivity between them. Means instance in one subnet can connect to instance in another subnet.

We can’t directly launch instance in amazon data centre. We have to launch it inside subnet. Subnet is inside any of the data center.

NOTE:-

NAAS- Networking As A Service

IAAS- Infrastructure As A Service

In AWS NAAS is provided by VPC

In OpenStack NAAS is provided by Neutron.

One VPC is provided by AWS. the name of it is Default. we can also create VPC. We have to assign a pool of IP’s to VPC at the time of creating.

Subnetting- From this IP pool we assign a particular IP range for Subnet in the VPC.

In every subnet 1st IP is reserved for — Network Name

2nd IP is reserved for — Router

3rd IP is reserved for — DHCP Server

4th IP is reserved for — form some use case

Last IP is reserved for- Broadcasting

Internet Gateway (IG)

It is the router in VPC. This router is Public-Facing Router. From this Router from the public can connect to instance running in subnet inside VPC. IG belong to VPC. VPC has one IG. Through Internet gateway public can connect to private (instance)and private can also connect to the public.

Routing table (For internet gateway)

Routing table created inside VPC. Routing table consists of information of Internet Gateway. Apply this Routing Table to the subnet of DHCP Server in which instance want internet connectivity.

NAT Gateway

Use of Nat gateway — when instance in private subnet want internet connectivity. means only instance can go to the public world/internet but anyone from internet/public can’t connect to instance in the private subnet.

NAT gateway is router basically. NAT gateway is always a part of the public subnet.

NAT gateway provides SNAT only.

Internet gateway provides both SNAT and DNAT.

Routing table (For NAT gateway)

Routing table created inside VPC. Routing table consists of information of NAT Gateway. Apply this Routing Table to the private subnet of DHCP Server in which instance want internet connectivity.

Private Subnet

In this subnet we not associate the routing table so that all VM’S inside this subnet can’t go to internet gateway for outside connectivity and also public will not able to connect to VM’S inside this subnet.

Public subnet

In this subnet, we attach the routing table so that all VM’S inside this subnet get connected to the outside or public world by using the internet gateway.

NOTE:-

DMZ- Demilitarize Zone Public subnet is known as DMZ.

Pre-requisite:-

Create an account on AWS

Create an IAM user with Admin Access power and download the .csv file.

Install AWS CLI on your base os (In my case I am using windows).

Install terraform in your base OS. Install terraform using this link >>> https://learn.hashicorp.com/terraform/getting-started/install.html

Now configure AWS then enter access key, Secret key and region.

Here I am expecting you already created a key pair.

this is the basic infrastructure blueprint of which we are going to creat

run this command to give your IAM user credentials

aws configure

First, we have to tell who is your provider means from whom you will Terraform contact to taking the services. In our case our provider is AWS.

provider "aws" {
region = "ap-south-1"
profile = "nischal"
}

Write an Infrastructure as code using Terraform, which automatically create a VPC.

resource "aws_vpc" "main" {
cidr_block = "192.168.0.0/16"
instance_tenancy = "default"
tags = {
Name = "nischal_vpc"
}
}

In that VPC we have to create 2 subnets

public subnet [ Accessible for Public World! ]

resource "aws_subnet" "subnet1" {
vpc_id = aws_vpc.main.id
availability_zone = "ap-south-1a"
cidr_block = "192.168.1.0/24"
map_public_ip_on_launch = true
tags = {
Name = "pub_1a"
}
}

private subnet [ Restricted for Public World! ]

resource "aws_subnet" "subnet2" {
vpc_id = aws_vpc.main.id
availability_zone = "ap-south-1b"
cidr_block = "192.168.2.0/24"
tags = {
Name = "priv_1b"
}
}

Create a public-facing internet gateway for connecting our VPC/Network to the internet world and attach this gateway to our VPC.

resource "aws_internet_gateway" "gw" {
vpc_id = "${aws_vpc.main.id}"
tags = {
Name = "int_gw"
}
}

Create a routing table for Internet gateway so that instance can connect to the outside world, update it.

resource "aws_route_table" "rt" {
vpc_id = "${aws_vpc.main.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.gw.id}"
}
tags = {
Name = "public"
}
}

and associate it with public subnet.

resource "aws_route_table_association" "subnet_association" {
subnet_id = aws_subnet.subnet1.id
route_table_id = aws_route_table.rt.id
}

Create a security group allowing port 80 so that our client can connect to our WordPress site on an instance running on the public subnet. Client can also do ssh to this instance running with WordPress in the public subnet.

resource "aws_security_group" "allow_tls" {
name = "allow_tls"
description = "Allow ssh,httpd,mysql"
vpc_id = "${aws_vpc.main.id}"
ingress {
description = "ssh port"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "httpd port"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = " port"
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "ssh port"
from_port = 0
to_port = 0
protocol = -1
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "sec_grp"
}
}

creating one EIP for nat gateway inside VPC. which gives one public static IP to the NAT Gateway

resource "aws_eip" "aws_eip_1" {
vpc = true
depends_on =["aws_internet_gateway.gw"]
}

Create a NAT gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC in the public network

resource "aws_nat_gateway" "nat_gw" {
allocation_id = "${aws_eip.aws_eip_1.id}"
subnet_id = "${aws_subnet.subnet1.id}"
depends_on =["aws_internet_gateway.gw"]
}

Creating Route table for private subnet (for NAT Gateway) .so that to access the internet it uses the nat gateway created in the public subnet

resource "aws_route_table" "rt2" {
vpc_id = "${aws_vpc.main.id}"
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = "${aws_nat_gateway.nat_gw.id}"
}
tags = {
Name = "private"
}
}

Associate this Routing table to the private subnet.

resource "aws_route_table_association" "subnet_association_2" {
subnet_id = aws_subnet.subnet2.id
route_table_id = aws_route_table.rt2.id
}

Create a security group allowing port 3306 in private subnet so that our WordPress VM that is in public subnet can connect with the same.

resource "aws_security_group" "allow_public" {
name = "allow_public"
description = "Allow ssh,httpd,mysql"
vpc_id = "${aws_vpc.main.id}"
ingress {
description = "TCP"
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups =[aws_security_group.allow_tls.id]
}
egress{
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "sec_grp_for_privat"
}
}
variable ssh_key_name{
default = "keywithtf"
}

Launch an ec2 instance which has Wordpress setup already having the security group allowing port 80 so that our client can connect to our wordpress site.

Also attach the key to instance for further login into it.

resource "aws_instance" "web" {
ami = "ami-7e257211"
instance_type = "t2.micro"
subnet_id ="${aws_subnet.subnet1.id}"
associate_public_ip_address = true
key_name ="nischal"
vpc_security_group_ids = [aws_security_group.allow_tls.id]
tags ={
Name = "publicos"
}
}

Launch an ec2 instance which has MYSQL setup already with security group allowing port 3306 in private subnet so that our WordPress VM can connect with the same.

Also attach the key with the same.

resource "aws_instance" "mysql" {
ami = "ami-08706cb5f68222d09"
instance_type = "t2.micro"
subnet_id ="${aws_subnet.subnet1.id}"
key_name ="${var.ssh_key_name}"
security_groups =[aws_security_group.allow_public.id]
tags ={
Name = "mysql_privatos"
}
}

Note: Wordpress instance has to be part of public subnet so that our client can connect our site.

MySQL instance has to be part of private subnet so that the outside world can’t connect to it.

Don’t forget to add auto IP assign and auto DNS name assignment option to be enabled.

Here we are adding one additional feature that is NAT Gateway to provide the internet access to instances (Database)running in the private subnet.

So our setup is ready. so let’s perform the task.

First I show you that I don’t have any VPC with the name that I mentioned above.

  • use this command to launch the entire environment
terraform apply— auto-approve

output

WordPress dashboard

We can destroy the complete infrastructure in one-click.

terraform destroy --auto-approve

Connect me on my LinkedIn as well.

--

--

No responses yet