WordPress Web-server with Secure Mysql Database in AWS
In this post, we are going to deploy a complete infrastructure of WordPress with MySQL database in which only WordPress can access to MySQL instance.
What is WordPress?
WordPress is a free and open-source content management system written in PHP and paired with a MySQL or MariaDB database.
What is Terraform?
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.
It an open-source infrastructure as a code software tool created by HashiCorp. It enables users to define and provision a data center infrastructure using a high-level configuration language known as Hashicorp Configuration Language.
Task Overview —
- Write an Infrastructure as code using Terraform, which automatically creates a VPC.
- In that VPC we have to create 2 subnets:
- public subnet [ Accessible for Public World! ]
- private subnet [ Restricted for Public World! ]
- Create a public-facing internet gateway to 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 the outside world, update and associate it with the public subnet.
- Launch an ec2 instance that has WordPress setup already having the security group allowing port 80 so that our client can connect to our WordPress site.
- Launch an ec2 instance that has MYSQL setup already with security group allowing port 3306 in a private subnet so that our WordPress VM can connect with the same.
Procedure —
Step 1
Create a file with an extension .tf
Step 2
Write the code in the same.
Providing credentials to AWS —
provider “aws” {region = “ap-south-1”profile = “default”}
Creating a VPC —
resource "aws_vpc" "task_vpc" {cidr_block = "192.168.0.0/16"instance_tenancy = "default"tags = {Name = "Task-3"}}
Creating a public and private subnet —
resource "aws_subnet" "public_subnet" {depends_on = [ aws_vpc.task_vpc]vpc_id = aws_vpc.task_vpc.idcidr_block = "192.168.3.0/24"availability_zone = "ap-south-1a"tags = {Name = "public_subnet"} }resource "aws_subnet" "private_subnet" {depends_on = [ aws_vpc.task_vpc]vpc_id = aws_vpc.task_vpc.idcidr_block = "192.168.2.0/24"availability_zone = "ap-south-1b"tags = {Name = "private_subnet"} }
Create an gateway —
resource "aws_internet_gateway" "task_ig" {depends_on = [ aws_vpc.task_vpc ]vpc_id = aws_vpc.task_vpc.idtags = {Name = "task_ig"}}
Create a route table and route table association —
resource "aws_route_table" "router" {depends_on = [ aws_internet_gateway.task_ig ]vpc_id = aws_vpc.task_vpc.idroute {cidr_block = "0.0.0.0/0"gateway_id = aws_internet_gateway.task_ig.id}tags = {Name = "router_task"} }resource "aws_route_table_association" "router-association" {depends_on = [ aws_route_table.router ]subnet_id = aws_subnet.public_subnet.idroute_table_id = aws_route_table.router.id}
Create AWS Eib , routing table and nat gateway —
resource "aws_eip" "task_ip" {vpc = truedepends_on = [aws_internet_gateway.task_ig]}resource "aws_nat_gateway" "task_nat" {allocation_id = aws_eip.task_ip.idsubnet_id = aws_subnet.public_subnet.idtags = {Name = "task NAT"} }resource "aws_route_table" "nat_route" {depends_on = [aws_nat_gateway.task_nat]vpc_id = aws_vpc.task_vpc.idroute {cidr_block = "0.0.0.0/0"nat_gateway_id = aws_nat_gateway.task_nat.id}tags = {Name = "NAT_RouteTable"}}
resource "aws_route_table_association" "NAT_assocation" {depends_on = [aws_subnet.private_subnet, aws_route_table.nat_route]subnet_id = aws_subnet.private_subnet.idroute_table_id = aws_route_table.nat_route.id}
Create an Security Group for MYSQL instance —
resource "aws_security_group" "MySQL_SG" {depends_on = [aws_security_group.WP_SG]name = "SG_MySQL"description = "Allow TLS inbound traffic"vpc_id = aws_vpc.task_vpc.idingress{description = "SSH"from_port = 22to_port = 22security_groups =[ aws_security_group.WP_SG.id]protocol = "tcp"cidr_blocks = ["0.0.0.0/0"]}ingress {description = "MySQL"from_port = 3306to_port = 3306protocol = "tcp"cidr_blocks = ["0.0.0.0/0"]}ingress {description = "MySQL redirection"from_port = 8080to_port = 8080protocol = "tcp"cidr_blocks = ["0.0.0.0/0"]}egress {from_port = 0to_port = 0protocol = "-1"cidr_blocks = ["0.0.0.0/0"]}tags = {Name = "MySQL_SG"}
Launching an ec2 instance using custom AMI —
Note — The ami used was creating by me using amazon linux and installing docker in the same.
resource "aws_instance" "MySQL" {depends_on = [aws_security_group.MySQL_SG, tls_private_key.task_key]ami = "ami-04ca6b22ca88bdbea"instance_type = "t2.micro"key_name = "task_key"vpc_security_group_ids = [ aws_security_group.MySQL_SG.id ]subnet_id = aws_subnet.private_subnet.iduser_data = <<-EOF#!/bin/bashsudo docker run -dit -p 8080:3306 --name mysql -e MYSQL_ROOT_PASSWORD=master -e MYSQL_DATABASE=Task-3-db -e MYSQL_USER=anmol -e MYSQL_PASSWORD=redhat mysql:5.6EOFtags = {Name = "MySQL-OS"}}
Generating private key and storing it to local storage —
resource "tls_private_key" "task_key" {algorithm = "RSA"}# Saving to local systemresource "local_file" "save_key" {depends_on = [ tls_private_key.task_key]content = tls_private_key.task_key.private_key_pemfilename = "task_key.pem"}# Sending public key to awsresource "aws_key_pair" "public_key" {depends_on = [local_file.save_key]key_name = "task_key"public_key = tls_private_key.task_key.public_key_openssh}
Creating a Security group for Wordpress Instance —
resource "aws_security_group" "WP_SG" {
name = "WordPress_SG"
description = "Allow TLS inbound traffic"
vpc_id = aws_vpc.task_vpc.id
ingress{
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "Http port"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
description = "Http redirection"
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 = "WordPress_SG"
}
}
Launching an ec2 instance for wordpress using custom ami and running wordpress on Docker —
Note — The ami used was creating by me using amazon linux and installing docker in the same.
resource "aws_instance" "WordPress" {depends_on = [tls_private_key.task_key, aws_security_group.WP_SG]ami = "ami-04ca6b22ca88bdbea"instance_type = "t2.micro"associate_public_ip_address = truevpc_security_group_ids = [ aws_security_group.WP_SG.id ]subnet_id = aws_subnet.public_subnet.idkey_name = "task_key"user_data = <<-EOF#!/bin/bashsudo docker run -dit -p 8000:80 --name wp wordpress:4.8-apacheEOFtags = {Name = "WordPress-OS"}}
To run the above code —
terraform apply
Note — make sure to delete the infrastructure as soon as your task is complete, to avoid unnecessary billing.
terraform destory
Output —
Open the public Ip of Wordpress instance and enter the credentials of the MYSQL Database created in other ec2 instance.