DevOps with Azure Functions - a holistic approach


Azure Functions is Microsoft's answer the serverless architecture. They are very popular due to the incredible integration they provide with Azure Services, SaaS providers and on-premise application. It definitely drives the whole microservice architecture design which is built on top of Azure's established Platform-as-a-Service. And enables developers to think about APIs and integration in a totally different way - serverless (even though there are still servers under the hood). It's even more exciting seeing so many organisations embarking in larger scale projects that take advantage of Functions and LogicApps. If you want to know more about the whole serverless design, Martin Fowler has an excellent post [here](http://martinfowler.com/articles/serverless.html" target="_blank). And this is only one of many.

As with all code that eventually ends up in production, it's important that there is a proper DevOps story. Continuous Integration(CI)/Continuous Deployment(CD) is still integral and vital, even in the new world order of serverless architecture.

The current state of DevOps for Functions

Azure Functions are one of the newest Azure offerings and, as such, the development story is still young and bumpy. The whole Product Group team is working hard to create better tooling support for the service. I expect (and I know of a few) big things to come out this year. In Nov 2016 the team released a number of different tools to allow you to work with Functions offline. You get to choose between Visual Studio on Windows and VS Code with the Azure Functions CLI. They both allow you to write, debug and test your functions locally, without the need to touch the browser. The second option will soon be available on Windows too for true cross-platform development.

At the moment you need to use VS2015 on Windows and the Functions CLI and VS Code on Mac/Linux. However, with the rate of change we're currently seeing, I won't be surprised if Visual Studio for MacOS gets a massive revamp to allow you to work with Azure resources in the coming months too. In other words, I expect the tooling problem to be resolved rather quickly (though don't quote me on this as I don't work for any of these teams - not yet anyway).

DevOps with Functions today

Functions already have a DevOps story. It's, however, tightly coupled to Source Control which can be configured to trigger deployments upon check in your code. You can find a lot more information on the official [Azure Continuous Deployment post](https://docs.microsoft.com/en-us/azure/azure-functions/functions-continuous-deployment" target="_blank). For quick reference, the following deployment sources are the supported:

  • Bitbucket
  • Dropbox
  • Git local repo
  • Git external repo
  • GitHub
  • Mercurial external repo
  • OneDrive
  • Visual Studio Team Services

But there's something I don't like about this. The fact that you don't get "security gates" of a normal build. No compilation and no testing. The deployment is also tied to an existing AppService on top of which our Function(s) run. The Function also needs to exist in order to allow you to deploy to it.

For other project types (web, desktop, console) we use a build and CI server so why should this be different for Functions? In the end, it's code. Mind you it can be different kinds of code (C#, Python, Node.js, PowerShell etc) the requirement still stands. I want to be able to build, test and deploy my Functions.

Compiled Functions were only announced a week ago so build and test is now available. The deployment, on the other hand is a bit tricky and requires jumping through a few hoops to get it to work. The goal of this mini-series of posts is to show you how to use ARM templates and PowerShell or the Azure CLI to properly integrate Functions in your CI/CD process.

Setting up CI/CD for Functions - the ideal scenario

At a very high level, this is what I would like to be able to do with Azure Functions

  1. Develop and test the code locally using supported tools
  2. Check in the new code to preferred source control
  3. Kick off an automated build
  4. Run a deployment step to deploy the Functions ARM template.
  5. Run a deployment step to deploy your Azure Function(s) code using the KUDU REST Api.

Step 4 and 5 rely on a 2 additional "services" which are recommended practices:

  • Service Principal to use for deployments with the right permissions (RBAC)
  • A KeyVault to store your sensitive information such as the Service Principal password etc

If you want to know how to create an Azure Service Principal, have a look at my earlier [blog post](GHOST_URL/service-principals-in-microsoft-azure/" target="_blank).

To create a [KeyVault](GHOST_URL/azure-key-vault-the-new-security-service-from-microsoft/" target="_blank), you can use the new Azure Fluent Management API, example [here](GHOST_URL/the-new-azure-management-fluent-api-is-has-landed/" target="_blank), the Azure PowerShell cmd-lets, the Azure CLI or the Portal.

And without further a do: these are the 3 deployment strategies for Azure Functions that satisfy some or all of my requirements above (1-5)

  1. [Deploying Azure Functions with ARM templates and the Kudu REST API](GHOST_URL/deploying-azure-functions-with-arm-templates-and-the-kudu-rest-api/" target="_blank)
  2. Deploying Azure Functions with ARM templates and embedded code
  3. Deploying Azure Functions with ARM templates and MSBuild

  • Share this post on