Serverless met Azure betekent dat code en workflows worden uitgevoerd wanneer een gebeurtenis daarom vraagt, terwijl traditioneel hosten draait om het beheren van doorlopende servercapaciteit.
Serverloos betekent niet dat er geen servers bestaan. Het betekent dat de ontwikkelaar of het platformteam zich minder bezighoudt met patching, capaciteitstoewijzing en runtimebeheer, terwijl Azure de onderliggende infrastructuur beheert. De verantwoordelijkheid verschuift daardoor naar goed applicatieontwerp: duidelijke triggers, betrouwbare verwerking, veilige toegang, kostenbewaking en zichtbaarheid in wat er gebeurt wanneer functies worden uitgevoerd.
Laatst bijgewerkt: 2026. De voorbeelden in dit artikel gaan uit van Azure Functions runtime v4, .NET 8 isolated worker, Azure CLI, Visual Studio Code en Azurite voor lokale opslagontwikkeling. Servicelimieten, prijsmodellen en runtime-ondersteuning kunnen veranderen; controleer daarom bij productieontwerp altijd de actuele Microsoft-documentatie en pricingpagina’s.
Een serverloze Azure-app bestaat meestal uit kleine onderdelen die reageren op gebeurtenissen. Een HTTP-aanvraag kan een functie starten, een bericht in een queue kan achtergrondverwerking activeren, een blob-upload kan een event publiceren en een workflow kan een integratieproces afhandelen. De app wordt daardoor opgebouwd rond gebeurtenissen in plaats van rond permanent draaiende servers.
Azure Functions is de meest directe ingang voor ontwikkelaars die eigen code willen uitvoeren na een trigger. Een functie kan bijvoorbeeld een API-aanroep verwerken, een bestand valideren, een bericht transformeren of een taak uitvoeren nadat data is opgeslagen. Bindings helpen om met services zoals Storage Queues, Blob Storage of databases te communiceren zonder alle verbindingslogica zelf te schrijven.
Azure Logic Apps past beter wanneer het probleem vooral uit integratie en orkestratie bestaat. Denk aan het verbinden van SaaS-applicaties, goedkeuringsstromen, notificaties of bedrijfsprocessen waarin de stappen belangrijker zijn dan maatwerkcode. Logic Apps kan functies aanroepen, maar de kernwaarde ligt in declaratieve workflows en connectors.
Event Grid vult een andere rol in. Het is bedoeld voor eventroutering: een service publiceert dat er iets is gebeurd, waarna een of meer subscribers daarop reageren. In een serverloze architectuur voorkomt dit dat componenten elkaar direct moeten kennen. Die ontkoppeling maakt het eenvoudiger om later extra verwerkers toe te voegen, bijvoorbeeld voor auditing, notificaties of dataverwerking.
Serverless is aantrekkelijk voor workloads met wisselende belasting, duidelijke events en beperkte verwerkingstijd per taak. Het model past goed bij API-endpoints met piekverkeer, bestandsverwerking, automatisering, integratie tussen systemen en achtergrondtaken die door queues of events worden aangestuurd. Ontwikkelaars hoeven dan geen permanente servercapaciteit te plannen voordat duidelijk is hoeveel verkeer er komt.
Er zijn ook scenario’s waarin een andere hostingvorm logischer is. Lange, stateful processen, workloads met zware runtime-afhankelijkheden of toepassingen die veel controle nodig hebben over het besturingssysteem passen vaak beter in containers. Azure Container Apps kan dan een middenweg zijn voor containergebaseerde apps met schaalgedrag dat dichter bij serverless ligt, terwijl AKS geschikt kan zijn wanneer een organisatie Kubernetes-beheer, netwerkcontrole en platformstandaardisatie nodig heeft.
Een veelgemaakte fout bij eerste serverless-projecten is dat elk stuk logica automatisch een functie wordt. Dat leidt snel tot versnippering, onduidelijke foutafhandeling en lastig te volgen afhankelijkheden. Een betere aanpak is om eerst de events en gegevensstromen te tekenen, daarna pas te bepalen welke onderdelen code, workflow of eventroutering moeten zijn.
Een bruikbaar beginnersscenario is een kleine intake-API. Een client verstuurt een JSON-bericht via HTTP naar een Azure Function. De functie valideert het bericht en zet het in een Storage Queue. Een tweede functie verwerkt het queuebericht en schrijft het resultaat naar Blob Storage. Event Grid kan vervolgens een melding publiceren wanneer een blob is aangemaakt, zodat een andere service later kan reageren zonder de verwerkingsfunctie aan te passen.
Voor lokale ontwikkeling is Azurite nuttig, omdat ontwikkelaars Storage Queues en Blob Storage kunnen testen zonder meteen cloudresources te gebruiken. App-instellingen horen niet hardcoded in de broncode. Lokaal kunnen User Secrets of een .env-bestand worden gebruikt; in productie is een combinatie van managed identities en Key Vault-referenties veiliger dan secrets rechtstreeks in configuratievelden plaatsen.
Onderstaand voorbeeld gebruikt Azure CLI om een resourcegroep, Storage-account en Function App aan te maken. De namen gebruiken variabelen zodat dezelfde stappen herhaalbaar blijven in een eigen testomgeving.
LOCATION=westeurope
RESOURCE_GROUP=rg-serverless-intake
STORAGE_ACCOUNT=stintake$RANDOM
FUNCTION_APP=func-intake-$RANDOM
az group create \
--name $RESOURCE_GROUP \
--location $LOCATION
az storage account create \
--name $STORAGE_ACCOUNT \
--resource-group $RESOURCE_GROUP \
--location $LOCATION \
--sku Standard_LRS
az functionapp create \
--name $FUNCTION_APP \
--resource-group $RESOURCE_GROUP \
--storage-account $STORAGE_ACCOUNT \
--consumption-plan-location $LOCATION \
--runtime dotnet-isolated \
--runtime-version 8 \
--functions-version 4
Deze stappen maken de minimale basis voor een .NET 8 isolated Function App op Azure Functions runtime v4. In een echte omgeving wordt daarna Application Insights gekoppeld, worden deploymentinstellingen via CI/CD beheerd en worden toegangsrechten zo beperkt mogelijk toegekend.
De HTTP-functie hieronder accepteert een verzoek, controleert of er inhoud aanwezig is en plaatst het bericht op een queue. De queuebinding houdt de code compact en laat de functie zich richten op validatie en intentie in plaats van op opslagdetails.
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using System.Net;
public class IntakeFunction
{
[Function("CreateIntake")]
[QueueOutput("intake-items", Connection = "AzureWebJobsStorage")]
public async Task<string> Run(
[HttpTrigger(AuthorizationLevel.Function, "post", Route = "intake")] HttpRequestData req)
{
var body = await new StreamReader(req.Body).ReadToEndAsync();
if (string.IsNullOrWhiteSpace(body))
{
var response = req.CreateResponse(HttpStatusCode.BadRequest);
await response.WriteStringAsync("Request body is required.");
return string.Empty;
}
return body;
}
}
De functie retourneert het bericht naar de queue-outputbinding. In productie hoort validatie strenger te zijn, bijvoorbeeld met een schema, correlation-id en duidelijke foutrespons. Bij lege berichten is het beter om geen queue-item te maken; de compacte sample laat vooral zien hoe trigger en binding samenwerken.
Een tweede functie kan de queue uitlezen en het resultaat opslaan. Bij queueverwerking is idempotentie belangrijk: dezelfde boodschap kan opnieuw worden aangeboden na een fout. De verwerker moet daarom veilig opnieuw kunnen draaien, bijvoorbeeld door een stabiele bericht-id te gebruiken of bestaande uitvoer te herkennen voordat data wordt overschreven.
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
public class ProcessIntakeFunction
{
private readonly ILogger _logger;
public ProcessIntakeFunction(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<ProcessIntakeFunction>();
}
[Function("ProcessIntake")]
[BlobOutput("processed/{rand-guid}.json", Connection = "AzureWebJobsStorage")]
public string Run([QueueTrigger("intake-items", Connection = "AzureWebJobsStorage")] string message)
{
_logger.LogInformation("Processing intake item.");
return message;
}
}
Deze verwerker leest berichten uit de queue en schrijft de inhoud naar Blob Storage. Zodra blobs worden aangemaakt, kan Event Grid die opslaggebeurtenissen doorsturen naar andere onderdelen. Voor robuuste verwerking is het verstandig om poison queues, retry policies, dead-lettering waar beschikbaar en consistente logging met operation-id of correlation-id mee te ontwerpen.
Een eerste serverloze app begint vaak zonder database, maar veel toepassingen hebben al snel relationele opslag nodig. Azure SQL Database kan vanuit Functions worden benaderd via reguliere clientlibraries of bindings waar die passend zijn. De belangrijkste ontwerpvraag is niet alleen hoe de functie verbinding maakt, maar ook hoe verbindingen worden hergebruikt, hoe timeouts worden behandeld en hoe herhaalde verwerking geen dubbele transacties veroorzaakt.
Wanneer functies als API worden aangeboden aan interne of externe clients, wordt governance belangrijk. Azure API Management kan helpen met policies, abonnementssleutels, throttling, versiebeheer en analyse rond API’s. Het voorkomt dat elke Function App zelf alle API-randvoorwaarden moet implementeren.
Logic Apps wordt vooral nuttig wanneer de app buiten de eigen codegrens treedt. Als een blobverwerking bijvoorbeeld een ticket moet openen, een e-mail moet sturen en een record in een SaaS-systeem moet bijwerken, kan een Logic App die stappen expliciet modelleren. Een Function kan dan de maatwerktransformatie doen, terwijl de workflow verantwoordelijk blijft voor de integratiestappen.
De keuze van het hostingplan bepaalt veel meer dan de factureringsvorm. Een Consumption-plan is vaak geschikt voor onregelmatige of beginnende workloads, maar kan koude starts hebben wanneer functies na inactiviteit opnieuw moeten worden opgestart. Ook kunnen netwerk- en duurvereisten invloed hebben op de vraag of Consumption passend is.
Premium-plannen bieden pre-warmed instances en mogelijkheden die beter aansluiten bij workloads met lagere latency-eisen, VNET-integratie of langere uitvoering. Dat betekent niet dat Premium automatisch de juiste keuze is. Voor voorspelbare belasting kan een Dedicated-plan of een containerplatform zinvoller zijn, zeker wanneer capaciteit toch al continu nodig is of wanneer meerdere apps dezelfde computeomgeving delen.
Performanceproblemen bij serverless komen vaak door afhankelijkheden buiten de functie zelf. Een trage databasequery, herhaald openen van clients, te grote berichten of onvoldoende partitionering kan meer impact hebben dan de function runtime. Hergebruik daarom clients waar dat kan, houd berichten klein, verplaats grote payloads naar Blob Storage en gebruik queues om pieken af te vlakken.
Concurrency verdient extra aandacht. Automatisch schalen kan downstreamsystemen overbelasten wanneer veel functie-instanties tegelijk verbinding maken met dezelfde database of API. In praktijk is het verstandig om schaalgedrag, retry-instellingen en downstreamlimieten samen te testen voordat een workload productiebelasting krijgt.
Serverless vraagt om observability vanaf het begin. Omdat er geen vaste server is waarop een ontwikkelaar even kan inloggen, moeten logs, metrics en traces laten zien waar een verzoek is gestart, welke afhankelijkheden zijn aangeroepen en waar een event eventueel is blijven hangen. Azure Monitor vormt hiervoor de basis binnen Azure.
Application Insights is vooral waardevol voor requestduur, foutpercentages, dependencies en distributed tracing. Bij serverloze apps is het nuttig om correlation-id’s consequent door te geven van HTTP-aanroep naar queuebericht en van queueverwerking naar bloboutput. Daarmee kan een team één zakelijke transactie volgen, ook wanneer die over meerdere functies loopt.
Voor diepere analyse kan Log Analytics worden gebruikt. De volgende KQL-query is bedoeld om recente mislukte requests en afhankelijkheden naast elkaar te bekijken tijdens het testen van een Function App.
let timeframe = 30m;
requests
| where timestamp > ago(timeframe)
| where success == false
| project timestamp, operation_Id, name, resultCode, duration
| union (
dependencies
| where timestamp > ago(timeframe)
| where success == false
| project timestamp, operation_Id, name, resultCode, duration
)
| order by timestamp desc
De query combineert mislukte binnenkomende requests en mislukte afhankelijkheden op basis van recente telemetrie. Tijdens een end-to-end test hoort dezelfde operation-id terug te komen in meerdere tabellen. Als dat niet gebeurt, ontbreekt meestal correlation in de code of wordt een nieuw event zonder context gepubliceerd.
Cold starts kunnen zichtbaar worden gemaakt door bij functiestart een custom dimension zoals coldStart te loggen, afhankelijk van de gebruikte runtime en implementatie. Ook zonder die dimensie zijn plots hogere responstijden na inactiviteit een signaal om het hostingplan, initialisatiecode en dependency-loading te onderzoeken. Alerts horen minimaal te kijken naar function failures, queue-lengte, dead-letter- of poison-queuegroei en foutieve dependencies.
Serverless neemt infrastructuurbeheer deels weg, maar beveiligingsontwerp blijft nodig. HTTP-triggers moeten niet onnodig anoniem toegankelijk zijn. Voor interne of zakelijke toepassingen ligt authenticatie via Microsoft Entra ID of een API-gateway vaak meer voor de hand dan losse function keys als primaire beveiligingslaag.
Managed identities zijn belangrijk omdat functies daarmee toegang kunnen krijgen tot Storage, Key Vault, SQL of andere Azure-services zonder secrets in code te plaatsen. App-instellingen kunnen nog steeds gevoelig zijn; waar secrets nodig zijn, horen Key Vault-referenties en strikte toegangsrechten bij de basisinrichting. Rollen moeten minimaal zijn en per omgeving worden gescheiden.
Netwerkbeveiliging hangt af van het gekozen plan en de afhankelijkheden. Niet elke serverloze workload heeft private networking nodig, maar wanneer functies met interne databases, private endpoints of bedrijfsnetwerken praten, moet die keuze al in de planselectie worden meegenomen. Beveiliging achteraf toevoegen is vaak lastiger dan vanaf het eerste ontwerp bepalen welke endpoints publiek, intern of volledig privé moeten zijn.
De eerste serverloze app op Azure leert vooral hoe events, bindings, opslag en monitoring samenwerken. Daarna verschuift de uitdaging naar betrouwbaarheid en ontwerpkeuzes: idempotente verwerking, foutafhandeling, retrygedrag, veilige configuratie en meetbare performance. Dat zijn dezelfde thema’s die terugkomen in professionele Azure-ontwikkeling.
Wie de stap naar certificering wil maken, kan de gebouwde sample gebruiken als oefenproject voor onderwerpen uit AZ-204: Developing Solutions for Microsoft Azure, waaronder Azure Functions, opslag, beveiliging en monitoring. Voor architectuurkeuzes rond governance, netwerken en platformontwerp sluit AZ-305 beter aan. De Microsoft-trainingen van Readynez kunnen helpen om zulke onderwerpen gestructureerd te plaatsen, maar de kern blijft dat een ontwikkelaar de services eerst in een echte kleine workload moet zien samenwerken.
De meest praktische volgende stap is om het voorbeeld lokaal met Azurite te bouwen, daarna in een aparte Azure-testomgeving te deployen en vervolgens bewust fouten te veroorzaken: een ongeldig bericht, een falende dependency en een groeiende queue. Pas wanneer die situaties zichtbaar, veilig en herstelbaar zijn, begint serverless te voelen als een beheerbare architectuur in plaats van alleen een snelle manier om code te starten.
Krijg onbeperkte toegang tot ALLE LIVE Microsoft-cursussen onder leiding van een instructeur die u wilt - allemaal voor de prijs van minder dan één cursus.
U bekijkt onze Netherlands (EUR) site van United States
Wilt u de site bekijken in
English
met prijzen in
Dollar?