Created a personal secure Network on AWS using Terraform

Abhayjit kumar
6 min readJul 28, 2020

Statement: We have to create a web portal for our company with all the security as much as possible.

So, we use Wordpress software with dedicated database server.Database should not be accessible from the outside world for security purposes.We only need to public the WordPress to clients.So here are the steps for proper understanding!

Architecture of Personal secure VPC and Integrate it with EC2

Steps:

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

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

a) public subnet [ Accessible for Public World! ]

b) private subnet [ Restricted for Public World! ]

3) Create a public facing internet gateway for 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) 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.

6) 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.

Solving this Architecture :

First of all we need to have provider that is AWS and we will give it a profile and the region where we will launch all the resources.

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

Now after this we can create resources in the “ap-south-1” region and use them first of all we will create a VPC , i am giving a random CIDR Block you can give according to your use .

resource "aws_vpc" "Aj_vpc" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"


tags = {
Name = "Aj_vpc"
}
}

By this we will have a VPC created from the resource name “Aj_vpc “ but it is empty we need to create subnets that are like our own private labs we are gonna create one Public and one Private subnet .

resource "aws_subnet" "public_subnet" {
vpc_id = "${aws_vpc.Aj_vpc.id}"
cidr_block = "10.0.1.0/24"
availability_zone = "ap-south-1a"
map_public_ip_on_launch = "true"
tags = {
Name = "public_subnet"
}
depends_on = [ aws_vpc.Aj_vpc, ]


}


resource "aws_subnet" "private_subnet" {
vpc_id = "${aws_Aj.ved_vpc.id}"
cidr_block = "10.0.2.0/24"
availability_zone = "ap-south-1a"
tags = {
Name = "private_subnet"
}

depends_on = [ aws_vpc.Aj_vpc, ]

By this we will have two subnet created in our VPC as you can see that public subnet has capability to assign the Public IP to the instances which will be launched inside it , so that it can connect to private world and people can see it. Now we will create a Internet Gateway that we will connect to the public subnet so that it can go out through it to the public world.

resource "aws_internet_gateway" "internet_gateway" {
vpc_id = "${aws_vpc.Aj_vpc.id}"
tags = {
Name = "internet_gateway"
}


depends_on = [ aws_vpc.Aj_vpc, ]
}

We also need a Routing Table that will have the rule or route to public access or the public world.

resource "aws_route_table" "route_table" {
vpc_id = "${aws_vpc.Aj_vpc.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.internet_gateway.id}"
}
tags = {
Name = "route_table"
}
depends_on = [ aws_internet_gateway.internet_gateway, ]
}
resource "aws_route_table_association" "association_routing_table" {
subnet_id = aws_subnet.public_subnet.id
route_table_id = aws_route_table.route_table.id
depends_on = [ aws_route_table.route_table, ]
}

This will set the route for any instance in the public subnet to go out on Internet . Now moving forward as we are gonna need security groups so the we can attach them to MYSQL and WordPress instance .

resource "aws_security_group" "wordpress" {
name = "wordpress"
description = "To connect with wordpress os"
vpc_id = "${aws_vpc.Aj_vpc.id}"




ingress {
description = "Http from VPC"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
ingress {
description = "SSH from VPC"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
ingress {
description = "HTTPS"
from_port = 443
to_port = 443
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 = "sgroup_wordpress"
}


depends_on = [ aws_vpc.Aj_vpc, ]
}


resource "aws_security_group" "mysql" {
name = "for-mysql"
description = "connect to mysql instance"
vpc_id = "${aws_vpc.Aj_vpc.id}"




ingress {
description = "MYSQL from VPC"
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = [ "0.0.0.0/0" ]
}
ingress {
description = "SSH from VPC"
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 = "sgroup_mysql"
}
depends_on = [ aws_vpc.Aj_vpc, ]
}

Now we will have two security groups one for the WordPress and one for MYSQL with their respective ports enabled . We will also need a private key to attach to WordPress and MYSQL (it will be better to create separate keys for each instance but i am using single key ).

resource "tls_private_key" "private_key" { 
algorithm = "RSA"
rsa_bits = "2048"
}




resource "aws_key_pair" "task-3-key" {
depends_on = [ tls_private_key.private_key, ]
key_name = "Aj-key"
public_key = tls_private_key.private_key.public_key_openssh
}

Now the keys will we created now the final step is to create instances for WordPress and MYSQL

resource "aws_instance" "wordpress" {
ami = "ami-7e257211"
instance_type = "t2.micro"
key_name = "Aj-key"
availability_zone = "ap-south-1a"
subnet_id = "${aws_subnet.public_subnet.id}"
security_groups = [ "${aws_security_group.wordpress.id}" ]
tags = {
Name = "Wordpress"
}
depends_on = [ aws_subnet.public_subnet, ]
}


resource "aws_instance" "mysql" {
ami = "ami-0447a12f28fddb066"
instance_type = "t2.micro"
key_name = "Aj-key"
availability_zone = "ap-south-1a"
subnet_id = "${aws_subnet.private_subnet.id}"
security_groups = [ "${aws_security_group.mysql.id}" ]
tags = {
Name = "MYSQL"
}
depends_on = [ aws_subnet.private_subnet, ]
}

Finally, full infrastructure is created.

Save the code in a file having .tf extension.

Run these commands for run the code:-

  • terraform init
  • terraform apply

After doing this our whole infrastructure is ready.

VPC CREATED :

SUBNET CREATED :

INTERNET GATEWAY :

ROUTING TABLE CREATED :

SECURITY GROUP CREATED :

INSTANCES CREATED :

Now we can see a full fledged WordPress site running .

Now we if we need to remove every thing, so just rum “terrafrom destroy” command from cmd .

Thank you for reading my article…

If it is helpful then please leave a clap for me .

--

--