Build a Fabric Pipeline That Works in Any Workspace (Step by Step)
Let me show you a problem first, then we'll fix it together.
The problem
In Fabric, you usually have more than one workspace. Something like:
- Dev — where you build and test things
- Prod — where the real data lives
You build a pipeline in Dev. It works. You deploy it to Prod. And here's the trap: the pipeline in Prod is an exact copy of the one in Dev. If you typed the Dev lakehouse anywhere inside it, the Prod pipeline will still write to the Dev lakehouse. Same pipeline, wrong target.
The usual "fix" is to open the Prod pipeline after every deployment and change the values by hand. That works until the day you forget. And you will forget.
The real fix is to make the pipeline figure out where it is by itself. That takes one small notebook. Let's build it.
What we're building
One tiny notebook runs first in every pipeline. It checks "which workspace am I in right now?" and answers with the right settings for that workspace. Everything after it just uses those settings.
flowchart LR
A([Pipeline starts]) --> B["GlobalParam notebook: which workspace am I in?"]
B --> C{"Answer"}
C -->|"I'm in Dev"| D["Use Dev settings, no alerts"]
C -->|"I'm in Prod"| E["Use Prod settings, alerts ON"]
D --> F([Rest of the pipeline runs])
E --> F
Same pipeline. Deploy it anywhere. It always does the right thing.
Step 1 — Create the notebook
In your Dev workspace: click + New item →
Notebook. Name it GlobalParam.
Paste this in the first cell:
import json
import notebookutils
# Ask Fabric: which workspace is this notebook running in right now?
ctx = notebookutils.runtime.context
workspace_id = ctx["currentWorkspaceId"]
# Our list of workspaces and the settings for each one.
# (You'll paste your real IDs in Step 2.)
ENVIRONMENTS = {
"PASTE-DEV-WORKSPACE-ID-HERE": {
"env": "dev",
"warehouse": "DW_WH_DEV",
"send_alerts": False,
},
"PASTE-PROD-WORKSPACE-ID-HERE": {
"env": "prod",
"warehouse": "DW_WH_PROD",
"send_alerts": True,
},
}
# Pick the settings for the workspace we're in
config = ENVIRONMENTS[workspace_id]
# Hand the settings back to the pipeline
notebookutils.notebook.exit(json.dumps(config))
What each part does, in plain words:
notebookutils.runtime.context— Fabric telling the notebook where it is. No setup needed; it just works.ENVIRONMENTS— a simple list: "if I'm in this workspace, use these settings."notebook.exit(...)— the notebook's way of returning an answer to the pipeline.
Notice send_alerts. Dev runs stay quiet. Prod failures send alerts. One
switch, and you never get pinged at night because a test run failed.
Step 2 — Find your workspace IDs
Open your Dev workspace in the browser and look at the address bar:
https://app.fabric.microsoft.com/groups/aaaa1111-bbbb-2222-cccc-333344445555/...
That long code after /groups/ is the workspace ID. Copy it, and paste it
into the notebook where it says PASTE-DEV-WORKSPACE-ID-HERE (keep the
quotes). Do the same for Prod.
Step 3 — Put the notebook first in your pipeline
Open your pipeline. Add a Notebook activity, name it
GlobalParam, and point it at the notebook you just made. Drag it to the
very front, and connect its green "on success" arrow to whatever used to run first.
That's it. Every run now starts by asking "where am I?"
Step 4 — Use the answer everywhere else
Anywhere you used to hardcode a value, replace it with this expression:
@json(activity('GlobalParam').output.result.exitValue).warehouse
Reading it right to left, it says: take GlobalParam's answer → read it as JSON →
give me the warehouse value. Swap warehouse for
env or send_alerts to get the other settings.
Two examples:
- A script activity that writes to the warehouse — put the expression in the warehouse/connection field instead of the typed name.
- Want alerts only in Prod? Add an If Condition before your Teams alert with:
@equals(json(activity('GlobalParam').output.result.exitValue).send_alerts, true)
Now the alert only fires where send_alerts is true — which is only Prod.
Step 5 — Test it, then deploy it
- Run the pipeline in Dev. Click on the GlobalParam activity's output — you should see
"env": "dev". Confirm it wrote to the Dev warehouse. - Deploy to Prod with your deployment pipeline.
- Run it in Prod. Check the output again — now it says
"env": "prod", and it wrote to Prod. You changed nothing after deploying.
That feeling — deploy, run, correct, no edits — is the whole point.
One thing that WILL trip you
Connections do not deploy. If your pipeline uses a connection (to a SQL server, an API, anything), Fabric's deployment pipeline copies the pipeline but not the connection. It must already exist in the Prod workspace, or the deployed pipeline fails. So before your first deploy: make sure every connection your pipeline uses also exists in the target workspace. Thirty seconds of checking saves an afternoon of confusion.
The short version
- Make a
GlobalParamnotebook that checks its own workspace ID and returns the right settings. - Run it first in every pipeline.
- Replace every hardcoded value with
@json(activity('GlobalParam').output.result.exitValue).your_setting. - Deploy anywhere. Change nothing. It just works.
Once this feels comfortable, the next level is putting your sources in a config table too, so one pipeline can load twenty sources — but that's its own post. Start here. This one notebook removes the most painful deployment mistake in Fabric.
More production Fabric patterns
I write about the Fabric habits that keep pipelines cheap and reliable — like how I cut our capacity usage from 70% to 30% on the same SKU.
How I Cut Fabric CU Usage 70% → 30% →