Task 4: Performing Task-3 with an additional feature, NAT(Network Address Translation) Gateway.

Task 4: Performing Task-3 with an additional feature, NAT(Network Address Translation) Gateway.

This task is an updated version of task-3, Here we are adding one for a feature and that is NAT Gateway so that our instance running in the private subnet can connect with the public world. If a private instance had some requirement to download some dependencies or some other requirement arises for private instance to connect to the internet then NAT Gateway is used.

What is NAT??

A NAT gateway gives cloud resources without public IP addresses access to the internet without exposing those resources to incoming internet connections.

NAT is a networking technique commonly used to give entire private network access to the internet without assigning each host a public IPv4 address. The hosts can initiate connections to the internet and receive responses, but not receive inbound connections initiated from the internet.

When a host in the private network initiates an Internet-bound connection, the NAT device's public IP address becomes the source IP address for the outbound traffic. The response traffic from the internet, therefore, uses that public IP address as the destination IP address. The NAT device then routes the response to the host in the private network that initiated the connection.

So, What exactly we are going to build!!

No alt text provided for this image

The following are steps for setting up this infrastructure.

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 connecting 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 connecting 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 that 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 the 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.

NOTE1:- Now, Here you can configure ec2 instances for WordPress and MySql yourself or you can use pre-configured instances if available or pull docker images and expose the relevant ports.

To configure instances by yourself is a little tedious job but I am linking one article of my friend on configuring WordPress and MySQL yourself. Click here for the article.

NOTE2:-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.

Recommended:- First, you should try this infrastructure manually and then use Terraform.

Now, let us start the implementation.

1)Creating VPC via terraform code.

# Create a VPC

resource "aws_vpc" "myvpc2" {
  cidr_block = "10.0.0.0/26"
  
tags = {
  Name = "myvpc2"
    }
  

}

So, to assign cidr_block you need to know how many IP addresses you need to allocate. Below is the detailed breakdown of the cidr_block which I have allocated.

No alt text provided for this image

Note3:- Here AWS reserves 5 IP Addresses from subnets so, plan according to that.

No alt text provided for this image

2)Creating Two subnets public and private:-

But wait what is a subnet?

  • A subnet is just like creating our own labs in one office. A subnet is a key component in VPC. A VPC can contain all public subnets or public or private subnet combination. A private Subnet is a subnet that doesn't have a route to the internet gateway. A subnet can be configured as a VPN-only subnet by routing traffic via a virtual private gateway.
  • I have created two labs Public and Private. Public subnets are for my WordPress frontend and a Private subnet is used for our critical database.
#CREATING SUBNETS


resource "aws_subnet" "subnet-1a" {
  vpc_id     = aws_vpc.myvpc2.id
  availability_zone = "ap-south-1a"
  cidr_block = "10.0.0.0/28"
  map_public_ip_on_launch = true
tags = {
  Name = "public-wordpress"
    }
  }


resource "aws_subnet" "subnet-1b" {
  vpc_id     = aws_vpc.myvpc2.id
  availability_zone = "ap-south-1a"
  cidr_block = "192.168.1.0/24"
   map_public_ip_on_launch = false
tags = {
  Name = "private-mysql"
     }
   }
No alt text provided for this image

Step3:- Creating an Internet gateway via Terraform.

What is an Internet Gateway?

  • The Internet gateway is just like a router. Gateway is the Internet Service Provider that gives you access to the entire Internet also it has enabled the SNAT and DNAT rule which can inbound and outbound traffic.
#CREATING INTERNET GATEWAY


resource "aws_internet_gateway" "task4gateway" {
  vpc_id = aws_vpc.myvpc2.id
  tags = {
    Name = "myIGW"
  }
}

Note4:- Now, One thing here to notice is that as soon as we allocated Internet getaway to the public subnet the available IPs for the public subnet will get reduced by one.

No alt text provided for this image

Step4:- Creating routing table via terraform code.

What is a Routing Table?

In computer networking a routing table, or routing information base, is a data table stored in a router or a network host that lists the routes to particular network destinations, and in some cases, metrics associated with those routes.

Now Internet gateway successfully created but how our instance come to know where is gateway ??? Because if the instance doesn't know where the is gateway so it's not possible to go to the internet. So for solving this problem, we have to create a routing table and have to attach with subnet whatever subnet we want to attach. But I attached internet gateway with the Public subnet, not the private subnet because I don't want my critical database can hack or something.

resource "aws_route_table" "route" {
  vpc_id = aws_vpc.myvpc2.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.task4gateway.id
  }
  tags = {
    Name = "public-RT"
  }
}
No alt text provided for this image

Now, Let's attach the public-RT route table to the Public Subnet.

#ASSOCIATING ROUTING TABLE WITH PUBLIC SUBNET

resource "aws_route_table_association" "route_association" {
  subnet_id      = aws_subnet.subnet-1a.id
  route_table_id = aws_route_table.route.id

}
No alt text provided for this image

Step 4:- Creating a NAT GATEWAY via terraform code.

Note:- We always attach NAT GATEWAY with public subnet only.

resource "aws_nat_gateway" "gw" {
depends_on = [aws_internet_gateway.gateway]
  allocation_id = aws_eip.eip.id
  subnet_id     = aws_subnet.subnet-1a.id
  tags = {
    Name = "myNatgateway"
  }
}



No alt text provided for this image

Now it's ok that we have successfully created NAT GATEWAY but how our DATABASE will come to know where is gateway Because if the database doesn't know where is gateway so it's not possible to go to the internet. So for solving this problem, we have to create a routing table and have to attach it with a private subnet where our database is running. So the database can go to the internet and nobody can come inside the database.

Creating and Associating the route table with private subnet.

resource "aws_route_table" "nat_route" {
  vpc_id = aws_vpc.main.id
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_nat_gateway.gw.id
  }
  tags = {
    Name = "private"
  }
}


resource "aws_route_table_association" "route_associate_nat" {
  subnet_id      = aws_subnet.subnet-1b.id
  route_table_id = aws_route_table.nat_route.id
}
No alt text provided for this image
No alt text provided for this image

Step5:- Creating Security Groups.

A security group acts as a virtual firewall for your instance to control incoming and outgoing traffic. When Amazon EC2 decides whether to allow traffic to reach an instance, it evaluates all of the rules from all of the security groups that are associated with the instance.

Creating a security group that allows port no. 80 (for webserver) and also allowing the port no. 22( for SSH), port no. 3306 (for the database), and allowing Http and Https with port no. 80 and 443.

#CREATING SECURITY GROUP FOR WORDPRESS


resource "aws_security_group" "wordpress-sg" {
  depends_on = [aws_vpc.myvpc2]
  vpc_id      = aws_vpc.myvpc2.id
      ingress {
    description = "Creating SSH security group"
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
 ingress {
    description = "Creating HTTP security group"
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
 ingress {
    description = "Creating HTTPS security group"
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"] 
 }
 ingress {
    description = "Creating MySQL port"
    from_port   = 3306
    to_port     = 3306
    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"
}
}
 


#CREATING SECURITY GROUP FOR MYSQL


 resource "aws_security_group" "mysql-sg" {
 depends_on = [aws_vpc.myvpc2]
 vpc_id      = aws_vpc.myvpc2.id
   
    ingress {
    description = "Creating MySQL port"
    from_port   = 3306
    to_port     = 3306
    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 = "mysql-sg"


}
}

Step6:-Launching WordPress ec2 Instance in public subnet via terraform code.

#LAUNCHING WORDPRESS EC2 INSTANCE

resource "aws_instance" "wordpress" {
  ami           = "i-0492debe667a3934a"
  instance_type = "t2.micro"
  subnet_id = aws_subnet.subnet-1a.id
  vpc_security_group_ids = [ aws_security_group.wordpress-sg.id ] 
   key_name = "mykey11" 
  tags = {
    Name = "Sanwordpress"
  }

Step7:-Launching MySql ec2 Instance in private subnet via terraform code.

#LAUNCHING MYSQL DATABASE EC2 INSTANCE


resource "aws_instance" "mysql" {
  ami           = "i-08dd3759529222ef9"
  instance_type = "t2.micro"
  subnet_id = aws_subnet.subnet-1b.id
  vpc_security_group_ids = [ aws_security_group.mysql-sg.id ] 
  key_name = "mykey11" 
  tags = {
    Name = "SanMysql"
  }
}
No alt text provided for this image

Finally here is our output 🙂🙂🙂

Now copy-paste our pubic IP or Public DNS on any web-browser to see the output.

No alt text provided for this image

Thank You....!!!!




To view or add a comment, sign in

More articles by Sanket Bari

Insights from the community

Others also viewed

Explore topics