Azure Data Factory

Het objectmodel (pipelines, activities, datasets, linked services), Copy Activity en integration runtimes in detail, Mapping Data Flows onder de motorkap, tumbling window triggers voor backfills, en parameterisatie voor herbruikbare pipelines.

11 min leestijd Gemiddeld Bijgewerkt: 2026-08-14 Cloud Data Platforms

Introductie

Azure Data Factory (ADF) is in eerdere hoofdstukken vooral zijdelings genoemd — als ingestion-tool in Introduction to Data Engineering, als ETL-stijl transformatietool in ETL vs ELT. Fabric's ingebouwde Data Factory-ervaring (zie Microsoft Fabric) deelt hetzelfde objectmodel en dezelfde pipeline-JSON-structuur als standalone ADF, maar richt zich op OneLake in plaats van op willekeurige Azure-resources als doel — wat in dit hoofdstuk volgt, is dus relevant voor beide, met standalone ADF als uitgangspunt omdat dat de meest volledige, meest gebruikte vorm is buiten Fabric-specifieke scenario's.

Het Objectmodel: Pipelines, Activities, Datasets, Linked Services

ADF's structuur bestaat uit vier concepten die strikt van elkaar te onderscheiden zijn, en waar beginners regelmatig verwarring over hebben.

Linked services zijn verbindingsconfiguraties — hoe ADF met een specifiek systeem praat (een Azure SQL-database, een Snowflake-account, een SFTP-server), inclusief authenticatie. Een linked service bevat geen data-specifieke informatie, alleen de verbinding zelf.

Datasets verwijzen naar een specifieke data-representatie binnen een linked service — een tabel, een map met CSV-bestanden, een specifieke API-endpoint. Eén linked service (bijvoorbeeld een Azure SQL-database) kan meerdere datasets hebben (verschillende tabellen binnen die database).

Activities zijn de daadwerkelijke uitvoerbare stappen — een Copy Activity die data van dataset A naar dataset B verplaatst, een Notebook Activity die een Databricks-notebook aanroept, een Lookup Activity die een enkele waarde ophaalt om verderop in de pipeline te gebruiken.

Pipelines groeperen activities in een logische, geordende (of vertakte) reeks, met afhankelijkheden tussen activities — functioneel een DAG, vergelijkbaar met een Airflow-DAG uit Introduction to Data Engineering, maar dan gedeclareerd als JSON in plaats van als Python-code.

{
  "name": "orders_ingestion_pipeline",
  "activities": [
    {
      "name": "Copy_Orders_to_Bronze",
      "type": "Copy",
      "inputs": [{ "referenceName": "SourceOrdersDataset", "type": "DatasetReference" }],
      "outputs": [{ "referenceName": "BronzeOrdersDataset", "type": "DatasetReference" }]
    },
    {
      "name": "Trigger_Silver_Transform",
      "type": "ExecuteDataFlow",
      "dependsOn": [{ "activity": "Copy_Orders_to_Bronze", "dependencyConditions": ["Succeeded"] }],
      "dataFlow": { "referenceName": "SilverOrdersDataFlow", "type": "DataFlowReference" }
    }
  ]
}

Copy Activity: het Werkpaard

De Copy Activity is verreweg de meest gebruikte activity in ADF, en verdient een preciezer begrip dan "het kopieert data". Bij het configureren kies je een source (waar data vandaan komt) en een sink (waar het naartoe gaat), elk met eigen instellingen — een SQL-source ondersteunt bijvoorbeeld een custom query in plaats van een hele tabel, een sink naar een warehouse ondersteunt keuzes tussen insert, upsert, of eerst de doeltabel leegmaken.

De prestaties van een Copy Activity worden bepaald door Data Integration Units (DIU's) — een abstracte maat voor de toegewezen rekenkracht en netwerkbandbreedte, vergelijkbaar in geest met warehouse-sizing uit Snowflake maar dan voor het kopieerproces zelf. Meer DIU's toewijzen (of ADF automatisch laten schalen) versnelt grote kopieertaken, tot een punt waarop de bron of het doel zelf de beperkende factor wordt — meer DIU's helpen dan niet meer, net zoals een groter warehouse niets oplevert als de brondatabase zelf de bottleneck is.

Integration Runtimes: waar Voert ADF Eigenlijk Uit?

Een concept zonder directe tegenhanger bij de andere platformen in dit handbook: de Integration Runtime (IR) bepaalt waar de daadwerkelijke dataverplaatsing en -berekening plaatsvindt, en er zijn drie varianten.

Azure IR is de standaard, volledig door Microsoft beheerde compute in de cloud — geschikt voor cloud-naar-cloud-scenario's, wat de meerderheid van moderne pipelines dekt.

Self-hosted IR draait op infrastructuur die jij zelf beheert — een virtuele machine binnen je eigen netwerk, of zelfs on-premises — specifiek nodig wanneer ADF toegang moet krijgen tot een bronsysteem dat niet publiek vanaf het internet bereikbaar is (een on-premises database achter een firewall, een intern SFTP-systeem). Dit is de meest voorkomende reden dat een organisatie een self-hosted IR nodig heeft: niet performance, maar netwerktoegang.

Azure-SSIS IR host SQL Server Integration Services-pakketten binnen ADF, specifiek bedoeld voor organisaties die bestaande SSIS-investeringen (het klassieke on-premises ETL-tool-landschap uit Introduction to Data Engineering) willen migreren naar de cloud zonder de pakketten volledig te herschrijven — een brug-technologie voor legacy-migraties.

Bouw de bijbehorende pipeline-structuur direct

Genereer een pipeline-schets, notebooks en medallion-architectuur.

Open Fabric Pipeline Generator

Mapping Data Flows: Visueel, maar Spark Eronder

ETL vs ELT noemde Mapping Data Flows al als voorbeeld van transformatie op een aparte compute-laag. De mechaniek erachter: wat je visueel opbouwt als een reeks transformatiestappen (filter, join, aggregate, derived column) compileert ADF bij uitvoering naar een Spark-job, uitgevoerd op een cluster dat ADF voor je beheert — je schrijft nooit zelf Spark-code, maar de onderliggende uitvoering is wel degelijk Spark, met dezelfde partitionerings- en shuffle-overwegingen die ook in PySpark aan bod komen.

Bron (Azure SQL: orders)
  → Filter (amount > 0)
  → Derived Column (order_month = month(order_date))
  → Aggregate (group by order_month, category; sum(amount))
  → Sink (Data Lake: gold/revenue_by_month)

Dit compileert tot een Spark-job met dezelfde onderliggende principes als een handgeschreven PySpark-transformatie, maar met een visuele interface eromheen — waardevol voor teams die de flexibiliteit van Spark willen zonder zelf Spark-code te onderhouden, met dezelfde afweging als bij Fabric's Dataflows Gen2 uit Microsoft Fabric: toegankelijk voor eenvoudigere logica, minder testbaar en versiebeheerbaar dan code voor complexere, kritieke transformaties.

Triggers: Voorbij een Simpel Schema

Een schedule trigger (elke nacht om 3 uur) dekt de meeste gevallen, maar twee andere triggertypes lossen specifieke problemen op die een simpel schema niet kan.

Tumbling window triggers verdelen tijd in aaneengesloten, niet-overlappende vensters (elk uur, elke dag) en garanderen dat elk venster precies één keer wordt verwerkt, inclusief automatische afhandeling van backfills: als je een pipeline vandaag activeert met een startdatum van drie maanden geleden, voert ADF automatisch alle tussenliggende vensters achtereenvolgens uit, elk met zijn eigen venster-specifieke parameters (WindowStart, WindowEnd) beschikbaar binnen de pipeline. Dit lost het probleem op dat een gewone schedule trigger niet heeft: gegarandeerde, herhaalbare verwerking per exact tijdvak, inclusief retries per individueel venster zonder de hele historie opnieuw te hoeven draaien.

Event-based triggers starten een pipeline zodra een specifieke gebeurtenis plaatsvindt — meestal het aankomen van een nieuw bestand in Azure Blob Storage — in plaats van te wachten op een vast tijdstip. Dit is relevant wanneer een externe partij bestanden op onvoorspelbare tijdstippen aanlevert: de pipeline reageert direct in plaats van te wachten tot het volgende geplande moment, wat de latency tussen aankomst en verwerking aanzienlijk verkort.

{
  "name": "hourly_tumbling_window",
  "type": "TumblingWindowTrigger",
  "typeProperties": {
    "frequency": "Hour",
    "interval": 1,
    "startTime": "2026-08-01T00:00:00Z",
    "delay": "00:05:00",
    "maxConcurrency": 5
  }
}

Parameterisatie: Eén Pipeline, Meerdere Omgevingen

Net als ref() in dbt (zie dbt Fundamentals) compile-time de juiste omgeving oplost, laat ADF pipelines en datasets parametriseren zodat dezelfde pipeline-definitie tegen dev, test en productie kan draaien zonder te dupliceren:

{
  "name": "CopyOrdersParameterized",
  "parameters": {
    "SourceSchema": { "type": "string", "defaultValue": "dev_staging" }
  },
  "activities": [
    {
      "name": "Copy_Orders",
      "type": "Copy",
      "typeProperties": {
        "source": { "type": "AzureSqlSource", "sqlReaderQuery": "SELECT * FROM @{pipeline().parameters.SourceSchema}.orders" }
      }
    }
  ]
}

Gecombineerd met dynamic content (expressies zoals @pipeline().parameters.X, @utcnow(), @concat()) kunnen zelfs bestandspaden, querytekst en connectiedetails runtime worden samengesteld — de sleutel om te voorkomen dat je voor elke nieuwe bron of omgeving een volledig nieuwe pipeline moet bouwen in plaats van bestaande, geparametriseerde pipelines te hergebruiken.

Foutafhandeling en Monitoring

Elke activity in ADF ondersteunt native retry policies — een aantal pogingen en een interval ertussen, ingesteld per activity in plaats van pipeline-breed — direct relevant voor de tijdelijke-fout-afhandeling uit Introduction to Data Engineering:

{
  "name": "Copy_Orders_to_Bronze",
  "type": "Copy",
  "policy": { "retry": 3, "retryIntervalInSeconds": 30, "timeout": "02:00:00" }
}

Voorbij retries op activity-niveau biedt ADF failure paths: een activity kan een andere activity triggeren specifiek bij falen (via een Failed-dependency-conditie), wat expliciete foutafhandelingslogica mogelijk maakt — bijvoorbeeld een Web Activity die een Slack- of Teams-melding stuurt zodra een kritieke Copy Activity faalt, los van de reguliere pipeline-flow. Voor monitoring op langere termijn integreert ADF met Azure Monitor: pipeline-runs, activity-duur en foutpercentages zijn hier centraal te bevragen en te alerteren, wat de basis vormt voor het soort observability dat in Monitoring & Observability verder wordt uitgewerkt.

CI/CD voor ADF: het adf_publish-Patroon

ADF-pipelines worden in de Git-gekoppelde weergave opgeslagen als JSON-bestanden per object (pipelines, datasets, triggers) in een collaboration branch (meestal main), maar dat is niet wat daadwerkelijk naar Azure wordt gedeployed. Bij het klikken op "Publish" genereert ADF automatisch Azure Resource Manager (ARM) templates en commit die naar een aparte, automatisch beheerde adf_publish-branch — dít is wat een CI/CD-pipeline (zie CI/CD for Data Engineering) daadwerkelijk deployt naar test- of productieomgevingen, met omgevingsspecifieke parameters (connectiestrings, schema-namen) los meegegeven via een parameters-bestand.

main (collaboration branch)          adf_publish (auto-gegenereerd)
├── pipeline/orders_pipeline.json  →  ├── ARMTemplateForFactory.json
├── dataset/bronze_orders.json     →  ├── ARMTemplateParametersForFactory.json
└── trigger/hourly_trigger.json    →  └── (gegenereerd bij elke Publish-actie)

Dit tweeledige model — leesbare JSON per object voor development en review, gecompileerde ARM-templates voor deployment — is wezenlijk anders dan hoe dbt of Databricks Repos code behandelen (waar het broncodebestand zelf ook het deploybare artefact is), en is een veelvoorkomende bron van verwarring bij teams die voor het eerst ADF's CI/CD-flow opzetten.

Best Practices

  • Gebruik tumbling window triggers voor elke pipeline waar exacte, herhaalbare tijdvak-verwerking en backfill-ondersteuning nodig zijn — een gewone schedule trigger biedt dat niet native.
  • Reserveer self-hosted IR specifiek voor netwerktoegang-scenario's, niet als standaardkeuze — Azure IR is eenvoudiger te onderhouden zodra publieke of peered cloud-connectiviteit volstaat.
  • Parametriseer pipelines vanaf het begin, ook als er nog maar één omgeving is — een pipeline die pas achteraf parametriseerbaar gemaakt moet worden, kost aanzienlijk meer herwerk dan er vooraf rekening mee houden.
  • Gebruik Mapping Data Flows voor matig complexe, wijzigende transformaties; verplaats kritieke, uitgebreid geteste businesslogica naar code (dbt, notebooks) zodra de complexiteit toeneemt.
  • Monitor DIU-verbruik en doorlooptijd samen, niet DIU's geïsoleerd — meer DIU's toewijzen aan een Copy Activity die door de bron wordt beperkt, is verspild budget.
  • Configureer failure paths voor kritieke pipelines, niet alleen retries — een fout die na alle retries alsnog faalt, moet iemand actief bereiken, niet stil in een logboek verdwijnen.
  • Begrijp het onderscheid tussen de collaboration branch en adf_publish voordat je een CI/CD-pipeline opzet — deployen vanuit de verkeerde branch is een veelgemaakte, verwarrende eerste fout.

Veelgemaakte Fouten

  • Linked services, datasets en activities door elkaar husselen conceptueel — bijvoorbeeld authenticatie-instellingen op datasetniveau proberen te zetten in plaats van op de linked service, wat hergebruik onnodig lastig maakt.
  • Self-hosted IR gebruiken wanneer Azure IR had volstaan, wat onnodige onderhoudslast (patches, beschikbaarheid van de VM zelf) toevoegt zonder functioneel voordeel.
  • Geen tumbling window trigger gebruiken voor tijdvak-gevoelige verwerking, waardoor backfills handmatig en foutgevoelig moeten worden uitgevoerd in plaats van automatisch per venster.
  • Pipelines hardcoderen per omgeving (een aparte pipeline-kopie voor dev en prod) in plaats van te parametriseren, wat wijzigingen dubbel werk maakt en de kans op configuratie-drift tussen omgevingen vergroot.
  • Complexe businesslogica permanent in Mapping Data Flows laten groeien zonder ooit te heroverwegen of het inmiddels beter als geteste, versiebeheerde code past.

Performance Tips

  • Gebruik parallelle kopieeractiviteiten (parallelCopies) bij het verplaatsen van veel, onafhankelijke bestanden of partities, in plaats van sequentieel te kopiëren.
  • Beperk het aantal actieve tumbling window-vensters tijdens een backfill via maxConcurrency, zodat een grote historische inhaalslag niet de bron of het doelsysteem overbelast.
  • Gebruik staged copy (eerst naar Blob Storage, dan naar het uiteindelijke doel) bij trage of instabiele directe verbindingen — dit isoleert netwerkfouten van het uiteindelijke laadproces.
  • Cache Lookup Activity-resultaten die binnen dezelfde pipeline-run herhaald nodig zijn, in plaats van dezelfde lookup-query meerdere keren uit te voeren.

Interviewvragen

"Wat is het verschil tussen een linked service en een dataset in ADF?" Let op: een linked service is de verbinding naar een systeem (met authenticatie); een dataset verwijst naar een specifieke data-representatie binnen die verbinding — één linked service kan meerdere datasets bedienen.

"Wanneer zou je een self-hosted integration runtime nodig hebben in plaats van Azure IR?" Let op: primair voor netwerktoegang tot systemen die niet publiek bereikbaar zijn (on-premises, achter een firewall), niet voor extra performance.

"Wat is een tumbling window trigger, en welk probleem lost het op dat een schedule trigger niet oplost?" Let op: gegarandeerde, exact-één-keer-verwerking per aaneengesloten tijdvak met automatische, parametriseerbare backfill-ondersteuning — een schedule trigger heeft dat mechanisme niet ingebouwd.

"Hoe werkt Mapping Data Flows onder de motorkap?" Let op: de visuele transformatiestappen compileren naar een Spark-job op door ADF beheerde compute — geen eigen executie-engine, maar een visuele laag boven Spark.

"Hoe zou je dezelfde pipeline tegen zowel een dev- als een productieomgeving laten draaien zonder te dupliceren?" Let op: parameterisatie van pipelines en datasets, gecombineerd met dynamic content-expressies, zodat omgevingsspecifieke waarden runtime worden ingevuld in plaats van hardcoded.

"Wat bepalen Data Integration Units (DIU's), en wanneer helpt meer DIU's toewijzen niet meer?" Let op: DIU's bepalen de toegewezen rekenkracht/bandbreedte voor een Copy Activity; zodra de bron of het doelsysteem zelf de beperkende factor is, levert meer DIU's geen extra snelheid op.

"Leg het adf_publish-patroon uit — waarom wordt niet direct vanuit de main-branch gedeployed?" Let op: de main-branch bevat leesbare JSON per object voor development en review; Publish genereert daaruit ARM-templates in een aparte, automatisch beheerde branch, en dát is wat CI/CD daadwerkelijk naar omgevingen deployt.

"Hoe zou je ervoor zorgen dat een team direct op de hoogte is als een kritieke pipeline faalt?" Let op: een failure path met een Web Activity die een melding stuurt (Slack/Teams), gecombineerd met retry policies op activity-niveau voor tijdelijke fouten, en Azure Monitor-integratie voor structurele alerting.

Relevante Documentatie

Samenvatting

ADF's objectmodel — linked services voor verbindingen, datasets voor data-representaties, activities voor uitvoerbare stappen, pipelines voor de DAG die ze samenbrengt — vormt de basis voor alles wat erop volgt. Copy Activity en DIU's regelen ruwe dataverplaatsing; integration runtimes bepalen waar dat gebeurt, met self-hosted IR specifiek voor netwerktoegang tot afgeschermde systemen. Mapping Data Flows biedt een visuele laag boven Spark voor teams die de kracht van Spark willen zonder zelf Spark-code te schrijven. Tumbling window triggers lossen het backfill- en exact-eenmaal-verwerkingsprobleem op dat een simpel schema niet aankan, en parameterisatie maakt pipelines herbruikbaar over omgevingen — hetzelfde principe als ref() in dbt, hier toegepast op orchestratie in plaats van transformatie. Retry policies en failure paths regelen foutafhandeling op activity-niveau; het adf_publish-patroon bepaalt hoe pipelines daadwerkelijk hun weg naar productie vinden, wezenlijk anders dan de directe code-als-artefact-benadering van dbt of Databricks Repos. Met de drie platformen en hun bijbehorende ingestion-tooling nu behandeld, verlegt het volgende hoofdstuk de aandacht naar de programmeertaal die door alle drie heen loopt: Python.

Hulp nodig bij het bouwen van een modern dataplatform?

DataPartner365 helpt organisaties met Microsoft Fabric, Snowflake, Databricks, dbt, Azure, data-architectuur en CI/CD.

Neem contact op met DataPartner365