In these series of posts, I will explain the internals of Azure Functions and how it works. By the end of it, you should be able to understand what happens once an Azure Function is deployed till the moment it is triggered and invocation completes.
Is it a Web App?
Yes, every Azure Function App that uses .Net as a Language runs as as.net core web app. When the app starts, it loads all your functions and proxies and set up the routes and listeners for each function.
Web App Structure
Just like any other Azure Web App, it consists of the following folders:
- data: This folder contains another folder named “functions” which has another folder called extensions. The extensions folder has a list of all extensions installed to your Functions App. Each file has a reference to a nuget package that has the extension implementation.
- Log Files
- site: it has the wwwroot which hosts the asp.net core web app and all the functions

But for Azure Functions App, the following folders are added:
.nuget

Contains all nuget packages installed when you install a new extension. A reference for each extension installed exist in a file under: data\functions\extensions. The sample extension file below specify the package :Microsoft.Azure.WebJobs.Extensions.ServiceBus
In Azure Functions 1.0, it was running on .Net 4.6 and the runtime already included all the supported triggers and bindings. But, with version 2.0, the runtime only includes http and timer binding and all the other bindings can be developed and installed separately using extensions. This allows you to develop your own extensions and upload it without the need to wait for a new version of Azure Functions.
{
"Id": "d3a33dd0-3941-4acf-a303-72773995901d",
"Status": 1,
"StartTime": "2019-01-02T02:49:23.5568341+00:00",
"EndTime": "2019-01-02T02:50:50.1029788+00:00",
"Error": null,
"Properties": {
"id": "Microsoft.Azure.WebJobs.Extensions.ServiceBus",
"version": "3.0.0"
}
}
ASP.NET
This folder contains all data protection keys used in the web app
To have a look at this folder structure and explore it yourself, use the following URL: https://%5BFUNCTION_APP_NAME%5D.scm.azurewebsites.net/DebugConsole
wwwroot folder structure

As you can see, there are 3 folders. Each folder represent a single function. All DLLs for each function exist in the bin folder.
The host.json
file by default only has the version number for the function
{
"version": "2.0"
}
Inside each function, there is a function.json
file that has the configuration for this function.
{
"generatedBy": "Microsoft.NET.Sdk.Functions-1.0.14",
"configurationSource": "attributes",
"bindings": [
{
"type": "timerTrigger",
"schedule": "0 */5 * * * *",
"useMonitor": true,
"runOnStartup": false,
"name": "myTimer"
}
],
"disabled": false,
"scriptFile": "../bin/FunctionApp1.dll",
"entryPoint": "FunctionApp1.Function2.Run"
}
The Azure Functions run-time use this file to load the metadata for each function during application startup. The most important properties are the scriptFile
which points to the DLL that has the code and the entryPoint
that has the exact c# method name that will be executed when the function triggers.
The configurationSource
specifies where to read the function configuration such as connection strings for the blob storage or service bus. attributes means it will be retrieved from code.
The binding
key lists all bindings for this function. For this sample, it is a timer and it is the trigger, so it has a single binding. For others, it can be bindings that represents input, output and a trigger.
In the next post, I will explain the internals of each function, and how the bindings and triggers works.