<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>JeffOps — Tech. Ops. Dev.</title>
  <link>https://jeffops.com/</link>
  <atom:link href="https://jeffops.com/rss.xml" rel="self" type="application/rss+xml"/>
  <description>Practical AI-tomation, platform engineering and enterprise ops from Jeff Wouters. Written from inside a 25,000-user environment, not from a vendor deck.</description>
  <language>en</language>
  <lastBuildDate>Sat, 01 Aug 2026 22:00:00 +0000</lastBuildDate>
  <item>
    <title>Azure Deployment Environments and Dev Box are in maintenance mode</title>
    <link>https://jeffops.com/posts/2026/azure-platform-engineering-maintenance-mode/</link>
    <guid isPermaLink="true">https://jeffops.com/posts/2026/azure-platform-engineering-maintenance-mode/</guid>
    <pubDate>Sat, 01 Aug 2026 22:00:00 +0000</pubDate>
    <description>The two Azure services most commonly recommended as the foundation of an internal developer platform are both in maintenance mode with no further features planned. Here is what Microsoft actually said, and what is left standing.</description>
    <category>platform-engineering</category><category>azure</category><category>idp</category><category>enterprise</category><category>ops</category>
    <content:encoded><![CDATA[<p>If you are part-way through a design that assumes either of these, this is worth knowing this week rather than next year.</p>
<p><strong>Azure Deployment Environments and Microsoft Dev Box are both in maintenance mode.</strong> Most of the "build an internal developer platform on Azure" writing currently in circulation nominates one or both as the foundation. That advice has not caught up.</p>
<p>Microsoft's <a href="https://learn.microsoft.com/azure/deployment-environments/maintenance-mode">wording for Azure Deployment Environments</a> is short enough to quote in full: "Azure Deployment Environments is in maintenance mode, with no additional features planned. Existing capabilities remain available."</p>
<p><a href="https://learn.microsoft.com/azure/dev-box/dev-box-windows-365-announcement">For Dev Box</a> it is more pointed: "Dev Box is now in maintenance mode, with no additional features planned", and "Customers should consider Windows 365 as the recommended path forward."</p>
<p>Several announced Dev Box features were cancelled before they shipped, including on-behalf-of creation, firewall service tags, developer offboarding, single sign-on for existing machines, auto-remediation and the latency improvements. There is no migration guide yet. The documentation says guidance will be provided.</p>
<p>Maintenance mode is not end of life, and nothing you are running today stops working. But it changes the calculation. A service with no further features is a service you should not be building a five-year platform strategy on top of, and it is a service whose gaps will stay gaps.</p>
<h2 id="what-has-not-gone-into-maintenance">What has not gone into maintenance</h2>
<p>The awkward part is that the two services now parked are the ones that felt most like a platform, in the sense of a thing a developer touches. What is left is less exciting and considerably more durable, because it is the substrate rather than the surface.</p>
<p><strong><a href="https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/subscription-vending">Landing zones and subscription vending</a>.</strong> This is the genuinely platform-shaped primitive in Azure: a request produces a subscription placed in the right management group, with networking, RBAC and identity already wired. It is the paved road, expressed as infrastructure rather than as a portal.</p>
<p>Read Microsoft's own framing carefully, because it cuts against the way golden paths are usually described. It is not "pick one blessed route and make everyone take it". Microsoft says that organisations "that only provide a 'one size fits all' approach to subscription vending often limit their internal customers' flexibility" and that "platform teams need to provide various product lines to cater to their organization's needs", noting that customers typically start with three: sandbox, corp connected, and online.</p>
<p>A small catalogue of paved roads, not one. That is a more useful model than the singular golden path, and it is the difference between a platform people route around and one they use.</p>
<p><strong><a href="https://azure.github.io/Azure-Verified-Modules/">Azure Verified Modules</a></strong> as the module layer. Read the support statement before you depend on it. The commitment is a meaningful response toward resolution within five business days, and Microsoft is explicit that this is "not for a fix within these durations". Modules also carry lifecycle states, including "orphaned" for when maintainers stop responding. That is fine, and it is a great deal better than writing your own modules from scratch. It is not the same as a supported product, and the difference matters when you are telling your organisation that this is the supported way to build.</p>
<p><strong>Azure Policy</strong> as the governance layer. Microsoft's framing here is the useful bit: <a href="https://learn.microsoft.com/platform-engineering/application-platform">start right and stay right</a>, meaning catalogued templates get you compliant at creation and policy keeps you compliant afterwards. Note the warning that comes attached, because it is the thing that will bite you: while policies "can enforce compliance, they can also break applications unexpectedly". Roll them out in rings, the same way you would roll out anything else that can take production down.</p>
<h2 id="on-portals-microsofts-advice-runs-against-the-instinct">On portals, Microsoft's advice runs against the instinct</h2>
<p>Worth quoting because it is the opposite of where most platform projects start. A developer portal, Microsoft says, is <a href="https://learn.microsoft.com/platform-engineering/developer-self-service">"a destination rather than a starting point"</a>. Before building somewhere new for people to go, extend the surfaces they already use: the IDE, the CLI, the DevOps tooling, chat.</p>
<p>That ordering is well supported by evidence from outside Microsoft. Spotify, who built the most popular developer portal there is, <a href="https://www.techtarget.com/searchitoperations/news/366558592/Behind-the-scenes-Spotify-Backstage-a-work-in-progress">put average Backstage adoption inside adopting organisations at around 10%</a>. Building a second front door and then asking people to learn it is a hard way to earn attention you could have had for free.</p>
<h2 id="one-caveat-if-you-standardise-on-azd-templates">One caveat if you standardise on azd templates</h2>
<p>Azure Developer CLI templates are a genuinely good accelerator, and Microsoft states plainly that the templates, "including those provided from Microsoft, are not supported by any Microsoft support program or service". They are provided as is.</p>
<p>That is fine for a starting point and a problem for a paved road. The moment you tell your organisation "this is the supported way to deploy", you have quietly assumed the support obligation yourself. Decide that deliberately rather than discovering it during an incident.</p>
<h2 id="what-i-would-take-from-this">What I would take from this</h2>
<p>The services that went into maintenance are the ones that looked like a product. The ones still standing are the ones that look like plumbing. That is not a coincidence, and there is a lesson in it about which layer is worth building your platform on.</p>
<p>More generally, it is a small live demonstration of a bigger point: <a href="/posts/2026/internal-developer-platform-expiry-date/">an internal platform is a bet on a gap, and the gap moves</a>. Sometimes it moves because the hyperscalers close it. Sometimes, as here, it moves because the hyperscaler you built on quietly stops developing the thing you built on. Either way, the assumption is worth re-pricing on a schedule rather than at the point where someone sends you a documentation link.</p>]]></content:encoded>
  </item>
  <item>
    <title>Your internal developer platform has an expiry date</title>
    <link>https://jeffops.com/posts/2026/internal-developer-platform-expiry-date/</link>
    <guid isPermaLink="true">https://jeffops.com/posts/2026/internal-developer-platform-expiry-date/</guid>
    <pubDate>Sat, 01 Aug 2026 22:00:00 +0000</pubDate>
    <description>The best documented internal platform in the public sector hit every operational target and was shut down anyway. A platform is not an asset you build, it is a bet that a gap is worth closing, and the gap closes without telling you.</description>
    <category>platform-engineering</category><category>idp</category><category>enterprise</category><category>adoption</category><category>ops</category>
    <content:encoded><![CDATA[<p>172 digital services. More than 60 departments, agencies and local authorities. 3,200 applications. Deployments more than 122 times a day. 99.95% uptime.</p>
<p>That is <a href="https://gds.blog.gov.uk/2022/07/12/why-weve-decided-to-decommission-gov-uk-paas-platform-as-a-service/">GOV.UK PaaS in July 2022</a>, on the day the Government Digital Service announced it was shutting it down.</p>
<p>By every operational measure in the platform engineering canon, it worked. It was decommissioned anyway, and the reasons GDS gave are the most useful thing published on this subject.</p>
<p>Here is the line the rest of this hangs on: <strong>a platform is not an asset you build, it is a bet that a particular gap is worth closing, and the gap closes without telling you.</strong></p>
<p>A word on where this comes from, because it should change how you read it. I run workplace technology for 25,000 people, which is enterprise IT rather than product engineering. I have never stood up a Backstage instance. What follows is not a war story. It is what the published evidence says when you go and read it, and the evidence turns out to be stranger than the advice built on top of it.</p>
<h2 id="what-actually-closed-govuk-paas">What actually closed GOV.UK PaaS</h2>
<p>GDS gave three reasons. Growth had stalled. The large cloud providers had, in their words, "upped their game and reduced the barriers to entry". And departments had built their own cloud engineering capability and were clustering around a Kubernetes based architecture on their own.</p>
<p>The tempting move is to pick whichever of those supports the argument you already hold. Read the first on its own and this is a straightforward adoption failure. Read the second and third on their own and it is pure market movement, nobody's fault.</p>
<p>They are the same event seen from two ends.</p>
<p>Growth stalls <em>because</em> the gap is closing. A team that can now stand up its own thing in an afternoon does not join your platform, and the number that surfaces on your dashboard is flat adoption. So adoption is the symptom you can see, and scarcity is the disease underneath it. That distinction is not academic, because it changes what you monitor. Adoption tells you how you did last quarter. Scarcity tells you how long you have got.</p>
<p>Every internal platform is an arbitrage on the difference between what your organisation can do on its own and what the market makes easy. That difference is the whole value of the thing. It narrows every year, and nobody sends you a note when it does.</p>
<p><div class="figure-scroll"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 780 440" width="780" height="440" role="img" aria-labelledby="gp-t gp-d" style="max-width:100%;height:auto;display:block;margin:1.5rem 0"><title id="gp-t">Why an internal platform has an expiry date</title><desc id="gp-d">Two schematic curves. The effort of doing it yourself falls steadily as the market improves, while the effort of doing it through your platform stays roughly flat. The shaded gap between them is the value the platform provides, and it closes on its own.</desc><defs><marker id="gp-a" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#0aa5c4"/></marker><marker id="gp-aw" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" fill="#d2593c"/></marker></defs><line x1="110" y1="46" x2="110" y2="340" stroke="currentColor" stroke-opacity="0.28" stroke-width="1.5"/><line x1="110" y1="340" x2="714" y2="340" stroke="currentColor" stroke-opacity="0.28" stroke-width="1.5"/><text x="100" y="50" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" fill="currentColor" fill-opacity="0.62" text-anchor="end" font-weight="400">more effort</text><text x="100" y="336" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" fill="currentColor" fill-opacity="0.62" text-anchor="end" font-weight="400">less</text><text x="714" y="358" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="11" fill="currentColor" fill-opacity="0.62" text-anchor="end" font-weight="400">time</text><polygon points="110.0,88.0 119.7,97.8 129.3,104.5 139.0,110.4 148.7,115.8 158.3,120.9 168.0,125.7 177.7,130.3 187.3,134.8 197.0,139.1 206.7,143.3 216.3,147.4 226.0,151.4 235.7,155.3 245.3,159.2 255.0,163.0 264.7,166.7 274.3,170.3 284.0,173.9 293.7,177.5 303.3,181.0 313.0,184.5 322.7,187.9 332.3,191.3 342.0,194.6 351.7,197.9 361.3,201.2 371.0,204.5 380.7,207.7 390.3,210.9 400.0,214.1 409.7,217.2 419.3,220.3 429.0,223.4 438.7,226.5 448.3,229.5 458.0,232.5 467.7,235.5 477.3,238.5 487.0,241.5 496.7,244.4 496.7,242.0 487.0,241.8 477.3,241.6 467.7,241.4 458.0,241.2 448.3,241.0 438.7,240.8 429.0,240.6 419.3,240.4 409.7,240.2 400.0,240.0 390.3,239.8 380.7,239.6 371.0,239.4 361.3,239.2 351.7,239.0 342.0,238.8 332.3,238.6 322.7,238.4 313.0,238.2 303.3,238.0 293.7,237.8 284.0,237.6 274.3,237.4 264.7,237.2 255.0,237.0 245.3,236.8 235.7,236.6 226.0,236.4 216.3,236.2 206.7,236.0 197.0,235.8 187.3,235.6 177.7,235.4 168.0,235.2 158.3,235.0 148.7,234.8 139.0,234.6 129.3,234.4 119.7,234.2 110.0,234.0" fill="#0aa5c4" fill-opacity="0.14" stroke="none"/><polyline points="110.0,234.0 119.7,234.2 129.3,234.4 139.0,234.6 148.7,234.8 158.3,235.0 168.0,235.2 177.7,235.4 187.3,235.6 197.0,235.8 206.7,236.0 216.3,236.2 226.0,236.4 235.7,236.6 245.3,236.8 255.0,237.0 264.7,237.2 274.3,237.4 284.0,237.6 293.7,237.8 303.3,238.0 313.0,238.2 322.7,238.4 332.3,238.6 342.0,238.8 351.7,239.0 361.3,239.2 371.0,239.4 380.7,239.6 390.3,239.8 400.0,240.0 409.7,240.2 419.3,240.4 429.0,240.6 438.7,240.8 448.3,241.0 458.0,241.2 467.7,241.4 477.3,241.6 487.0,241.8 496.7,242.0 506.3,242.2 516.0,242.4 525.7,242.6 535.3,242.8 545.0,243.0 554.7,243.2 564.3,243.4 574.0,243.6 583.7,243.8 593.3,244.0 603.0,244.2 612.7,244.4 622.3,244.6 632.0,244.8 641.7,245.0 651.3,245.2 661.0,245.4 670.7,245.6 680.3,245.8 690.0,246.0" fill="none" stroke="#0aa5c4" stroke-width="2"/><polyline points="110.0,88.0 119.7,97.8 129.3,104.5 139.0,110.4 148.7,115.8 158.3,120.9 168.0,125.7 177.7,130.3 187.3,134.8 197.0,139.1 206.7,143.3 216.3,147.4 226.0,151.4 235.7,155.3 245.3,159.2 255.0,163.0 264.7,166.7 274.3,170.3 284.0,173.9 293.7,177.5 303.3,181.0 313.0,184.5 322.7,187.9 332.3,191.3 342.0,194.6 351.7,197.9 361.3,201.2 371.0,204.5 380.7,207.7 390.3,210.9 400.0,214.1 409.7,217.2 419.3,220.3 429.0,223.4 438.7,226.5 448.3,229.5 458.0,232.5 467.7,235.5 477.3,238.5 487.0,241.5 496.7,244.4 506.3,247.3 516.0,250.2 525.7,253.1 535.3,256.0 545.0,258.9 554.7,261.7 564.3,264.5 574.0,267.3 583.7,270.1 593.3,272.9 603.0,275.7 612.7,278.4 622.3,281.2 632.0,283.9 641.7,286.6 651.3,289.3 661.0,292.0 670.7,294.7 680.3,297.3 690.0,300.0" fill="none" stroke="#d2593c" stroke-width="2" stroke-dasharray="6 4"/><text x="128" y="66" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="13.5" fill="#d2593c" fill-opacity="1" text-anchor="start" font-weight="600">Doing it yourself</text><text x="128" y="84" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="11.5" fill="currentColor" fill-opacity="1" text-anchor="start" font-weight="400">falls every quarter, without anyone telling you</text><text x="128" y="272" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="13.5" fill="#0aa5c4" fill-opacity="1" text-anchor="start" font-weight="600">Doing it through your platform</text><text x="128" y="290" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="11.5" fill="currentColor" fill-opacity="1" text-anchor="start" font-weight="400">roughly flat, and you pay to keep it there</text><text x="240" y="200" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="12.5" fill="currentColor" fill-opacity="1" text-anchor="middle" font-weight="600">the gap you are arbitraging</text><text x="240" y="216" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="10.5" fill="currentColor" fill-opacity="0.62" text-anchor="middle" font-weight="400">when this closes, so does the platform</text><circle cx="496.7" cy="242.0" r="5.5" fill="none" stroke="#d2593c" stroke-width="2"/><line x1="496.7" y1="231.0" x2="496.7" y2="132" stroke="#d2593c" stroke-width="1.5" stroke-dasharray="3 3"/><text x="508.66666666666663" y="124" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="12.5" fill="#d2593c" fill-opacity="1" text-anchor="start" font-weight="600">the abstraction stops being scarce</text><text x="508.66666666666663" y="142" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="11" fill="currentColor" fill-opacity="1" text-anchor="start" font-weight="400">nothing failed; the market moved</text><text x="110" y="406" font-family="-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif" font-size="12" fill="currentColor" fill-opacity="0.75" text-anchor="start" font-weight="400">GOV.UK PaaS reached this point with 172 services, 3,200 apps and 99.95% uptime, and was retired anyway.</text><text x="110" y="426" font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace" font-size="12" fill="currentColor" fill-opacity="0.6" text-anchor="start" font-weight="400">Schematic. The shape is the argument; neither curve is measured.</text></svg></div></p>
<p>One detail worth sitting with. The UK government's <a href="https://roadmap-for-modern-digital-government.campaign.gov.uk/digital-and-data-infrastructure/common-systems-platforms">roadmap for modern digital government</a> commits to a fresh generation of shared platforms, including a new one called internal.gov.uk "for people who work in the public sector to connect via instant messaging functionality, forums and a secure code repository", due June 2026. It makes no reference to GOV.UK PaaS, and gives no account of why the last one was retired.</p>
<p>The organisation that wrote the best post-mortem in this field did not cite it in its own next plan.</p>
<h2 id="the-literature-was-not-written-for-you">The literature was not written for you</h2>
<p>If you run an enterprise IT estate rather than a product engineering organisation, this is the part that matters.</p>
<p>Look at who the examples are. Team Topologies publishes <a href="https://teamtopologies.com/industry-examples/tag/Platform+Teams">thirteen platform team industry examples</a>. Exactly one is public sector. The rest are Docker, Flo Health, Trade Me, Improbable, PureGym, Footasylum, Uswitch and similar. Every prescription in the field, golden paths, thinnest viable platform, stream-aligned teams, cognitive load, assumes a population of product engineers shipping services they own.</p>
<p>That is not most enterprise IT. If your estate is Microsoft 365, a service management tool, a fleet of endpoints, a dozen line-of-business applications and a handful of integrations, your users are not stream-aligned product teams. Your cognitive load problem is not deployment pipelines. And your adoption problem is not that developers prefer their own tooling, it is that a department will buy a SaaS product on a corporate card rather than wait for you.</p>
<p>The strange part is that the canonical definition already covers you. <a href="https://tag-app-delivery.cncf.io/whitepapers/platforms/">CNCF's platforms white paper</a> says platform users "include but aren't limited to app developers and operators, data scientists, COTS software operators, and information workers". Information workers are in the founding definition. Almost nothing built on top of that definition acknowledges they exist.</p>
<p>The one author writing directly for this audience is Gregor Hohpe, whose 2024 book <a href="https://architectelevator.com/book/platformstrategy/"><em>Platform Strategy</em></a> has a substantial in-house IT section, including one titled "IT Platform and IT Services Are Antonyms". His failure mode for enterprise platforms will be familiar: outdated by the time they launch, restricting rather than enabling, and mandated in a last-ditch attempt to make the economics work. His evidence base is a decade of practitioner experience rather than measurement, and he names no organisations.</p>
<h2 id="and-the-evidence-under-the-advice-is-thin">And the evidence under the advice is thin</h2>
<p>Worth knowing before you cite any of it at your own leadership.</p>
<p>Start with the number everyone repeats, some version of "70% of platform initiatives fail". <a href="https://thenewstack.io/why-up-to-70-of-platform-engineering-teams-fail-to-deliver-impact/">The New Stack repeats it</a> and, to its credit, links its sources, which is how you can check them. Follow the first link and the "up to 70%" traces to a webinar registration page titled "Platform leadership 101: Why 67% of platform initiatives are failing", whose entire stated methodology is a single sentence: "Both our community surveys and broader market studies reveal that 67% of platform leaders are missing the mark on building successful, scalable Internal Developer Platforms." Follow the second, for the claim that half of platform teams are disbanded within eighteen months, and you reach a <a href="https://www.gartner.com/en/infrastructure-and-it-operations-leaders/topics/platform-engineering">Gartner topic page</a> that does not contain that claim at all. Its only statistic is a forecast that 80% of large software engineering organisations will have platform teams by 2026.</p>
<p>So the citation is not thin. It is broken.</p>
<p>The academic position is documented, and it is worse. A <a href="https://www.frontiersin.org/journals/computer-science/articles/10.3389/fcomp.2026.1814498/full">multivocal literature review published in Frontiers in Computer Science</a> in May 2026 searched five databases and found "fewer than a dozen peer-reviewed papers from reputable venues that address platform engineering directly". No tier-A source proposes or validates a maturity model, so every maturity model in circulation comes from grey literature. And on scorecards, the main governance mechanism inside most developer portals, it found "no peer-reviewed empirical evidence of effectiveness exists despite widespread commercial adoption".</p>
<p>Be fair to the method here: a multivocal review deliberately includes grey literature, so a low proportion of academic sources is partly the point of the technique. The absolute count is the number that bites. Fewer than a dozen papers, for a discipline with a conference circuit and a tooling market.</p>
<p>The canonical artefacts have not aged well either. The <a href="https://tag-app-delivery.cncf.io/whitepapers/platform-eng-maturity-model/">CNCF Platform Engineering Maturity Model</a> was released in November 2023 and is still v1.0. The working group that owned it no longer exists: when <a href="https://www.cncf.io/blog/2025/05/07/10-years-in-cloud-native-toc-restructures-technical-groups/">CNCF restructured its technical groups in May 2025</a>, the assessment work was recorded in CNCF's own tracker as <a href="https://github.com/cncf/toc/issues/1679">"having paused in recent months due to recent TOC changes"</a>, with the authors asking that the TOC "provide guidance as to the correct place within the community to conduct this ongoing work". A <a href="https://cloud-native-platform-engineering.github.io/pemm-assessment/">pilot assessment tool</a> has since appeared outside the CNCF repositories, still asking for feedback.</p>
<p>None of that means platform engineering is wrong. It means the confident numbers in your inbox are not measurements, and you should discount accordingly, including the ones in this piece.</p>
<h2 id="what-is-actually-measured-including-the-uncomfortable-part">What is actually measured, including the uncomfortable part</h2>
<p><a href="https://dora.dev/research/2024/dora-report/">DORA's 2024 report</a>, nearly 3,000 respondents, is the strongest measured evidence in the field. Internal developer platform users showed 8% higher individual productivity and 10% higher team performance.</p>
<p>Throughput also decreased by 8%, and change stability decreased by 14%.</p>
<p>That is the field's flagship research reporting that platforms made delivery slower and less stable. DORA's own hypotheses are that a platform can add handoffs between systems and teams, or that it lets teams ship faster and therefore break more, or that instability signals teams were never properly onboarded. The report links that instability to increased developer burnout, and cautions against deploying platform engineering as a burnout remedy.</p>
<p><a href="https://dora.dev/capabilities/platform-engineering/">DORA's 2025 report</a>, <a href="https://cloud.google.com/blog/products/ai-machine-learning/announcing-the-2025-dora-report">nearly 5,000 technology professionals</a>, adds the finding that matters most right now: when platform quality is high, the effect of AI adoption on organisational performance is "strong and positive", and when platform quality is low that effect is "negligible". If you are being asked to demonstrate returns on AI, the platform is not a competing priority. It is the precondition. That is the strongest argument for doing this work I have found anywhere, and note that it is conditional on quality rather than on existence.</p>
<p>One discrepancy worth carrying. DORA 2025 reports 90% of organisations have adopted at least one platform and 76% have dedicated platform teams. A <a href="https://www.cncf.io/announcements/2026/03/24/cncf-and-slashdata-report-finds-platform-engineering-tools-maturing-as-organizations-prepare-for-ai-driven-infrastructure/">CNCF and SlashData survey</a> of more than 400 developers in March 2026 found only 28% have a dedicated platform engineering team. Those two are not describing the same thing. When someone quotes an adoption figure at you, ask what they counted.</p>
<h2 id="nobody-uses-these-things">Nobody uses these things</h2>
<p>Spotify, the company that created Backstage, has <a href="https://www.techtarget.com/searchitoperations/news/366558592/Behind-the-scenes-Spotify-Backstage-a-work-in-progress">publicly estimated the average Backstage adoption rate at 10%</a> inside the organisations that install it. Nine in ten of the people it was built for carry on as before.</p>
<p>The vendor surveys agree, which is notable given who pays for them. <a href="https://www.vmware.com/docs/vmw-weave-state-of-platform-engineering-report-vol-4-2025">State of Platform Engineering Volume 4</a>, published by Weave Intelligence with 518 respondents, found that "nearly 30 percent of platform teams still report that they do not measure success at all", and that adoption "is still frequently driven by extrinsic push or mandate (36.6%) rather than the intrinsic value necessary for true user pull (28.2%)".</p>
<p>Which returns you to where the idea started. When Evan Bottcher <a href="https://martinfowler.com/articles/talk-about-platforms.html">defined the digital platform</a> in 2018, one word was doing real work: "a foundation of self-service APIs, tools, services, knowledge and support which are arranged as a <strong>compelling</strong> internal product". Compelling, not mandated. A platform that needs a mandate has already failed its own definition. Even Microsoft's guidance, which has every commercial reason to encourage you, <a href="https://learn.microsoft.com/platform-engineering/about/product-mindset">says it plainly</a>: "Customers should want to use your platform, but not be mandated to use it."</p>
<p>That advice is correct, and in a regulated enterprise it is unusable as written. Which brings me to the part the literature does not cover.</p>
<h2 id="three-things-i-would-do-differently">Three things I would do differently</h2>
<p><strong>Mandate the control, never the path.</strong> In a bank, an insurer, a hospital or a government department, "don't mandate it" is not available to you, because an unpaved road is an audit finding. So mandate the outcome instead: encryption, identity, logging, network placement, data residency. Leave the route optional. This costs you nothing you actually needed, and it buys you the only honest adoption metric there is, because now the percentage of compliant workloads that came through your paved road tells you how many teams chose you when a legal alternative existed. Compare that with measuring how many workloads are compliant, which measures your auditors rather than your platform.</p>
<p><strong>Your service catalogue is the portal you already have.</strong> Microsoft's own advice is that a developer portal is <a href="https://learn.microsoft.com/platform-engineering/developer-self-service">"a destination rather than a starting point"</a>, and that you should extend the surfaces people already use before you build a new one. In enterprise IT that surface is the service management tool, because it is where people already go when they want something. Self-service in this world usually means a request with an approval attached, not a git push, and there is no shame in that. Building a second front door and then asking the organisation to learn it is how you arrive at 10%.</p>
<p><strong>Put the expiry review in the diary, and decide now who raises it.</strong> Every six months, write down what your platform makes easy, then price what it would cost a team to do that today without you, using whatever the hyperscalers shipped last quarter. If the answer is "about the same", you are running GOV.UK PaaS in 2022. The second half of that sentence is the hard one. Nobody retires a platform without embarrassment, because the person best placed to notice the gap has closed is the person whose job closes with it. GDS could do it because GDS had plenty of other work. A platform team inside a bank has no such luxury, and that, rather than sunk cost, is the real reason platforms outlive their scarcity. Name the person who is expected to raise it while naming them is still cheap.</p>
<p>Underneath all three sits the question nobody writes about: who funds this. In a product organisation the platform team is paid for out of engineering and nobody asks again. In enterprise IT it is funded by whoever will sign for it, and an unmandated central platform re-justifies its budget every year against projects with a named business sponsor, and loses. The person who signs is also the person who will be asked at the next audit why the controls are not uniform. Which is the first recommendation again, arriving from the other direction.</p>
<h2 id="the-two-things-that-are-both-true">The two things that are both true</h2>
<p>The discipline's own flagship research says platforms reduced throughput and stability. Its most-quoted failure statistic traces to a webinar title and a Gartner page that does not contain it. The company that built the most popular portal puts adoption at one in ten.</p>
<p>And the platform is still the thing that determines whether your AI spending returns anything at all.</p>
<p>You hold those together by changing what a platform is for. Not an asset you build and then defend, but a bet on a gap, priced at the start, repriced on a schedule, and closed without embarrassment when the market closes it for you. GOV.UK PaaS was not a failure. It was a correct decision at the beginning and a correct decision at the end, and the only mistake available was keeping it because shutting it down would have looked like one.</p>
<p>Start by writing down which gap you are betting on. If you cannot name it in a sentence, you do not have a platform, you have a project.</p>
<p><em>If you are building on Azure, two of the services most commonly recommended as the foundation went into maintenance mode this year. That is a separate post: <a href="/posts/2026/azure-platform-engineering-maintenance-mode/">Azure Deployment Environments and Dev Box are in maintenance mode</a>.</em></p>]]></content:encoded>
  </item>
  <item>
    <title>HowTo test Architecture in .NET with NetArchTest</title>
    <link>https://jeffops.com/posts/2023/howto-test-architecture-in-dotnet-with-netarchtest/</link>
    <guid isPermaLink="true">https://jeffops.com/posts/2023/howto-test-architecture-in-dotnet-with-netarchtest/</guid>
    <pubDate>Sun, 12 Nov 2023 23:00:00 +0000</pubDate>
    <description>Have you ever wondered how to ensure that your .NET code follows the architectural design and conventions that you have chosen? Do you want to avoid the common pitfalls of violating the principles of separation of concer</description>
    <category>dotnet</category><category>netarchtest</category><category>architecture</category><category>testing</category><category>dev</category>
    <content:encoded><![CDATA[<p>Have you ever wondered how to ensure that your .NET code follows the architectural design and conventions that you have chosen? Do you want to avoid the common pitfalls of violating the principles of separation of concerns, dependency inversion, or layering? If so, then you might be interested in NetArchTest, a fluent API for .NET Standard that can enforce architectural rules in unit tests.</p>
<p>Recently I stumbled upon the NetArchTest package by Ben Morris.</p>
<h2 id="what-is-netarchtest">What is NetArchTest?</h2>
<p>NetArchTest is a .NET library that allows you to create tests that enforce conventions for class design, naming, and dependency in .NET code bases. It is inspired by the ArchUnit library for Java. It uses a fluid API that allows you to string together readable rules that can be used in test assertions. You can use it with any unit test framework and incorporate it into your build pipeline.</p>
<p>It is available as a NuGet package.</p>
<h2 id="how-to-use-netarchtest">How to use NetArchTest?</h2>
<p>The basic steps to use NetArchTest are:</p>
<ol>
<li>Select a set of types from a path, assembly, or namespace using the static <code>Types</code> class.</li>
<li>Filter the types using one or more predicates, such as <code>ResideInNamespace</code>, <code>HaveDependencyOn</code>, <code>ImplementInterface</code>, etc. You can chain the predicates using <code>And</code> or <code>Or</code> conjunctions.</li>
<li>Apply one or more conditions using the <code>Should</code> or <code>ShouldNot</code> methods, such as <code>BeSealed</code>, <code>BeAbstract</code>, <code>HaveNameStartingWith</code>, etc.</li>
<li>Obtain a result from the rule by using an executor, such as <code>GetTypes</code> to return the types that match the rule or <code>GetResult</code> to determine whether the rule has been met. The result will also return a list of types that failed to meet the conditions.</li>
</ol>
<p>Here are some examples of rules that you can create with NetArchTest:</p>
<p>Classes in the presentation layer should not directly reference repositories:</p>
<pre><code class="language-csharp">var result = Types.InCurrentDomain()
    .That()
    .ResideInNamespace(&quot;MyProject.Presentation&quot;)
    .ShouldNot()
    .HaveDependencyOn(&quot;MyProject.Data&quot;)
    .GetResult()
    .IsSuccessful;
</code></pre>
<p>Classes in the data layer should implement <code>IRepository</code>:</p>
<pre><code class="language-csharp">var result = Types.InCurrentDomain()
    .That()
    .ResideInNamespace(&quot;MyProject.Data&quot;)
    .Should()
    .ImplementInterface(typeof(IRepository))
    .GetResult()
    .IsSuccessful;
</code></pre>
<p>All the service classes should be sealed:</p>
<pre><code class="language-csharp">var result = Types.InCurrentDomain()
    .That()
    .ImplementInterface(typeof(IService))
    .Should()
    .BeSealed()
    .GetResult()
    .IsSuccessful;
</code></pre>
<h2 id="want-to-read-more-on-its-origin">Want to read more on its origin?</h2>
<p>Ben's written a nice blog post about how he came to write this package. Especially if you're interested in what motivates people, and the path they've walked, take a look at his blog post.</p>
<h2 id="why-use-netarchtest">Why use NetArchTest?</h2>
<p>NetArchTest can help you to:</p>
<ul>
<li>Maintain the consistency and quality of your code base over time.</li>
<li>Avoid the need for manual code reviews or static analysis tools that may not capture your specific architectural requirements.</li>
<li>Create a self-testing architecture that can be verified by automated tests.</li>
<li>Communicate and document your architectural design and conventions through code.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>NetArchTest is a powerful and easy-to-use library that can help you to test your architecture in .NET. It can help you to enforce the rules and conventions that you have chosen for your code base and avoid the common pitfalls of architectural decay. You can use it with any unit test framework and integrate it into your build pipeline. If you are interested in learning more about NetArchTest, you can check out its GitHub repository or its NuGet page. Happy testing!</p>]]></content:encoded>
  </item>
</channel>
</rss>
