Using Workload Identity in GKE to connect to CloudSQL instances

Workload identity is, I guess, the way to connect from GKE to CloudSQL. I fumbled a bit with this, so here me notes.

First you need to enable workload identity on your kubernetes cluster:

Enable Workload Identity

After that, you need to create kubernetes namespace and kubernetes service account called ksa-sql-workload:

[somedude@k2 ~]$ kubectl create namespace myknamespace
[somedude@k2 ~]$ kubectl create serviceaccount ksa-sql-workload --namespace myknamespac

Following that, create GCP service account gsa-sql-workload.

[somedude@k2 ~]$ gcloud iam service-accounts create gsa-sql-workload --project=somedudegproject

Add role to GCP service account. 123456789012 is the project ID of you GCP project. Here, gsa-sql-workload service account is assigned cloudsql.client role:

[somedude@k2 ~]$ gcloud projects add-iam-policy-binding 123456789012 --member "serviceAccount:gsa-sql-workload@@somedudegproject.iam.gserviceaccount.com" --role "roles/cloudsql.client"

Next, you bind GCP service account with kubernetes service account, so that kubernetes service account gets privileges of GCP service account. Sheesh…

[somedude@k2 ~]$ gcloud iam service-accounts add-iam-policy-binding --role "roles/iam.workloadIdentityUser" --member "serviceAccount:somedudegproject.svc.id.goog[myknamespace/ksa-sql-workload]" gsa-sql-workload@somedudegproject.iam.gserviceaccount.com

Updated IAM policy for serviceAccount [gsa-sql-workload@somedudegproject.iam.gserviceaccount.com].
bindings:
- members:
  - serviceAccount:somedudegproject.svc.id.goog[myknamespace/ksa-sql-workload]
  role: roles/iam.workloadIdentityUser
etag: A1234567890=
version: 1

Finally, annotate the service account:

[somedude@k2 ~]$ kubectl annotate serviceaccount ksa-sql-workload --namespace myknamespace iam.gke.io/gcp-service-account=gsa-sql-workload@somedudegproject.iam.gserviceaccount.com
serviceaccount/ksa-sql-workload annotated

If you enabled workload identity on cluster node pool, you can use nodeSelector in deployment to make sure your containers land on workload identity enabled nodes.

template:
  metadata:
    labels:
      app: ...
  spec:
    ...
    affinity:
      ...
    tolerations:
      ...
    ...
    serviceAccountName:
      workload-somedude-id
    nodeSelector:
      iam.gke.io/gke-metadata-server-enabled: "true"

    containers:

Reference