Deploying WordPress on Kubernetes with AWS RDS using Terraform

Image for post
Image for post

About Kubernetes

If you want to run any program then we need an operating system. To install the operating system we have four ways

Baremetel

Virtual Machine

Cloud

Container

Docker is container technology. In docker within a second, we can launch and terminate OS. If you want your OS inside docker keeps on running and if it fails then it will start automatically then to setup multiple things but with the help of COE(container orchestration engine), we can avoid all setup. We just have to tell COE what we want and it will launch for us.

Kubernetes is one of the COE. It is a management tool. If you deploy any container with the help of Kubernetes then it will keep track of that container. Even if that container goes down it will again launch for you. This is just one use case there are many more.

About AWS — RDS

As we all know AWS is a public cloud that provides us multiple services. AWS also provides us Database As A Service. Service name is RDS. (Relational Database Service) Amazon RDS makes it easy to set up, operate, and scale a relational database in the cloud. with the help of RDS, we can achieve fast performance, high availability, and security. we have multiple database instances available in RDS like Amazon Aurora, MySQL, MariaDB, Oracle Database. Here I am using MySQL.

About Hybrid Setup

Here I am launching a WordPress site on container technology and to manage this container I am taking help of Kubernetes. To store Data of WordPress we need a Database. In this application our critical part is Database. If the WordPress site goes down Kubernetes will launch again but If the database goes down we will lose our complete data. For this, I am launching a database on AWS to achieve high availability and security. To automate all this process so that just in one click my complete setup is ready, I am using Terraform here.

Lets Start…

In this example, I am writing code for launching WordPress and Database in different files. And to ensure everything will execute in the correct order I am putting dependencies.

Step 1

We have to give the service provider information to Terraform.

provider "aws" {
region = "ap-south-1"
profile = "abhimanyu"
}

Step 2

Create a Security group for RDS. Inside the security group, we have to allow incoming traffic from MySQL port i.e port number 3306.

resource "aws_security_group" "rds" {
name = "rds"
description = "Allow mysql inbound traffic"
ingress{
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"]
}
}

Step 3

Launch the database instance for WordPress using the above security group.

resource "aws_db_instance" "wordpressdb" {
depends_on = [aws_security_group.rds]
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "wordpressdb"
username = "wordpressuser"
password = "mysql15.7"
parameter_group_name = "default.mysql5.7"
publicly_accessible = true
skip_final_snapshot = true
vpc_security_group_ids= [aws_security_group.rds.id]
tags = {
name = "wordpres-mysql"
}
}

As our Database code is ready Now we have to write code for launching WordPress using Kubernetes

Step 4

We have to give the Kubernetes service provider information to Terraform.

provider "kubernetes" {
config_context = "minikube"
}

Step 5

Create a new Namespace for WordPress. The namespace provides us logical separation.

resource "kubernetes_namespace" "hybrid-setup" {
metadata {
name = "hybrid-setup"
}
}

Step 6

We have to create a PVC claim. PVC stands for Persistent Volume Claim. It is a request for storage by the user. With the help of PV( Persistent Volume ), we can achieve data availability. i.e Even if the WordPress server goes down and it will launch again within a second, we won’t lose any settings or data which is stored in the WordPress container

resource "kubernetes_persistent_volume_claim" "wordpress_pvc" {
depends_on = [aws_db_instance.wordpressdb]
metadata {
name = "newwordpressclaim"
namespace = kubernetes_namespace.hybrid-setup.id
}
spec {
access_modes = ["ReadWriteOnce"]
resources {
requests = {
storage = "5Gi"
}
}
}
}

Step 7

Launch WordPress deployment. In deployment, we can specify how many WordPress servers we want to launch, and it will launch for us. It will also take care of all running pods inside it. If one of the pod goes down it will launch again with the same configuration within seconds.

resource "kubernetes_deployment" "wordpress" {
depends_on = [kubernetes_persistent_volume_claim.wordpress_pvc]
metadata {
name = "wordpress"
namespace = kubernetes_namespace.hybrid-setup.id
labels = {
Env = "wordpress"
}
}
spec {
replicas = 1
selector {
match_labels = {
Env = "wordpress"
}
}
template {
metadata {
labels = {
Env = "wordpress"
}
}
spec {
container {
name = "wordpress"
image = "wordpress:4.8-apache"
env{
name = "WORDPRESS_DB_HOST"
value = aws_db_instance.wordpressdb.address
}
env{
name = "WORDPRESS_DB_USER"
value = aws_db_instance.wordpressdb.username
}
env{
name = "WORDPRESS_DB_PASSWORD"
value = aws_db_instance.wordpressdb.password
}
env{
name = "WORDPRESS_DB_NAME"
value = aws_db_instance.wordpressdb.name
}
port {
container_port = 80
}
volume_mount{
name = "pv-wordpress"
mount_path = "/var/lib/pam"
}
}
volume{
name = "pv-wordpress"
persistent_volume_claim{
claim_name = kubernetes_persistent_volume_claim.wordpress_pvc.metadata[0].name
}
}
}
}
}
}

Step 8

Expose this pod to the outside world so that our clients can WordPress site.

resource "kubernetes_service" "expose" {
depends_on = [kubernetes_deployment.wordpress]
metadata {
name = "exposewp"
namespace = kubernetes_namespace.hybrid-setup.id
}
spec {
selector = {
Env = "${kubernetes_deployment.wordpress.metadata.0.labels.Env}"
}
port {
node_port = 32123
port = 80
target_port = 80
}
type = "NodePort"
}
}

Step 9 ( optional )

After everything is completed I want to run the WordPress on chrome. For this, I am using null_resource to run commands on windows.

resource "null_resource" "runwebpage"  {
depends_on = [kubernetes_service.expose]
provisioner "local-exec" {
command = "chrome http:://192.168.99.102:${kubernetes_service.expose.spec[0].port[0].node_port}"
}
}

Here I have given static IP which is allocated to Minikube by my system. To get this IP run the following command in cmd of windows.

Image for post
Image for post

If you have done step 9 then terraform will automatically open following page on chrome.

Image for post
Image for post

If you see this page means everything is working well. After this, you can continue to install WordPress and create a login.

With the help of below, you can monitor RDS on AWS WebUI.

You can also confirm about WordPress on windows using the following commands.

Image for post
Image for post

Github link

Thanks for reading …

Written by

Love to write technical blog

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store