Azure Functions (and Go)

I’m a HUGE Azure Webjob fan, they’re so useful for a wide variety of scenarios. Being able to setup a Webjob listening to an input queue and just throw messages at it is such a nice way to do adhoc data processing. Azure Functions is a nice improvement over Webjobs (but basically do the same thing). Whereas Webjobs are constantly running in the context of you Application Service (and potentially using up your App Service quotas), Azure Functions aren’t tied to App Service plans and best of all, you’re only charged for when they’re actually processing something. Setup them up and if they don’t process anything for a month, you get charged nothing. You don’t need to tear them down and restart them, they’re just there ready and waiting.

There are plenty of tutorials/pages on Azure Functions, so I wont go into the general details of how they work, but what I will touch on it how to run Go in them. Now, Go within Azure Functions isn’t a first class citizen. Javascript and C# are first class citizens; Azure Functions know how to execute those and it does that well. One nice feature Microsoft has provided is the ability to run batch files. Batch files can in run anything <queue evil laugh/>

What I’m describing isn’t specific to Go, infact I blatantly stole it from an Azure website describing how to do this with Java. But I’m not a Java fan-boy…

Firstly, setting up an Azure Function is pretty straight forward (under a minute to complete). Essentially go to the Azure Functions Portal (you can also do it via the regular Azure Portal) , give your function a name and region then hit “create”. It’s THAT easy!

You’ll get redirected to the Azure Portal, select “Create your own custom function”




Then you have a LOT of options for triggering the processing of data. Expand to see all the options, then select QueueTrigger-Batch (if you want to use queues that is, which I do).



Now that we have configured the function will really be triggered by a batch file we can make it in turn call our Go compiled binary (yes, I keep talking about Go here, but in reality this will work for any executable regardless of the language it was coded in).


The input queue message is converted into an environment variable (see line 2), then we call azurefunction.exe. Where does Azure Functions know about azurefunction.exe?  Click on the “view files” then “upload”, then you can upload any files required for processing the messages.

One last thing to do in the portal is to specify how the Azure Function returns its results. In my case I also want the output to be via Azure Queues. To enable this, select Integrate on the left menu, select New Output and then Azure Queue Storage.




Now, EVERYTHING so far has had nothing to do with Go. So now we’ve done the Azure plumbing, let’s actually Go do some work (BOOM BOOM!)

In this example my super sophisticated Azure Function will count the number of characters in the input message and send that result to the output message. Rocket Surgery for the win!

The entire source for my Go application is:


package main

import (
_ “net/http/pprof”

func main() {
inputMessage := os.Getenv(“inputMessage”)
outputMessageLocation := os.Getenv(“outputQueueItem”)

if inputMessage != “” {
// just write the length to the queue location. Just to prove this works.
cacheFile, err := os.OpenFile(outputMessageLocation, os.O_WRONLY|os.O_CREATE, 0)
if err != nil {
log.Fatalf(“Unable to open file %s %s”, outputMessageLocation, err)
l := len(inputMessage)
s := strconv.Itoa(l)


The code is extremely simple. The input messages comes from the “inputMessage” environment variable. We get the location of the output file via the “outputQueueItem” environment variable. We create a file at that location, write the results (length of input) and hey presto, one usable Azure Function!

Now, we compile this and upload via the Azure portal (mentioned earlier). Now for testing!

Select “Develop” on the left hand menu on the Azure Portal (see screenshot below) and then on the “test” button on the right hand side. This will allow you put some test inputs on the queue and check the results.



Enter some test data. In the above case I just entered “abcde” then hit RUN. You can see some of the debugging in the lower window. The input has been read, data processed and result thrown onto a queue (check your azure queue with your favourite azure viewing tool).

Now, given this is all just a batch file wrapper, you can see that the time to execute isn’t brilliant. You can see the entire process was about 750ms, and 600ms of that seems to be just the firing up of the azurefunction.exe executable from the batch file. Still, I think that being able to set these up, and “almost” fire and forget about them is really nice. You’re only charged for the time they’re running.

I’ll definitely be tinkering with these more, I can see them being hugely useful!


3 thoughts on “Azure Functions (and Go)

  1. Great post – thank You.
    I’ve uploaded my own assembly (EGB24Message) using the “upload” feature that You mention. But I receive an error when saving/compiling:
    2017-08-28T12:52:07.131 run.csx(2,1): error CS0006: Metadata file ‘EGB24Message’ could not be found
    2017-08-28T12:52:07.131 run.csx(7,7): error CS0246: The type or namespace name ‘EGB24Message’ could not be found (are you missing a using directive or an assembly reference?)

    I have tried different things regarding the namespace – also having no namespace in my assembly. Everything so far without any luck.

    do I neeed to do something special in order for my azurefunction to be able to “see” my assembly?

    The content of my run.csx is:
    #r “Newtonsoft.Json”
    #r “EGB24Message”

    using System.Net;
    using System;
    using Newtonsoft.Json;
    using EGB24Message;

    public static async Task Run(HttpRequestMessage req, TraceWriter log)
    log.Info(“C# HTTP trigger function processed a request.”);
    b24Message msg = new b24Message();
    return req.CreateResponse(HttpStatusCode.OK, “test”);
    catch(Exception ex)
    return req.CreateResponse(HttpStatusCode.BadRequest, new {error = $”Error parsing XML document {ex.Message}”});


    Any help would be very much appreciated.
    Kind regards Torben

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s