Azure Functions
Custom home-page, catch-all and custom http bindings
Playing with route
in host.json
and routePrefix
in HttpTrigger
, we can get:
- removing
/api
from the http URL - changing the home-page of the Function
- create a catch-all for all not-mapped http requests
- custom function mapping
>>> Some tricks are not official nor documented. Use them at your own risk. <<<
Remove the /api
from URL, setting routePrefix to empty in the host.json
file:
"http": {
"routePrefix": ""
}
Custom homepage: create an http function with Route = "/"
[FunctionName("HomePage")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "/")] HttpRequest req,
ILogger log)
{
return new ContentResult()
{
Content = "<html><body><h1>This is my home page</h1></body></html>",
ContentType = "text/html",
StatusCode = 200
};
}
Catch-all http requests, with Route = "{*url}"
. Important: http function are mapped in alphabetic order. Name the catch all function with “zzz” or something similar at the beginning to place it a the end of list. Otherwise, it will hide some functions.
[FunctionName("ZZZCatchAll")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "{*url}")] HttpRequest req,
ILogger log)
{
string responseMessage = $"Catch-all! - {DateTime.UtcNow.ToString("O")} - {req.Path}";
return new OkObjectResult(responseMessage);
}
Custom path, e.g. https//xxxxxxxxxxxxx.azurewebsites.net/mycustompath/isalive2
[FunctionName("isalive2")]
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "mycustompath/isalive2")] HttpRequest req,
ILogger log)
{
// ...
}
Usage Metrics and Billing
Azure Functions are billed based on GB-seconds and total number of executions. For each execution, it considers the GB of used RAM multiplied by the seconds of exectution. At the comment, in Europe region, it is € 0.000015/GB-s and € 0.183 per million of executions.
Example: a function runs 10 times and every execution lasts 4 seconds and uses 0.5 GB ram:
Pricing | Total | |
---|---|---|
10 x 4 x 0.5 = 20 GB-s | € 0.000015 /GB-s | € 0,0003 |
10 runs | € 0.000000183 /run | € 0.00000183 |
€ 0.00030183 |
From the example it is clear that the majority of the costs of an Azure Function normally comes from RAM and execution time. So, keep RAS usage as low as possible, and be as fast as possible.
The metrics exposed on Azure Portal, are based on MB-milliseconds. So, a conversion is required: divided the MB-milliseonds value by 1024000 to get the GB-seconds value.
Example: on a day, an Azure Function accumulated 4.5 billion MB-milliseconds. The corresponding GB-seconds is: 4.5 x 10^9 / 1024000 =~ 4.5 x 10^3 = 4500 GB-seconds
corresponding to € 0.0675
To summarize:
Description | Unit |
---|---|
Billing Execution Unit | GB-seconds |
Portal and Metric Execution Unit | MS-milliseconds |
Change Storage Account
Every Function App needs a storage account to run. It can be changed but a small down-time and a redeployment are required.
Steps:
- create a new storage account. V1 is hightly recommened for minor costs compared to V2.
You cannot any more create it from Portal. Use AZ CLI or equivalent.
az storage account create --name xxxxxxxxxx --resource-group zzzzzzzz --location westeurope --sku Standard_LRS --kind Storage
- stop the Function
- change the configuration. In the following entry, enter the connections to the new storage account:
- AzureWebJobsStorage
- WEBSITE_CONTENTAZUREFILECONNECTIONSTRING
- start the function. If the function is running on a consumption plan (server-less), the Function App results empty. In such a case, re-deploy the Function app.
- now the function app is running again.