Recently Google introduced its serverless offering called Cloud Run which abstracts away all infrastructure management, so you can focus on building apps. By combining Cloud Run, Cloud Build and Cloud Source Repositories, we can build a simple, serverless CI/CD pipeline that automatically deploys an app whenever new commits are pushed. Basically you’ll get a Heroku-style interface for much less money and about 20 minutes of work.
Under the hood, we’ll deploy all of the resources using Terraform. You can find the example code used in this post on my GitHub. First, let’s have a look at the steps involved.
I’ve broken this guide down into the following steps:
- Installing the necessary tools
- Enabling the appropriate permissions
- Running Terraform to deploy the resources
- Deploying a custom app
- Viewing the app
- Cleaning up afterward
- Next steps
Install the necessary tools
In order to complete this guide, you’ll need to install the following tools:
- Terraform: This guide uses Terraform to deploy the resources and manage all the infrastructure as code.
- Docker: Docker is required for local development and to push Docker images to Google Container Registry.
- Git: Git is used to clone the example code and trigger new deployments.
- GCP: You will need a GCP account with billing enabled. There is a free tier that includes $300 of free credit over a 12 month period. You will also need to install the gcloud command-line tool.
Enable the appropriate permissions
This guide requires certain permissions to be configured correctly for the CI/CD pipeline to work. To make life easier I’ve put together a small shell script that can do this for you automatically. This script will automatically enable the following APIs:
Then add certain IAM policy bindings so Cloud Build and Cloud Run can work correctly. First ensure you have set the
GOOGLE_CLOUD_PROJECT environment variable to your GCP project ID (e.g:
project-foo-123456). Then, let’s execute the script:
$ git clone https://github.com/robmorgan/terraform-cloudrun-example.git $ cd terraform-cloudrun-example # from the terraform-cloudrun-examples directory $ ./bin/setup-iam-permissions.sh
You can also manually enable the APIs using the following links:
- Enable the Cloud Build API
- Enable the Cloud Run API
- Enable the Container Registry API
- Enable the Cloud Resource Manager API
Note: Be sure to select the appropriate GCP project.
Then to add the IAM policy binding, simply run:
$ gcloud iam service-accounts add-iam-policy-binding \ [PROJECT_NUM][email protected] \ --member=serviceAccount:[PROJECT_NUM]@cloudbuild.gserviceaccount.com \ --role=roles/iam.serviceAccountUser \ --project=[PROJECT_ID]
Note: Be sure to swap
[PROJECT_ID] with your GCP Project ID Number and your GCP Project ID.
Grant Cloud Build Permissions
Lastly, we need to ensure Cloud Build has the appropriate permissions to deploy to the Cloud Run service.
- Visit the Cloud Build settings page.
- In the Service account permissions panel, set the status of the Cloud Run Admin role to Enabled.
If the GCP console opens a modal that says ‘Additional steps may be required’, you can safely click the ‘SKIP’ button.
The following Google Cloud Build page has more information on the required permissions.
Deploy the Resources using Terraform
If you haven’t already, you should clone the following repository containing the example code, then switch
$ git clone https://github.com/robmorgan/terraform-cloudrun-example.git $ cd terraform-cloudrun-example
Next, copy the
terraform.tfvars.example file to
terraform.tfvars. You will need to replace the value of
Now we can use Terraform to deploy all of the necessary resources. Simply run the following commands:
Terraform will then deploy all of the necessary resources for our pipeline including a Cloud Run service, Git repository and a Cloud Build trigger. This step will take approximately 1-2 minutes to complete. After Terraform has completed, you’ll see a bunch of outputs similar to the following:
Apply complete! Resources: 2 added, 0 changed, 1 destroyed. Outputs: registry_url = us.gcr.io/your-project-123456 repository_http_url = https://source.developers.google.com/p/your-project-123456/r/sample-node-app trigger_id = b4d81a09-20e7-4d2c-9902-577d8c160989 url = https://sample-docker-service-s4fqxvtrpq-uc.a.run.app
You can test the sample application by opening the URL in your browser:
$ open $(terraform output url)
You should see something similar to the following:
So far we’ve launched a Sample Google App, however, in the next step we’ll deploy a custom app of our own.
Deploying a Custom App
Because Cloud Run uses Docker under the hood, you can use any of your favourite languages including Go, Python, PHP, Java and Node.JS to write your apps! For the purposes of this guide, we’ll use my basic Node app to demonstrate how to deploy custom apps. First, start by cloning it using Git:
$ git clone https://github.com/robmorgan/sample-node-app.git $ cd sample-node-app
Then run the following commands to add our Cloud Source Repository as a Git remote:
$ git config --global credential.'https://source.developers.google.com'.helper gcloud.sh $ git remote add google https://source.developers.google.com/p/[PROJECT_ID]/r/[REPO_NAME]
Note: You must substitute
[PROJECT_ID] with your GCP Project ID and
[REPO_NAME] with your Cloud Source Repositories repo name. You can find these values by running
terraform output repository_http_url in the
Now it’s time to push the app source code to our Cloud Source Repository:
$ git push google master
Google Cloud Build will trigger a new build and automatically deploy the resulting Docker container on Cloud Run.
This is handled automatically as my sample Node app contains a
file in the root of the repository.
Note: As we’ve deployed a custom app by pushing to Cloud Source Repositories, we should update the image reference in the
terraform.tfvars file otherwise Terraform will deploy the Google sample app next time it’s invoked.
View the App
Once again we can open the URL in our web browser to see that the custom app has been deployed:
# change to the 'terraform-cloudrun-example' directory $ open $(terraform output url)
You should see something similar to the following:
Even though Cloud Run is dirt cheap to run your apps, we can easily clean up using the Terraform
$ terraform destroy
In about 30 seconds, Terraform will undeploy the app and destroy all of the resources we’ve created.
This guide gave an example of how to deploy a simple CI/CD pipeline using serverless technologies. Under the hood, Cloud Run is built on top of an open standard - Knative which you should read more about. Additionally, you may want to explore adding a relational database using Cloud SQL so you can run stateful apps.