Git and NodeJS on Azure Functions

31 Oct 2016 in Tech

I had a fun time piecing together all of the required documentation to get a version controlled set of functions deployed to Azure Functions.

Here's the steps you need to follow:

  • Create a new function app via the portal
  • Open up that app and click on Function app settings
  • Click Configure continuous integration and click Setup
  • Choose a Local Git Repository as your source
  • Skip the performance test section and click OK at the bottom

At this point, you have a deployment source configured. If you click on New Function you'll see a message saying that the view is now read only.

Click on Function app settings again and click on App Service Settings at the bottom. This opens a screen that shows an overview of your functions. In the right column, there will be a Git clone url, clone that to your local machine.

Once it's finished cloning, there will be a file named hosts.json in your folder. You can ignore this file.

Each folder that you create inside the repo will be a different function (See Continuous deployment requirements). Here, I've created a function named TestNodeOne:

bash
.
└── TestNodeOne
├── function.json
├── index.js
└── package.json

Your package.json looks just like every other package.json for a node app. Azure won't automatically run npm install so you'll need to run npm install yourself if you have any dependencies.

function.json is the function definition, which contains the bindings for your function (where it reads from and writes to). There's the Bindings & Triggers documentation, but here's a simple example for a HTTP function. I've disabled authentication by providing "authLevel": "anonymous". You probably want to use "authLevel": "function":

json
{
"bindings": [
{
"webHookType": "",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"authLevel": "anonymous"
},
{
"name": "res",
"type": "http",
"direction": "out"
}
],
"disabled": false
}

Finally, you have to implement your function. Your function will receive a context object which you can use throughout the function's life-cycle. You set your response value on context.res before calling context.done() to indicate that you're done processing. Here's what my function looks like:

javascript
module.exports = function (context) {
context.log(JSON.stringify(context));
context.res = { status: 200, body: "Hello World" };
context.done(null);
};

All of the available context functions are documented in the Azure documentation

Once you're done, git commit then git push to deploy your application:

bash
Password for 'https://[email protected]:443':
Counting objects: 2, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (1/1), done.
Writing objects: 100% (2/2), 229 bytes | 0 bytes/s, done.
Total 2 (delta 0), reused 0 (delta 0)
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id '338a367d75'.
remote: Generating deployment script.
remote: Running deployment command...
remote: Handling function App deployment.
remote: ..............
remote: npm WARN [email protected] No description
remote: npm WARN [email protected] No repository field.
remote: npm WARN [email protected] No license field.
remote: Running post deployment command(s)...
remote: Deployment successful.
To https://yourfunctionproject.scm.azurewebsites.net:443/YourFunctionProject.git
e0e4360..338a367 master -> master

Once it's deployed, you'll be able to call the function by navigating to https://yourfunctionproject.azurewebsites.net/api/TestNodeOne (see URL to trigger the function)

I probably wouldn't work directly with the Git repo that Azure provide you with, instead opting to keep everything in my own repo on GitHub. That way, your continuous integration system can run any tests for the functions and publish to the Azure repo itself to trigger a deploy.