WordPress Application Deployment on Kubernetes Pod with MySQL database on AWS RDS using Terraform

Juzer Patanwala
5 min readSep 1, 2020

--

In this guide,we will be creating an Infrastructure as a Code(IaaS) using terraform,which automatically deploys WordPress application along with Database.We will be using AWS RDS service for creating the database making it publicly accessible for our WordPress server which will be deployed on Kubernetes pod using a single-node minikube cluster.

What is AWS RDS?

Amazon Relational Database Service (Amazon RDS) is a web service that makes it easier to set up, operate, and scale a relational database in the AWS Cloud. It provides cost-efficient, resizable capacity for an industry-standard relational database and manages common database administration tasks.

Amazon RDS provides a selection of instance types optimized to fit different relational database use cases.

What is Kubernetes?

Kubernetes is an open source project that has become one of the most popular container orchestration tools around; it allows you to deploy and manage multi-container applications at scale. While in practice Kubernetes is most often used with Docker, the most popular containerization platform, it can also work with any container system

Kubernetes clusters can be either Single-node or Multi-node.Here,we will be using minikube for automatically creating a single-node Kubernetes cluster.

Create Single-node Kubernetes cluster using minikube

All this can be done with a single command.After that just start the minikube cluster.

minikube start --vm-driver virtualbox
minikube start

Provide AWS credentials and kubernetes cluster configuration context

For using AWS services we have to provide our AWS profile in the terraform code which contains our credentials.Also,we have to provide cluster cnfiguration context of kubernetes cluster.

provider "aws" {
region = "ap-south-1"
profile = "juzer"
}
provider "kubernetes" {
config_context_cluster = "minikube"
}

Create a security group for RDS allowing MySQL access

We will be creating a security group with ingress rule allowing access to port 3306 publicly.

resource "aws_security_group" "sql_sg" {
name = "mysqlsg"
description = "Allow MYSQL inbound traffic"
vpc_id = "vpc-5de8f535"
ingress {
description = "Allow MYSQL"
from_port = 3306
to_port = 3306
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_mysql"
}
}

Create AWS RDS Instance

Here,we will be creating DB Instance which is publicly accessible so that it can be accessed by the WordPress server running outside the cloud.Also, I have used MySQL(5.7.30) as database engine,you can select any other as well.

resource "aws_db_instance" "mysql" {

allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7.30"
instance_class = "db.t2.micro"
name = "mysql_wordpress"
username = "admin"
password = "juzer7894"
parameter_group_name = "default.mysql5.7"
publicly_accessible = "true"
port = "3306"
vpc_security_group_ids= ["${aws_security_group.sql_sg.id}",]
final_snapshot_identifier = "false"
skip_final_snapshot = "true"
}

With this,our MySQL Database is successfuly deployed on AWS.

Now,we will be deploying the WordPress server on Kubernetes.

Create Kubernetes Deployment with WordPress as container image

Here,we will create a Kubernetes deployment which ensures that the said number of replicas of the WordPress pod is always running.Deployment in Kubernetes uses labels as selector for determining it’s target pods.Thus,we will provide the labels of our WordPress pod as selector to the deployment(RepicaSet can also be used instead of Deployment).

resource "kubernetes_deployment" "WordPress_deploy" {
depends_on = [aws_db_instance.mysql]
metadata {
name = "wp"

}

spec {
replicas = 1

selector {
match_labels = {
app = "wordpress"
}
}

template {
metadata {
name = "wp-pod"
labels = {
app = "wordpress"
}
}

spec {
container {
image = "wordpress:4.8-apache"
name = "wp_cloud"


}

}

Create NodePort service for exposing WordPress server

Kubernetes pods are by default isolated which means they cannot be accessed from other systems or networks.For making our WordPress server accessible we have to expose the port no 80 of the pod.This can be done by using the NodePort service of Kubernetes which exposes the port 80 such that whenever any client comes to the IP of the node on the Node Port specified,they will automatically get redirected to the Port 80 of WordPress pod.

NodePort also uses labels for finding the target pods whose port 80 will get exposed.

resource "kubernetes_service" "service" {
depends_on = [kubernetes_deployment.WordPress_Deploy]
metadata {
name = "wp-service"
}
spec {
selector = {
app = kubernetes_deployment.WordPress_deploy.metadata.0.labels.app
}

port {
port = 8080
target_port = 80
}

type = "NodePort"
}
}

Now,we can use the following terraform commands for deploying our entire setup.

terraform init //Initializes plug-ins
terraform apply

Finally,our WordPress server is successfully deployed on the top of Kubernetes.

We can use kubectl all all command for viewing all the deployments and services created.

Now,we can access our WordPress application using the minikube node IP:NodePort.

If this screen is visible,then the deployment is successfull.

We have to provide the database name,username and password we have used while creating the RDS database.Notice,instead of localhost,we have to provide the RDS instance end-point in the Database Host field.

After this,we can just install WordPress and log-in with provided username and password.

Hence,we have successfully deployed the WordPress application on Kubernetes pod with AWS RDS Database.

Thank You!

--

--

Juzer Patanwala

Cloud Engineer @ Searce Inc || Technical Content Writer || Technology and Automation Enthusiast