Cloud Native CI/CD Pipeline with Notifications in GCP
Wed Feb 22 2023
We have built our Cloud Native - Continuous Integration / Continuous Deployment pipeline with GCP to build, test and deploy an application (Next.js) with interim status notifications.
Docker
has been used extensively in this pipeline, from building the application, testing the application through webdriverIO docker service in Selenium Hub - chrome/firefox setup and then persist application image in the repository and finally deploy the image.
At this juncture, we would also like to highlight the challenges that we have resolved while setting up this pipeline, While the first was more related to
Ui tests as a git submodule to Next.js application repository
(please have a look into our blog here) and next one was related topassing multiple NEXT_PUBLIC env variables with docker at runtime
(have a look into our past blog here for more detail).
Let’s get into our Cloud Native CI/CD pipeline as shown below with multiple steps. Each step gets executed with a cloud component. Within Cloud Build, we have Cloud Builder
to execute that step in the build pipeline. Cloud Builders are container images used to execute the step and have added a list of cloud builders used in this pipeline at last in the Appendix section. All the steps are defined in the cloudbuild.yml
file and the pipeline gets started with the help of Cloud Build Trigger
. With this pipeline, build gets triggered with a push to main branch.
Build process gets started by pulling the code with submodules from cloud source repositories
using cloud builder gcr.io/cloud-builders/git
and then pipeline gets to the next step, to build application images with docker. For this, we have a docker-compose.yml
file, with cloud builder docker/compose:1.19.0
executing this step, to bring up services like application (Next.js app), selenium-hub, chrome/firefox and have them running on their defined ports and within the cloudbuild
network. This cloudbuild
network allows them to communicate with each other like, Ui tests will use application service to test the image.
With multiple NEXT_PUBLIC env variables, application service will take time to load them. So, we have added a healthcheck
to the application service that ensures the application is running. Also, If docker takes more time to have the service up or has some issues, passing timeout
value (seconds) will stop the pipeline.
Moving on to the next step - Test Execution, webdriverIO tests get executed by installing the test dependencies from package.json and start running the test on host with cloud builder node:18
. At the end of test execution, with hook class, we are writing the test Exit Code
(0 Pass / 1 Fail) to a file and sharing the test status via Google Chat webhook. Here, tests might fail. So, setting allow_failure: true
to proceed with the next pipeline step. After test execution gets completed, we are pushing the test results to cloud bucket with cloud builder gcr.io/cloud-builders/gsutill
. With this, our Continuous Integration pipeline steps gets completed and let’s get into Continuous Deployment pipeline steps.
Before pushing the image to Container Registry
, we have Check Gate to verify the test results and in check gate, we are reading the test exit code file using cloud builder ubuntu
. For test failures with exit code 1 - Cloud Build pipeline gets stopped ! With exit code 0 (all tests passed), pipeline gets to the next step - Push Image. Using cloud builder gcr.io/cloud-builders/docker
we are tagging the image to latest
and pushing it to the Container Registry. Then, the image with latest
tag from Container Registry is deployed to Cloud Run with cloud builder gcr.io/google.com/cloudsdktool/cloud-sdk
and the application is available to public users.
Between the deployment pipeline steps, we are using cloud builder curlimages/curl
to share pipeline step notifications via GoogleChat webhook. Also, we have a step to clear last run test results using cloud builder gcr.io/cloud-builders/gsutill
and it gets executed first before pulling the code. Sometimes the last build might have failed in between and no test results to clear. So, we are setting allow_failure: true
to proceed with the next pipeline step.
We would love to hear from you! Reach us @
info@techconative.com