TASK-4:AWS VPC with public, private subnets, internet gateway and NAT gateway

AmanGoyal
7 min readApr 27, 2021

Task Overview:

1. Write an Infrastructure as code using terraform, which automatically create 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 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:

  1. WordPress instance has to be part of the public subnet so that our client can connect our site.
  2. MySQL instance has to be part of a private subnet so that the outside world can’t connect to it.
  3. Don’t forget to add auto IP assign and auto DNS name assignment option to be enabled

Pre-requisites:

  1. You must have an AWS account and One IAM user WITH Administration power in it . Also you should have User’s Credential file .
  2. AWS CLI , Terraform associated with Command line .
  3. You must Configure Your IAM profile to Command line .

Some New terms Related to this Task

  1. VPC: Virtual Private Cloud :- Provision a logically isolated section of the AWS cloud where you can launch AWS resources in a virtual network that you define.
  2. NAT Gateway :-It is 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 (Amazon VPC).
  3. Internet Gateway :-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.
  4. Elastic IP :- An Elastic IP address is a static IPv4 address designed for dynamic cloud computing. An Elastic IP address is associated with your AWS account. With an Elastic IP address, you can mask the failure of an instance or software by rapidly remapping the address to another instance in your account.

So Now We start with Writing Infrastructure as a Code .

Step1 :- first we will tell terraform about provider

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

Step2 :- Now we will create one VPC and provide it CIDR block range

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

here we have provided CIDR block range 192.168.0.0/16

Step3 :- As we have created one VPC , so now we need to create 2 subnets .
1. Public Subnet :- It will be accessible to Public . We will Deploy our WordPress Instance here so everyone can access it .
2. Private subnet :- It won’t be Accessible to public . We will Deploy our MySQL Instance here So no one can access it . No direct Traffic can access it .

resource "aws_subnet" "subnet1" {
vpc_id = aws_vpc.myvpc.id
cidr_block = "192.168.0.0/24"
availability_zone = "ap-south-1a"
map_public_ip_on_launch = truetags = {
Name = "public-subnet"
}
}
resource "aws_subnet" "subnet2" {
vpc_id = aws_vpc.myvpc.id
cidr_block = "192.168.1.0/24"
availability_zone = "ap-south-1b"tags = {
Name = "private-subnet"
}
}

Step4 :- Now we are going to create Elastic IP . It will be used To attach with Public Subnet .

Step5 :-Now create Internet gateway and NAT Gateway to control and manage Traffic and to connect with Subnets

resource "aws_nat_gateway" "natgw" {
allocation_id = aws_eip.eip.id
subnet_id = aws_subnet.subnet1.idtags = {
Name = "nat-gateway"
}
}resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.myvpc.idtags = {
Name = "igw"
}
}

Step6 :- Now We will create route table . It contains some set of Rules that are used to determine where network traffic from your subnet or gateway is directed.
We will also Connect Route table to subnets

resource "aws_route_table" "rt1" {
vpc_id = aws_vpc.myvpc.idroute {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}tags = {
Name = "rt1"
}
}resource "aws_route_table_association" "associate1" {
subnet_id = aws_subnet.subnet1.id
route_table_id = aws_route_table.rt1.id
}resource "aws_route_table" "rt2" {
vpc_id = aws_vpc.myvpc.idroute {
cidr_block = "0.0.0.0/0"
gateway_id = aws_nat_gateway.natgw.id
}tags = {
Name = "rt2"
}
}resource "aws_route_table_association" "associate2" {
subnet_id = aws_subnet.subnet2.id
route_table_id = aws_route_table.rt2.id
}

Step7 :- Now we are going to create one Key pair to attach . It is Called Key Pair as Internally it creates one public and one private key . Public key to encrypt data and private to decrypt it .

provider "tls" {}
resource "tls_private_key" "t" {
algorithm = "RSA"
}
resource "aws_key_pair" "test" {
key_name = "mykey"
public_key = tls_private_key.t.public_key_openssh
}
provider "local" {}
resource "local_file" "key" {
content = tls_private_key.t.private_key_pem
filename = "mykey.pem"

}

Step8 :- Now we will create Security groups for WordPress Instances and define all ingress and egress rules in it .

resource "aws_security_group" "wp_sg" {
name = "wp"
description = "Allow TLS inbound traffic"
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 = "wp_sg"
}
}

Same thing we will do for MySQL instance

resource "aws_security_group" "mysql_sg" {
name = "basic"
description = "Allow MySQL"
vpc_id = aws_vpc.myvpc.idingress {
description = "mysql"
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}ingress {
description = "ssh"
from_port = 22
to_port = 22
protocol = "tcp"
security_groups = [ aws_security_group.wp_sg.id ]
}tags = {
Name = "mysql_sg"
}
}

Step9 :- Now Finally we will launch our instances

resource "aws_instance" "wp_os" {
ami = "ami-7e257211"
instance_type = "t2.micro"
key_name = "mykey123"
subnet_id = aws_subnet.subnet1.id
vpc_security_group_ids = [ aws_security_group.wp_sg.id ]
tags = {
Name = "wp_os"
}
}resource "aws_instance" "mysql_os" {
ami = "ami-08706cb5f68222d09"
instance_type = "t2.micro"
key_name = "mykey123"
subnet_id = aws_subnet.subnet2.id
vpc_security_group_ids = [ aws_security_group.mysql_sg.id ]
tags = {
Name = "mysql_os"
}
}

We are done completely with code

Step10:- Now we are going to initialize and download plugins for the code by running Following command on Command prompt .

terraform init

We also can validate our code and plan it . By validate we check the validity of code whether code is well written or not . By plan we check the upcoming changes that will occur if we run apply command

terraform validate terraform plan

if any error come up with upper given commands then correct that and then run Apply command .

terraform apply --auto-approve

After Completion of work , Delete complete setup by Following command

terraform destroy --auto-approve

Finally! After completing the last step ,we can successfully access the WordPress site.

And that’s all with this task .

Special Thanks to Mr. Vimal Daga sir for enlighten us with this much knowledge .

You can check out my LinkedIn profile.

Also you can check out my GitHub profile.

--

--