Simplifying Continuous Deployment to Cloud Run with Cloud Build including Custom Domain Setup(SSL)

Raju Dawadi
Google Cloud - Community
6 min readApr 13, 2019

Cloud Run is fully managed Serverless product launched by Google Cloud for public beta availability which offers to run docker image in Serverless environment. With the introduction of Cloud Run allowing to run docker irrespective of run time environment, the limitation of Cloud Function for limited environment and version is mitigated by Cloud Run which can be run live in few minutes. Also, Cloud Run can be utilized on GKE with Istio and Knative.

Cloud Run + Cloud Build

In this post, we will walk through from github commit to continuous deployment to Cloud Run along with custom domain for http endpoint. The codes and configurations used in this post is on my CloudRun-Demo github repo.

Our Simple Go Application

We have a simple http server running on port 8080

package mainimport (
"fmt"
"net/http"
"os"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "<html><head><title>Cloud Run Demo</title></head><body><h1>Greetings from Cloud Run !!!</h1></body></html>\n")
}
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
http.HandleFunc("/", handler)
http.ListenAndServe(":"+port, nil)
}

Dockerfile

For making our final docker image smaller and secure, we are using multi stage build with final artifact on distroless base image.

FROM golang:1.12 AS build-env
ADD . /app
WORKDIR /app
RUN go get -d ./... && \
CGO_ENABLED=0 GOOS=linux go build -o main .
FROM gcr.io/distroless/base
WORKDIR /app/
COPY --from=build-env /app/main .
CMD ["./main"]

If you are interested in learning more about distroless image, here is one of my post:

Cloudbuild.yaml for Google Cloud Build to create docker image and push to container registry(gcr)

steps:
- name: gcr.io/cloud-builders/docker
args: ['build', '-t', 'gcr.io/$PROJECT_ID/cloudrun-demo:${SHORT_SHA}', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ["push", "gcr.io/$PROJECT_ID/cloudrun-demo"]

Adding Trigger on Cloud Build

Head over to Cloud Build Trigger and create a new trigger for github(or other source repositories) by adding authentication.

Select cloudbuild.yaml as build configuration. For now, we keep trigger for all branches but the selection can be managed with regex for both branch and tags along with files filter.

This steps adds a webhook trigger on github for all events by default.

Github Trigger by Cloud Build

Now, for triggering a new build, we can manually “Run Trigger” for specific branch from Code Build Trigger Page or make a change on our code and push to github. We can view the build logs from history page.

In this demo, we are using $SHORT_SHA for tagging docker image which includes the first seven characters of git commit hash. So, our image is of format gcr.io/pv-lb-test/cloudrun-demo:201c141 .

Time to create Cloud Run Service

Head over to Cloud Run on the Google Cloud Console and “Create Service” with the “Container Image URL” as we got from the Cloud Build above. Give a service name and regional location as Cloud Run is regional resource. If you want to allow invocation from any user, select the “Allow Unauthenticated Invocations” checkbox.

Additional settings allows us to grant spec(Memory Allocation) for each container and maximum concurrent request a container can handle. If the concurrency is reached, Cloud Run automatically scales out new container. If you want to add more environment variables, the key-value pairs can be added.

Optionally, the service can be created with cli command:

$ gcloud beta deploy --image [image-url] --region us-central1 --platform managed

After saving the service, in about a minute, you can get a URL for invocation in format: https://cloudrun-demo-doiyqpty6a-uc.a.run.app

Continuous Deployment to Cloud Run

Time to make the game moving !!!

For the deployment of new image to Cloud Run from Cloud Build as commit is pushed to github, we need to grant the deployment access to Cloud Build serviceaccount which is of format [id]@cloudbuild.gserviceaccount.com .

Add following permission to the IAM user from IAM & admin console.

  • Service Account User
  • Cloud Run Admin

And append the following deployment commands on cloudbuild.yaml file.

- name: 'gcr.io/cloud-builders/gcloud'
args: ['run', 'deploy', 'cloudrun-demo', '--image', 'gcr.io/$PROJECT_ID/[Project-Name]:${SHORT_SHA}', '--region', 'us-central1', '--platform', 'managed']

Change the [Project-Name] and region based on your favorite Cloud Run service name.

Optionally, we can trigger new version deployment with:

gcloud run deploy cloudrun-demo --image gcr.io/$PROJECT_ID/[Project-Name]:[Branch] --region us-central1 --platform managed

For confirmation, we add a change on our Go application http response and push the commit to github. After some time, we can see our changes deployed on the URL. Also, we can see from the Cloud Build log that our image on gcr is deployed:

Step #2: Service [cloudrun-demo] revision [cloudrun-demo-00010] has been deployed and is serving traffic at https://cloudrun-demo-doiyqpty6a-uc.a.run.app

Getting Custom Domain

Rather than the random URL we got from the service, we can use our own nice domain name linked with Cloud Run. For that, we need to verify the domain ownership with Webmaster Central.

On the Cloud Run page on gcloud console, click on MANAGE CUSTOM DOMAIN and add a mapping with servicename and domain.

Add mapping on Cloud Run

Click on “VERIFY IN WEBMASTER CENTRAL” where you can get the domain verification options for various domain registrar or provider.

If you provider is not listed there, simply choose last option “other” which gives two options: CNAME and TXT records.

Webmaster Central Cname Verification

As I am using Google Cloud DNS for managing my record sets, I am going for CNAME record.

CNAME record set on Google Cloud DNS

In few minutes, the record will be propagated. You can confirm by entering your domain on whatsmydns. After is succeeded, click on “Verify” on the Webmaster Central page.

Domain Verified on Webmaster Central

On the Cloud Run page, click on “CONTINUE VERIFICATION AND CLOSE”.

Now, if you again click on “ADD MAPPING”, the verified domain appears on the list below the service name selection. If you want to use the primary domain, leave the third option as it is.

Click on “CONTINUE” and it will give few IP addresses to add on “A” and “AAAA” record set of the domain.

Then you can invoke the Cloud Run service with nice domain name.

In few minutes, the SSL certificate issued by Let’s Encrypt Authority is also provisioned for the custom domain.

By this way, we can make continuous deployment to cloud run and enjoy serverless architecture on our own container.

That’s it for now, if you are interested on getting my interesting updates, find me on Linkedin, Twitter.

--

--