Azure Functions supports both writing functions in F#, and binding to Azure blobs. There is documentation for binding to blobs as well as using F# with Azure Functions, but there are a few gotchas, so here’s a quick overview of what you can do.

We can set up our F# Azure function to be triggered by a blob quite easily by selecting the built-in blob trigger template:

As you can see, the myBlob parameter is a Stream, but there are several supported types. You can use string if the blob has text contents. Also, you can ask for an ICloudBlob if you want direct access to things like the blob Metadata, which you can do like this:

According to the docs we should also be able to define a CLI mutable type and bind to that as well, if our blob contains JSON. However, I have not been able to get this to work, and it appears to be a limitation with the blob bindings in Azure Functions at the moment.

If you’re wondering what the name parameter is, this comes from the path setting of the trigger:

This means that we can use that name when we define our output bindings. You can also use patterns like {filename}.{ext} and even create a random filename with {rand-guid} so it’s quite flexible.

Output bindings can be set up in the Integrate tab of the portal. Here I’ve set up four bindings:

I can use these bindings to choose where I want to write the output blob to. Here I’m using the {name} of the input blob and writing it to a different folder (taking care that this doesn’t cause a recursive triggering of my function!)

My four output blobs are going to each use a different binding technique. Output 1 uses a string, which we need to declare as byref<string>. Output 2 uses a TextWriter. Output 3 uses a Stream. And Output 4 uses the return value of the function (set up by naming the parameter in the binding $return), which will be a string:

Finally, you can also use ICloudBlob and CloudBlockBlob with blob output bindings, but it’s a little tricky as you have to go into function.json and set the direction of the binding to “inout” as explained in this issue on GitHub. These bindings are great for if you want to set metadata on your blob.

Finally, it’s worth remembering that you don’t have to use output bindings if you don’t want to. If the supported bindings are too limited for you (for example you want to have complete control over the output filename), there’s nothing stopping you writing your own code to directly talk to blob storage.

So say we want to use CloudBlockBlob because we want to set metadata on our blob as well as writing to it. We could make a helper method to get hold of a CloudBlockBlob from a given storage account setting name, container and blob name:

About Mark Heath

I'm a Microsoft MVP and software developer based in Southampton, England, currently working as a Software Architect for NICE Systems. I create courses for Pluralsight and am the author of several open source libraries. I currently specialize in architecting Azure based systems and audio programming. You can find me on: