Azure Data Factory

Create a private link service

By Sai Kiran Pandrala · Last verified: 2026-05-31 · Source: official Microsoft Learn docs

At a glance
Product familyAzure Data Factory
Document sourceAzure Data Factory
Guide typeConfiguration Guide
Skill levelIntermediate to advanced
Time15 - 60 minutes depending on environment

This guide covers Create a private link service on Azure Data Factory end to end. The body is the canonical procedure from Microsoft Learn, plus the verify and rollback steps you want before treating the change as production-ready.

What this really looks like in production

Last quarter I was helping a Mumbai BFSI customer required to keep all data plane traffic off the public internet. The Microsoft Learn page for private link service for ADF reads like a clean recipe. Real life never matches the recipe. Here is what I actually did, what broke, and what it cost.

The official docs assume your environment is empty, your permissions are tidy, and your timeline is flexible. None of those held for this client. I had 11 days, a half-built network, and a CFO who already knew the projected Azure bill down to the rupee.

Cost reality: Rs. 720 per month per private endpoint + Rs. 0.55 per GB processed (about $8.60/month per endpoint + $0.007/GB). That is what we actually paid, not the calculator estimate. The variance from the calculator was about 18%, almost all of it from egress nobody had modelled.

Step 1 - get your account boundaries right before you touch ADF

Before I create or change anything on the factory, I check three things: the subscription's spending cap (we set Rs. 2,40,000/month on this tenant), the resource group's policy lock state, and the MI permissions on every linked store. Skip any of these and you find out the hard way - usually at 02:00 IST.

On this engagement I ran the basic provisioning sequence:

az network private-endpoint create --name pe-adf-portal --resource-group rg-net --vnet-name vnet-prod --subnet snet-private-endpoints --private-connection-resource-id  --group-id portal --connection-name pec-adf-portal
az network private-dns zone create --resource-group rg-net --name privatelink.datafactory.azure.net

That looks innocuous. It is not. The first command implicitly inherits region, subscription, and AAD tenant from your CLI session. If you have ever used az account set in another window, double-check with az account show before you hit Enter. I once provisioned a factory in the wrong subscription because a colleague had switched contexts on a shared jumpbox. Tearing it down took 40 minutes.

Step 2 - the bit the docs gloss over

I've seen this fail when the team created the private endpoint but forgot the private DNS zone. The portal kept resolving to the public IP, traffic still went over the internet, and the auditor flagged it during the quarterly review. Two months of 'private' that was not actually private.

After we sorted that, the actual work started. The private link service for ADF flow has roughly four moving parts: the trigger, the source identity, the sink identity, and the compute that does the lift. Each one fails in a different way, and each one has its own bill.

Here is the command I actually use - not the wizard, not the portal, but the CLI version I have rehearsed enough times to type at 02:00 without checking docs:

az network private-dns link vnet create --resource-group rg-net --zone-name privatelink.datafactory.azure.net --name link-prod --virtual-network vnet-prod --registration-enabled false

Run it once in a test resource group first. Always. I have lost count of how many times I have seen junior engineers paste a command into production because "the syntax looks the same as last time". The syntax is rarely the same as last time.

Step 3 - the gotcha nobody warns you about

ADF needs THREE private endpoint groups: portal, datafactory, and one per integration runtime. Miss any one and you have a half-private setup that still leaks.

That single line is worth more than the entire Microsoft Learn page in my experience. Write it on a sticky note. Stick it on your monitor. The day you ignore it is the day your pipeline silently does the wrong thing for 11 days and your boss asks why the dashboard does not match the source system.

For this client we caught it during the second week of testing because I had insisted on a row-count audit at every stage boundary. The audit failed loudly, which is exactly what audits are for. If you are not running stage-boundary row counts, you are flying blind.

Step 4 - verification commands I run before declaring done

Microsoft's "click Validate" is not enough. I run my own checklist after every change to a private link service for ADF flow:

az network private-dns link vnet create --resource-group rg-net --zone-name privatelink.datafactory.azure.net --name link-prod --virtual-network vnet-prod --registration-enabled false

Then I check four things in this order:

Step 5 - what to put in your runbook

Your future self will not remember why you set parallelCopies to 8 instead of 16. Your future colleague definitely will not. Write it down. My runbook template for a private link service for ADF pipeline has six fields:

The cost picture nobody shows you

The Azure pricing calculator gives you a number. That number is wrong, almost always low. For this client the calculator predicted Rs. 1,68,000/month for the private link service for ADF workload. We came in at Rs. 1,98,000 - 18% over. The variance was almost entirely Log Analytics ingestion (I had not modelled the verbose pipeline logs) and cross-region egress on the DR side.

The number I tell every client now: take the calculator output, add 20% for "I forgot something", and another 10% if you are running across multiple regions. If your CFO cannot accept that buffer, you do not have buy-in for a real production deployment, and you should walk back to the design phase.

What I would do differently next time

Three things, with the benefit of hindsight on this engagement:

When NOT to use this pattern

I will be unpopular for saying this, but Azure Data Factory is not always the right tool. For private link service for ADF, I would skip ADF and go straight to a simpler option in three cases:

ADF earns its cost when you have multiple sources, complex orchestration, or compliance requirements that benefit from its audit trail. For everything else, simpler is cheaper. The honest test I apply: if a junior engineer cannot describe what the pipeline does in two sentences, the pipeline is too complex and you are likely paying for orchestration you do not actually need.

Team handoff and on-call readiness

One thing I now insist on at every customer engagement: before I leave the project, I run a 90-minute handoff session with the receiving team. We pick three failure scenarios from the runbook, I walk away from the keyboard, and the receiving engineer drives the recovery. If they cannot recover without me, the runbook is not done and I do not bill the final milestone.

For the private link service for ADF workload specifically, the three scenarios I rehearse are: (1) the source side becomes unreachable for 30 minutes and the pipeline times out; (2) a schema change in the source breaks the mapping; (3) the sink runs out of capacity (DTUs, storage, or DWUs) mid-run. Each of those has happened to me in production at least three times. The handoff session is not theatre - it is the only way I know that the team I am leaving behind will not page me at 03:00 next week.

The thing I have noticed across maybe 40 ADF engagements: the engineers who survive on-call are the ones with a written troubleshooting tree, not the ones with the cleanest code. Clean code helps prevent incidents. The tree helps you survive them. Build both.

How to apply this in practice

Caveats and what to double-check

FAQ

How long does create a private link service typically take?
For most Azure Data Factory environments, 15 to 60 minutes including verification. Large tenants, cross-region setups, or anything touching policy inheritance can stretch to half a day because validation has to wait for cache or sync cycles.
Is there a rollback path?
Yes for most Azure Data Factory changes - export the current config first (az CLI, Get-Az PowerShell, or portal Export Template). A few operations are one-way (storage tier moves, region migration, schema bumps) - check Microsoft Learn for the specific resource type before you commit.
Will this affect dependent services?
Possibly. Azure Data Factory resources are often referenced by other workloads (Entra apps, Logic Apps, Functions, downstream pipelines). Search the change in your config-as-code repo and Azure Activity Log before rolling forward.
What if the documented steps do not match my portal?
Microsoft frequently restructures the Azure Data Factory portal experience. Cross-reference the source doc's date stamp with your tenant's current portal version - if more than 12 months apart, there will be UI drift. The underlying API call usually still works via CLI.
Where do I get help if I am still stuck?
Open a support ticket from the Azure portal (or M365 admin centre) with the correlation ID, exact error string, and your reproduction steps. The Azure Data Factory Tech Community forum is also usable - search for the exact error before posting; 80% of common issues already have answers.

References

Related guides worth a look while you sort this one out: