Note: This was originally posted at martinheinz.dev

Serverless applications have been cool and hype for a while now and some interesting and useful platforms/tools/frameworks are emerging now. One of them is OpenFaaS which is open source Function as a Service tool for developing cloud-native serverless applications.

In this blog post, I want to show you how to setup (IMHO) the ideal project and workflow for developing OpenFaaS functions, as well as creating your first function using Golang.

Note: Full source code for this post can be found here: https://github.com/MartinHeinz/openfaas-functions

Why OpenFaaS

You might be asking, why — out of all the frameworks like AWS Lambda, Google Cloud Run, OpenWhisk etc. — would I choose OpenFaaS? Well, there are quite few reasons for me:

No Vendor-Lock — One big reason for me to choose OpenFaaS over other alternatives, is the fact, that I’m not gonna get vendor locked. Why does it matter so much, though? It matters, because at some point, you might decide, that you want to move to other platform or even completely move away from serverless, which you can’t really do with tools like AWS Lambda that forces you to use AWS.

— One big reason for me to choose OpenFaaS over other alternatives, is the fact, that I’m not gonna get vendor locked. Why does it matter so much, though? It matters, because at some point, you might decide, that you want to move to other platform or even completely move away from serverless, which you can’t really do with tools like AWS Lambda that forces you to use AWS. Cloud Native — Next advantage is that it runs in cloud environments like Kubernetes, OpenShift or k3s (used in this tutorial). I consider this an advantage because spinning up small Kubernetes cluster is pretty cheap, fast and simple nowadays and deploying OpenFaaS in it is simple too, as you will see below.

— Next advantage is that it runs in cloud environments like Kubernetes, OpenShift or k3s (used in this tutorial). I consider this an advantage because spinning up small Kubernetes cluster is pretty cheap, fast and simple nowadays and deploying OpenFaaS in it is simple too, as you will see below. Any Language — OpenFaaS is able to use any runtime, thanks to the fact that all the functions run in Docker containers. You can even build your own templates from which you build your functions.

— OpenFaaS is able to use any runtime, thanks to the fact that all the functions run in Docker containers. You can even build your own templates from which you build your functions. Performance — Another nice thing about OpenFaaS, is its performance, more specifically — or in other words — ability to scale pods to zero when idle, and HTTP-based (beta) templates with lower latency, caching and persistent connections (you will see that in next blog post).

Setting Up

To start building some cool functions, we first need to install few tools. Here’s list of them with instructions:

k3s — To run the functions we need a cloud environment and considering that we will be using local machine, we should probably choose the most lightweight option possible, here I will use Ranchers k3s (alternatively you could also use KinD). To install use following commands:

OpenFaaS — As mentioned previously, OpenFaaS is a Cloud Native platform, so we need to put it into our Cloud environment ( k3s):

fass-cli To be able to interact with the deployed OpenFaaS we also need its CLI:

Taskfile — Lastly, our setup uses Taskfile — replacement for Make — to automate common tasks. To install it, you need to run:

First Function

Now that we have all our tools ready, let’s build our first OpenFaaS function. Before we actually do any coding, we need to pull templates on top of which we will build the functions:

Above, we can see the one template we are interested in — the go template. Let's create function from it:

From the output, we can see which files were created — handler.go and first-func.yml . First of them contains function responsible for handling incoming requests, other one is YAML stack file, that describes the function - it contains information like image name, path to handler, language etc. There are also more values that can be specified, those you can find here. You probably noticed that we also specified prefix flag - we need that, to be able to push image of our built function to remote repository, which is in this case Docker Hub and the prefix is Docker Hub username. OpenFaaS will then use this image from remote registry, when we deploy the function.

I will leave fiddling with code and implementing cool features to you and I will just build, push and deploy the Hello World function as is:

And just like that, we have our function running in OpenFaaS on k3s. We can view it both in UI and commandline. For UI view, you can navigate to OPENFAAS_URL (which should be http://127.0.0.1:31112) and for shell you can run following commands to display and invoke the function:

I think, this was quite simple and we can build upon this. In the next blog post, we will explore how to make use of newer (beta) of-watchdog templates as well as how to build our own template store including our optimized templates using Go modules. You can have a sneak peak in my template repository here.

Unit Tests

It might seem like we’re done here, but there’s one thing we are missing — Unit Test(s).

To write our unit test we simply create handler_test.go file alongside handler.go and put this test in there:

You might have actually noticed, that the go test command was ran during Docker build, so all we need to run tests is build the function like before:

You might think that it is redundant to test little pieces of code like these kinds of serverless functions, but you should not neglect testing just because the code is simple or short, everything should be tested if possible.

Made Simple with Taskfile

In the beginning of the post, I asked you to install Taskfile, but we haven’t actually used it yet, so let’s change that and make the workflow simpler and create, build, deploy or debug the function with Taskfile targets that I already created for you:

First step — create the function with specified name, using some template:

in the background this task downloads templates for you, creates the function and then adds the files to git staging area.

Next, let’s build it:

Nothing fancy, it just builds the function, but you can also go ahead and build, push and deploy the function in one command:

Now, to check if everything works as expected, let’s check logs:

This will give description of Kubernetes deployment object as well as function logs that should look like this:

And if logs aren’t enough, you can debug the function with:

This will run the function locally in Docker and attach terminal to the to watchdog process logs. Now, that the function is running on your machine, you can use cURL to invoke it:

To see what’s happening inside the Taskfile.yml or to check out little more detailed documentation, please check out Taskfile.yml in my repository here and README.md here.

The Simplest CI/CD

The final thing we need to setup is CI/CD pipeline and we can do that with one last Taskfile target that I omitted in previous section — task verify - this command downloads faas-cli , if not present on the machine and builds each function in the repository using YAMLs stored in functions directory:

For a full code listing, please see files in repository, specifically .travis.yml here and verify.sh here.

Conclusion

As you can see from this article, it can be really easy to start developing serverless applications and I hope you will give it a shot, considering that serverless is not just hype anymore and these technologies are quite mature. If you want to see more details and complete source code from this post please see my repository here and in case you have some suggestions/improvements/issues feel free to submit issue or just star it. 🙂

As mentioned earlier — in the next blog post, we will look at how to set up own template store, create custom templates and use it to create better functions.