Continuous Delivery of Azure Functions with TFS

In my previous post (Going Serverless - Azure Functions put to use), I showed you how to create a simple serverless app that did some basic alerting based on events on an Azure Service Bus. Now although this example did show you how to create the function and successfully run it, it didn’t show you how to do it properly: by rubbing some DevOps on it.

The code I used before was simple enough to maintain but I can imagine you would want to use Visual Studio to develop your functions. Luckily there’s an extension for that. After you’ve installed the extension (make sure to get the updated one and heed the prerequisites), you will be able to create a new Function App quite easily and although it’s not as complete as the docker integration (yet), you can use it to deploy your functions using web deploy rather than the source control integration from the portal.

Creating the App

In Visual Studio create a new solution using the wizard by selecting the (C# -> ) ‘Cloud’ -> ‘Azure Functions’ project type. You will see a project structure very similar to what you’re used to from other project types. It will feature a few files:

  • host.json - contains global config for all the functions within your project.
  • appsettings.json - this is pretty self-explanatory, right?
  • ProjectReadme.html - you can safely remove this.

Now as you may have noticed, there’s no actual function yet. You still have to add it by right-clicking the project-node and selecting the ‘Add’ -> ‘New Azure Function’ option.

Add new Azure Function

Pick the ‘ServiceBusTopicTrigger - C#’ type and enter the parameters like before.

Parameters Added

You will notice that after creating the functions, you’ll end up with what we have before, including the project.json we had to manually create in the portal. That also means we can just reuse the code from before :-) Take a look at your function.json file and notice that it has a green squiggly underneath the manage permissions (which we have to use, remember?), I didn’t actually test it with the capital ‘M’ there, but I changed it to ‘manage’ before publishing. Let me know if you do try and succeed!
Unfortunately, Visual Studio doesn’t understand this project type completely just yet, so adding NuGet packages is a manual process. You’ll also notice that IntelliSense is limited, it’ll work just fine if you’re using the assemblies which you get out-of-the-box, but if you use external references, I have found it to be lacking.

Why use Visual Studio at all?

By now you might be wondering what the advantage of using Visual Studio is over just creating a function in the portal. Well, there are several reasons:

  • You might want to store your sources in source control and you’re using TFS - which is not supported in the portal.
  • You might want to create more complex solutions, where you share code over functions for instance. You can do this by adding an empty function and loading it in another by using the #load "..\shared\shared.csx" directive at the top of your file (below the #R directives).
  • You can debug your functions. The first time you’ll try this, you will be prompted to download the Azure Functions CLI.

So read on if you want to see how to deploy this from source control.

TFS

I want my release to inject some variables using Guillaume’s replace token build task, then package and publish it. Seeing as a function isn’t really something that you’ll build, it’s rather strange that you’ll need a build to feed your release definition, so you might consider a build definition which directly deploys your function to an Azure Web Application, this won’t allow you to use environments though and because functions don’t support application slots yet, I like using a staging environment before going to production. Whichever way you’ll go, you will have to know that a web deploy is the only possible way to deliver your function to the cloud now.
I will assume that you have created a web application and/or build definition before, so I won’t go into that and assume that it’s all in place.

My build simply copies all files to a file container on the server, nothing special there. My release definition contains 4 steps per environment:

  • Replace Tokens: replaces all tokens with the correct servicebus topics, the email address, etc.
  • Archive Files: zip the $(System.DefaultWorkingDirectory)/AwesomeNotifier/AwesomeNotifier folder and create a zip-file with $(System.DefaultWorkingDirectory)/package.zip as name.
  • Deploy Azure App Service: select your subscription, the app name and tell it which package to use ($(System.DefaultWorkingDirectory)/package.zip in our case).
  • Azure App Service Manage: select your subscription, select the start method, and select the application.
Finished Release Definition

Now if you set the trigger of your build to Continuous Integration and automatically create a release and deploy your (test) environment after a succesful build, you’ll have created a working continuous delivery pipeline to update your Azure Function using Visual Studio and TFS. Good luck!

Share Comments