AWS VPC ARCHITECTURE USING TERRAFORM

Virtual Private Network (VPC)

AmanGoyal
9 min readApr 25, 2021

A virtual private cloud (VPC) is an on-demand configurable pool of shared computing resources allocated within a public cloud environment, providing a certain level of isolation between the different organizations (denoted as users hereafter) using the resources. The isolation between one VPC user and all other users of the same cloud (other VPC users as well as other public cloud users) is achieved normally through allocation of a private IP subnet and a virtual communication construct (such as a VLAN or a set of encrypted communication channels) per user.

Amazon VPC concepts

Amazon VPC is the networking layer for Amazon EC2. The following are the key concepts for VPCs:

  • Virtual private cloud (VPC) — A virtual network dedicated to your AWS account.
  • Subnet — A range of IP addresses in your VPC.
  • Route table — A set of rules, called routes, that are used to determine where network traffic is directed.
  • Internet gateway — A gateway that you attach to your VPC to enable communication between resources in your VPC and the internet.
  • VPC endpoint — Enables you to privately connect your VPC to supported AWS services and VPC endpoint services powered by PrivateLink without requiring an internet gateway, NAT device, VPN connection, or AWS Direct Connect connection. Instances in your VPC do not require public IP addresses to communicate with resources in the service. Traffic between your VPC and the other service does not leave the Amazon network.

OBJECTIVE:-

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!

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.

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. Don’t forgot to add auto ip assign and auto dns name assignment option to be enabled.

So , Here we go with the task !!

We are going to create one user on our aws account and give it Administration power. then we are going to link that account with our command line. then we will write a terraform code for complete setup and launch it for setup using command line .

Step1.

Create one IAM user with administration power

Also provide administration power to it .

NOTE:- Must download this .csv file as it contains id and access key .

Now link our created user with command line by downloaded download.csv file .

Step 2.

Now go for Terraform code . lets write it !

First provide the provider and USER ID that we are gonna use

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

Create VPC and provide a CIDR block range

resource “aws_vpc” “main”{
cidr_block = “192.168.0.0/16”
instance_tenancy = “default”

tags = {
Name = “myvpc”
}
}

Now we will create one Public subnet and one Private subnet . Public subnet for WordPress site and Private subnet for its backend MySQL . our Public subnet will not be accessible for outside world except WordPress . We will also provide the ip range for both the subnets.

resource “aws_subnet” “subnet1” {
vpc_id = aws_vpc.main.id
cidr_block = “192.168.1.0/24”
availability_zone = “ap-south-1a”
map_public_ip_on_launch = true

tags = {
Name = “public_subnet”
}
}

resource “aws_subnet” “subnet2” {
vpc_id = aws_vpc.main.id
cidr_block = “192.168.2.0/24”
availability_zone = “ap-south-1b”

tags = {
Name = “private_subnet”
}
}

here , ip range that i provided to subnet 1is :- 192.168.1.0/24
ip range to subnet 2 is :- 192.168.2.0/24

Now , create public facing internet gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC

resource “aws_internet_gateway” “igw” {
vpc_id = aws_vpc.main.id

tags = {
Name = “internet_gateway”
}
}

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

for this we are going to connect our route table to public subnet .

resource “aws_route_table” “route_table”{
vpc_id = aws_vpc.main.id

tags = {
Name = “my_rt”
}
}

resource “aws_route_table_association” “a” {
subnet_id = aws_subnet.subnet1.id
route_table_id = aws_route_table.route_table.id
}

resource “aws_route” “r”{
route_table_id = aws_route_table.route_table.id
destination_cidr_block = “0.0.0.0/0”
gateway_id = aws_internet_gateway.igw.id
}

Now , Create keypair to attach to OS that we are going to launch for further login

provider “tls” {}
resource “tls_private_key” “this” {
algorithm = “RSA”
}
resource “aws_key_pair” “test” {
key_name = “mykey12”
public_key = tls_private_key.this.public_key_openssh
}
provider “local” {}
resource “local_file” “key” {
content = tls_private_key.this.private_key_pem
filename = “mykey12.pem”

}

Now , Create security group for Both the instances:-

  1. For WordPress instance :- In it we need to allow following protocols
    a. HTTP :- For connecting from internet . it allows on port no 80
    b. SSH :- For login . it allows on port 22
    c. ICMP :- For pinging , allows on port 8
  2. For MySQL :- In it we only need to allow our WordPress to be connect
    so allow only 3306 port

resource “aws_security_group” “wp_sg” {
name = “wp_sg”
description = “Allow HTTP ,SSH and ICMP inbound traffic”
vpc_id = aws_vpc.main.id

ingress {
description = “SSH”
from_port = 22
to_port = 22
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}
ingress {
description = “HTTP”
from_port = 80
to_port = 80
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}
ingress {
description = “ICMP”
from_port = 8
to_port = 0
protocol = “icmp”
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”
}
}

resource “aws_security_group” “mysql_sg” {
name = “mysql_sg”
description = “Allow MySQL inbound traffic”
vpc_id = aws_vpc.main.id
ingress {
description = “mysql_security_group”
from_port = 3306
to_port = 3306
protocol = “tcp”
cidr_blocks = [“0.0.0.0/0”]
}
tags = {
Name = “mysql_sg”
}
}

Now launching instances , for this we need to have AMI of WordPress and MYSQL .

for WordPress we are going to use this AMI ID :-ami-7e257211
But before using it we need to Subscribe to this AMI and accept its term and conditions . then we can use it . we will add wp_sg security group to it along with key that we generated.

resource “aws_instance” “wp_os” {
ami = “ami-7e257211”
instance_type = “t2.micro”
key_name = “mykey12”
vpc_security_group_ids = [ aws_security_group.wp_sg.id ]
subnet_id = aws_subnet.subnet1.id
tags = {
Name = “wp_os”
}
}

Now launching instance for MYSQL

resource “aws_instance” “mysql_os” {
ami = “ami-08706cb5f68222d09”
instance_type = “t2.micro”
key_name = “mykey12”
subnet_id = aws_subnet.subnet2.id
vpc_security_group_ids = [ aws_security_group.mysql_sg.id ]
tags = {
Name = “mysql_os”
}
}

Here , our Terraform code is completed . Now all we need to do is run it .

Step3

For run the code first run following command on command line . it will download all the plugins required for the terraform file

terraform init

you can check ,that everything is ok , by following command . it will check our code that everything is valid or not , moreover if there is any indentation mistake or not . If there is any will tell us error and line number.

terraform validate

Now , to create whole architecture use this command

terraform apply — auto-approve

complete setup is deployed . BY using Public ip of WordPress instance we can log in to WordPress site .As there is no public ip available at MySQL instance so we cant login to it moreover we didn’t allow HTTP and SSH in it .

Screenshots of setup What it looks like:-

Images:- (1.) linking IAM user to CMD (2.) Downloading terraform Plugins (3.) Checking Validation of code

Images:-(1.) Applied Code (2.) Aurora interface get by Public ip of WP for Instance id (3.) Aurora Interface main

Images:-(1.) interface after login to WordPress (2.) Scroll down and Get login link (3.) WordPress Interface, login here and start create blog

Images:-(1.)VPC created by code (2.) Subnets inside VPC (3.) Internet Gateway

Images:-(1.)Route table (2.) Details of associated subnets (3.) Routes

Images:-(1.)Created Key(mykey12) (2.) OS. running WordPress and MySQL

Images:-(1.)Security groups (2.) Command for delete all the setup

To delete complete setup use command

terraform destroy — auto-approve

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

You can check out my LinkedIn profile here 👆.

--

--