Azure Functions
SkillFiles & storageBuild serverless applications with Azure Functions. Create HTTP and event-driven functions with input/output bindings, configure triggers for queues, timers, and blob storage. Use Durable Functions for stateful orchestration workflows.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Azure Functions skill
What this skill tells your AI
The instructions your AI receives, as published by terminalskills/skills in skills/azure-functions/SKILL.md and read by ahel’s review.
Azure Functions is a serverless compute service that runs event-driven code without managing infrastructure. Its unique binding system connects to Azure services declaratively, and Durable Functions enable complex stateful workflows.
Core Concepts
- Trigger — what causes a function to run (HTTP, timer, queue, blob, etc.)
- Input Binding — declaratively read data from a service when function runs
- Output Binding — declaratively write data to a service after function runs
- Function App — a container for one or more functions sharing configuration
- Hosting Plan — Consumption (pay-per-execution), Premium, or Dedicated
- Durable Functions — extension for stateful orchestrations and workflows
Project Setup
# Create a new function project
func init my-functions --worker-runtime node --language javascript
cd my-functions
# Create a new HTTP-triggered function
func new --name HandleWebhook --template "HTTP trigger" --authlevel anonymous
# Create Azure resources
az group create --name my-app-rg --location eastus
az storage account create \
--name myappfuncstorage \
--resource-group my-app-rg \
--sku Standard_LRS
az functionapp create \
--name my-app-functions \
--resource-group my-app-rg \
--storage-account myappfuncstorage \
--consumption-plan-location eastus \
--runtime node \
--runtime-version 20 \
--functions-version 4
HTTP Functions
// src/functions/handleWebhook.js — HTTP triggered function
const { app } = require('@azure/functions');
app.http('handleWebhook', {
methods: ['POST'],
authLevel: 'anonymous',
route: 'webhooks/{source}',
handler: async (request, context) => {
const source = request.params.source;
const body = await request.json();
context.log(`Webhook from ${source}:`, body);
// Process webhook
const result = await processWebhook(source, body);
return {
status: 200,
jsonBody: { received: true, id: result.id }
};
}
});
Timer Functions
// src/functions/dailyCleanup.js — runs on a CRON schedule
const { app } = require('@azure/functions');
app.timer('dailyCleanup', {
schedule: '0 0 2 * * *', // 2:00 AM daily
handler: async (myTimer, context) => {
context.log('Running daily cleanup at', new Date().toISOString());
const deleted = await cleanupExpiredSessions();
context.log(`Deleted ${deleted} expired sessions`);
}
});
Queue Trigger with Output Binding
// src/functions/processOrder.js — triggered by queue, writes to Cosmos DB
const { app, output } = require('@azure/functions');
const cosmosOutput = output.cosmosDB({
databaseName: 'app-db',
containerName: 'processed-orders',
connection: 'CosmosDBConnection',
createIfNotExists: true
});
app.storageQueue('processOrder', {
queueName: 'order-queue',
connection: 'AzureWebJobsStorage',
return: cosmosOutput,
handler: async (queueItem, context) => {
context.log('Processing order:', queueItem.orderId);
const processedOrder = {
id: queueItem.orderId,
...queueItem,
status: 'processed',
processedAt: new Date().toISOString()
};
// Returned value goes to Cosmos DB via output binding
return processedOrder;
}
});
Blob Trigger
// src/functions/processImage.js — triggered when blob is uploaded
const { app } = require('@azure/functions');
app.storageBlob('processImage', {
path: 'uploads/{name}',
connection: 'AzureWebJobsStorage',
handler: async (blob, context) => {
const fileName = context.triggerMetadata.name;
context.log(`Processing blob: ${fileName}, size: ${blob.length} bytes`);
// Resize image, extract metadata, etc.
await generateThumbnail(blob, fileName);
}
});
Durable Functions
// src/functions/orderOrchestrator.js — orchestrate multi-step order processing
const { app } = require('@azure/functions');
const df = require('durable-functions');
// Orchestrator function
df.app.orchestration('orderOrchestrator', function* (context) {
const order = context.df.getInput();
// Step 1: Validate inventory
const inventory = yield context.df.callActivity('checkInventory', order.items);
if (!inventory.available) {
yield context.df.callActivity('notifyCustomer', {
orderId: order.id,
message: 'Items out of stock'
});
return { status: 'cancelled', reason: 'out_of_stock' };
}
// Step 2: Process payment
const payment = yield context.df.callActivity('processPayment', {
amount: order.total,
customerId: order.customerId
});
// Step 3: Ship order (with retry)
const retryOptions = new df.RetryOptions(5000, 3); // 5s interval, 3 attempts
const shipment = yield context.df.callActivityWithRetry(
'shipOrder', retryOptions, order
);
// Step 4: Notify customer
yield context.df.callActivity('notifyCustomer', {
orderId: order.id,
message: `Shipped! Tracking: ${shipment.trackingNumber}`
});
return { status: 'completed', tracking: shipment.trackingNumber };
});
// Activity functions
df.app.activity('checkInventory', { handler: async (items) => { /* ... */ } });
df.app.activity('processPayment', { handler: async (payment) => { /* ... */ } });
df.app.activity('shipOrder', { handler: async (order) => { /* ... */ } });
df.app.activity('notifyCustomer', { handler: async (notification) => { /* ... */ } });
// HTTP starter
app.http('startOrder', {
route: 'orders/start',
methods: ['POST'],
extraInputs: [df.input.durableClient()],
handler: async (req, context) => {
const client = df.getClient(context);
const order = await req.json();
const instanceId = await client.startNew('orderOrchestrator', { input: order });
return client.createCheckStatusResponse(req, instanceId);
}
});
Deployment
# Deploy to Azure
func azure functionapp publish my-app-functions
# Set application settings
az functionapp config appsettings set \
--name my-app-functions \
--resource-group my-app-rg \
--settings "CosmosDBConnection=AccountEndpoint=..."
# View function logs
func azure functionapp logstream my-app-functions
Best Practices
- Use bindings to avoid boilerplate for reading/writing Azure services
- Choose Consumption plan for sporadic workloads, Premium for consistent traffic
- Use Durable Functions for multi-step workflows instead of chaining queues
- Store connection strings in Application Settings, not code
- Set
FUNCTIONS_WORKER_PROCESS_COUNTfor CPU-bound workloads - Use managed identities instead of connection strings where possible
- Enable Application Insights for monitoring and diagnostics
- Keep functions small and focused — one trigger, one purpose
Signals
- GitHub stars
- 150
- Forks
- 19
- Last commit
- Sep 2026
ahel review
S4info
community integration — published by terminalskills, not azure
Automated review, not a security audit. Ruleset v1.
Advanced
- Catalog kind
- skill
- Gateway key
azure-functions-terminalskills- Source
- github.com/terminalskills/skills