How to run Timer-triggered Azure Functions locally on Mac?

1.9k views Asked by At

I want to execute a timer-triggered function in my local development environment (Node, OS X) but it seems to require some changes to the HTTP-triggered functions setup I have.

Here's the code related to the timer function so far:

/cron-job/function.json defines a timer input binding scheduled to run every minute. It also has a reference to the code entry point (compiled from Typescript):

{
  "bindings": [
    {
      "type": "timerTrigger",
      "direction": "in",
      "name": "timer",
      "schedule": "0 */1 * * * *"
    }
  ],
  "scriptFile": "../dist/cron-job/index.js"
}

/cron-job/index.ts

import { AzureFunction, Context } from '@azure/functions'

const timerTrigger: AzureFunction = async function (
  context: Context,
  timer: any,
) {
  console.log('context', context)
  console.log('timer', timer)

  // move on with async calls...
}

export default timerTrigger

/local.settings.json

{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsStorage": ""
  }
}

When I try to start the function app:

 ~/Projects/test-api (dev) $ func start --verbose

I get an error:

Missing value for AzureWebJobsStorage in local.settings.json. This is required for all triggers other than httptrigger, kafkatrigger. You can run 'func azure functionapp fetch-app-settings <functionAppName>' or specify a connection string in local.settings.json.

When I add AzureWebJobsStorage setting to the local.settings.json I get another error:

The listener for function 'Functions.cron-job' was unable to start.
The listener for function 'Functions.cron-job' was unable to start. Microsoft.Azure.Storage.Common: Connection refused. System.Net.Http: Connection refused. System.Private.CoreLib: Connection refused.
3

There are 3 answers

0
Max Ivanov On BEST ANSWER

After some research I came up with a working setup which I figured I should share.

The issues with my original setup were:

  1. Not having "AzureWebJobsStorage": "UseDevelopmentStorage=true" in the local.settings.json. I already had a HTTP triggered function up and running but it appears timer trigger requires that setting. For local development when using a storage emulator, UseDevelopmentStorage=true shortcut can be used.

  2. Not having Storage Emulator installed. It seems that on Windows it's part of the Microsoft Azure SDK and/or it can be installed as a standalone tool. It's not available for Mac and Linux though. However there's an open-source alternative available: Azurite, which is going to replace the Storage Emulator.

As a reference, I've created a Typescript starter repository which can be extended for writing your own Azure Timer-triggered functions: azure-timer-function-starter-typescript

0
KaranSingh On

To run Azure Timer function locally on Mac, you can provide storage account connection string in local.settings.json for AzureWebJobsStorage. Set "AzureWebJobsStorage": "<storage account connection string>"

You can get the storage account connection string from Azure portal. Create a storage account in Azure portal. Go to storage account access keys and copy the connection string.

On Windows, setting "AzureWebJobsStorage": "UseDevelopmentStorage=true" or "AzureWebJobsStorage": "<storage account connection string>" both would work.

0
olk On

After starting your Azure function locally, you can execute it by sending a following POST request. This method works other than HTTP and Event Grid triggers.

URL: http://localhost:<your port>/admin/functions/<your function name>

Body payload: { "input": "test" } in application/json

You can read more from official documents. https://learn.microsoft.com/en-us/azure/azure-functions/functions-manually-run-non-http