Uditanshu Kumar
6 min readJul 26, 2020

--

CREATE A PERSONAL VPC USING NAT GATEWAY AND INTEGRATE WITH EC2…

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

Problem Statement :::

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

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

→public subnet [ Accessible for Public World! ]

→ private subnet [ Restricted for Public World! ]

3. Create a public facing internet gateway toconnect 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 outside world, update and associate it with public subnet.

5. Create a NAT gateway for 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 instance for further login into it.

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

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 outside world can’t connect to it.

Let’s Start ……………………………………………

Step 1: We will provide our resource provider name followed by account details along with the region name.

//Provider

provider “aws”{
region = “ap-south-1”
profile = “Udit”
}

Step 2: Create a personal Virtual Private Cloud…

//creating VPC
resource “aws_vpc” “udit_vpc” {
cidr_block = “192.168.0.0/16”
instance_tenancy = “default”

tags = {
Name = “udit_vpc”
}
}

Step 3: Create 2 subsets…. public and private…

//creating subnets
resource “aws_subnet” “udit_public_subnet” {
vpc_id = “${aws_vpc.udit_vpc.id}”
cidr_block = “192.168.0.0/24”
availability_zone = “ap-south-1a”
map_public_ip_on_launch = true

tags = {
Name = “udit_public_subnet”
}
}

resource “aws_subnet” “udit_private_subnet” {
vpc_id = “${aws_vpc.udit_vpc.id}”
cidr_block = “192.168.100.0/24”
availability_zone = “ap-south-1b”

tags = {
Name = “udit_private_subnet”
}
}

Step 4: Create a public facing internet gateway to connect our VPC/Network to the internet world .

resource “aws_internet_gateway” “internet_gateway” {
vpc_id = “${aws_vpc.udit_vpc.id}”

tags = {
Name = “internet_gateway”
}
}

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

resource “aws_route_table” “udit_route1” {
vpc_id = “${aws_vpc.udit_vpc.id}”

route {
cidr_block = “0.0.0.0/0”
gateway_id = “${aws_internet_gateway.internet_gateway.id}”
}

tags = {
Name = “udit_route1”
}
}

resource “aws_route_table_association” “route_association1” {
subnet_id = aws_subnet.udit_public_subnet.id
route_table_id = aws_route_table.udit_route1.id
}

Step 6: Create a NAT gateway toconnect our VPC/Network to the internet world and attach this gateway to our VPC in the public network.

resource “aws_eip” “udit_elasticip”{
vpc = true
}

resource “aws_nat_gateway” “nat_gateway” {
allocation_id = aws_eip.udit_elasticip.id
subnet_id = aws_subnet.udit_public_subnet.id

tags = {
Name = “nat_gateway”
}
}

Step 7: Create a routing table for the NAT gateway and associate it with the private subnet.. so that instance inside the subnet can connect to the outside world.

resource “aws_route_table” “udit_route2” {
vpc_id = “${aws_vpc.udit_vpc.id}”

route {
cidr_block = “0.0.0.0/0”
gateway_id = “${aws_nat_gateway.nat_gateway.id}”
}

tags = {
Name = “udit-route2”
}
}

resource “aws_route_table_association” “route_association2” {
subnet_id = aws_subnet.udit_private_subnet.id
route_table_id = aws_route_table.udit_route2.id
}

Step 8: We will create public and private key using tls_private_key keyword. These key pairs will be used to login to our aws instance from our local system using SSH .

//key creation
resource “tls_private_key” “udit_key_pair”{
algorithm = “RSA”
}

resource “aws_key_pair” “udit_key”{
key_name = “udit33”
public_key = tls_private_key.udit_key_pair.public_key_openssh

depends_on = [
tls_private_key.udit_key_pair
]
}

Step 9: Create Security groups for mysql, wordpress and bastion host. In wordpress we will allow inbounds to port no 22 and 80 , in mysql we will allow inbounds only from wordpress and bastion-host and in bastion host we will allow ssh so that admin can login to mysql from bastion- host whenever required.

// Wordpress Security Group

resource “aws_security_group” “wordpress_sg” {
name = “wordpress_sg”
description = “Allow ssh, http and icmp”
vpc_id = “${aws_vpc.udit_vpc.id}”

ingress {
description = “Allow Icmp”
from_port = 1
to_port = 1
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]

}

ingress {
description = “Allow SSH”
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}

ingress {
description = “Allow HTTP”
from_port = 80
to_port = 80
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 = “wordpress_sg”
}
}

//Bastion Host Security Group…

resource “aws_security_group” “bastion_host_sg” {
name = “bastion_host_sg”
description = “Allow ssh”
vpc_id = “${aws_vpc.udit_vpc.id}”

ingress {
description = “Allow 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 = “bastion_host_sg”
}
}

//MYSql Security Group 1…..[ Allow Wordpress ]

resource “aws_security_group” “mysql_sg1” {
name = “mysql_sg1”
description = “Allow wordpress”
vpc_id = “${aws_vpc.udit_vpc.id}”

ingress {
description = “Allow Wordpress”
from_port = 3306
to_port = 3306
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
security_groups = [ “${aws_security_group.wordpress_sg.id}”]
}

egress {
from_port = 0
to_port = 0
protocol = “-1”
cidr_blocks = [“0.0.0.0/0”]
}

tags = {
Name = “mysql_sg1”
}
}

//MYSql Security Group 2…..[ Allow Bastion — Host]

resource “aws_security_group” “mysql_sg2” {
name = “mysql_sg2”
description = “Allow Bastion Host”
vpc_id = “${aws_vpc.udit_vpc.id}”

ingress {
description = “allow bastion host”
from_port = 22
to_port = 22
protocol = “tcp”
security_groups = [ “${aws_security_group.bastion_host_sg.id}”]
}

egress {
from_port = 0
to_port = 0
protocol = “-1”
cidr_blocks = [“0.0.0.0/0”]
}

tags = {
Name = “mysql_sg2”
}
}

Step 10: Launch Word-press and Bastion-Host in the public subnet and attach respective security groups to it …

resource “aws_instance” “wordpress_instance” {
ami = “ami-01b9cb595fc660622”
instance_type = “t2.micro”
subnet_id = aws_subnet.udit_public_subnet.id
associate_public_ip_address = true
key_name = “udit33”
vpc_security_group_ids = [ “${aws_security_group.wordpress_sg.id}”]

tags = {
Name = “Wordpress Instance”
}
}

resource “aws_instance” “bastion_instance” {
ami = “ami-07a8c73a650069cf3”
instance_type = “t2.micro”
subnet_id = aws_subnet.udit_public_subnet.id
associate_public_ip_address = true
key_name = “udit33”
vpc_security_group_ids = [ “${aws_security_group.bastion_host_sg.id}”]

tags = {
Name = “Bastion Host Instance”
}
}

Step 11: Launch MySQL in the private subnet..

resource “aws_instance” “mysql_instance” {
ami = “ami-0025b3a1ef8df0c3b”
instance_type = “t2.micro”
subnet_id = aws_subnet.udit_private_subnet.id
key_name = “udit33”
vpc_security_group_ids = [ “${aws_security_group.mysql_sg1.id}”, “${aws_security_group.mysql_sg2.id}”]

tags = {
Name = “Mysql Instance”
}
}

Finally….Launch the Wordpress site using the Wordpress instance IP….

Thank YOU…

--

--