M365 Show -  Microsoft 365 Digital Workplace Daily
M365 Show with Mirko Peters - Microsoft 365 Digital Workplace Daily
GitHub, Azure DevOps, or Fabric—Who’s Actually in Charge?
0:00
-18:03

GitHub, Azure DevOps, or Fabric—Who’s Actually in Charge?

Here’s a statement that might sting: without CI/CD, your so‑called Medallion Architecture is nothing more than a very expensive CSV swamp.

Subscribe to the M365.Show newsletter so you i can reach Gold Medallion on Substack!

Now, the good news: we’re not here to leave you gasping in that swamp. We’ll show a practical, repeatable approach you can follow to keep Fabric Warehouse assets versioned, tested, and promotable without midnight firefights. By the end, you’ll see how to treat data pipelines like code, not mystery scripts.

And that starts with the first layer, where one bad load can wreck everything that follows.

Bronze Without Rollback: Your CSV Graveyard

Picture this: your Bronze layer takes in corrupted data. No red lights, no alarms, just several gigabytes of garbage neatly written into your landing zone. What do you do now? Without CI/CD to protect you, that corruption becomes permanent. Worse, every table downstream is slurping it up without realizing. That’s why Bronze so often turns into what I call the CSV graveyard. Teams think it’s just a dumping ground for raw data, but if you don’t have version control and rollback paths, what you’re really babysitting is a live minefield.

People pitch Bronze as the safe space: drop in your JSON files, IoT logs, or mystery exports for later. Problem is, “safe” usually means “nobody touches it.” The files become sacred artifacts—raw, immutable, untouchable. Except they’re not. They’re garbage-prone. One connector starts spewing broken timestamps, or a schema sneaks in three extra columns. Maybe the feed includes headers some days and skips them on others. Weeks pass before anyone realizes half the nightly reports are ten percent wrong. And when the Bronze layer is poisoned, there’s no quick undo.

Think about it: you can’t just Control+Z nine terabytes of corrupted ingestion. Bronze without CI/CD is like writing your dissertation in one single Word doc, no backups, no versions, and just praying you don’t hit crash-to-desktop. Spoiler alert: crash-to-desktop always comes. I’ve seen teams lose critical reporting periods that way—small connector tweaks going straight to production ingestion, no rollback, no audit trail. What follows is weeks of engineers reconstructing pipelines from scratch while leadership asks why financials suddenly don’t match reality. Not fun.

Here’s the real fix: treat ingestion code like any other codebase. Bronze pipelines are not temporary throwaway scripts. They live longer than you think, and if they’re not branchable, reviewable, and version-controlled, they’ll eventually blow up. It’s the same principle as duct taping your car bumper—you think it’s temporary until one day the bumper falls off in traffic.

I once watched a retail team load a sea of duplicated rows into Bronze after an overnight connector failure. By the time they noticed, months of dashboards and lookups were poisoned. The rollback “process” was eight engineers manually rewriting ingestion logic while trying to reload weeks of data under pressure. That entire disaster could have been avoided if they had three simple guardrails.

Step one: put ingestion code in Git with proper branching. Treat notebooks and configs like real deployable code.

Step two: parameterize your connection strings and schema maps so you don’t hardwire production into every pipeline.

Step three: lock deployments behind pipeline runs that validate syntax and schema before touching Bronze. That includes one small but vital test—run a pre-deploy schema check or a lightweight dry‑run ingestion. That catches mismatched timestamps or broken column headers before they break Bronze forever.

Now replay that earlier horror story with these guardrails in place. Instead of panicking at three in the morning, you review last week’s commit, you roll back, redeploy, and everything stabilizes in minutes. That’s the difference between being crushed by Bronze chaos and running controlled, repeatable ingestion that you trust under deadline.

The real lesson here? You never trust luck. You trust Git. Ingestion logic sits in version control, deployments run through CI/CD with schema checks, and rollback is built into the process. That way, when failure hits—and it always does—you’re not scrambling. You’re reverting. Big difference. Bronze suddenly feels less like Russian roulette and more like a controlled process that won’t keep you awake at night.

Fixing Bronze is possible with discipline, but don’t take a victory lap yet. Because the next layer looks polished, structured, and safe—but it hides even nastier problems that most teams don’t catch until the damage is already done.

Silver Layer: Where Governance Dies Quietly

At first glance, Silver looks like the clean part of the Warehouse. Neat columns, standard formats, rows aligned like showroom furniture. But this is also where governance takes the biggest hit—because the mess doesn’t scream anymore, it tiptoes in wearing a suit and tie. Bronze failures explode loudly. Silver quietly bakes bad logic into “business-ready” tables that everyone trusts without question.

The purpose of Silver, in theory, is solid. Normalize data types, apply basic rules, smooth out the chaos. Turn those fifty date formats into one, convert text IDs into integers, iron out duplicates so the sales team doesn’t have a meltdown. Simple enough, right? Except when rules get applied inconsistently. One developer formats phone numbers differently from another, someone abbreviates state codes while someone else writes them out, and suddenly you’ve got competing definitions in a layer that’s supposed to define truth. It looks organized, but the cracks are already there.

The worst slip? Treating Silver logic as throwaway scripts. Dropping fixes straight into a notebook without source control. Making changes directly against production tables because “we just need this for tomorrow’s demo.” I’ve seen that happen. It solves the urgent problem but leaves test and production permanently out of sync. Later, your CI/CD jobs fail, your reports disagree, and nobody remembers which emergency tweak caused the divergence. That’s not cleanup—that’s sabotage by convenience.

Here’s where we cut the cycle. Silver needs discipline, and there’s a blunt three‑step plan that works every time:

Step one: put every transformation into source control with pull‑request reviews. No exceptions. That’s filters, joins, derived columns—everything. If it changes data, it goes in Git.

Step two: build automated data‑quality checks into your CI pipeline. Null checks, uniqueness checks, type enforcement. Even something as basic as a schema‑compatibility check that fails if column names or types don’t match between dev and test. Make your CI run those automatically, so nobody deploys silent drift.

Step three: promote only through CI/CD with approvals, never by direct edits. That’s how dev, test, and prod stay aligned instead of living three separate realities you can’t reconcile later.

Automated checks and PRs prevent “polite” Silver corruption from becoming executive‑level panic. Think about it—errors masked as clean column names are the ones that trigger frantic late‑night calls because reports look wrong, even though the pipelines say green. With governance in place, those failures get stopped at the pull request instead of at the boardroom.

Professional payoff? You stop wasting nights chasing down half‑remembered one‑off fixes. You stop re‑creating six months of ad‑hoc transformations just to figure out why customer counts don’t match finance totals. Instead, your rules are peer‑reviewed, tested, and carried consistently through environments. What happens in dev is what happens in prod. That’s the standard.

Bottom line: if Bronze chaos is messy but obvious, Silver chaos is clean but invisible. And invisible failures are worse because leadership doesn’t care that your layer “looked” tidy—they care that the numbers don’t match. Guardrails in Silver keep authority in your data, not just surface polish in your tables.

Now we’ve talked about the quiet failures. But sometimes governance issues don’t wait until the monthly audit—they land in your lap in the middle of the night. And that’s when the next layer starts to hurt the most.

Gold Layer: Analytics at 3 AM

Picture this: you’re asleep, your phone buzzes, and suddenly finance dashboards have gone dark. Senior leadership expects numbers in a few hours, and nobody wants to hear “sorry, it broke.” Gold is either reliable, or it destroys your credibility before breakfast.

This is the layer everyone actually sees. Dashboards, KPIs, reports that executives live by—Gold is the plate you’re serving, not the prep kitchen in back. Mess up here, and it doesn’t matter how meticulous Bronze or Silver were, because the customer-facing dish is inedible. That’s why shortcuts in Gold cost the most.

Without CI/CD discipline, one casual schema tweak upstream can wreck trust instantly. Maybe someone added a column in Silver without testing. Maybe a mapping fix changed values in ways nobody noticed. Suddenly the quarter‑end metrics don’t reconcile, and you’re scrambling. Unlike Bronze, you can’t shrug and reload later—leaders already act on the data. You need guarantees that Gold only reflects changes that were tested and approved.

Too many teams instead resort to panic SQL patch jobs. Manual updates to production tables at 4 a.m., hoping the dashboard lights back up in time for the CFO. Sure, the query might “fix” today, but prod drifts into its own reality while dev and test stay behind. No documentation, no rollback, and good luck remembering what changed when the issue resurfaces.

If you want sanity, Gold needs mirrored environments. Dev, test, and prod must run the same pipelines, with the same logic and schema alignment, so promoting a change means moving tested code forward—not experimenting on prod. That alone will save half your crisis calls.

Then layer in automated checks. CI/CD pipelines should run schema‑compatibility tests before promotions. At a minimum: verify that all expected columns still exist and retain the right data types, run a regression test comparing a small sample across environments, and fire a smoke query that asserts critical KPIs fall within expected ranges. If any of those break, stop the deployment there. Better to get a failure email during business hours than a screaming dashboard at dawn.

And about rollback: if you package deployments and keep versioned artifacts, reverting Gold is as simple as redeploying the last known‑good build. This isn’t magic—it’s just good hygiene. Without versioning, rollback turns into archaeology: trying to remember which schema state matched last week while executives wait. With versions aligned, rollback is a controlled redeploy, not a guessing game.

Here’s a veteran pro tip: if you ever cave and patch prod live, log it immediately. Commit the change to source control, open a pull request documenting the hotfix, and sync dev/test afterward. Don’t let prod become a shadow universe. Treat a hotfix like code so the whole stack realigns.

All this boils down to one blunt truth: Gold is not a finish line—it’s production software. Treating it with less rigor than an app release is what keeps you in 3 a.m. fire drills. Guardrails, versioning, automated checks, dedicated environments—all standard for app dev, all just as mandatory for analytics.

The payoff is obvious. With CI/CD in Gold, deployments become predictable, KPIs don’t vanish overnight, models train on reliable data, and you—the data engineer—actually get to keep some weekends to yourself. You’re no longer firefighting dashboards, you’re running a stable production system.

Of course, discipline inside Gold is only half of the equation. The other half is figuring out which tool is actually steering your deployments—and that’s where the politics start to matter.

Who’s Actually in Charge: GitHub, Azure DevOps, or Fabric?

When teams argue about deployment, the conversation almost always drifts into tool wars. Somebody swears GitHub is the answer, someone else pushes Azure DevOps, and then Fabric shows up with its built‑in deployment options. The problem? None of them alone solves everything, and pretending one tool is “the boss” wastes more time than it saves.

Here’s the pattern we see most often. Developers prefer GitHub, because it feels natural: pull requests, branches, merge checks, clean history. It’s the diary of every change. Enterprise governance teams lean toward Azure DevOps, because it adds structure: gates, approvals, audit trails, process discipline that compliance officers like. Then you have Fabric, offering web‑based deployment features right in the service. Handy, but more suited for packaging assets and moving them between environments in a lightweight way, not replacing full lifecycle management. And here’s the caveat—before you rely on any Fabric export/import workflow, confirm in your tenant how it actually behaves.

So rather than treating this like a showdown, treat it like a stack. A recommended architecture pattern goes like this: GitHub, or any Git host, as the single source of truth for notebooks, SQL files, and pipeline configs. That’s where developers branch, merge, and review work without stepping on each other. Then use Fabric’s deployment features when you need to bundle workspace objects into deployable packages that move through dev, test, and prod. Finally, put Azure DevOps—or any orchestration tool with gates—on top to handle approvals, staged rollouts, and the audit trail. That way, every step is recorded, authorized, and reversible.

Think about a real‑world example. You want to roll a Warehouse schema update from dev to test. Fabric’s deployment feature can move the package quickly, so you can validate it in test without hacking production. GitHub, meanwhile, keeps the script versioned and reversible: if someone’s join logic breaks, you can roll back to the previous commit. Then, Azure DevOps ensures nothing hits production until someone with the right role signs off after QA. The whole flow catches changes at the right level instead of waiting for customers to stumble on them in a dashboard.

Picture it like this: Fabric is the car—your Warehouse doesn’t move without it. GitHub is the map—shows where you’ve been, lets you plan your route, and gives you rollback if you take a wrong turn. Azure DevOps is traffic control—stops you from blowing through the red light because somebody wanted to get home faster. Different roles, same journey. You don’t need to crown one tool king; you need them to work side by side.

Pro tip here: don’t make tool preference the starting question. Start with needs. Who in your org must have audit logs? Who needs fast branches and merge checks? Who enforces gated approvals? Map those requirements, then assign the right tool to own each capability. Flip the question from “Which product should we standardize on?” to “Which part of governance does each cover best?” Suddenly it’s less about opinions and more about architecture.

The winning combination usually looks the same: Fabric for packaging and moving analytics assets; GitHub for collaboration, branching, and rollback safety; and Azure DevOps for enforcement and approvals. That’s not a marketing slide, that’s a common best‑practice stack teams have had success with. Use Fabric alone if you’re a small shop moving things quickly. Wrap in GitHub when more than one person edits the code. Layer Azure DevOps when governance and compliance come knocking. Each one fills a gap the others leave wide open.

So here’s the sanity check before you decide: map out your priorities. If rollback matters, pick your source control first. If compliance matters, ensure orchestration has approvals and logs. If speed matters, lean on Fabric’s deployment features for the quick hops. When you line up those needs against the tools, the decision makes itself. Tools aren’t the boss—you are.

And once the tools are aligned, there’s still one more challenge. Because stitching GitHub, DevOps, and Fabric together doesn’t guarantee success. What makes or breaks deployments isn’t the product stack, it’s whether you enforce discipline on every release. That’s the real difference between analytics you trust and analytics that wake you up at night.

Avoiding the Deployment Nightmare

Avoiding the Deployment Nightmare isn’t about wishful thinking—it’s about cutting off the predictable mistakes before they torch your pipeline. We’ve all seen the fairy‑tale pitch of smooth automated delivery: every commit sails into prod without friction, dashboards never blink red, and nobody’s phone buzzes at 2 a.m. Reality check? If you don’t enforce discipline, CI/CD doesn’t prevent chaos—it just automates it faster.

And the truth is, most blow‑ups aren’t some exotic zero‑day bug. They come from boring, obvious shortcuts. Someone skips spinning up a dev environment because “it takes too long.” Someone bypasses validation because “the CFO needs it in an hour.” Or someone pushes a hotfix straight into production and then swears they’ll clean it up later. Spoiler: they never clean it up. That half‑hour saved today becomes a nightmare month down the road.

The worst fallout from those shortcuts is divergence. Dev, test, and prod slowly stop being the same thing. One gets patched a certain way, another carries a manual tweak nobody documented, and production turns into Frankenstein stitched together with duct tape. When numbers don’t match across environments, no one remembers which “just this once” fix caused the split, and suddenly quarterly revenue stats don’t even reconcile with themselves.

Here’s a scar to prove the point: a team once patched null handling directly in Gold to keep dashboards alive. On the surface, no red lights—problem solved. But staging had clean transforms, while prod carried that rogue tweak. Two weeks later, machine learning models trained on staging didn’t match real‑world outputs. Cue re‑training, wasted sprint cycles, and confused leadership. That’s the pattern: every prod‑only fix is a time bomb.

So how do you stop this? Strip it down to three rules, simple enough to memorize:

Rule A: Isolate environments, and never skip promotions. Dev to test, test to prod—always in that order. Promotion only happens forward. No “we’ll just slide this one change straight into prod.” If you want speed, automate the promotion pipeline, don’t bypass it. The fix is simple: script your environment setup once, containerize or template it, then reuse it. Stop treating environment prep as optional—make it part of the pipeline.

Rule B: Enforce automated tests and gates. Every commit needs to face checks before promotion, non‑negotiable. That means running unit tests for notebook logic or SQL transformations and a small integration test over a golden dataset. These tests catch silent schema drift or broken joins before they sneak into production. Add gates for approvals too—real human sign‑off where business impact is high. Think of it as a bouncer at the club door: no test pass, no entry.

Rule C: Make rollback a single‑click path. Don’t wait until disaster strikes to figure out how to undo. Package each deployment as a versioned artifact. That way, “rollback” means re‑deploying the last known good build, not digging through old scripts like digital archaeologists. Treat rollback like save points in a game—you wouldn’t wipe them before the boss fight. Same logic here.

There’s one more layer teams forget: observability. It’s not enough to just deploy—you need eyes on what happens before and after. That means pre‑deploy checks to confirm schema matches expectations, and post‑deploy monitoring that throws alerts if a KPI suddenly shifts outside a reasonable band. One common pattern: set automated checks so if a key metric moves more than a certain threshold—say, revenue swings wildly—you get notified before the boardroom does. This isn’t fancy AI; it’s making sure the lights flash red when data turns sideways.

Bottom line: avoiding deployment nightmares isn’t about building the fanciest YAML file. It’s rules and guardrails baked into the process so mistakes get blocked early, changes only move forward, and rollback is always one command away. That’s what separates teams still patching in prod from teams that actually trust their analytics pipelines.

And once those three rules are second nature—environment isolation, automated gates, and quick rollback—you’re ready to face the bigger picture. Because at some point, it’s not just about single fixes or shortcuts. It’s about what really gives structure to the whole architecture.

Conclusion

Subscribe at m365 dot show for a golden Age, and follow the M365.Show LinkedIn page for MVP‑led livestreams where we stress‑test this stuff in real tenant chaos. That’s your survival kit.

Three takeaways to tattoo on your brain: One, treat every layer as code—Bronze, Silver, Gold—it all lives in source control. Two, never let a change sneak forward without automated tests and promotion gates. Three, use the tools together: GitHub for collaboration, Fabric for packaging, Azure DevOps for governance. Four, Hit Subscribe!

The Medallion architecture only becomes resilient when you wrap CI/CD discipline around it—otherwise it’s plumbing that leaks at scale. Tell us in the comments: which layer wakes you up at 3 a.m.—Bronze, Silver, or Gold?

Discussion about this episode

User's avatar