Deploying Public Wordpress and Private MySQL on AWS EC2 Service…

✨ In this article I would like to secure the web portal which involves WordPress as front end and MySQL database as back end which contains all users data of web portal …
📝 Description: Write an Infrastructure as code using terraform, which automatically create a VPC.
✅ In that VPC we have to create 2 subnets:
1. public subnet [ Accessible for Public World! ]
2. private subnet [ Restricted for Public World! ]
✅Create a public facing internet gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC.
✅ Create a routing table for Internet gateway so that instance can connect to outside world, update and associate it with public subnet.
✅ Create a NAT gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC in the public network
✅ Update the routing table of the private subnet, so that to access the internet it uses the nat gateway created in the public subnet
✅ 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.
✅ 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 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.
🏄 Let’s jump to the practical
🎯 Step 1: Set the aws provider with your selected region and profile…
# AWS Provider
provider "aws" {
region = "ap-south-1"
profile = "<profile name>"
}
🎯 Step 2: Create a new VPC with certain IP range …
# creating VPC
resource "aws_vpc" "vpcmain" {
cidr_block = "192.168.0.0/16"
instance_tenancy = "default"
enable_dns_hostnames = "true"
tags = {
Name = "tf_nkvpc"
}
}
🎯 Step 3: Create one public subnet to launch wordpress and one private subnet to launch MySQL …
# public subnet
resource "aws_subnet" "subnet1a_public" {
vpc_id = "${aws_vpc.vpcmain.id}"
cidr_block = "192.168.0.0/24"
availability_zone = "ap-south-1a"
map_public_ip_on_launch = "true" tags = {
Name = "nksubnet-1a-public"
}
}# private subnet
resource "aws_subnet" "subnet1b_private" {
vpc_id = "${aws_vpc.vpcmain.id}"
cidr_block = "192.168.1.0/24"
availability_zone = "ap-south-1b"
map_public_ip_on_launch = false tags = {
Name = "nksubnet-1b-private"
}
}
while giving the CIDR_Block to subnets, give the range which is in the range of VPC CIDR_Block … Otherwise it will give you error …
🎯 Step 4: Create a public facing internet gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC. And a routing table for Internet gateway so that wordpress instance can connect to outside world, update and associate it with public subnet.
# Internet Gateway
resource "aws_internet_gateway" "myingw" {
vpc_id = "${aws_vpc.vpcmain.id}" tags = {
Name = "nk_internet_gw"
}
}# Creating route table
resource "aws_route_table" "routingingw" {
depends_on = [
aws_internet_gateway.myingw
] vpc_id = "${aws_vpc.vpcmain.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.myingw.id}"
}
tags = {
Name = "rtinternetgw"
}
}# Associate route table with public subnet
resource "aws_route_table_association" "sb-ass1" {
depends_on = [
aws_route_table.routingingw
] subnet_id = "${aws_subnet.subnet1a_public.id}"
route_table_id = "${aws_route_table.routingingw.id}"
}
🎯 Step 5: Create a NAT gateway for connect our VPC/Network to the internet world and attach this gateway to our VPC in the public network. And update the routing table of the private subnet, so that to access the internet it uses the nat gateway created in the public subnet… To create the NAT Gateway we need to allocate one Elastic IP to NAT Gateway …
# Elastic IP
resource "aws_eip" "awseip" {
vpc = true
tags = {
Name = "myeip"
}
}# NAT Gateway
resource "aws_nat_gateway" "mynatgw" {
depends_on = [
aws_eip.awseip
] allocation_id = "${aws_eip.awseip.id}"
subnet_id = "${aws_subnet.subnet1a_public.id}" tags = {
Name = "gw NAT”
}
}# route table
resource "aws_route_table" "routingnatgw" {
depends_on = [
aws_nat_gateway.mynatgw
] vpc_id = "${aws_vpc.vpcmain.id}"
route {
cidr_block = "0.0.0.0/0"
gateway_id = "${aws_nat_gateway.mynatgw.id}"
}
tags = {
Name = "rtnatgw"
}
}# Associate route table with private subnet
resource "aws_route_table_association" "sb-ass2" {
depends_on = [
aws_route_table.routingnatgw
] subnet_id = "${aws_subnet.subnet1b_private.id}"
route_table_id = "${aws_route_table.routingnatgw.id}"
}
🎯 Step 6: 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.
# creating Security group
resource "aws_security_group" "wpsecurity" {
depends_on = [
aws_route_table_association.sb-ass1
] name = "wp_security"
description = "Allow SSH, HTTP for WP"
vpc_id = "${aws_vpc.vpcmain.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 = "wp_sg"
}
}# launching ec2 instance
resource "aws_instance" "wordpress" {
depends_on = [
aws_security_group.wpsecurity
] ami = "ami-0e306788ff2473ccb"
instance_type = "t2.micro"
associate_public_ip_address = true
subnet_id = "${aws_subnet.subnet1a_public.id}"
key_name = "mykey11"
availability_zone = "ap-south-1a"
vpc_security_group_ids = [aws_security_group.wpsecurity.id] tags = {
Name = "wp_os"
}
}
After launching MySQL instance, then we have to connect wordpress with MySQL Instance for storing the data … Now create a instance with MySQL Setup …
🎯 Step 7: Launch an ec2 instance which has MYSQL setup already with security group allowing port 3306 in private subnet so that our wordpress instance can connect with the same.
# creating security group
resource "aws_security_group" "mysqlsecurity" {
depends_on = [
aws_route_table_association.sb-ass2
] name = "mysql_security"
description = "Allow MySQL(3306) and wp_security for MySQL"
vpc_id = "${aws_vpc.vpcmain.id}" ingress {
description = "MySQL"
from_port = 3306
to_port = 3306
protocol = "tcp"
security_groups = [ aws_security_group.wpsecurity.id ]
} egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = [ "0.0.0.0/0" ]
} tags = {
Name = "mysql_sg"
}
}# launching instance and setup MySQL
resource "aws_instance" "mysql" {
depends_on = [
aws_instance.wordpress
] ami = "ami-0e306788ff2473ccb"
instance_type = "t2.micro"
subnet_id = "${aws_subnet.subnet1b_private.id}"
availability_zone = "ap-south-1b"
vpc_security_group_ids = [aws_security_group.mysqlsecurity.id] user_data = <<END
#!/bin/bash
sudo yum install mariadb-server mysql -y
sudo systemctl enable mariadb.service
sudo systemctl start mariadb.service
mysql -u root <<EOF
create user 'kumar'@'${aws_instance.wordpress.private_ip}' identified by 'rootpass';
create database mywpdb;
grant all privileges on mywpdb.* to 'kumar'@'${aws_instance.wordpress.private_ip}';
exit
EOF
END tags = {
Name = "sql_os"
}
}
🎯 Step 8: Now connect to wordpress instance and setup wordpress using docker container and then start the container using wordpress image along with MySQL username and password etc,…
resource "null_resource" "login-to-wp" {
depends_on = [
aws_instance.mysql
] connection {
type = "ssh"
user = "ec2-user"
private_key = file(“/home/nithish/Downloads/mykey11.pem”)
host = aws_instance.wordpress.public_ip
} provisioner "remote-exec" {
inline = [
"sudo su <<END",
"yum install docker httpd -y",
"systemctl enable docker",
"systemctl start docker",
"docker pull wordpress:5.1.1-php7.3-apache",
"sleep 20",
"docker run -dit -e WORDPRESS_DB_HOST=${aws_instance.mysql.private_ip} -e WORDPRESS_DB_USER=kumar -e WORDPRESS_DB_PASSWORD=rootpass -e WORDPRESS_DB_NAME=mywpdb -p 80:80 wordpress:5.1.1-php7.3-apache",
"END",
]
}
}
🎯 Step 9: Using terraform we can write a code to open the wordpress IP in any browser … Here is the code,..
resource "null_resource" "openwpsite" {
depends_on = [
null_resource.login-to-wp
] provisioner "local-exec" {
command = "google-chrome http://${aws_instance.wordpress.public_ip} &"
}
}
🎯 Now run the terraform code …
terraform apply --auto-approve




→By writing the step 9 code, the terraform code automatically opens the browser and browse the wordpress instance IP …

🎯 After Done with the task, destroy all the services using below cmd:
terraform destroy --auto-approve
👏 Finally, the task done ,…
🤝 Thanks for reading,…
📄 Here is the GitHub Link…
…. Signing Off ….