Setup CI/CD using Github Actions to deploy to Google Kubernetes Engine

Ravish Goel
4 min readJul 26, 2023

--

Let’s spring into action…

Let’s assume that you have already created a Cluster on GKE, called autopilot-cluster-1.

By the time this action is complete GCP creates an Identity by the name of Compute Engine default service account which you can cross-check under IAM tab. This entity looks like this:

By default this Service Account has all the necessary permissions required to push Docker images to Artifact Registry, create Deployments on GKE, and pull images inside Pod containers. If you want to create a new Service Account, make sure that you assign proper roles to this new account to accomplish the aforementioned tasks. Roles like Artifact Registry Reader, Artifact Registry Writer, Kubernetes Engine Developer etc.

Now, the next step is to generate a JSON key for this Service Account, that will further be used to configure Docker to authenticate to Artifact Registry Docker repositories. Go to Service Accounts tab under IAM and generate a JSON key using the GUI as shown in the images below:

The JSON key will be downloaded to your machine as a JSON file.

Hope you already have installed gcloud CLI! Now, on the terminal, type the following command to connect to the cluster:

gcloud container clusters get-credentials autopilot-cluster-1 --region <cluster region> --project <project ID>

Now, the next step is to setup authentication for Docker. Please make sure that you have enabled Artifact Registry API and created a Repository before proceeding further as shown below:

On the terminal type the following commands in the same order:

gcloud auth activate-service-account 1234567890-compute@developer.gserviceaccount.com --key-file=<path to the JSON key>
gcloud auth configure-docker <artifact registry region>-docker.pkg.dev
gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://<artifact registry region>-docker.pkg.dev

You are all set!

Now, try to build and push a Docker image from your local to Artifact Registry.

docker build -t <artifact registry region>-docker.pkg.dev/<project ID>/<artifact registry repository>/<image name>:<image tag> -f Dockerfile .
docker push <artifact registry region>-docker.pkg.dev/<project ID>/<artifact registry repository>/<image name>:<image tag>

The image should reflect in Artifact Registry as shown below:

Time for some action!

Now, in your Github repository, under Settings tab, you need to create two Secrets — GKE_PROJECT and GKE_SA_KEY as shown below:

Add the project ID to GKE_PROJECT and the JSON value of Service Account key to GK_SA_KEY.

Now, in your repository create a Github Actions YAML file under .github/workflows and copy and paste the following code into it.

name: Build and Deploy to GKE

on:
push:
branches:
- main

env:
PROJECT_ID: ${{ secrets.GKE_PROJECT }}
GKE_CLUSTER: autopilot-cluster-1 # cluster name
GKE_ZONE: europe-central2 # cluster zone
IMAGE: micro # image name
IMAGE_TAG: test # image tag
GAR_ZONE: europe-central2 # artifact registry zone
GAR_REPO: obiwan # artifact registry repository

jobs:
setup-build-publish-deploy:
name: Setup, Build, Publish, and Deploy
runs-on: ubuntu-latest
environment: production

steps:
- name: Checkout
uses: actions/checkout@v3

# Setup gcloud CLI
- id: 'auth'
uses: 'google-github-actions/auth@v0'
with:
credentials_json: '${{ secrets.GKE_SA_KEY }}'

# Configure Docker to use the gcloud command-line tool as a credential
# helper for authentication
- name: Docker configuration
run: |-
gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://$GAR_ZONE-docker.pkg.dev

# Get the GKE credentials so we can deploy to the cluster
- name: Set up GKE credentials
uses: google-github-actions/get-gke-credentials@v0
with:
cluster_name: ${{ env.GKE_CLUSTER }}
location: ${{ env.GKE_ZONE }}

# Build the Docker image
- name: Build
run: |-
docker build \
--tag "$GAR_ZONE-docker.pkg.dev/$PROJECT_ID/$GAR_REPO/$IMAGE:$IMAGE_TAG" \
--build-arg GITHUB_SHA="$GITHUB_SHA" \
--build-arg GITHUB_REF="$GITHUB_REF" \
.
# Push the Docker image to Google Container Registry
- name: Publish
run: |-
docker push "$GAR_ZONE-docker.pkg.dev/$PROJECT_ID/$GAR_REPO/$IMAGE:$IMAGE_TAG"

# Deploy the Docker image to the GKE cluster
- name: Deploy
run: |-
kubectl apply -f deploy.yml
kubectl get pods

Kubernetes deployment YAML config (deploy.yml) must exist in order to specify the state. Also, make sure you replace the following env key values with yours:

GKE_CLUSTER: autopilot-cluster-1    # cluster name
GKE_ZONE: europe-central2 # cluster zone
IMAGE: micro # image name
IMAGE_TAG: test # image tag
GAR_ZONE: europe-central2 # artifact registry zone
GAR_REPO: obiwan # artifact registry repository

Now, commit something to the main branch and be ready to see the magic!

Hope you enjoyed the article!

--

--