Running Azure Functions Locally with the CLI and VS Code

6 minute read • December 1, 2016

Donna Malayeri
Update 5/31: We now have official documentation for the Azure Functions Core Tools and this blog post is now out of date. See Develop and debug Azure functions locally. After our General Availability release of Azure Functions on November 15, lots of customers have been asking how to develop Azure Functions on a local development machine, before pushing working code to Azure. I’m happy to announce that we have some great new functionality to share on this front. You can now use your favorite editor and local development tools and trigger from events in your Azure resources. You can use Visual Studio 2015, Visual Studio Code, or just a command line and any code editor.

Visual Studio 2015

Customers who use Visual Studio should check out the preview Azure Functions Tools for Visual Studio 2015. This allows you to create local Functions projects, add new Functions from templates within Visual Studio, run functions locally, and debug C# functions. Get the tools and learn more on the Web Tools team blog. visual-studio-functions-debugging

VS Code and azure-functions-cli

If you prefer VS Code or want to debug JavaScript functions, you can use the Azure Functions CLI. Note that currently the Azure Functions CLI only works on Windows, but we’re working on support for other platforms. (Note that C# debugging support is currently only available in Visual Studio, not VS Code.)

Installing

Make sure you’re using Node version 6.x LTS or later (required by the Yeoman dependency), then do:
npm i -g azure-functions-cli
The Azure Functions CLI is actually the Azure Functions “host” packaged with a command line interface and some other utilities. This is the exact same runtime that’s used in Azure, it’s not an emulator or simulator. It is distributed through npm because it uses Yeoman for scaffolding, but the core functionality is just a .NET 4.6 executable. (That’s why it currently only works on Windows.)

Creating a function project

When running locally, a function project (the equivalent of a Function App in Azure) is just a directory with the files host.json and appsettings.json. See the product documentation for more about the Azure Functions folder structure. From a command prompt, do the following:
mkdir MyAwesomeFunctionProj
cd MyAwesomeFunctionProj
func init
You’ll see the following output:
Writing .gitignore
Writing host.json
Writing appsettings.json
Initialized empty Git repository in C:/CDriveCode/MyAwesomeFunctionProj/.git/
Notice the file appsettings.json, which is where you set local environment variables and connection strings (more on this later).

Creating a simple function

Now, let’s create a simple HTTP triggered Node function via func new 1 I chose HttpTrigger-JavaScript and named it HttpTrigger-JS. 2

Running the function

This HTTP triggered function is very simple, it just takes in a “name” argument as either a query parameter or JSON body content, and outputs “Hello name”. To edit the function code, let’s open up VS Code:
code .
In Visual Studio Code, go to View -> Integrated Terminal
func run .\HttpTrigger-JS\ -c "{\"name\": \"Donna\"}"
terminal You’ll see that a separate window launches, which is the Functions host. By default, it will listen on http://localhost:7071. In the Functions host window, you’ll see that the URL of HTTP triggers is listed. You can then use a web debugging tool like Fiddler or Postman to create more complex requests. 4

Debugging the function in Visual Studio Code

Running a function is great, but debugging is where the magic happens. To run the code and attach the JavaScript debugger, do the following:
  • In a command prompt (either the Integrated Terminal or a regular command prompt), run the function as before and add the --debug flag:
    func run .\HttpTrigger-JS\ -c "{\"name\": \"Debugging!\"}" --debug
  • Add a breakpoint to index.js.
  • In the Debug tab, select F5 or the play button
  • In the terminal or command prompt, press any character and you’ll see your breakpoint being hit!
5 6

Running a queue-triggered function

Now let’s create a function that triggers from a queue in Azure. First, run func new and select QueueTrigger-JavaScript. Name the function QueueTriggerJS. Setting a connection string Next, we need a value for a storage account connection string. You can either do this by editing appsettings.json manually or by using the Azure Functions CLI. To edit manually:
  • To go Azure Storage Explorer or the Azure Portal and copy your storage connection string
  • Add the value to appsettings.json:
    {
        "IsEncrypted": false,
        "Values": {
             "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=youraccountname;AccountKey=XXX"
          }
    }
Using the Azure Functions CLI: Log in to Azure, then set the active subscription. You can list your Function Apps in Azure and pull down connection strings for a particular app:
func azure login
func azure account set 
func azure functionapp list
func azure functionapp fetch 
You’ll see the following output. Settings will be encrypted by default and stored in appsettings.json.
Loading AzureWebJobsStorage = *****
Loading AzureWebJobsDashboard = *****
To view settings values on the command line, run:
func settings list -a
If you want edit the file in an unencrypted form, run:
func settings decrypt
Editing the Function configuration If you haven’t already, open the Functions directory in Visual Studio Code by running code . Now, edit QueueTriggerJS/function.json and set the value AzureWebJobsStorage for the value for connection. Your function.json will look like the following:
{
    "disabled": false,
    "bindings": [
        {
            "name": "myQueueItem",
            "type": "queueTrigger",
            "direction": "in",
            "queueName": "js-queue-items",
            "connection":"AzureWebJobsStorage"
        }
    ]
}
Now it’s time to run the function. There are two ways to trigger it: add new items to a queue named js-queue-items or use the Functions CLI to trigger the function directly.

Triggering a function using “func run”

To trigger directly, run the following in the Functions CLI:
func run .\QueueTriggerJS\ --debug -c "I love this CLI!"
You’ll see the following output:
Executing: 'Functions.QueueTriggerJS' - Reason: 'This function was programmatically called via the host APIs.'
Function started (Id=c2603348-a0c5-4d7a-b938-5d3e66ed35fd)
JavaScript queue trigger function processed work item I love this CLI!
Function completed (Success, Id=c2603348-a0c5-4d7a-b938-5d3e66ed35fd)
Executed: 'Functions.QueueTriggerJS' (Succeeded)
Note: if you this error, it means you haven’t set a value for AzureWebJobsStorage in appsettings.json: Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.QueueTriggerJS'. Microsoft.Azure.WebJobs.Host: Object reference not set to an instance of an object. Error indexing method 'Functions.QueueTriggerJS'. Now, let’s run and attach a debugger, the same as before:
func run .\QueueTriggerJS --debug -c "Foo"

Triggering a function with a queue message

The cool thing about the local development experience is that you can trigger off of Azure resources directly, rather than just simulating via func run. By default, the Functions CLI will poll for new queue items every minute. For development purposes, it’s helpful to poll more frequently. Add the following to your host.json file, to poll every 2 seconds:
{
     "queues": {
        "maxPollingInterval": 2000
     }
}
Launch Azure Storage Explorer and create a queue js-queue-items in storage account you’ve specified in the AzureWebJobsStorage connection string: 7 8 Then, in Visual Studio Code, we see out breakpoint being hit: 9 This is just a taste of what you can accomplish with the Azure Functions CLI. Try it out today and let us know what you think!

Provide feedback

The Azure Functions CLI is still in preview and under active development. If you find any issues, please post a GitHub issue and include the title “CLI:”. The CLI is open source and can be found in a branch of the azure-webjobs-script repo. You can also reach out to me on Twitter @lindydonna. For general feedback and questions about Azure Functions: