Build a simple automated deployment pipeline for Cloud Run (Step by step tutorial)


In this post, I am going to show you how easily one can make a deployment pipeline for their next app by just copying down the source code. We will be using a simple NodeJs Dockerized application to be hosted on Cloud Run. By the end of this read, you will be able to make a deployment for any language.

  • Container Registry -: It will store all Docker Images to be used in Cloud Run
  • Google Storage -: It will save our state of Terraform.
  • Cloud Run -: Serverless platform where our final app will be hosted
  • Terraform -: It will help us to spin up Cloud Run instance and to create multiple working environments like staging and production
  • Go -: It will help us to trigger Terraform command whenever we want to with Github Actions
  • Github Actions -: It will help us as an entry point to trigger those Go command and Go will trigger terraform

Why Cloud Run, Go, and Terraform?

Cloud Run

Cloud Run is a managed compute platform that enables you to run containers and Google Scales Containers as per the request and you pay per usage. The management of the infrastructure overhead is handled by Google itself so we can focus on building apps. Google has awesome doc at Cloud Run


Go is a very popular programming language these days due to its fast, reliable, and simple architecture. With Go, we can generate binaries that will execute without installing anything so this feature is pretty handy while working with OS


Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. So with Terraform, we can build the infrastructure like we build an app with Code i.e Infrastructure as Code.


  1. You are familiar with how Go works
  2. You are familiar with how Cloud Run works i.e specifying container image. If not check this article
  3. You are familiar with how Terraform spins up a new server and how Terraform manages state
  4. You are familiar with Dockerizing the application.

Deployment tutorial steps

We will be building deployment pipelines in the following four steps-:

1. Dockerize application

First, we will create an application and dockerize it. Let's create a index.js the file inside the src directory and create a hello world response.

2. Infrastructure setup with Terraform

First, we will write a terraform file where we will tell Terraform to spin up the Cloud Run instance. Let's create a GitHub project and create a folder cicd under which there are files need for terraform to create a cloud run instance with a given image.

terraform apply -var image_tag=docker_image_tag -var-file=dev.tfvars -auto-approve

3. Triggering Terraform with Go

With Go, we can create binaries that will run without installing any further dependencies. Go will build a docker image and push it to the container registry if the image does not exist in the registry and trigger Terraform to deploy a new image to Cloud Run.

cmd := exec.Command(“terraform”, “init”, “-backend-config”, “bucket=tf-test-app”)

4. Glue everything with Github Action and Bash file

Finally, these two things will run inside Github Action Container upon manual command trigger i.e deploy dev master . As we have recently created deploybash inside cicdwhich will process our deploy dev master command and triggers Github Repository Dispatch which will trigger deploy.yml with payloads i.e name of environment and branch. Github Action will checkout to the branch given at deploy command and that will trigger deployer binary with environment name and as we already discussed how `deployer. go` handles the incoming request

Add More Environments

We have only seen setting up one environment i.e dev. But with more team members we will need more environment that could be production, staging,test1, test 2 based on your preference.

func getTfVarFileName(env string) string {if env == "dev" {return "dev.tfvars"}if env == "production" {return "prof.tfvars"}panic("Please select correct environment only dev & production available at the moment")}func getCredentialsFilePath(env string) string {if env == "dev" {return "credentials/dev-cred.json"}if env == "production" {return "credentials/prod-cred.json"}panic("error on loading credentials")}


This is just a basic idea of how to make CI/CD with minimal tools. With this approach, one can make CI/CD for normal application in a company, attach other google services in Terraform too like Cloud SQL, Redis, etc.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store