Deploying a Go function on Google Cloud Platform

Jorge Galvis
The Startup
Published in
6 min readJan 12, 2020

Function as a Service (FaaS) is a compute model provided by several Cloud Companies nowadays, in which, you deploy a unit of your application (a function) without worrying about the provisioning and the underlaying hardware. Instead, you take care of its association as a callback of an event. For more details about how FaaS works you can check this article that I wrote.

Through this entry, I will show how to deploy a HTTP GET endpoint under FaaS using Google Cloud Platform (GCP). The API will look like yet another Hello World endpoint. But in upcoming articles, I will be updating it until it gets into the shape of an API with a few endpoints on both, GET and POST calls, with a database interaction. Actually, I will be building a serverless backend for tracking blood pressure measurements. Every progress I do on the application will be detailed in a different article.

So for now, I will cover:

  • Application overview.
  • Installing GoLang.
  • Writing the endpoint in local.
  • Running the endpoint locally.
  • Deploying the function to GCP.
  • Running the endpoint from GCP.

Without no hesitation, let’s get hands on.

Application overview

I suffer of hypertension, so I need to check my blood pressure several times a day and I need to track these measurements for adjusting my diet. Doing this by hand is very annoying. So, I’m gonna build an app for myself, and in the process, I will learn the basics of Go (plus another techs). The overall design (draft) for the app I want to get looks like:

Initial design — draft

Basically, I want to have Single Page Application (SPA) client, that talks to an API, this API handles all calls for reading and adding new measurements from/to the database. Finally an ETL (Extract, Transform, Load) will be aggregating the data for future reporting/notification (I’m still not clear with this feature, we will see). My intention is to deploy the solution on GCP, initially manually, and later on I will try to use Terraform (or something similar) for automating the infrastructure.

Installing GoLang

On the official documentation you can find how to install Go for different platforms and architectures. Alternatively, for MacOS, you can install Go using brew manager as follows:

brew update
brew install golang

For checking your installation you can run:

go version

It should return the version you just installed (in my case go1.13.4).

By default, the workspace directory is located in $HOME/go. It is possible to set another directory as workspace. If you want to do so, please follow this post.

Writing the endpoint in local

First thing I worked on was the initial app’s structure. I wanted to decouple the initial function (hello world endpoint) for making local testing easier (will be covered in a future article) and, at the same time, I wanted to make it work on Docker locally. So I followed Martin Heinz post and the official Go documentation for Google Cloud Functions and I came up with the following hierarchy:

.
├── Dockerfile
├── callbacks
│ └── home.go
└── cmd
└── main.go

The endpoint itself, is located in the home.go file, which belongs to the package callbacks:

callbacks/home.go

As you can see, it is a regular function that uses the net/http package. The main.go file is the API entry point, and it looks like:

cmd/main.go

Here, I imported the HomePage callback, and I attached it to the root route. Honestly, I’m not happy with this structure, but as I go further with the implementation I will adjust it and I will make it look like a decent Go API project. For today’s goal is ok as it is.

One final note on the implementation is that the code needs to live within the Go’s workspace. In my case, in $HOME/go/src.

Running the endpoint locally

For running the API locally I ran the following command:

go run cmd/main.go

and I went to the web browser on port 5000 (http://localhost:5000) and check the output. You can also go to another TTY and run:

curl http://localhost:5000
Welcome to the homepage

It works, fantastic! but really what I wanted was to run it on Docker. For doing so, I needed an OS image. I was so lazy for writing a Docker image from the scratch, so I took the work of Andri and Victor and adjusted it a little bit:

Dockerfile

Cool, with the image definition I could now build it and run the small endpoint from a container:

docker build -t jorlugaqui/ahm .docker run --rm -p 5000:5000 jorlugaqui/ahm

If you try to hit the endpoint again it should return the same response.

Deploying the function to GCP

Before being able to deploy anything to GCP you need a valid account, and the Google cloud SDK installed in your machine. Also once the GCP project gets created, you need to activate the Google Cloud Functions API. You can follow the quick-start guide for getting all set. Also, for getting familiar with FaaS on GCP please check this guideline.

Ok, let’s deploy our function. Let’s first get authenticated:

gcloud config set project <your-gcp-project>gcloud auth login

And now let’s actually perform the deployment:

cd callbacks
gcloud functions deploy <function-name-here> --runtime go111 -- trigger-http --entry-point=HomePage --memory=128MB

Notice I how deployed the function being within the callbacks directory. Also, the flags I used are very self explanatory, but in case of doubt, please revise the official docs.

If everything went well, you should receive a response with the URL (HTTP trigger) assigned to the function:

availableMemoryMb: 128
entryPoint: HomePage
httpsTrigger:
url: https://<your-region>-<your-project>.cloudfunctions.net/<your-function>
labels:
deployment-tool: cli-gcloud
..
serviceAccountEmail: ...
status: ACTIVE
timeout: 60s
updateTime: ‘2020–01–11T00:46:30Z’
versionId: ‘4’

You can also get confirmation about the function’s deployment from the GCP console:

GCP cloud functions dashboard
GCP function detail

Running the endpoint on GCP

All I need to do now is to go the URL provided by GCP, running:

curl https://<your-region>-<your-project>.cloudfunctions.net/<your-function>

Or consuming the endpoint from the browser:

Endpoint consumed from browser

Conclusions

There are a lot of pending tasks in order to complete the application I have in mind. But I’m not in a rush, so I will be delivering more posts describing any progress I can do within the following weeks/months. For this occasion, my intention was to show how to deploy a dummy endpoint under FaaS with GCP using Goland. If you want to try the progress done til now, the code can be found in (sorry, no README yet):

References

P.S.

Last time I wrote something here was like three years ago. I’m definitely more than happy because I’m back writing 🎉.

--

--