TASK-3: WORDPRESS OPEN FOR PUBLIC WORLD AND DATABASE RESTRICTED FOR PUBLIC WORLD
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.
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.
First of all lets discuss some technical terms before moving to the terraform script:
- Routing Table: A route table contains a set of rules, called routes, that are used to determine where network traffic from our subnet or gateway is directed.
- Subnet: A subnet, or subnetwork, is a network inside a network. Subnets make networks more efficient. Through subnetting, network traffic can travel a shorter distance without passing through unnecessary routers to reach its destination.
- VPC: 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 can use both IPv4 and IPv6 in your VPC for secure and easy access to resources and applications.
Now let's get started with terraform script:
We have to select our provider in this case it is AWS. By selecting the provider terraform will be able to download the required plugins.
Then we have to select the region in which we want to set up our instances.
Here we have to provide profile name. If you wish you can hardcode your credentials instead of profile name but it is not recommended !
provider "aws" {
region = "ap-south-1"
profile = "Ddhruv"
}
Here we will create a VPC with name 'vpc_1'.
resource "aws_vpc" "vpc_1" {
cidr_block = "10.0.0.0/16"
instance_tenancy = "default"
enable_dns_hostnames = "true"
tags = {
Name = "vpc_1"
}
}
So, we will create two subnets.
- Public subnet: It will be accessed by the public world hence it will be connected with the EC2 instances having the frontend of wordpress.
- Private subnet: As it is private it could not be accessed by public which makes the EC2 instance conncectd with database of the wordpress secure.
resource "aws_subnet" "public_subs" {
vpc_id = aws_vpc.vpc_1.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-south-1a"
map_public_ip_on_launch = "true"
depends_on = [aws_vpc.vpc_1]
tags = {
Name = "public_subs"
}
}
resource "aws_subnet" "private_subs" {
vpc_id = aws_vpc.vpc_1.id
cidr_block = "10.0.2.0/24"
availability_zone = "ap-south-1b"
map_public_ip_on_launch = "false"
depends_on = [aws_vpc.vpc_1]
tags = {
Name = "private_subs"
}
}
Now we will create a gateway which can provide connectivity between internet and our vpc. The gateway has been named "net_way".
resource "aws_internet_gateway" "net_way" {
vpc_id = aws_vpc.vpc_1.id
depends_on = [aws_vpc.vpc_1]
tags = {
Name = "net_way"
}
}
Now creating the route table and route table association
resource "aws_route_table" "r_table" {
vpc_id = aws_vpc.vpc_1.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.net_way.id
}
depends_on = [aws_vpc.vpc_1]
tags = {
Name = "r_table"
}
}
resource "aws_route_table_association" "rt_associate" {
subnet_id = aws_subnet.public_subs.id
route_table_id = aws_route_table.r_table.id
depends_on = [aws_subnet.public_subs]
}
Creating a security group which allows port 80 and 22 (ingress only!)
resource "aws_security_group" "s_g" {
name = "s_g"
description = "Allow TLS inbound traffic"
vpc_id = aws_vpc.vpc_1.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"]
}
depends_on = [aws_vpc.vpc_1]
tags = {
Name = "s_g"
}
}
Now creating our first instance. It will host the frontend of Wordpress. Here we will connect it to the public subnet. It has been connected to public subnet so public world can access it. The EC2 instance has been name "wordpress".
resource "aws_instance" "wordpress" {
ami = "ami-049cbce295a54b26b"
instance_type = "t2.micro"
key_name = "aaa111"
subnet_id = aws_subnet.public_subs.id
vpc_security_group_ids = [ "${aws_security_group.s_g.id}"]
tags = {
Name = "wordpress"
}
}
Here the output will be displayed on the cmd. The output is nothing but the public IP of wordpress ec2 instance.
output "wordpress_public_ip"{
value=aws_instance.wordpress.public_ip
}
Now let's create a security group for the backend instance which by default works on port 3306. After we had made the security group it's time to launch the second ec2 instance which will host the backend for wordpress and is connected to the private subnet to protcct it from hacker attacks and data losses. The instance has been named "sql_os".
resource "aws_security_group" "sql_s_g" {
name = "basic"
description = "Allow TLS inbound traffic"
vpc_id = aws_vpc.vpc_1.id
ingress {
description = "t3mysql"
from_port = 3306
to_port = 3306
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
depends_on = [aws_vpc.vpc_1]
tags = {
Name = "sql_s_g"
}
}
resource "aws_instance" "sql_os" {
ami = "ami-08706cb5f68222d09"
instance_type = "t2.micro"
key_name = "aaa111"
subnet_id = aws_subnet.private_subs.id
vpc_security_group_ids = [aws_security_group.sql_s_g.id]
tags = {
Name = "sql_os"
}
}
Once we are done with the above steps, we can proceed to the final step. This code snippet will launch chrome browser as soon as the wordpress site is UP.
resource "null_resource" "null" {
depends_on = [aws_instance.wordpress,aws_instance.sql_os]
connection {
type = "ssh"
user = "ec2-user"
private_key = file("C:/Users/ACER/Downloads/aaa111.pem")
host = aws_instance.wordpress.public_ip
}
provisioner "local-exec" {
command = "start chrome http://${aws_instance.wordpress.public_ip}/wordpress"
}
}
Okay so , we are done with theory and let's have some demo.
First of lets run the command :
terraform init
It will download all the necessary plugins.
Then we will run
terraform plan
Then run the following command:
terraform apply
When the terraform has successfully applied the script it takes about 2-3 minutes to compltely load the wordpress site , it depends on your internet speed too!
The above image is the home page of the wordpress.
In the above image you can see two OS running.
Now our wordpress has been successfully deployed so it time to celebrate.
But wait ! my aws account is on free tire and it comes with some limitations so let's destroy the whole setup first.
Give the following command to destroy the whole setup
terraform destroy
NOTE: The command displayed above is very destructive command so use it on your own risk ! I shall not been held responsible if anything goes wrong :)
So, 11 items were destroyed.
Way link to my Github repo
Thank you !