GitLab CI/CD Pipeline – Push Image to GRC and Cannary Deploy to GKE | GCP Infrastructure overview

When the infrastructure is done and all resources are in place we need to create a CI/CD pipeline to allow our code to be deployed. We choose GitLab’s CI/CD pipeline to deploy new code to production.

We will test, build, push image to Google Container Registry and deploy a simple Go app to Google Kubernetes Engine. The app can be found in repo but feel free to use directly your docker image, it’ s straight forward 🙂

Some remarks on .gitlab-ci.yml file, skipping the basics:


We manage deploys in 4 stages, 4 + 1 because one is a bit fatty

  - test
  - build
  - cannary
  - deploy


  stage: test
  image: node:latest
      - node_modules/
    - npm install
    - npm test

The stage pulls the latest node image and perform npm install and npm test and it keeps node_modules/ cached for further runs


  stage: build
  image: docker:latest
    - docker:dind
    # Login to Google Cloud Registry
    - base64 -d $GCP_SA_KEY | docker login -u _json_key --password-stdin

    - docker build -t$CI_COMMIT_TITLE -t .
    - docker push$CI_COMMIT_TITLE
    - docker push
  # only:
  #   - tags

Before building docker image we need to authenticate in GCR to have where to push new images. We use a service-account.json key for authentication step, which need a cluster admin and storage write permissions

$GCP_SA_KEY is the serice-account.json encoded in base64 variable defined in GitLab -> Settings -> CI/CD -> Variables. To encode the json in base64

base64 project-292212-69fc45252989.json > project-292212-69fc45252989-base64.json

$CI_COMMIT_TITLE is a gitlab environment variable containing the commit title. A full list of predefined vars here

Optionally, we can define when this stage will be triggered.


  stage: cannary
  image: google/cloud-sdk
  - docker:dind
    # Login to Google Cloud 
    - gcloud auth activate-service-account --key-file=$GOOGLE_CLOUD_ACCOUNT
    - gcloud config set project project-292212
    - gcloud config set compute/zone europe-west4
    - gcloud container clusters get-credentials project-292212-gke-cluster-2ab5 --zone europe-west4 --project project-292212
    - kubectl config current-context
  # Make gcloud available
  - source /root/.bashrc
  - sed -e "s|GIT_VERSION|$CI_COMMIT_TITLE|g" cannary.yml | kubectl apply -f -

Auto deploy to a cannary stage in Google Kubernetes Engine. In deployment.yaml is a simple Kubernetes Deploy which takes the latest app version from Google Cloud Registry and apply to GKE. For this, we need the google/cloud-sdk image, which includes kubectl (thanks to this StackOverflow answer), and we need to configure cluster access to kubectl in before_script:job. We added a simple variable to our cannary.yml Deploy and apply it through kubectl


Last step is the same but we added when: manual to manually promote deploy to production, if the cannary looks good.

Some useful resources:

Connection between GitLab and Kubernetes Cluster can be made through GitLab’s Cluster Management

Configure Gitlab CI with Google Container Registry article is the inspiration for the build-push stage

GitLab repo: