In this post we will see how to setup NAT gateway on the previous post of setting up wordpress and mysql : https://mynk.home.blog/2020/10/04/deploying-wordpress-and-mysql-on-ec2-in-custom-vpc-using-terraform/
Most of the process like making vpc, internat gateway etc. would remain the same except we just added the NAT gateway in our VPC.
Workflow
- Creating a VPC and in this two subnet
- Public Subnet – accessible from public world
- Private Subnet – not accessible from public subnet
- Public facing internet gateway for VPC
- Routing table for subnet
- NAT gateway for VPC
- Launching preconfigured wordpress instance in public subnet
- Launching preconfigured mysql instance in private subnet
Provider and Key
# configure the provider
provider "aws" {
region = "ap-south-1"
profile = "terraform-user"
}
#Creating private key
resource "tls_private_key" "key" {
algorithm = "RSA"
rsa_bits = 4096
}
resource "aws_key_pair" "generated_key" {
key_name = "task3_key"
public_key = tls_private_key.key.public_key_openssh
depends_on = [
tls_private_key.key
]
}
#Downloading priavte key
resource "local_file" "file" {
content = tls_private_key.key.private_key_pem
filename = "E:/Terraform/tasks cloud trainig/task3/task3_key.pem"
file_permission = "0400"
depends_on = [ aws_key_pair.generated_key ]
}
VPC and Subnet
VPC (virtual private network) is a Lab in which we can create sub-labs known as subnets.
# creating a vpc
resource "aws_vpc" "vpc" {
cidr_block = "192.169.0.0/16"
instance_tenancy = "default"
enable_dns_hostnames = true
tags = {
Name = "vpc"
}
}
# creating subnet in 1a
resource "aws_subnet" "sub_1a" {
vpc_id = "${aws_vpc.vpc.id}"
cidr_block = "192.169.1.0/24"
availability_zone = "ap-south-1a"
map_public_ip_on_launch = true
tags = {
Name = "sub_1a"
}
depends_on = [ aws_vpc.vpc ]
}
# creating a subnet in 1b
resource "aws_subnet" "sub_1b" {
vpc_id = "${aws_vpc.vpc.id}"
cidr_block = "192.169.2.0/24"
availability_zone = "ap-south-1b"
tags = {
Name = "sub_1b"
}
depends_on = [ aws_vpc.vpc ]
}


Internet-Gateway
It allows VPC to connect with public world (internet).
# creating igw
resource "aws_internet_gateway" "igw" {
vpc_id = "${aws_vpc.vpc.id}"
tags = {
Name = "igw"
}
depends_on = [ aws_vpc.vpc ]
}
Route Table and association
Route table controls the routing. Each subnet should be associated with route table. By default it route table is attached but we want to add more routes we can, same as I did below to provide subnet 1a public access.
# creating route table
resource "aws_route_table" "r" {
vpc_id = "${aws_vpc.vpc.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.igw.id}"
}
tags = {
Name = "r"
}
depends_on = [ aws_internet_gateway.igw, aws_vpc.vpc ]
}
# associating route table
resource "aws_route_table_association" "a" {
subnet_id = aws_subnet.sub_1a.id
route_table_id = aws_route_table.r.id
depends_on = [ aws_route_table.r ]
}
NAT gateway
NAT Gateway is a highly available AWS managed service that makes it easy to connect to the Internet from instances within a private subnet in an Amazon Virtual Private Cloud.
We will need elastic IP for it so.
resource "aws_eip" "public_ip" {
vpc = true
}
resource "aws_nat_gateway" "NAT-gw" {
allocation_id = aws_eip.public_ip.id
subnet_id = aws_subnet.public.id
tags = {
Name = "NAT-GW"
}
}
Route Table and association for NAT
resource "aws_route_table" "r2" {
vpc_id = aws_vpc.vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_nat_gateway.NAT-gw.id
}
tags = {
Name = "NAT_table"
}
}
resource "aws_route_table_association" "a2" {
subnet_id = aws_subnet.private.id
route_table_id = aws_route_table.r2.id
}
Security Group for wordpress
Security groups are firewall to an instance which controls the port traffic.
# sg for wordpress
resource "aws_security_group" "wp_sg" {
name = "wp sg"
description = "Allow http ssh all"
vpc_id = "${aws_vpc.vpc.id}"
ingress {
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"]
}
ingress {
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 = "wp sg"
}
}

Security Group for mysql
# sg for mysql
resource "aws_security_group" "mysql_sg" {
name = "mysql sg"
description = "ssh and mysql port"
vpc_id = "${aws_vpc.vpc.id}"
ingress {
description = "mysql port"
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = [aws_vpc.vpc.cidr_block]
}
ingress {
description = "ssh"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [aws_vpc.vpc.cidr_block]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "mysql sg"
}
depends_on = [ aws_vpc.vpc ]
}
EC2 instance
# wordpress ami
resource "aws_instance" "wordpress" {
depends_on = [ aws_subnet.sub_1a, aws_security_group.wp_sg, ]
ami = "ami-02b9afddbf1c3b2e5"
instance_type = "t2.micro"
key_name = "task3_key"
vpc_security_group_ids = ["${aws_security_group.wp_sg.id}"]
subnet_id = aws_subnet.sub_1a.id
tags = {
Name = "WordPress"
}
}
# mysql ami
resource "aws_instance" "mysql" {
depends_on = [ aws_subnet.sub_1b, aws_security_group.mysql_sg, ]
ami = "ami-0d8b282f6227e8ffb"
instance_type = "t2.micro"
key_name = "task3_key"
vpc_security_group_ids = ["${aws_security_group.mysql_sg.id}"]
subnet_id = aws_subnet.sub_1b.id
tags = {
Name = "Mysql"
}
}

Final Step
terraform init
terraform plan
terraform apply
After launching connect to wordpress instance, open directory /var/www/html/ and open wp-config.php and put your mysql instance private ip and restart httpd service.
systemctl restart httpd
And now open wordpress public dns name or public IP.
I images used are given in the previous post : https://mynk.home.blog/2020/10/04/deploying-wordpress-and-mysql-on-ec2-in-custom-vpc-using-terraform/
Thank You!



