VPC Infrastructure using TerraForm

Piyush Mehta
5 min readOct 7, 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.

Amazon Virtual Private Cloud (Amazon VPC) lets you provision a logically isolated section of the AWS Cloud where you can launch AWS resources in a virtual network that you define. You have complete control over your virtual networking environment, including selection of your own IP address range, creation of subnets, and configuration of route tables and network gateways. You can use both IPv4 and IPv6 in your VPC for secure and easy access to resources and applications. You can create a public-facing subnet for your web servers that have access to the internet. You can also place your backend systems, such as databases or application servers, in a private-facing subnet with no internet access.

Now Let’s Start Writing our TerraForm Code.

First we need to provide our AWS Profile and Region

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

(Optional) Creation of a new KeyPair

resource "tls_private_key" "KeyGen" {algorithm = "RSA"rsa_bits = 4096} // Key Generation Using RSA Algorithmresource "local_file" "KeyFile" {content = tls_private_key.KeyGen.private_key_pemfilename = "TerraKey.pem"file_permission = 0400} // Copying the Key Content to a local fileresource "aws_key_pair" "KeyAWS" {key_name = "TerraKey"public_key = tls_private_key.KeyGen.public_key_openssh}

Creation of VPC

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

Note: cidr_block specifies the IPv4 range.

Now inside this VPC we need to create 2 Subnets:

Private Subnet:

A private subnet sets that route to a NAT instance. Private subnet instances only need a private ip and internet traffic is routed through the NAT in the public subnet.

resource "aws_subnet" "privateSN" {tags = {Name = "subnet_private"}vpc_id     = aws_vpc.TerraVPC.idcidr_block = "192.168.1.0/24"availability_zone = "ap-south-1b"}

Public Subnet:

A public subnet is a subnet that’s associated with a route table that has a route to an Internet gateway.

resource “aws_subnet” “publicSN” {tags = {Name = “subnet_public”}vpc_id = aws_vpc.TerraVPC.idcidr_block = “192.168.0.0/24”availability_zone = “ap-south-1a”}

We’ll now create a Public facing internet gateway to connect our VPC to the internet world and attach this gateway to our VPC.

resource "aws_internet_gateway" "gateway" {tags = {Name = "iGateWay"}vpc_id = aws_vpc.TerraVPC.id}

Creation of Routing Table for Internet Gateway

resource "aws_route_table" "ig_rt" {vpc_id = aws_vpc.TerraVPC.idroute {cidr_block = "0.0.0.0/0"gateway_id = aws_internet_gateway.gateway.id}tags = {Name = "igRouteTable"}}

Associate this to our Public Subnet

resource "aws_route_table_association" "publicAssociation" {subnet_id      = aws_subnet.publicSN.idroute_table_id = aws_route_table.ig_rt.id}

Creation of Security Groups

Before launching our Instances, we’ll require Security Groups, were suitable inbound and outbound traffic details will be defined.

Security Group for our MySql Instance:

resource "aws_security_group" "database" {name        = "mysql"description = "Allow SSH and MYSQL"vpc_id      = aws_vpc.TerraVPC.idingress {description = "MYSQL"protocol    = "tcp"from_port   = 3306to_port     = 3306security_groups = [aws_security_group.webserver.id]}egress {from_port   = 0to_port     = 0protocol    = "-1"cidr_blocks = ["0.0.0.0/0"]}tags = {Name = "DatabaseSG"}}

Security Group for our Webserver Instance:

resource "aws_security_group" "webserver" {name        = "for_wordpress"description = "Allow HTTPS n SSH"vpc_id      = aws_vpc.TerraVPC.idingress {description = "HTTP"from_port   = 80to_port     = 80protocol    = "tcp"cidr_blocks = ["0.0.0.0/0"]}ingress {description = "SSH"from_port   = 22to_port     = 22protocol    = "tcp"cidr_blocks = ["0.0.0.0/0"]}egress {from_port   = 0to_port     = 0protocol    = "-1"cidr_blocks = ["0.0.0.0/0"]}tags = {Name = "mywebserver_sg"}}

All Cool, now at last we need to launch 2 instances:

Database Instance:

resource "aws_instance" "mysql" {ami           = "ami-08706cb5f68222d09"instance_type = "t2.micro"subnet_id = aws_subnet.privateSN.idvpc_security_group_ids = [aws_security_group.database.id]key_name = "TerraKey"tags = {Name = "MySql_os"}}

Webserver Instance:

resource "aws_instance" "wordpress" {ami           = "ami-000cbce3e1b899ebd"instance_type = "t2.micro"associate_public_ip_address = truesubnet_id = aws_subnet.publicSN.idvpc_security_group_ids = [aws_security_group.webserver.id]key_name = "TerraKey"tags = {
Name = "wordpress_os"
}
}

Now that our Code is ready, we need to execute is using terraform command.

terraform init
terraform validate
terraform apply --auto-approve

Final Output:

Just like how easy it was to create the above Infrastructure, its removal is also easy.

terraform destroy --auto-approve

--

--