NAT gateway working

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!

Leave a comment

Design a site like this with WordPress.com
Get started