WordPress on Kubernetes with GCP and Workload Identity: part 1

We just announced Beta availability of Config Connector – Kubernetes Extension that allows you to manage Google Cloud service as native Kubernetes resources. This post is part 1 of the two part series that will show, how you can configure a WordPress site running on Kubernetes, powered by GCP MySQL database and Workload Identity. As you will see, Config Connector lets you build that are fully declarative, idempotent, auto-healing, just like any Kubernetes user would expect.

Provision GCP project and GKE cluster

First of all, we’ll create a project and a cluster. You can update the snippet below, substituting your [PROJECT_ID] and [BILLING_ACCOUNT] or skip the part that is creating a project.

To clarify, this command to create the cluster is using Beta API that enables Workload Identity. Workload Identity significantly simplifies authorization. Consequently, it is now the recommended way to access GCP APIs from Kubernetes. In the second part of this post, I will summarize all the required steps to configure workload identity.

gcloud beta container clusters create ${CLUSTER_ID} --identity-namespace=${PROJECT_ID}.svc.id.goog --zone $ZONE

Architecture

Now let’s create the resources. This diagram illustrates what we are about to create:

Wordpress on Kubernetes with GCP and Workload Identity

Boxes on the diagram represent resources that we are creating, there are 5 Kubernetes resources: StatefulSet, Secret for DB credentials, Kubernetes service account, ClusterIP service and LoadBalancer service.

and 6 GCP resources: SQLInstance, SQLDB, SQLUser, ServiceAccount and 2 IAM Policy objects.

GCP Configuration

Let’s go over the configuration for GCP objects. Each of the snippets below is .yaml that is you can kubectl apply once you have Config Connector installed.

MySQL Instance

Firstly, we’ll create Cloud SQL Instance. View openAPI schema section from the downloaded CRD (example) for more properties and more samples here.

apiVersion: sql.cnrm.cloud.google.com/v1alpha3
kind: SQLInstance
metadata:
  labels:
    label-one: "value-one"
  name: wp-db
spec:
  databaseVersion: MYSQL_5_7
  region: us-central1
  settings:
    tier: db-f1-micro

Secondly, we’ll create SQL database and user.

MySQL Database

apiVersion: sql.cnrm.cloud.google.com/v1alpha3
kind: SQLDatabase
metadata:
  labels:
    label-one: "value-one"
  name: wordpress
spec:
  charset: utf8
  instanceRef:
    name: wp-db

MySQL User

apiVersion: sql.cnrm.cloud.google.com/v1alpha3
kind: SQLUser
metadata:
  name: wordpress
spec:
  instanceRef:
    name: wp-db
  host: "%"
  password: change-me

Finally, we’ll configure IAM objects.

Service Account

apiVersion: iam.cnrm.cloud.google.com/v1alpha1
kind: IAMServiceAccount
metadata:
  name: sql-wp-sa
spec:
  displayName: Service Account for WP access

IAM Policy Member: Cloudsql Role

Let’s now create a policy to allow our newly created service account manage SQL

apiVersion: iam.cnrm.cloud.google.com/v1alpha1
kind: IAMPolicyMember
metadata:
  name: sql-sa-policy
spec:
  member: serviceAccount:sql-wp-sa@[PROJECT_ID].iam.gserviceaccount.com
  role: roles/cloudsql.client
  resourceRef:
    kind: Project
    name: [PROJECT_ID]

IAM Policy: workload identity member

And finally, this configuration links together Google service account with Kubernetes service account, by binding it to workloadIdentityUser role and Kubernetes service account as member.

apiVersion: iam.cnrm.cloud.google.com/v1alpha1
kind: IAMPolicy
metadata:
  name: sql-wp-sa-wi-policy
spec:
  resourceRef:
    apiVersion: iam.cnrm.cloud.google.com/v1alpha1
    kind: IAMServiceAccount
    name: sql-wp-sa
  bindings:
    - role: roles/iam.workloadIdentityUser
      members:
        - serviceAccount:[PROJECT_ID].svc.id.goog[default/sql-wp-ksa-wi]

This is it for today. We have created the cloud resources for our WordPress site running on Kubernetes with GCP and Workload Identity. In the second part of this post we will configure Kubernetes objects, tying it all together.

Leave a Comment