Work with Azure Functions Core Tools

Azure Functions Core Tools lets you develop and test your functions on your local computer from the command prompt or terminal. Your local functions can connect to live Azure services, and you can debug your functions on your local computer using the full Functions runtime. You can even deploy a function app to your Azure subscription.

Note

Don't mix local development with portal development in the same function app. When you create and publish functions from a local project, you won't be able to maintain or modify project code in the portal.

Developing functions on your local computer and publishing them to Azure using Core Tools follows these basic steps:

Prerequisites

The specific prerequisites for Core Tools depend on the features you plan to use:

Publish: Core Tools currently depends on either the Azure CLI or Azure PowerShell for authenticating with your Azure account. This means that you must install one of these tools to be able to publish to Azure from Azure Functions Core Tools.

Install extensions: To manually install extensions by using Core Tools, you must have the .NET 6.0 SDK installed. The .NET SDK is used by Core Tools to install extensions from NuGet. You don't need to know .NET to use Azure Functions extensions.

Core Tools versions

There are four versions of Azure Functions Core Tools. The version you use depends on your local development environment, choice of language, and level of support required.

Choose one of the following version tabs to learn about each specific version and for detailed installation instructions:

Supports version 4.x of the Functions runtime. This version supports Windows, macOS, and Linux, and uses platform-specific package managers or npm for installation. This is the recommended version of the Functions runtime and Core Tools.

You can only install one version of Core Tools on a given computer. Unless otherwise noted, the examples in this article are for version 4.x.

Install the Azure Functions Core Tools

Azure Functions Core Tools includes a version of the same runtime that powers Azure Functions runtime that you can run on your local development computer. It also provides commands to create functions, connect to Azure, and deploy function projects.

Starting with version 2.x, Core Tools runs on Windows, macOS, and Linux.

The following steps use a Windows installer (MSI) to install Core Tools v4.x. For more information about other package-based installers, see the Core Tools readme.

Download and run the Core Tools installer, based on your version of Windows:

Changing Core Tools versions

When changing to a different version of Core Tools, you should use the same package manager as the original installation to move to a different package version. For example, if you installed Core Tools version 3.x using npm, you should use the following command to upgrade to version 4.x:

npm install -g azure-functions-core-tools@4 --unsafe-perm true

If you used Windows installer (MSI) to install Core Tools on Windows, you should uninstall the old version from Add Remove Programs before installing a different version.

Create a local Functions project

A Functions project directory contains the following files and folders, regardless of language:

File name Description
host.json To learn more, see the host.json reference.
local.settings.json Settings used by Core Tools when running locally, including app settings. To learn more, see local settings.
.gitignore Prevents the local.settings.json file from being accidentally published to a Git repository. To learn more, see local settings
.vscode\extensions.json Settings file used when opening the project folder in Visual Studio Code.

To learn more about the Functions project folder, see the Azure Functions developers guide.

In the terminal window or from a command prompt, run the following command to create the project and local Git repository:

func init MyFunctionProj

This example creates a Functions project in a new MyFunctionProj folder. You're prompted to choose a default language for your project.

The following considerations apply to project initialization:

  • If you don't provide the --worker-runtime option in the command, you're prompted to choose your language. For more information, see the func init reference.

  • When you don't provide a project name, the current folder is initialized.

  • If you plan to publish your project to a custom Linux container, use the --docker option to make sure that a Dockerfile is generated for your project. To learn more, see Create a function on Linux using a custom image.

Certain languages may have more considerations:

  • Core Tools lets you create function app projects for the .NET runtime as both in-process and isolated worker process C# class library projects (.csproj). These projects, which can be used with Visual Studio or Visual Studio Code, are compiled during debugging and when publishing to Azure.

  • Use the --csx parameter if you want to work locally with C# script (.csx) files. These files are the same ones you get when you create functions in the Azure portal and when using version 1.x of Core Tools. To learn more, see the func init reference.

Register extensions

Starting with runtime version 2.x, Functions triggers and bindings are implemented as .NET extension (NuGet) packages. For compiled C# projects, you simply reference the NuGet extension packages for the specific triggers and bindings you're using. HTTP bindings and timer triggers don't require extensions.

To improve the development experience for non-C# projects, Functions lets you reference a versioned extension bundle in your host.json project file. Extension bundles makes all extensions available to your app and removes the chance of having package compatibility issues between extensions. Extension bundles also removes the requirement of installing the .NET SDK and having to deal with the extensions.csproj file.

Extension bundles is the recommended approach for functions projects other than C# complied projects, and for C# script. For these projects, the extension bundle setting is generated in the host.json file during initialization. If bundles aren't enabled, you need to update the project's host.json file.

The easiest way to install binding extensions is to enable extension bundles. When you enable bundles, a predefined set of extension packages is automatically installed.

To enable extension bundles, open the host.json file and update its contents to match the following code:

{
    "version": "2.0",
    "extensionBundle": {
        "id": "Microsoft.Azure.Functions.ExtensionBundle",
        "version": "[2.*, 3.0.0)"
    }
}

To learn more, see Register Azure Functions binding extensions.

There may be cases in a non-.NET project when you can't use extension bundles, such as when you need to target a specific version of an extension not in the bundle. In these rare cases, you can use Core Tools to locally install the specific extension packages required by your project. To learn more, see Install extensions.

Local settings

When running in a function app in Azure, settings required by your functions are stored securely in app settings. During local development, these settings are instead added to the Values object in the local.settings.json file. The local.settings.json file also stores settings used by local development tools.

Because the local.settings.json may contain secrets, such as connection strings, you should never store it in a remote repository. To learn more about local settings, see Local settings file.

By default, these settings aren't migrated automatically when the project is published to Azure. Use the --publish-local-settings option when you publish to make sure these settings are added to the function app in Azure. Values in the ConnectionStrings section are never published.

The function app settings values can also be read in your code as environment variables. For more information, see the Environment variables section of these language-specific reference articles:

When no valid storage connection string is set for AzureWebJobsStorage and a local storage emulator isn't being used, the following error message is shown:

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

Get your storage connection strings

Even when using the Azurite storage emulator for development, you may want to run locally with an actual storage connection. Assuming you have already created a storage account, you can get a valid storage connection string in one of several ways:

  1. From the Azure portal, search for and select Storage accounts.

    Select Storage accounts from Azure portal

  2. Select your storage account, select Access keys in Settings, then copy one of the Connection string values.

    Copy connection string from Azure portal

Create a function

To create a function in an existing project, run the following command:

func new

When you run func new, you're prompted to choose a template in the default language of your function app. Next, you're prompted to choose a name for your function. In version 1.x, you're also required to choose the language.

You can also specify the function name and template in the func new command. The following example uses the --template option to create an HTTP trigger named MyHttpTrigger:

func new --template "Http Trigger" --name MyHttpTrigger

This example creates a Queue Storage trigger named MyQueueTrigger:

func new --template "Azure Queue Storage Trigger" --name MyQueueTrigger

To learn more, see the func new command.

Run functions locally

To run a Functions project, you run the Functions host from the root directory of your project. The host enables triggers for all functions in the project. The start command varies depending on your project language.

func start

Note

Version 1.x of the Functions runtime instead requires func host start. To learn more, see Azure Functions Core Tools reference.

When the Functions host starts, it outputs the URL of HTTP-triggered functions, like in the following example:

Found the following functions:
Host.Functions.MyHttpTrigger

Job host started
Http Function MyHttpTrigger: http://localhost:7071/api/MyHttpTrigger

Important

When running locally, authorization isn't enforced for HTTP endpoints. This means that all local HTTP requests are handled as authLevel = "anonymous". For more information, see the HTTP binding article.

Passing test data to a function

To test your functions locally, you start the Functions host and call endpoints on the local server using HTTP requests. The endpoint you call depends on the type of function.

Note

Examples in this topic use the cURL tool to send HTTP requests from the terminal or a command prompt. You can use a tool of your choice to send HTTP requests to the local server. The cURL tool is available by default on Linux-based systems and Windows 10 build 17063 and later. On older Windows, you must first download and install the cURL tool.

For more general information on testing functions, see Strategies for testing your code in Azure Functions.

HTTP and webhook triggered functions

You call the following endpoint to locally run HTTP and webhook triggered functions:

http://localhost:{port}/api/{function_name}

Make sure to use the same server name and port that the Functions host is listening on. You see this in the output generated when starting the Function host. You can call this URL using any HTTP method supported by the trigger.

The following cURL command triggers the MyHttpTrigger quickstart function from a GET request with the name parameter passed in the query string.

curl --get http://localhost:7071/api/MyHttpTrigger?name=Azure%20Rocks

The following example is the same function called from a POST request passing name in the request body:

curl --request POST http://localhost:7071/api/MyHttpTrigger --data '{"name":"Azure Rocks"}'

You can make GET requests from a browser passing data in the query string. For all other HTTP methods, you must use cURL, Fiddler, Postman, or a similar HTTP testing tool that supports POST requests.

Non-HTTP triggered functions

For all functions other than HTTP and Event Grid triggers, you can test your functions locally using REST by calling a special endpoint called an administration endpoint. Calling this endpoint with an HTTP POST request on the local server triggers the function. You can call the functions administrator endpoint (http://localhost:{port}/admin/functions/) to get URLs for all available functions, both HTTP triggered and non-HTTP triggered.

When running locally, authentication and authorization is bypassed. However, when you try to call the same administrator endpoints on your function app in Azure, you must provide an access key. To learn more, see Function access keys.

Important

Access keys are valuable shared secrets. When used locally, they must be securely stored outside of source control. Because authentication and authorization isn't required by Functions when running locally, you should avoid using and storing access keys unless your scenarios require it.

To test Event Grid triggered functions locally, see Local testing with viewer web app.

You can optionally pass test data to the execution in the body of the POST request. This functionality is similar to the Test tab in the Azure portal.

You call the following administrator endpoint to trigger non-HTTP functions:

http://localhost:{port}/admin/functions/{function_name}

To pass test data to the administrator endpoint of a function, you must supply the data in the body of a POST request message. The message body is required to have the following JSON format:

{
    "input": "<trigger_input>"
}

The <trigger_input> value contains data in a format expected by the function. The following cURL example is a POST to a QueueTriggerJS function. In this case, the input is a string that is equivalent to the message expected to be found in the queue.

curl --request POST -H "Content-Type:application/json" --data '{"input":"sample queue data"}' http://localhost:7071/admin/functions/QueueTrigger

Publish to Azure

The Azure Functions Core Tools supports two types of deployment:

Deployment type Command Description
Project files func azure functionapp publish Deploys function project files directly to your function app using zip deployment.
Kubernetes cluster func kubernetes deploy Deploys your Linux function app as a custom Docker container to a Kubernetes cluster.

Before you publish

Important

You must have the Azure CLI or Azure PowerShell installed locally to be able to publish to Azure from Core Tools.

A project folder may contain language-specific files and directories that shouldn't be published. Excluded items are listed in a .funcignore file in the root project folder.

You must have already created a function app in your Azure subscription, to which you'll deploy your code. Projects that require compilation should be built so that the binaries can be deployed.

To learn how to create a function app from the command prompt or terminal window using the Azure CLI or Azure PowerShell, see Create a Function App for serverless execution.

Important

When you create a function app in the Azure portal, it uses version 4.x of the Function runtime by default. To make the function app use version 1.x of the runtime, follow the instructions in Run on version 1.x. You can't change the runtime version for a function app that has existing functions.

Deploy project files

To publish your local code to a function app in Azure, use the publish command:

func azure functionapp publish <FunctionAppName>

The following considerations apply to this kind of deployment:

  • Publishing overwrites existing files in the function app.

  • Use the --publish-local-settings option to automatically create app settings in your function app based on values in the local.settings.json file.

  • A remote build is performed on compiled projects. This can be controlled by using the --no-build option.

  • Your project is deployed such that it runs from the deployment package. To disable this recommended deployment mode, use the --nozip option.

  • Java uses Maven to publish your local project to Azure. Instead, use the following command to publish to Azure: mvn azure-functions:deploy. Azure resources are created during initial deployment.

  • You'll get an error if you try to publish to a <FunctionAppName> that doesn't exist in your subscription.

Kubernetes cluster

Functions also lets you define your Functions project to run in a Docker container. Use the --docker option of func init to generate a Dockerfile for your specific language. This file is then used when creating a container to deploy. To learn how to publish a custom container to Azure without Kubernetes, see Create a function on Linux using a custom container.

Core Tools can be used to deploy your project as a custom container image to a Kubernetes cluster.

The following command uses the Dockerfile to generate a container and deploy it to a Kubernetes cluster.

func kubernetes deploy --name <DEPLOYMENT_NAME> --registry <REGISTRY_USERNAME> 

To learn more, see Deploying a function app to Kubernetes.

Install extensions

If you aren't able to use extension bundles, you can use Azure Functions Core Tools locally to install the specific extension packages required by your project.

Important

You can't explicitly install extensions in a function app with extension bundles enabled. First, remove the extensionBundle section in host.json before explicitly installing extensions.

The following items describe some reasons you might need to install extensions manually:

  • You need to access a specific version of an extension not available in a bundle.
  • You need to access a custom extension not available in a bundle.
  • You need to access a specific combination of extensions not available in a single bundle.

When you explicitly install extensions, a .NET project file named extensions.csproj is added to the root of your project. This file defines the set of NuGet packages required by your functions. While you can work with the NuGet package references in this file, Core Tools lets you install extensions without having to manually edit this C# project file.

There are several ways to use Core Tools to install the required extensions in your local project.

Install all extensions

Use the following command to automatically add all extension packages used by the bindings in your local project:

func extensions install

The command reads the function.json file to see which packages you need, installs them, and rebuilds the extensions project (extensions.csproj). It adds any new bindings at the current version but doesn't update existing bindings. Use the --force option to update existing bindings to the latest version when installing new ones. To learn more, see the func extensions install command.

If your function app uses bindings or NuGet packages that Core Tools doesn't recognize, you must manually install the specific extension.

Install a specific extension

Use the following command to install a specific extension package at a specific version, in this case the Storage extension:

func extensions install --package Microsoft.Azure.WebJobs.Extensions.Storage --version 5.0.0

You can use this command to install any compatible NuGet package. To learn more, see the func extensions install command.

Monitoring functions

The recommended way to monitor the execution of your functions is by integrating with Azure Application Insights. You can also stream execution logs to your local computer. To learn more, see Monitor Azure Functions.

Application Insights integration

Application Insights integration should be enabled when you create your function app in Azure. If for some reason your function app isn't connected to an Application Insights instance, it's easy to do this integration in the Azure portal. To learn more, see Enable Application Insights integration.

Enable streaming logs

You can view a stream of log files being generated by your functions in a command-line session on your local computer.

Built-in log streaming

Use the func azure functionapp logstream command to start receiving streaming logs of a specific function app running in Azure, as in the following example:

func azure functionapp logstream <FunctionAppName>

Note

Built-in log streaming isn't yet enabled in Core Tools for function apps running on Linux in a Consumption plan. For these hosting plans, you instead need to use Live Metrics Stream to view the logs in near-real time.

Live Metrics Stream

You can view the Live Metrics Stream for your function app in a new browser window by including the --browser option, as in the following example:

func azure functionapp logstream <FunctionAppName> --browser

This type of streaming logs requires that Application Insights integration be enabled for your function app.

x86 emulation on ARM64

Functions doesn't currently support local Python function development on ARM64 devices. Use the following steps to develop Python functions on a Mac with an M1 chip by running in an emulated x86 environment.

Enable Rosetta in Terminal

  1. In your Mac, open Finder, choose Applications, and locate Terminal.

  2. Control-click Terminal and select Get Info. You can also create a separate parallel environment by duplicating the Terminal and renaming it.

    Screenshot of selecting Get Info by control-clicking Terminal

  3. Select Open using Rosetta.

    Screenshot of the Terminal configured to open using Rosetta

  4. Open Terminal, which now has Rosetta enabled, and make sure your shell is zsh.

  5. Run the following command to validate the x86 emulation.

    $ arch
    

    A response of i386 indicates your terminal is running an x86 emulated environment.

Install required packages

Reinstall all dependencies required by Functions in this environment, which includes the following packages:

Also, reinstall any other packages required by your Python project.

Set aliases (optional)

You can optionally set aliases to make it easy to reference the right versions in Rosetta.

The following is an example of how to create a .zshrc file to configure your zsh terminal:

# file: .zshrc
# rosetta terminal setup
if [ $(arch) = "i386" ]; then
    alias python="/usr/local/bin/python3"
    alias brew86='/usr/local/bin/brew'
    alias pyenv86="arch -x86_64 pyenv"
    alias func="/usr/local/Cellar/azure-functions-core-tools@4/4.0.4785/func"
fi

Run the following command to apply the aliases:

$ source .zshrc

Validate you're referencing the correct versions by using the which command, as shown in the following examples:

Command Example response
$ which python python: aliased to /usr/local/bin/python3
$ which func func: aliased to /usr/local/Cellar/azure-functions-core-tools@4/4.0.4785/func

These example responses are based on the previous example .zshrc file.

Now, you're set up to use Azure Functions in the x86 environment from the Terminal.

If you're using Visual Studio Code, you can integrate Rosetta with the built-in Terminal. For more information, see Enable emulation in Visual Studio Code.

Next steps

Learn how to develop, test, and publish Azure functions by using Azure Functions core tools. Azure Functions Core Tools is open source and hosted on GitHub. To file a bug or feature request, open a GitHub issue.