Recently I’ve been thinking about different ways to work Azure Functions, and the pros and cons of each. I wanted to better understand the Azure Functions Core Tools (also known as the CLI), and that role that plays in developing functions locally and then publishing them to Azure. I’d recently seen a Microsoft guy use this in his demos, and I was wondering if I was missing an important aspect of Azure Functions (which I try to stay on top of). Between Visual Studio Code/full Visual Studio/the command-line approach with the Core Tools, there’s a lot of overlap – so which is best when?
Azure Functions v2:
OK, back to the development options. First let’s be clear on what the process looks like with each.
Option 1 - with Azure Functions Core Tools/CLI
The command-line approach can be interesting because it’s the same across platforms, although to be fair it’s currently only version 2 of Azure Functions which can be used across macOS and Linux. But what you get here is the ability to:
- Create your function
- Run it locally
- Deploy to a Function App in Azure
PRE-REQS:
- Ensure you have .NET and node.js installed on your machine (for npm)
- Install Azure Functions Core Tools using npm install -g azure-functions-core-tools@core
- See Install the Azure Functions Core Tools for more info
PROCESS:
We’ll create a simple HTTP function in JavaScript in this case. As you might expect, we run commands at the command-line to create new functions and work with them.
- Create a folder for the function you’ll create, and open a command prompt there.
- Type func init to initalize the folder with the files needed for an Azure Function:
- To create a function, type func new to start the process. In V1 functions, you’ll need to provide:
- Provide a name for your function:
- Now open the function folder in VS Code (you do know about the “code .” command to open to the current directory right?):
- <VS Code opens>
- If you have the VS Code extension for Azure Functions installed, you’ll see this:
This is basically asking you if you’d like to switch to the VS Code way of doing things. For now, we’ll close this message to work with the command-line/Core Tools experience.
- Now you can add code to your function as needed.
- Now type func run <Your function name> to run the function locally –the first time you do this, you’ll see this message that we need to OK:
- In the case of a HTTP function like this, we should pass some content in the POST body using the --content flag. To match up with the default code that the generator added, let’s pass some JSON including a ‘name’ attribute:
- You should now see the functions runtime spin up and serve your function:
- Since your function is being served on a local endpoint, you’ll most likely want to use Postman or similar as you develop the code (as per the earlier recommendation) since this is much richer than the --content flag. The output from the Core Tools will tell you the URL to hit, but by default it is http://localhost:7071/api/[function name]:
Publishing the (JavaScript) function using the CLI and Visual Studio Code
After developing the code some more, we can deploy directly to a Function App in Azure with other commands. Most likely you’ll need to login first, and this is done with the following command:
func azure login --username [username] --password [password]
If you don’t provide a username/password, you’ll be prompted interactively:
You may need to explicitly choose the Azure subscription (once you’ve signed-in) with this command, for example if that account has access to multiple subscriptions:
func azure account set [AzureSubscriptionID]
From here you can use the following to deploy the function:
func azure functionapp publish <FunctionAppName>
This is great, but something is missing – debugging!
Debugging the (JavaScript) function using the CLI and Visual Studio Code
At first I thought it wasn’t possible to debug functions locally using the CLI, but it is by combining it with VS Code. The process is:
- Put a breakpoint in your code in VS Code
- Run your function from the CLI and add the --debug flag – so func run <Your function name> –debug
- Hit F5 (or go to the Debug tab and press Play)
- Make a request to your function’s local URL e.g. http://localhost:7071/api/[function name]:
- Your breakpoint will now be hit and you can make use of all of VS Code’s debugging capabilities:
- DevOps scenarios, where you have some automation scripts to run/test your functions (either locally or by deploying them up to Azure)
- You're trying to be ultra-hip
Option 2 – with Visual Studio Code
PRE-REQS:
- You’ll need the Azure Functions VS Code extension. This can be obtained from https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions. It looks like this when installed:
PROCESS:
Creating a function in VS Code is easy:
- First, create a folder on your machine to host the files – I named my folder “COB-JS-Functions” to reflect what we’re doing here.
- Open VS Code to this folder.
- Hit CTRL SHIFT + P for the VS Code command bar, and start typing “Azure Functions” to pull up those commands. Select the “Create New Project” command:
- Follow the prompts in the command bar to select the folder – accept the default if you’re already in the folder you created earlier:
- When it comes to selecting a language, select your preference – I’m using JavaScript here (and you might want to consider my overall message that C# functions are generally easier in full-blown Visual Studio!):
- Your folder will now be scaffolded with the starter files:
- Now let’s add an individual function. Hit CTRL SHIFT + P again, and find the “Create Function” command under Azure Functions:
- Accept that we’ll use the current folder:
- Select the trigger:
- Enter the name for your function:
- And then the authentication type:
- A bunch of new files will now be added to your folder, including the “index.js” file for your function implementation:
You can now code away and start to build out your function. Most likely you’ll want to bring in some npm modules for a JavaScript function, and start to work against the Graph, SharePoint or whatever you need. I really like being guided through the process through the VS Code command palette, I think it works really well.
Debugging Azure Functions locally in Visual Studio Code
VS Code works great as a debugger for JavaScript functions, PowerShell scripts and more. The next sections have a couple of notes on language-specific details:
For JavaScript Functions
JavaScript mainly “just works”, although you’ll need to hit the local URL your function is hosted on (e.g. with Postman or similar) by default. You can go a step further and amend your launch.json file so that F5 does everything - I had to add a configuration for ‘launch’ as well as ‘attach’. The process looks like this:
- Add a breakpoint to your code.
- Once your launch.json is good, ensure you have a “launch” configuration selected in the debug config selector – this ensures node.js is started, rather than assuming it’s running already and you can attach to it:
- You should see VS Code spin up the functions host for you by running func host start:
- You’ll actually need to hit the URL for your function to start the execution and hit your breakpoint. VS Code makes this easy by providing a clickable link in the terminal output:
- This will open a new browser tab, hit your function endpoint, and your breakpoint will be hit
For PowerShell Functions
See my “Running a PowerShell script in the cloud with an Azure Function, PnP and the Graph” article, specifically the “Debugging our PowerShell script locally with F5” section – I show the process in detail here. In short it works well, but remember that PowerShell only has experimental language status in Functions V1, and this did not go forward into V2.
For C# Functions
Well, debugging C# functions which are .cs files (not .csx) in Visual Studio Code is somewhat different – the OmniSharp extension is required (https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp) and there is some shennanigans involved to debug V1 functions since they are 32-bit. See https://github.com/Microsoft/vscode-azurefunctions/blob/master/docs/func64bit.md. Overall I feel that full Visual Studio is a simpler approach for C# functions.
Publishing files to an Azure Function from VS Code:
In the spirit of re-use, this section comes straight from my PowerShell functions article :) The steps here are the same regardless of your function language.
You can publish your function to Azure in a variety of ways, but VS Code makes this easy:
- Switch to Azure tab in VS Code (bottom icon):
- Find the Function App you created earlier. Right-click on it, and select “Deploy to Function App”:
- Step through prompts in the VS Code command palette – the defaults are generally what you need:
- Accept the prompt:
- VS Code will then start the publish operation:
- You’ll then find that your files have been deployed as a Function to the selected Function App:
Option 3 – using Visual Studio
Visual Studio is my preferred option for C# functions (for the moment at least).
PRE-REQS:
- Ensure you have the Azure Functions Visual Studio extension installed – this comes bundled into the Azure development workload of Visual Studio 2017 or can be obtained from https://marketplace.visualstudio.com/items?itemName=VisualStudioWebandAzureTools.AzureFunctionsandWebJobsTools. It looks like this when installed (in Tools and Extensions):
See https://docs.microsoft.com/en-us/azure/azure-functions/functions-develop-vs for more details.
PROCESS:
There is a VS project template, so creating a new project is easy:
- Create a new project using Create > New Project:
- Add a new Function from the context menu on the project:
Select the trigger type:
Debugging a function in Visual Studio:
This is as simple as adding a breakpoint and hitting F5. For C# functions, as things stand this is much simpler than the other options. You’ll see the Core Tools function host spin-up, and the URL of your function will be provided – you’ll need to hit this in a browser or with Postman, although you could configure the “Debug” tab of your project to launch a browser or script to do this automatically (similar to the idea of editing the launch.json file if using Visual Studio Code):
Your breakpoint will then be hit:
Remember that you can also debug a function running live in Azure if it was published in debug mode. If you’re developing against a dev/test Office 365 tenant and Azure subscription this can be very helpful (but not recommended for production obviously). Use the Cloud Explorer to find your function, right-click and select “Debug”.
Publishing a function from Visual Studio
Anyone who’s worked with functions in VS is probably familiar with this, but as you’d expect it’s a slick experience:
But as the saying goes, friends don’t let friends publish Azure Functions directly to production (and potentially other environments too). Use one of the other deployment methods, perhaps one based on continuous deployment if appropriate.
Summary
That was quite a lot detail. In summary, if you write the majority of your other code with VS Code and/or are writing functions in JavaScript, then VS Code is probably your best choice – just make sure you install the Azure Functions VS Code extension. If you’re mainly using full Visual Studio, then stick with that for functions development too – just make sure you install the Azure Functions Visual Studio extension if your VS instance doesn’t have it already.
Using the Core Tools directly from the command-line is best-suited to CI/CD/DevOps automation, or those who feel the need to be particularly hipster.