Running Go Programs as IBM Cloud Functions

Share this post:

IBM Cloud Functions is a functions-as-a-service platform that is powered by Apache OpenWhisk. It is a readily extensible serverless platform that supports functions authored in various programing languages including Node.js,PythonSwiftJava, and PHP.

A feature of IBM Cloud Functions that has been around for some time but not well documented is support for native binaries: any executable that is binary compatible with a standard OpenWhisk container may run as a serverless function. 

This approach affords you an even greater choice of languages for your serverless applications. You can develop using GoRust, and even C and C++. Moreover, functions may be composed irrespective of their implementation language, empowering you to use the right language for the task at hand while building complex serverless applications.

The native executable must conform to the following conventions:

  • The program shall accept a single command line argument as input. The argument is a JSON object that is encoded as a string. The object represents the input argument to the function.
  • The program must return a JSON object as a JSON formatted string, emitted to stdout as the final log line before the program terminates.
  • The program may log to stdout and stderr otherwise as desired.
  • The executable program must be called exec and should be self-contained (e.g., statically linked). Otherwise, make sure to package all dependencies.

Showing not telling

I’ll illustrate the capability by writing a program in Go and running it using IBM Cloud Functions. The source below is a variant of an example I’ve used before to explain Docker actions.

package main

import "encoding/json"
import "fmt"
import "os"

func main() {
    // program receives one argument: the JSON object as a string
    arg := os.Args[1]

    // unmarshal the string to a JSON object
    var obj map[string]interface{}
    json.Unmarshal([]byte(arg), &obj)

    // can optionally log to stdout (or stderr) 
    fmt.Println("hello Go action")

    name, ok := obj["name"].(string)
    if !ok { name = "Stranger" }

    // last line of stdout is the result JSON object as a string
    msg := map[string]string{"msg": ("Hello, " + name + "!")}
    res, _ := json.Marshal(msg)

Save the code above to a file sample.go and build it. You must set the GOOS and GOARCH properties to cross-compile the binary if you build the binary on another platform. The executable must be called exec.

GOOS=linux GOARCH=amd64 go build -o exec

The rest is standard OpenWhisk workflow to create an action. The executable must be Zip compressed. And the action is created using the --native parameter to indicate this is a native executable using the wsk command line interface.

zip exec
wsk action create helloGo --native

The action is invoked as any other action.

$ wsk action invoke helloGo -r -p name Gopher 
    "msg": "Hello, Gopher!"

Logs may be fetched using wsk as well.

$ wsk activation logs --last --strip
my first Go action.

The Go action may be turned into a web action, to make it accessible via a browser or curl.

$ wsk action update helloGo --web true
$ curl `wsk action get helloGo --url | tail -1`.json?name=GoWeb
  "msg": "Hello, GoWeb!"

Beyond Golang

You run a Rust action in a similar way using the steps described in another blog. In general, any binary that you statically compile may run as a native action. This makes IBM Cloud Functions, or your own deployment of OpenWhisk, a flexible platform for serverless computing. Try it and join the growing OpenWhisk community on Slack. You can also contribute on GitHub.

More How-tos stories
May 6, 2019

Are You Ready for SAP S/4HANA Running on Cloud?

Our clients tell us SAP applications are central to their success and strategy for cloud, with a deadline to refresh the business processes and move to SAP S/4HANA by 2025. Now is the time to assess, plan and execute the journey to cloud and SAP S/4HANA

Continue reading

May 3, 2019

Kubernetes Tutorials: 5 Ways to Get You Building Fast

Ready to start working with Kubernetes? Want to build your Kubernetes skills? The five tutorials in this post will teach you everything you need to know about how to manage your containerized apps with Kubernetes.

Continue reading

May 3, 2019

Using Portworx to Deploy and Manage an HA MySQL Cluster on IBM Cloud Kubernetes Service

This tutorial is a walkthrough of the steps involved in deploying and managing a highly available MySQL cluster on IBM Cloud Kubernetes Service.

Continue reading