Create a VPC, NAT GateWayAnd Deploy Public WordPress Site With Private MYSQL Database Using Terraform

Sathvika Kolisetty
8 min readJul 14, 2020

--

Virtual Private Cloud

Amazon Virtual Private Cloud (Amazon VPC) lets you provision a logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you define. You have complete control over your virtual networking environment, including a selection of your own IP address range, creation of subnets, and configuration of route tables and network gateways. You can use both IPv4 and IPv6 in your VPC for secure and easy access to resources and applications.

You can easily customize the network configuration of your Amazon VPC. For example, you can create a public-facing subnet for your web servers that have access to the internet. You can also place your backend systems, such as databases or application servers, in a private-facing subnet with no internet access. You can use multiple layers of security, including security groups and network access control lists, to help control access to Amazon EC2 instances in each subnet.

Subnet

If a subnet’s traffic is routed to an internet gateway, the subnet is known as a public subnet. In this diagram, subnet 1 is a public subnet. If you want your instance in a public subnet to communicate with the internet over IPv4, it must have a public IPv4 address or an Elastic IP address (IPv4). For more information about public IPv4 addresses, see Public IPv4 addresses. If you want your instance in the public subnet to communicate with the internet over IPv6, it must have an IPv6 address.

If a subnet doesn’t have a route to the internet gateway, the subnet is known as a private subnet. In this diagram, subnet 2 is a private subnet.

If a subnet doesn’t have a route to the internet gateway but has its traffic routed to a virtual private gateway for a Site-to-Site VPN connection, the subnet is known as a VPN-only subnet. In this diagram, subnet 3 is a VPN-only subnet. Currently, we do not support IPv6 traffic over a Site-to-Site VPN connection.

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

An internet gateway is a horizontally scaled, redundant, and highly available VPC component that allows communication between your VPC and the internet.

An internet gateway serves two purposes: to provide a target in your VPC route tables for internet-routable traffic and to perform network address translation (NAT) for instances that have been assigned public IPv4 addresses.

An internet gateway supports IPv4 and IPv6 traffic. It does not cause availability risks or bandwidth constraints on your network traffic.

Routing table

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

Problem Statement

Performing the following steps:

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

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

1. public subnet [ Accessible for Public World! ]

2. 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 with the public subnet.

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

6. Update the routing table of the private subnet, so that to access the internet it uses the nat gateway created in the public subnet

7. 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 an instance for further login into it.

8. 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.

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

First, we have to give AWS credentials

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

Use this command to run the above file and initialize the plugins.

terraform init

After this run, one single command and whole infrastructure will be ready

terraform apply

Follow the below procedure in order to create an entire environment

Step1

Create VPC using terraform.

resource "aws_vpc" "myvpc" {
cidr_block = "192.168.0.0/16"
instance_tenancy = "default"
enable_dns_hostnames = truetags = {
Name = "myvpc"
}
}

Step2

Creating Public Subnet using terraform:

resource "aws_subnet" "public" {
vpc_id = aws_vpc.myvpc.id
cidr_block = "192.168.0.0/24"
availability_zone = "ap-south-1a"tags = {
Name = "publicsubnet"
}
}

Private Subnet: A private subnet is that where there is no association of subnet to the routing table. They don’t know about the Internet Gateway, that’s the reason no one can connect from the outside world to this Subnet.

Step3

Create Private Subnet using terraform.

resource "aws_subnet" "private" {
vpc_id = aws_vpc.myvpc.id
cidr_block = "192.168.1.0/24"
availability_zone = "ap-south-1b"tags = {
Name = "privatesubnet"
}
}

Step4

Create an Internet Gateway using terraform.

resource "aws_internet_gateway" "gw" {
vpc_id = aws_vpc.myvpc.idtags = {
Name = "myigw"
}
}

Routing Table

A Route table contains a set of rules, called routes, that are used to determine where network traffic from your subnet or gateway is directed.

Step5

Create a Routing Table using terraform code.

resource "aws_route_table" "forig" {
vpc_id = aws_vpc.myvpc.idroute {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.gw.id
}tags = {
Name = "igroutetable"
}
}

Routing Table Association

Provides a resource to create an association between a Route table and a subnet or a Route table and an internet gateway or virtual private gateway.

Step6

Create a Routing Table Association using terraform code.

resource "aws_route_table_association" "asstopublic" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.forig.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. The client can also do ssh to this instance running with WordPress in the public subnet.

Step7

Create a WordPress Security Group using terraform.

resource "aws_security_group" "webserver" {
name = "wordpress"
description = "Allow http and ssh"
vpc_id = aws_vpc.myvpc.idingress {
description = "http"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "ssh"
from_port = 22
to_port = 22
protocol = "tcp"
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 = "web_sg"
}
}

Step8

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

resource "aws_eip" "nat" {
vpc=true
}

Step9

Create a NAT gateway to 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.nat.id
subnet_id = aws_subnet.public.id
depends_on = [aws_internet_gateway.gw]
tags = {
Name = "gw NAT"
}
}

Step10

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" "forprivate" {
vpc_id = aws_vpc.myvpc.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat-gw.id
}
tags = {
Name = "fordatabase"
}
}

Step11

Associate this Routing table to the private subnet.

Step12

Create a Database Security Groups using terraform.

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

resource "aws_security_group" "database" {
name = "for_sql"
description = "Allow sql and ssh"
vpc_id = aws_vpc.myvpc.idingress {
description = "mysql"
from_port = 3306
to_port = 3306
security_groups = [aws_security_group.webserver.id]
protocol = "tcp"
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 = "db_sg"
}
}

Step 13

Create a WordPress Instance with Public Subnet using terraform.

resource "aws_instance" "wordpress" {
ami = "ami-000cbce3e1b899ebd"
instance_type = "t2.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.webserver.id]
associate_public_ip_address = true
key_name = "mykey"tags = {
Name = "wordpress"
}
}

Step 14

Create a Database Instance with Private Subnet using terraform.

resource "aws_instance" "mysql" {
ami = "ami-0019ac6129392a0f2"
instance_type = "t2.micro"
subnet_id = aws_subnet.private.id
vpc_security_group_ids = [aws_security_group.database.id]
key_name = "mykey"tags = {
Name = "mysql"
}
}

Here we give the instance Id of WordPress which was launched with Public Subnet. then you will get this type of result.

We can destroy the complete infrastructure in one-click.

You can find the entire Terraform code in my GitHub repo

--

--

No responses yet