JavaScript Function Apps in Azure
There is not a lot of stuff around to guide you through the process of deploying JavaScript Function Apps to Azure, so I had to go through a lot of trial and error in completing this process. But the process is definately not that complicated, so I decided to list my steps below.
As per the Microsoft definition, you can export a JavaScript function that executes when triggered within a set folder structure. At the root of the project, there's a shared host.json
file that can be used to configure the function app.
Folder Structure
PROJECT NAME:
- timerTrigger
> index.js
> function.json
- queueTrigger
> index.js
> function.json
azure-pipelines.yml
host.json
package.json
Host file (host.json)
This file should be in the root of the folder, it basically controls how the application is interpreted by the Azure hosting environment.
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[1.*, 2.0.0)"
}
}
Sample Function (index.js)
The JavaScript functions can be very simple as you can see by the example below, you can even import external libraries into them like axios
or moment
.
const moment = require('moment');
module.exports = function(context) {
console.log(`Triggered Function at ${moment.toISOString()}`);
};
Build & Deploy
It is fairly simple to deploy a project like this to Azure. You create a YAML file in the root of your project called azure-pipelines.yml
It will contain two different stages, a Build stage and a Deployment stage.
Build Stage
stages:
- stage: Build
displayName: Build Stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
npm install
displayName: 'Build Functions'
- task: ArchiveFiles@2
displayName: 'Archive files'
inputs:
rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
includeRootFolder: false
archiveType: zip
archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
replaceExistingArchive: true
- upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
artifact: drop
What is this Stage doing?
It pulls the code from a git repository, sets the correct build image, ubuntu-latest
, installs Node on the image, runs npm install
for all your dependencies, and then archives the files to a drop
location to be picked up by the deployment stage.
Deployment Stage
- stage: Deploy
displayName: Deploy Stage
dependsOn: Build
condition: succeeded()
jobs:
- deployment: Deploy
displayName: Deploy
environment: 'function-app'
pool:
vmImage: 'ubuntu-latest'
strategy:
runOnce:
deploy:
steps:
- task: AzureFunctionApp@1
displayName: 'Deploy to Azure Functions'
inputs:
azureSubscription: '$(azureSubscription)'
appType: functionAppLinux
appName: 'function-app'
package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
What is this Stage doing?
It takes the Zipped files that were the result of npm run install && npm run build
and deploy to the Azure Function App that you set up in the Portal. This state only runs if the build stage is completed successfully.
Wrap Up
And that is pretty much it ... you now have a simple JavaScript function can be run in the Azure Cloud, either on a schedule, or respond to events in the Azure Cloud environment.
You can see a simple functioning application on Github.