Introducing the Serverless Framework for Azure Functions
The [Serverless Framework](https://serverless.com/framework/docs/" target="_blank) is a new Open Source initiative that allows you to deploy auto-scaling, pay-per-execution, event-driven functions to some of the biggest cloud providers. At moment it only support AWS Lamda, Azure Functions and Apache OpenWhisk. However, this list is due to grow fast so watch this space.
In this post, I'll show you how to us the Serverless Framework with Azure Functions so that you can create, run and deploy Functions easily, in effect providing an alternative 'DevOps story' around Functions.
Install the Serverless Framework
Fire up your command line of choice and install Serverless
npm install -g serverless
You'll then need to install the Azure plugin that allows you to work with Azure Functions:
npm i -g serverless-azure-functions
You now have Serverless and the ability to work with Azure Functions installed on your machine.
Managing Azure Credentials
For Serverless to interact with your Azure Subscription, it needs the appropriate credentials. I applaud the effort of the team to lead developers down the right route and force the use of a Service Principal. If you don't know what that is in the context of Azure or how to create it, have a look at my older post [here](GHOST_URL/service-principals-in-microsoft-azure/" target="_blank).
Once you have a service principal in place, you need to add them into your session. Technically there are 2 ways to do this.
- Add them in the current session (they will only be available in the current windows/cmd) and disappear once you've closed it down (more secure)
- Add them as user environment variables which is more permanent (less secure)
The security concerns the fact that you'll need to store the SP credentials in clear text, so my recommendation would be to go with option #1 even if it's a bit more tedious.
P.S - the team is working on an interactive way to login and/or create SPs through the Serverless CLI so watch this space.
To set the necessary variables you'll need to use the commands supported by your current tool (Bash, Powershell or CMD). I included the commands for each tool below:
Create your first Function
To create your first function using Serverless, type:
serverless create --template azure-nodejs --name yourFunctionName
At the moment the only template supported is
Node.js
but there's a request for adding C# and F# support. The boiler plate code should be fairly simple and easy to add. With this project being open source and in high demand, I can see this happening soon.
Calling the above command creates the necessary files for your Function. The important ones are: serverless.yml
and handler.js
. The serverless.yml
contains the definition of your Function, the resources and the location of your Application service. At the moment it's a bit limited and there are a few crucial configuration setting missing (more on this in a bit). The second file, handler.js
contains the code of our function.
Let's break down the serverless.yml
to understand what's going on here
provider:
name: azure
location: West US
plugins:
- serverless-azure-functions
functions:
hello:
handler: handler.hello
events:
- http: true
x-azure-settings:
authLevel : anonymous
- The
service
defines the Function AppService name. It's also used to create a Resource Group as<service>-rg
. This is hardcoded for now, which means that you cannot deploy a function on an existing resource group, unless you've named one using this format. - The
plugins
section is used to define the plugins that the Serverless framework needs to use. In this instance we're using the Azure Functions one but we could be calling multiple plugins. There's a list of all available plugins [here](https://github.com/serverless/serverless#v1-plugins" target="_blank) - The
functions
section is where we define the function code, the events/triggers and the authorisation level. In this case:hello
is the function namehandler
is the entry point.handler.hello
maps to our exported function definition in thehandler.js
fileevents
correspond to the trigger, in this case an http trigger.
You can find more about how to work with events by referring to the documentation [here](https://serverless.com/framework/docs/providers/azure/events/" target="_blank)
Deploy your function to Azure
Before running or deploying your code, you need to restore any dependencies. Consequently, you need to run npm install --save
to restore all npm packages referenced by your code. Then, you can deploy your function by running the following command:
serverless deploy
.
The command will zip the files necessary for your application, login to Azure, deploy the resources for your Function (resource group, App Service and Function definition) and finally deploy the code. I will also run the npm install
command to ensure that all reference dependencies are deployed accordingly.
You can then invoke/run your function with serverless invoke --function <function name> -- data <payload>
Below I've included 2 examples, one with no data (default) and one with some data in the payload.
Of course, this being an HttpTrigger based function, you could use your browser or any other tool capable of generating Http requests (Postman, Fiddler, your browser etc). However, for this to work you need the Function URL which can be found in the Azure Portal.
What works well
I like the abstraction that the framework provides. If you prefer working with yml and can follow the documentation, then you can create and deploy functions easily both for development but also for CI/CD scenarios. It only took 3-4 commands to go from 0 (no code) to 100 (code deployed and running on Azure). Unlike the Azure CLI which only works on Windows, this is a truly cross-platform tool that allows you to create and deploy functions from non-Windows machines.
What's missing (and coming soon)
There are many features missing that could make this a compelling alternative to using the Azure Functions CLI. I've listed a few below based on my observations while working with the framework:
- no local debugging. All functions run in the context of Azure and are executed remotely
- no way to deploy to a pre-existing resource group. At the moment it's an all or nothing
- removing the function removes the code and all associated resources so, again, it's an all or nothing approach - scorched earth
- limited to a node-js template at the moment. No support for all the other languages supported by Azure Functions (C#, F#, PoSH etc)
- defining the Azure credentials is a bit tricky and not as clear as it should be
- there's no way to use ARM templates with the serverless framework.
But it's not all bad news. Most of the issues highlighted above are being addressed as we speak. It's also very exciting to see how active and passionate the serverless community. I would be keen to see this extended beyond AWS and Azure to allow easy interoperability between different providers.
I would urge you to have a go and see how the serverless framework can be used in the context of your serverless infrastructure. Comments are welcome.