Azure Functions Guide
Triggers & Bindings
| Trigger | Description |
|---|---|
| HTTP | REST endpoints, webhooks |
| Timer | Cron expression scheduled |
| Blob Storage | On new/modified blob |
| Queue Storage | Azure Queue messages |
| Service Bus | Queue or topic messages |
| Event Hub | High-throughput event streams |
| Event Grid | Event subscriptions |
| Cosmos DB | Change feed trigger |
function.json & Code Example
// function.json (in-process model)
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": ["get", "post"]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "queue",
"direction": "out",
"name": "outputQueue",
"queueName": "work-items",
"connection": "AzureWebJobsStorage"
}
]
}
// Python function (isolated worker model)
import azure.functions as func
import json
app = func.FunctionApp()
@app.function_name(name="HttpTrigger")
@app.route(route="hello", methods=["GET", "POST"])
def http_trigger(req: func.HttpRequest) -> func.HttpResponse:
name = req.params.get('name', 'World')
return func.HttpResponse(f"Hello, {name}!")
@app.function_name(name="TimerTrigger")
@app.schedule(schedule="0 */5 * * * *", arg_name="timer")
def timer_trigger(timer: func.TimerRequest) -> None:
logging.info("Timer trigger fired")
Durable Functions
// Orchestrator function
const df = require('durable-functions');
module.exports = df.orchestrator(function*(context) {
// Sequential activities
const x = yield context.df.callActivity('ProcessOrder', context.df.getInput());
const y = yield context.df.callActivity('SendConfirmation', x);
// Parallel fan-out
const tasks = [1, 2, 3].map(i =>
context.df.callActivity('ProcessItem', i)
);
const results = yield context.df.Task.all(tasks);
// Wait for external event (human approval)
const approval = yield context.df.waitForExternalEvent('Approval');
if (approval) {
yield context.df.callActivity('Finalize', results);
}
return results;
});
// Activity function
module.exports = async function(context) {
const input = context.bindings.input;
return { processed: true, id: input.orderId };
};
Deployment Slots
# Create staging slot
az functionapp deployment slot create \
--name my-function-app \
--resource-group myRG \
--slot staging
# Deploy to staging slot
az functionapp deployment source config-zip \
--name my-function-app \
--resource-group myRG \
--slot staging \
--src function.zip
# Swap staging to production
az functionapp deployment slot swap \
--name my-function-app \
--resource-group myRG \
--slot staging \
--target-slot production
# List slots
az functionapp deployment slot list \
--name my-function-app \
--resource-group myRG
App Settings
# Set app settings
az functionapp config appsettings set \
--name my-function-app \
--resource-group myRG \
--settings \
DB_CONNECTION_STRING="Server=..." \
QUEUE_NAME="work-items" \
MAX_BATCH_SIZE=100
# Reference Key Vault secret
az functionapp config appsettings set \
--name my-function-app \
--resource-group myRG \
--settings "[email protected](VaultName=myVault;SecretName=db-pass)"
# Enable managed identity
az functionapp identity assign \
--name my-function-app \
--resource-group myRG
# List settings
az functionapp config appsettings list \
--name my-function-app \
--resource-group myRG
Hosting Plans
| Plan | Billing | Cold Start | Max Duration |
|---|---|---|---|
| Consumption | Per-execution | Yes | 10 min |
| Flex Consumption | Per-execution + instances | Minimal | Unlimited |
| Premium | Per-instance | No (pre-warmed) | Unlimited |
| Dedicated (App Service) | Per-plan | No | Unlimited |
| Container Apps | Per-consumption | Configurable | Unlimited |