AWS VPC and Networking

How to create VPC in Terraform and AWS networking using Terraform

*Task 3*

Gauri Raskar
6 min readJul 26, 2020

--

What we want to achieve?

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!

How can we achieve our goal?

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.

Step 1 : First we have to configure AWS , for that we will provide an AWS provider

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

Step 2 : We will create VPC using terraform

First let’s understant what is VPC

Amazon Virtual Private Cloud (Amazon vpc) enables you to launch AWS resources into a virtual network that you’ve defined. This virtual network closely resembles a traditional network that you’d operate in your own data center, with the benefits of using the scalable infrastructure of AWS.

Here we will create our own VPC which is lwvpc with cidr block here the prefix is “192.168.0.0” with The total number of bits in this address is 16 by doing this we provide a network address that is used for the identification of our network

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

Step 3: Create public and private subnet in our VPC

Now we will create two sunbets in this VPC we created in above step, we will create one private and one public VPC

Public subnet: For Wordpress instance so that client will be able to visit our web app

Private subnet: For MySQL instance so that no one can outside world connect to our private database

resource "aws_subnet" "lwsubnet1" {
vpc_id = "${aws_vpc.lwvpc.id}"
cidr_block = "192.168.0.0/24"
tags = {
Name = "lwsubnet1"
}
}
resource "aws_subnet" "lwsubnet2" {
vpc_id = "${aws_vpc.lwvpc.id}"
cidr_block = "192.168.1.0/24"
tags = {
Name = "lwsubnet2"
}
}

Step 4 : Create Internet Gateway

Now let’s create Internet Gateway

The gateway supports connections initiated from within the egress and connections initiated from the internet (ingress).

Resources (Wordpress Instance) that need to use the gateway for internet access must be in a public subnet and have public IP addresses.

resource "aws_internet_gateway" "gw" {
vpc_id = "${aws_vpc.lwvpc.id}"
tags = {
Name = "gw"
}
}

Step 5 :Create Routing Table

Each public subnet that needs to use the internet gateway must have a Router Table rule that specifies the gateway as the target.

resource "aws_route_table" "r" {
vpc_id = "${aws_vpc.lwvpc.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.gw.id}"
}
tags = {
Name = "r"
}
}

Step 6 :Associate Routing Table

Here we associate out public subnet from VPC to the router table which we have created for our VPC to allow internet access

resource "aws_route_table_association" "a" {
subnet_id = "${aws_subnet.lwsubnet1.id}"
route_table_id = "${aws_route_table.r.id}"
}

Step 7 : Create keys for instance

resource "tls_private_key" "webserver_private_key" {
algorithm = "RSA"
rsa_bits = 4096
}
resource "local_file" "private_key" {
content = tls_private_key.webserver_private_key.private_key_pem
filename = "webserver_key.pem"
file_permission = 0400
}
resource "aws_key_pair" "webserver_key" {
key_name = "webserver"
public_key = tls_private_key.webserver_private_key.public_key_openssh
}

Step 8 : Security Group for wordpress instance

Since we want clients to visit our web app we must allow http port in our security group for wordpress instance.

resource "aws_security_group" "allow_http_ssh" {
name = "allow_http_ssh"
description = "Allow http inbound traffic"
vpc_id = "${aws_vpc.lwvpc.id}"
ingress {
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 = "allow_http_ssh"
}
}

Step 9 : Create Wordpress Instance

We will create our Wordpress instance in public subnet to which we have associated our routing table which allows all internet traffic we will enable “associate_public_ip_address” to true so that we will get auto IP assinged

resource "aws_instance" "task3_wordpress" {
ami = "ami-0732b62d310b80e97"
instance_type = "t2.micro"
key_name =aws_key_pair.webserver_key.key_name
subnet_id=aws_subnet.lwsubnet1.id

vpc_security_group_ids = [aws_security_group.allow_http_ssh.id]
associate_public_ip_address ="true"
connection {
type = "ssh"
user = "ec2-user"
host = aws_instance.task3_wordpress.public_ip
port = 22
private_key = tls_private_key.webserver_private_key.private_key_pem
}

tags = {
Name = "wordpress_task3"
}
}

Step 10 : Security group for MySQL instance

resource "aws_security_group" "sg_mysql" {
name = "sg_mysql"
description = "Allow 3306 inbound traffic"
vpc_id = "${aws_vpc.lwvpc.id}"
ingress {
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"
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 = "sg_mysql"
}
}

Step 11 : MySQL instance

resource "aws_instance" "task3_mysql" {
ami = "ami-08706cb5f68222d09" //amzaon linux with
instance_type = "t2.micro"
subnet_id = "${aws_subnet.lwsubnet2.id}"
key_name = aws_key_pair.webserver_key.key_name
vpc_security_group_ids = [aws_security_group.sg_mysql.id]
associate_public_ip_address ="true"
connection {
type = "ssh"
user = "ec2-user"
host = aws_instance.task3_mysql.public_ip
port = 22
private_key = tls_private_key.webserver_private_key.private_key_pem
}

tags = {
Name = "task3_mysql"
}
}

Now our Instances are created

Step 12 : Installation

resource "null_resource" "nullremote"  {depends_on = [
aws_instance.wordpress
]
connection {
type = "ssh"
user = "ec2-user"
host = aws_instance.wordpress.public_ip
port = 22
private_key = tls_private_key.webserver_private_key.private_key_pem
}
provisioner "remote-exec" {
inline = [
"sudo yum install httpd docker -y",
"sudo systemctl start docker",
"sudo docker pull wordpress",
"sudo docker run -dit -p 80:80 wordpress",
]
}
}

We will create null-resource so that we will install docker on our wordpress instance and on docker we will pull wordpress image

wordpress installation

Step 13 : Now let’s configure MySQL

We have used MySQL ami while creating our MySQL instance now we will configure

Configuring MySQL

What have we done so far?

created VPC in AWS , Subnets in our VPC, Routing Table, Internet Gateway, Association of Routing Table

--

--