Create GKE Cluster and Deploy WordPress Application Using Terraform

Creating a Google Kubernetes Engine (GKE) cluster and deploying a WordPress application using Terraform involves several steps. Terraform is a powerful infrastructure-as-code tool that allows you to define and manage cloud resources in a declarative manner. In this post, I’ll guide you through creating a basic GKE cluster and deploying WordPress to it.

Before you begin, make sure you have the following prerequisites:

  • A Google Cloud Platform (GCP) account and a project set up.
  • Terraform installed on your local machine.
  • Google Cloud SDK (gcloud) installed and authenticated with your GCP project.
  • A basic understanding of Terraform and Kubernetes.

Here are the steps to create a GKE cluster and deploy WordPress using Terraform:

Set Up Your Terraform Configuration:

Create a directory for your Terraform configuration and create a main.tf file with the following contents:
I used the code from the GitHub repository and cloned it to a server using Git command to complete the process of setting up the entire article.

Initialize Terraform:

Run the following command in your Terraform directory to initialize the Google Cloud provider:

$ terraform init

Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/kubernetes...
- Finding hashicorp/google versions matching "4.74.0"...
- Finding latest version of hashicorp/helm...
- Installing hashicorp/kubernetes v2.23.0...
- Installed hashicorp/kubernetes v2.23.0 (signed by HashiCorp)
- Installing hashicorp/google v4.74.0...
- Installed hashicorp/google v4.74.0 (signed by HashiCorp)
- Installing hashicorp/helm v2.11.0...
- Installed hashicorp/helm v2.11.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running “terraform plan” to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

Terraform Plan:

I ran the ‘terraform plan’ command, but there are some necessary actions that need to be taken before proceeding.

$ gcloud auth login

Go to the following link in your browser:

$ gcloud config set project PROJECT_ID
$ gcloud config set project kindy-34411
Updated property [core/project].

$ gcloud auth application-default login

These credentials will be used by any library that requests Application Default Credentials (ADC).

$ terraform plan
data.google_container_engine_versions.gke_version: Reading...
data.google_client_config.provider: Reading...
data.google_client_config.provider: Read complete after 0s [id=projects/"kindy-34411"/regions/"us-central1"/zones/<null>]
data.google_container_engine_versions.gke_version: Read complete after 2s [id=2023-09-21 03:28:39.334811264 +0000 UTC]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

.............

Plan: 8 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + kubernetes_cluster_host = (known after apply)
  + kubernetes_cluster_name = "kindy-34411-gke"
  + project_id              = "kindy-34411"
  + region                  = "us-central1"

─────────────────────────────────────────────────────

Note: You didn’t use the -out option to save this plan, so Terraform can’t guarantee to take exactly these actions if you run “terraform apply” now.

Terraform Apply:

Apply the Terraform configuration to create the GKE cluster and deploy WordPress:

$ terraform apply
data.google_container_engine_versions.gke_version: Reading...
data.google_client_config.provider: Reading...
data.google_client_config.provider: Read complete after 0s [id=projects/"kindy-34411"/regions/"us-central1"/zones/<null>]
data.google_container_engine_versions.gke_version: Read complete after 1s [id=2023-09-21 03:31:16.488954756 +0000 UTC]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

.............

Plan: 8 to add, 0 to change, 0 to destroy.

Changes to Outputs:
  + kubernetes_cluster_host = (known after apply)
  + kubernetes_cluster_name = "kindy-34411-gke"
  + project_id              = "kindy-34411"
  + region                  = "us-central1"

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

google_compute_network.vpc: Creating...
google_compute_network.vpc: Still creating... [10s elapsed]
google_compute_network.vpc: Creation complete after 12s [id=projects/kindy-34411/global/networks/kindy-34411-vpc]
google_compute_subnetwork.subnet: Creating...
google_compute_subnetwork.subnet: Still creating... [10s elapsed]
google_compute_subnetwork.subnet: Creation complete after 14s [id=projects/kindy-34411/regions/us-central1/subnetworks/kindy-34411-subnet]
google_container_cluster.primary: Creating...
google_container_cluster.primary: Still creating... [10s elapsed]

.............

Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Outputs:

kubernetes_cluster_host = "37.122.74.177"
kubernetes_cluster_name = "kindy-34411-gke"
project_id = "kindy-34411"
region = "us-central1"

Setup Completed.

Connecting GKE Cluster:

$ gcloud container clusters get-credentials kindy-34411-gke --zone us-central2-a
Fetching cluster endpoint and auth data.
kubeconfig entry generated for kindy-34411-gke.

Verifying Cluster:

$ kubectl get nodes
NAME                                                  STATUS   ROLES    AGE    VERSION
gke-kindy-34411-kindy-34411-65a8ba69-cfsn   Ready    <none>   7m2s   v1.27.4-gke.900
gke-kindy-34411-kindy-34411-65a8ba69-gt2m   Ready    <none>   7m2s   v1.27.4-gke.900

$ kubectl get all
NAME                                            READY   STATUS    RESTARTS   AGE
pod/hello-app-5fd4d7d9d5-2vztr                  1/1     Running   0          8m7s
pod/ingress-nginx-controller-5dcc7dbd55-5kbzz   1/1     Running   0          6m41s
pod/wordpress-78bb764d54-hqnz9                  1/1     Running   0          8m3s
pod/wordpress-mysql-b759dbb45-9mslj             1/1     Running   0          8m3s

NAME                                         TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
service/hello-app                            ClusterIP      10.211.245.106   <none>        8080/TCP                     8m9s
service/ingress-nginx-controller             LoadBalancer   10.211.248.41    34.30.97.23   80:32605/TCP,443:32150/TCP   6m42s
service/ingress-nginx-controller-admission   ClusterIP      10.211.255.163   <none>        443/TCP                      6m42s
service/kubernetes                           ClusterIP      10.211.240.1     <none>        443/TCP                      12m
service/wordpress                            ClusterIP      10.211.249.145   <none>        80/TCP                       8m4s
service/wordpress-mysql                      ClusterIP      None             <none>        3306/TCP                     8m4s

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/hello-app                  1/1     1            1           8m8s
deployment.apps/ingress-nginx-controller   1/1     1            1           6m42s
deployment.apps/wordpress                  1/1     1            1           8m4s
deployment.apps/wordpress-mysql            1/1     1            1           8m4s

NAME                                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/hello-app-5fd4d7d9d5                  1         1         1       8m8s
replicaset.apps/ingress-nginx-controller-5dcc7dbd55   1         1         1       6m42s
replicaset.apps/wordpress-78bb764d54                  1         1         1       8m4s
replicaset.apps/wordpress-mysql-b759dbb45             1         1         1       8m4s

Cleanup (Optional):

If you want to destroy the resources created by Terraform when you’re done, you can use:

$ terraform destroy
Destroy complete! Resources: 8 destroyed.

This example provides a basic setup for deploying WordPress on a GKE cluster using Terraform. Depending on your specific requirements, you may want to customize the configuration further, such as setting up a managed Cloud SQL database for WordPress, configuring SSL certificates, and so on.

References:

https://kubernetes.io/docs/
https://www.redhat.com/en/topics/containers/what-is-kubernetes
https://www.ibm.com/topics/kubernetes
https://www.infoworld.com/article/3268073/what-is-kubernetes-your-next-application-platform.html
https://www.terraform.io/
https://developer.hashicorp.com/terraform/intro
https://registry.terraform.io/
https://registry.terraform.io/providers/hashicorp/terraform/latest
https://developer.hashicorp.com/terraform/language/resources
https://www.pluralsight.com/resources/blog/cloud/the-ultimate-terraform-cheatsheet

 

Avatar photo

Asif Khan

Responsible and proactive professional with more than 13 years of experience in IT systems, open source software applications, DevOps, Linux systems, and cloud operations. My main goals are to automate things, keep them safe, and make sure they are strong. I am very good at planning and building the infrastructure for services that people really want. I was drawn to the fast-paced world of cloud computing because it has resources that can be scaled up or down as needed. One of my best skills is being able to use a lot of different DevOps tools to set up, release management, and microservices ecosystems, as well as for provisioning, orchestration, and configuration management.