Launching AWS VPC, Public and Private Subnets using Terraform
Task Description:-
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.
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.
Note: Wordpress instance is a part of public subnet so that our client can connect our site and MYSQL instance is a part of private subnet so that outside world can't connect to it.
Terraform Code :-
Provider -
Firstly, we will provide the Provider to the Terraform which is aws along with region and profile.
provider "aws" { region = "ap-south-1" profile = "yashika"
}
VPC -
We created a VPC that has certain range of IP address's which is also known as CIDR. This will be provided to the subnets.
Here, I am providing the IP address range or CIDR = 192.168.0.0/16
resource "aws_vpc" "vpc_task3" { cidr_block = "192.168.0.0/16" instance_tenancy = "default" enable_dns_hostnames = true enable_dns_support = true tags = { Name = "vpc_task3" } }
Now, we have to create two Subnets - one is Public and one is Private.
Public Subnet -
This Subnet is connected to the internet. This Subnet is launched in the availability zone ap-south-1a to launch the Wordpress. Also enable the auto public ip assign so that client can access the site.
resource "aws_subnet" "public_subnet" { vpc_id = aws_vpc.vpc_task3.id cidr_block = "192.168.0.0/24" availability_zone = "ap-south-1a" map_public_ip_on_launch = true tags = { Name = "public_subnet" } }
Private Subnet -
This Subnet is not conneted to internet so that the MYSQL in it is secure and cannot be access by the outside. It is in the availability zone ap-south-1b region.
resource "aws_subnet" "private_subnet" { vpc_id = aws_vpc.vpc_task3.id cidr_block = "192.168.1.0/24" availability_zone = "ap-south-1b" tags = { Name = "private_subnet" } }
Internet Gateway -
Next we created an internet gateway so that our public subnet can connect to outside world and client can access the Wordpress site.
resource "aws_internet_gateway" "igw_task3" { vpc_id = aws_vpc.vpc_task3.id tags = { Name = "igw_task3" }
}
Route Tables -
Creating a route table. A route table contains a set of rules, called routes, that are used to determine where network traffic from your subnet or gateway is directed. Also we have to associate the route table to our public subnet so that it can know where is the internet gateway to connect to the outside world.
resource "aws_route_table" "route_task3" { vpc_id = aws_vpc.vpc_task3.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.igw_task3.id } tags = { Name = "task3_routeTable" } }
resource "aws_route_table_association" "route_assosciation" { subnet_id = aws_subnet.public_subnet.id route_table_id = aws_route_table.route_task3.id }
AMI -
For launching instances in the subnets we used our own created AMI which has docker and httpd installed. It also has docker images - wordpress:5.1.1-php7.3-apache and mysql:5.7
Mysql Instance -
We launched an instance in the private subnet using our own AMI. We will launch a docker container for MYSQL inside this instance.
The security group for MYSQL instance - two inbound rules, one for port 3306 as mysql runs on this port and another port 8080 as we will use this port to expose our mysql docker container.
resource "aws_instance" "mysql" { ami = "ami-0b2bbc9c1b51a5544" instance_type = "t2.micro" subnet_id = aws_subnet.private_subnet.id key_name = "mykey" vpc_security_group_ids = [ aws_security_group.sg1.id ] user_data = <<-EOF #!/bin/bash sudo docker run -dit -e MYSQL_ROOT_PASSWORD=redhat -e MYSQL_DATABASE=mydb -e MYSQL_USER=yashika -e MYSQL_PASSWORD=redhat -p 8080:3306 --name mysqlos mysql:5.7 EOF tags = { Name = "mysql" } }
Security Group :-
resource "aws_security_group" "sg1" { name = "sg1" description = "Allow TCP inbound traffic" vpc_id = aws_vpc.vpc_task3.id ingress { description = "TLS from VPC" from_port = 3306 to_port = 3306 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "TLS from VPC" from_port = 8080 to_port = 8080 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 = "mysql_http" } }
Wordpress Instance -
We launched another instance in the public subnet for the WordPress. But again for this we have first create a security group which allows port 80 since WordPress runs on port 80. Then we launch EC2 instance using my AMI inside which we launch docker container for the WordPress.
resource "aws_instance" "wordpress1"{ ami = "ami-0b2bbc9c1b51a5544" instance_type = "t2.micro" subnet_id = aws_subnet.public_subnet.id key_name = "mykey" vpc_security_group_ids = [ aws_security_group.wp.id ] user_data = <<-EOF #!/bin/bash sudo docker run -dit -p 8000:80 --name wp wordpress:5.1.1-php7.3-apache EOF tags = { Name = "wordpress1" } }
Security Group :-
resource "aws_security_group" "wp" { name = "wp" description = "Allow TLS inbound traffic" vpc_id = aws_vpc.vpc_task3.id ingress { description = "TLS from VPC" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ingress { description = "TLS from VPC" from_port = 8000 to_port = 8000 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_wp" }
}
Now to download the required plugins we will run the following command -
terraform init
For creating the whole infrastructure, run the following command -
terraform apply --auto-approve
So now we can access the WordPress using the public IP of the of the Wordpress instance, which stores all its data in the MYSQL which is running in the private subnet so that our data is secure.
We can see all the deployments in our AWS Management Console -
VPC
SUBNETS
INTERNET GATEWAY
ROUTE TABLE
INSTANCES
SECURITY GROUPS
After entering the IP of Wordpress, we have to do the setup.
GitHub Link:-
THANK YOU !!
Great 👍👍