Azure Platform Operations: Why Platforms Drifts After Go-Live

This is the first post in the Azure Platform Operations series, about what actually happens to a platform after go-live.

I’ve seen all four of these happen on Azure platforms that people would describe as mature. Good landing zones. Good platform teams. Good architecture. Every one of them still failed in production for reasons nobody designed for.

An app registration’s client secret expired. Nobody was watching for it. The service it fed authentication for went down mid-afternoon, and the first anyone heard about it was the incident channel lighting up.

An AVD estate grew, pool by pool, over eighteen months. Some session hosts domain-joined, some Entra-joined, added by whoever was under pressure that sprint. No documentation of which was which or why. Then the person who’d built the domain-joined pools left, and the platform team inherited GPOs and LAPS configuration they had no access to and no context on, sitting awkwardly inside an otherwise cloud-native estate.

A resource built in Terraform got a “quick fix” applied directly in the portal, because it was faster and the person doing it didn’t think it through. The next pipeline run reverted it. Nobody had told the workload team not to touch it, and nobody had told the platform team it had been touched.

A platform team inherited an enterprise mandate to patch every server through SCCM. They complied because it wasn’t a battle worth fighting. The problem was SCCM assumed an estate of domain-joined machines with on-prem visibility. Their cloud workloads became compliant on paper while patch visibility quietly deteriorated. The first missed updates weren’t found by operations, they were found by an audit.

Four different failure modes. Same root cause. The platform that got signed off on go-live day wasn’t the platform anyone was still operating six months later, and how the two would stay in sync was never decided.

Day 0 gets all the attention

Landing zone design, IaC pipelines, policy baselines, network topology. Most of what gets written about Azure platforms, including most of what I write about, is day 0. Getting the thing built and getting it built well.

Day 1 gets almost none.

What happens after go-live, when the platform team’s attention moves to the next build and the thing that’s live starts quietly drifting away from the design it was handed over as. Secrets don’t renew themselves. Session host pools don’t stay consistent on their own. Terraform state doesn’t defend itself against someone with portal access and good intentions.

None of the four examples above were caused by a bad landing zone design, a missing scanner, or a tool doing something wrong. They were caused by a decision that never got made: who watches this, and what happens when it starts to drift.

Platform drift isn’t just configuration drift. It’s the gradual divergence between the architecture you designed, the ownership model you documented, and the platform people actually operate every day. Technology changes, people change, priorities change. Unless someone is actively managing that drift, it accumulates.

The shared operating model

Here’s the assumption I think most platform teams make without saying it out loud: once something is built on the platform, the platform team operates the platform layer and the workload team operates their workload, and that division is obvious enough that nobody needs to write it down.

It isn’t obvious. Not across an app registration that a workload team owns but a platform-level conditional access policy also touches. Not across an AVD pool where the platform team owns the image and the network but a business unit owns which users get assigned to it. Not across a Terraform-deployed resource where the pipeline is platform-owned but someone in the workload team has portal access “just in case.”

A shared operating model isn’t platform team owns everything or workload team owns everything. It’s both, deliberately split, with the split written down somewhere more durable than institutional memory.

Service tiers: deciding ownership up front

The way I’ve found useful to make that split concrete is to map ownership against the layers of your landing zone, connectivity, identity, management, workload subscriptions, and assign each layer a tier.

Platform-owned. The platform team builds it, operates it, and the workload team has no write access. Your management group hierarchy, your core policy assignments, your hub networking. Nobody outside the platform team should be able to drift this even by accident.

Shared responsibility. Platform team owns the baseline, workload team operates within it. An AVD host pool the platform team built and patches, but the workload team manages session host assignment and app packages inside it. Both sides need to know exactly where their half ends.

Workload-owned, with guardrails. The workload team builds and operates it, inside constraints the platform team enforces through policy rather than through doing the work themselves. Most application infrastructure sits here. The platform team’s job isn’t to run it, it’s to make sure it can’t drift outside the guardrails without triggering something.

None of the four failures above happened because the tier was wrong. They happened because the tier was never decided. The app registration sat in a grey area nobody owned. The domain-joined AVD pools were built as if they were workload-owned, then became platform-owned by default the moment the original builder left, with none of the access or documentation to match. The Terraform-managed resource was platform-owned in design and workload-touchable in practice, because that gap was never closed. And the patching tooling was platform-owned in name, inherited from an on-prem model that was never going to give a cloud platform team the one thing tiered ownership depends on: visibility.

The point isn’t governance for governance’s sake. It’s making ownership explicit enough that monitoring, documentation and operational processes naturally follow.

This has to be an architecture decision, not an afterthought

Service tiers are an architecture decision, not an operational one. They work when you decide them at landing zone design time, alongside the connectivity and identity architecture, not bolted on after something’s already broken and you’re retroactively working out who should have been watching it. If you’re building or revisiting a landing zone with IaC, this is the point to decide it, while the boundaries are still cheap to draw and before six months of drift makes them expensive to redraw.

What’s coming in this series

This is the first post in a series about what actually happens to a platform after go-live. Keeping your landing zone current without breaking the workload teams sitting on top of it. Patch management at scale, and the parts of it nobody talks about. The Terraform provider and module debt that quietly accumulates. Certificate expiry and identity lifecycle, and how you catch it before it catches you. Platform observability, and what a platform team actually needs to be watching.

Every one of them comes back to the same thing. The platform you hand over on go-live day isn’t the platform you’ll be operating six months later.

The gap between those two platforms is where most operational failures begin, quietly, and usually not on a day anyone was watching for it.

Your subscription could not be saved. Please try again.
Your subscription to deniscooper.co.uk has been successful.

Join Cloud Engineers Who Build Smarter on Azure

Free checklists, practical guides and the latest posts — built for cloud engineers working with Azure and Terraform.

Leave a Comment