Azure WebJobs provide a great way to run scripts or programs as background processes in the context of an App Service web app. Supported formats for these background processes include:
- .cmd, .bat, .exe (using Windows cmd)
- .ps1 (using PowerShell)
- .sh (using bash)
- .php (using php)
- .py (using python)
- .js (using Node)
- .jar (using java)
WebJobs can be run one of three ways: on-demand, continuously, or on a schedule via a CRON expression.
On a recent client project, I was working with a WebJob that needed to be executed once every hour (i.e. scheduled). In deploying the WebJob, I realized that the schedule I had configured would not be honored until ‘Always On’ had been enabled.
Unfortunately for me (and my client), this Application Setting is disabled unless your App Service Plan is configured with a Standard or Premium pricing tier! 💰💰💰
My client was rather hesitant to scale-up their free (F1) App Service Plan, so I was faced with coming up with a poor man’s solution that does not introduce an additional Azure expenditure.
Azure Functions to the Rescue
For the solution I turned to Azure’s serverless architecture — Azure Functions.
With Azure Functions, you pay only for the time your code is running. In other words, you’re charged based on how long your code takes to execute and by the number of resources your Azure Function needs to operate.
If you check-out the pricing calculator for Azure Functions, you’ll also notice that the first 400,000 GB/s of execution and 1,000,000 executions are free as well. Quite an improvement!
Most importantly, Azure Functions can be scheduled using a CRON expression without having the Standard or Premium App Service Plan dependency!
Building out the Solution
To start, we need to fetch a few Properties from our WebJob:
Copy the WebJob’s Name, WEB HOOK URL, USERNAME, and PASSWORD.We’ll need these values later in order to kick-start the WebJob.
Next, we need to create a Function App in the Azure Portal using New > Compute > Function App.
Note : I created a new Resource Group container for my Function App. You will likely need to do the same due to validation errors with Dynamic and non-Dynamic web apps residing in the same region (more info here).
Once your Function App has been created, let’s jump in and create our actual function!
In the function creation dialog, choose a timer scenario, C# as the language and click Create this function.
Once created, replace the code in the run.csx file with the below code sample (GitHub Gist) and Save your function.
You’ll want to replace the userName, password, webJobName, and webHookURL variables with the values we copied previously from the WebJob itself.
Now that we’ve got our C# logic in place to trigger the WebJob’s endpoint via a web request — let’s update our function to ensure it runs on a schedule. If you open up the Integrate menu, you can set the Schedule using a CRON expression.
That’s it! If you jump back to your WebJob and open the Logs, you’ll see your WebJob running at your configured interval thanks to your new helper function. 👍
Depending on your scenario, you may be able to simply re-factor your WebJob into an Azure Function and bypass the poor man’s work-around entirely. That said, this is a handy way to initiate a WebJob via it’s WebHook URL and a simple Web Request.