Azure Functions: Serverless zonder de bullshit

Hoe Azure Functions werkt in production workloads, met concrete voorbeelden en praktische tips die je nergens anders leest.

Jean-Pierre Broeders

Freelance DevOps Engineer

21 februari 20265 min. leestijd

Azure Functions: Serverless zonder de bullshit

Azure Functions wordt al jaren gebruikt in productieomgevingen. Niet voor hello-world demo's, maar voor echte workloads waar uptime belangrijk is. Wat volgt zijn de praktische lessen die je meestal pas leert nadat iets mis is gegaan.

Wat Azure Functions eigenlijk is

Het is serverless compute van Microsoft. Code schrijven, pushen naar Azure, en zij runnen het voor je. Betalen alleen voor wat je gebruikt. Klinkt geweldig, toch?

In de praktijk betekent het geen VM's beheren. Geen OS patches, geen load balancers configureren, geen nachten wakker liggen omdat een Kubernetes cluster weer eens ondersteboven ligt. Voor veel use cases is dat een godsgeschenk.

Een concreet voorbeeld: Image resizing

Een typisch scenario: een e-commerce platform waar productfoto's worden geupload, vaak 5-10MB groot. Die moeten geresized worden naar thumbnails, medium, en large versies.

Eerste versie: een monolithische API die de uploads handelt en synchronous de images resizet. Werkt prima tot het platform viral gaat op Instagram. De API valt om onder de load.

Tweede versie met Azure Functions:

[FunctionName("ResizeImage")]
public static async Task Run(
    [BlobTrigger("uploads/{name}", Connection = "StorageConnection")] Stream imageStream,
    string name,
    [Blob("thumbnails/{name}", FileAccess.Write)] Stream thumbnailStream,
    [Blob("medium/{name}", FileAccess.Write)] Stream mediumStream,
    ILogger log)
{
    log.LogInformation($"Processing image: {name}");
    
    using var image = await Image.LoadAsync(imageStream);
    
    // Thumbnail: 150x150
    var thumbnail = image.Clone(x => x.Resize(new ResizeOptions
    {
        Size = new Size(150, 150),
        Mode = ResizeMode.Crop
    }));
    await thumbnail.SaveAsync(thumbnailStream, new JpegEncoder { Quality = 85 });
    
    // Medium: max 800px
    var medium = image.Clone(x => x.Resize(new ResizeOptions
    {
        Size = new Size(800, 800),
        Mode = ResizeMode.Max
    }));
    await medium.SaveAsync(mediumStream, new JpegEncoder { Quality = 90 });
}

Blob trigger betekent: zodra er een file in de uploads container komt, start deze functie automatisch. De output wordt geschreven naar de thumbnails en medium containers.

Scale? Automatisch. Als er 1000 uploads tegelijk binnenkomen, spawnt Azure gewoon meer instances. Kosten? Van €200/maand voor een dedicated VM naar €15/maand gemiddeld.

Dingen die niemand je vertelt

Cold starts zijn echt. Als een functie een tijdje niet gebruikt is, duurt de eerste request 2-5 seconden. Voor een API endpoint is dat onaanvaardbaar. Oplossingen:

  • Premium plan (altijd warm, maar duurder)
  • Ping functie elke 5 minuten om 'm warm te houden
  • Accepteren dat het voor async workloads niet uitmaakt

Dependencies zijn lastig. Native libraries kunnen niet zomaar geïnclude worden. ImageSharp werkt omdat het pure .NET is. Maar probeer maar eens iets met FFmpeg - dan wordt het ingewikkeld.

Timeouts. Consumption plan: max 10 minuten. Daarna wordt de functie gewoon afgesloten. Langlopende jobs moeten anders gepland worden, of gebruikmaken van Durable Functions.

Local development setup

De Azure Functions Core Tools zijn... oké. Niet geweldig, maar werkbaar:

func init MyFunctionApp --dotnet
cd MyFunctionApp
func new --name ProcessOrder --template "Http trigger"
func start

Local storage emulator gebruiken? Azurite is nu de standaard:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet"
  }
}

Voor complexere scenarios kan deployen naar een dev environment in Azure handiger zijn. De turnaround tijd is acceptabel en dan wordt ook echt getest hoe het in productie werkt.

Monitoring en debugging

Application Insights is niet optioneel. Seriously. Zonder goede logging ben je blind.

log.LogMetric("ImageProcessingTime", stopwatch.ElapsedMilliseconds);
log.LogInformation("Processed {fileName} in {duration}ms", name, stopwatch.ElapsedMilliseconds);

Custom metrics kosten niks extra en geven inzicht in performance patterns. Processing times, file sizes, error rates loggen - als iets mis gaat, is data nodig om mee te werken.

Deployment pipeline

GitHub Actions voor CI/CD. Simpel en betrouwbaar:

- name: Deploy to Azure Functions
  uses: Azure/functions-action@v1
  with:
    app-name: my-function-app
    package: ./output
    publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}

Slot swaps voor zero-downtime deploys. Deploy naar staging slot, test, swap naar productie. Als het misgaat, terug swappen in 10 seconden.

Wanneer NIET Azure Functions

Het werkt niet voor alles. Stateful applicaties? Nee. Lange batch jobs? Nee. Real-time websockets? Lastig.

Het is perfect voor:

  • Event-driven processing (queue messages, blob uploads, database changes)
  • API endpoints met lage tot medium traffic
  • Scheduled jobs (dagelijkse reports, cleanup tasks)
  • Webhook handlers

Kosten in perspectief

Voor dat image resizing project:

  • 50.000 executions/dag
  • Gemiddeld 200ms runtime
  • 512MB geheugen
  • ~€12/maand

Een vergelijkbare VM zou €50-100/maand kosten, plus tijd om die te beheren.

Serverless is niet altijd goedkoper, maar het schaalt beter en vraagt minder operationele overhead. Voor een freelancer is dat tijd die besteed kan worden aan klantwerk in plaats van infrastructure babysitting.

Conclusie

Azure Functions werkt goed als je weet waar de grenzen liggen. Het is geen silver bullet, maar voor de juiste use cases bespaart het tijd en geld.

Start klein. Een simpele HTTP trigger of queue processor. Leer hoe het schaalt, hoe monitoring werkt, hoe deployment pipelines opgezet moeten worden. Dan kan beoordeeld worden of het past bij het project.

En als iemand vertelt dat serverless "auto-magically" alles oplost - ren weg. Er is geen magie, alleen trade-offs die bewust gemaakt moeten worden.

Wil je op de hoogte blijven?

Schrijf je in voor mijn nieuwsbrief of neem contact op voor freelance projecten.

Neem Contact Op