<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>Microsoft Mission Critical Blog articles</title>
    <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/bg-p/MicrosoftMissionCriticalBlog</link>
    <description>Microsoft Mission Critical Blog articles</description>
    <pubDate>Tue, 08 Sep 2026 18:48:36 GMT</pubDate>
    <dc:creator>MicrosoftMissionCriticalBlog</dc:creator>
    <dc:date>2026-09-08T18:48:36Z</dc:date>
    <item>
      <title>Managing SharePoint Online Version History at Scale to Recover Storage</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/managing-sharepoint-online-version-history-at-scale-to-recover/ba-p/4553571</link>
      <description>&lt;H2&gt;&lt;SPAN data-contrast="auto"&gt;Summay&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;SharePoint Online version history is one of those features that users love, but admins eventually have to govern.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Versioning protects users from accidental edits, bad changes, and overwritten content. It gives people a way to restore&amp;nbsp;previous&amp;nbsp;versions of documents without opening a ticket. That is a good thing.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;But at tenant scale, version history can also consume a surprising amount of storage.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Highly active libraries, large Office files, frequent edits, migrations, sync activity, and years of&amp;nbsp;retained&amp;nbsp;versions can quietly add up. Eventually, admins need to answer a few practical questions:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;H&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;ow many file versions do we have?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;How much storage are those versions consuming?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Which sites would benefit most from cleanup?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;What policy should we&amp;nbsp;apply&amp;nbsp;going forward?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;How much space could we recover before making changes?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;How do we clean up versions safely across many sites?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That is why I built this tool:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt; &amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/mikelee1313/SPOVersions-ApplicationTools" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;SPOVersions-ApplicationTools&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The main script is:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt; &amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/mikelee1313/SPOVersions-ApplicationTools/blob/main/Apply-SPOVersions-Tool.ps1" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;Apply-SPOVersions-Tool.ps1&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Why version history planning matters&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft's official guidance for SharePoint version storage makes&amp;nbsp;an important point: version limits should support your organization's recovery&amp;nbsp;objectives&amp;nbsp;while also controlling storage consumption.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft documents this here:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/sharepoint/plan-version-storage" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;Plan version storage for document libraries in SharePoint&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The key idea is balance.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If you keep too many versions for too long, storage consumption can grow quickly. If you trim too aggressively, users may lose the ability to recover from accidental or unwanted changes.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;A good version history strategy needs to consider both:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Goal&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Why it matters&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Recovery&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Users need enough version history to restore useful prior versions.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Storage control&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Admins need to prevent version history from consuming excessive quota.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Consistency&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Tenant defaults and site-level policies should be understandable and repeatable.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Exceptions&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Some business areas may need different&amp;nbsp;version&amp;nbsp;retention behavior.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Safe cleanup&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Existing versions should be analyzed before&amp;nbsp;deletion&amp;nbsp;jobs are created.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The goal is not simply to&amp;nbsp;delete&amp;nbsp;versions. The goal is to understand version storage, set the right policy, and clean up intentionally.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;What Microsoft recommends admins consider&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft's documentation calls out three major planning questions:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="%1." data-font="" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:0,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769242&amp;quot;:[65533,0],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;%1.&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Determine&amp;nbsp;the default&amp;nbsp;version&amp;nbsp;history limits for new document libraries.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="%1." data-font="" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:0,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769242&amp;quot;:[65533,0],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;%1.&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Identify&amp;nbsp;exceptions needed from&amp;nbsp;organization&amp;nbsp;default limits.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="%1." data-font="" data-listid="2" data-list-defn-props="{&amp;quot;335552541&amp;quot;:0,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769242&amp;quot;:[65533,0],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;%1.&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Decide whether existing content should be updated to align with the&amp;nbsp;organization&amp;nbsp;limits.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That third point is where many admins need&amp;nbsp;tooling.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;It is one thing to configure a&amp;nbsp;tenant&amp;nbsp;default for new libraries. It is another thing to understand what already exists across hundreds or thousands of sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Existing content is often where the storage opportunity is.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Automatic vs. manual version limits&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;SharePoint&amp;nbsp;provides&amp;nbsp;different ways&amp;nbsp;to manage version history.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Mode&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;What it does&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Best fit&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Automatic&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;SharePoint uses intelligent trimming based on version age. Recent versions are preserved more densely, while older versions are thinned over time.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Recommended default for many organizations that want Microsoft-managed optimization.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Manual with count and&amp;nbsp;expiration&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Admins specify how many major versions to keep and how long versions should remain.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Useful when you want more direct control and predictable cleanup.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Manual with count only&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Admins keep a configured number of versions without age-based expiration.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Useful when a fixed restore count matters, but it can consume more storage.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft's guidance highlights that automatic trimming is designed to preserve high-value versions while&amp;nbsp;optimizing&amp;nbsp;storage. Manual policies can be useful, but they require careful planning because low limits or short&amp;nbsp;expiration&amp;nbsp;windows can affect restore scenarios.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That is why I wanted this tool to include reporting and What-If analysis before&amp;nbsp;cleanup.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;What the tool does&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Apply-SPOVersions-Tool.ps1&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;is an interactive PowerShell tool built with PnP PowerShell to help admins manage SharePoint Online version policies across multiple site collections.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;At&amp;nbsp;a high level, the tool helps admins:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Audit current&amp;nbsp;version&amp;nbsp;policies across sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Apply automatic or manual version limits.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Review version policy status.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Generate&amp;nbsp;version&amp;nbsp;history reports.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Run What-If analysis to estimate storage recovery.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Create batch&amp;nbsp;delete&amp;nbsp;jobs for cleanup.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="7" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Monitor cleanup&amp;nbsp;job status.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="8" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Set tenant-level defaults for new sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This makes it useful for both planning and implementation.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Why I built it as an admin workflow&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Version cleanup should not start with deletion.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The safer workflow is:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Discover current settings.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Generate&amp;nbsp;version&amp;nbsp;history reports.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Estimate storage recovery.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Decide the right policy.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Apply policy to selected sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Queue cleanup jobs.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="7" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Monitor job status.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="8" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Repeat as part of governance.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That is how the tool is structured.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt; &amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;It is not just a cleanup script. It is a planning and execution tool.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Site discovery options&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The tool can work from a defined list of site URLs or discover sites automatically.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;For larger tenants, I usually prefer a site list because it gives admins better control over rollout scope.&amp;nbsp;You can start with a pilot group,&amp;nbsp;validate&amp;nbsp;results, then&amp;nbsp;expand.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;For smaller tenants or discovery scenarios, auto-discovery can be useful.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The tool supports:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;SharePoint sites&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;OneDrive for Business sites&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Exclusion of common system sites&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Confirmation before processing discovered sites&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That confirmation step matters. When a script can&amp;nbsp;operate&amp;nbsp;across many sites, admins should have a checkpoint before changes are made.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Key operations:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;OL&gt;
&lt;LI aria-level="3"&gt;
&lt;H5&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; Get current version policies&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;Before changing anything, admins can retrieve current&amp;nbsp;version&amp;nbsp;policy settings for all selected sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;This helps answer:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Which sites already use automatic trimming?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Which sites use manual limits?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Which sites have inconsistent settings?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Which sites may need exceptions?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;This is useful for building a baseline.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL start="2"&gt;
&lt;LI aria-level="3"&gt;
&lt;H5&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; Set version policies across sites&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;After planning, admins can apply version policies across site collections.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;The tool supports:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Automatic version trimming&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Manual major version limits&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Optional&amp;nbsp;expiration&amp;nbsp;after a specified number of days&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;Automatic trimming is useful when you want SharePoint to&amp;nbsp;optimize&amp;nbsp;storage intelligently. Manual limits are useful when the organization has a defined policy, such as keeping a specific number of major versions or expiring versions after a specific period.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL start="3"&gt;
&lt;LI aria-level="3"&gt;
&lt;H5&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; Check version policy status&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;Policy changes may take time to apply.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;The tool can check propagation&amp;nbsp;status,&amp;nbsp;so admins can verify whether pending changes&amp;nbsp;are completed&amp;nbsp;successfully.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;This is important during staged rollouts because you want to confirm policy state before moving on to cleanup.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL start="4"&gt;
&lt;LI aria-level="3"&gt;
&lt;H5&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; Generate version history reports&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;This is one of the most important parts of the workflow.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;The tool can&amp;nbsp;submit&amp;nbsp;version history report jobs for each site. Those reports are written to a dedicated document library created by the tool:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;Admin_SiteCollection_VersionReport_DONOTDELETE&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;Using a dedicated library avoids some of the issues that can happen when report files are written into normal user-facing document libraries.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;The reports provide the raw data needed to understand version storage usage.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL start="5"&gt;
&lt;LI aria-level="3"&gt;
&lt;H5&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; Run What-If analysis&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;This is the feature I think most admins should start with.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;The What-If analysis downloads completed version history reports and simulates a version policy without making changes.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;That means admins can estimate:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Total versions analyzed&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Versions that would be deleted&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Total version storage&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Storage that could be recovered&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Percent of version storage that could be freed&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" style="list-style-type: none;"&gt;
&lt;UL class="lia-indent-padding-left-30px"&gt;
&lt;LI class="lia-indent-padding-left-30px" aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Per-site savings&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;This gives&amp;nbsp;admins&amp;nbsp;data before they commit to a cleanup policy.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;For example, a What-If analysis might show that one site can recover a large amount of storage while another site has&amp;nbsp;very little&amp;nbsp;benefit. That helps prioritize action.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL start="6"&gt;
&lt;LI aria-level="3"&gt;
&lt;H5&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; Create batch&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;delete&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;jobs&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:240,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;Once the admin understands the impact and chooses a policy, the tool can create batch&amp;nbsp;delete&amp;nbsp;jobs to remove excess versions.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;This is the destructive part of the workflow, so it should come after reporting and What-If analysis.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;Admins can use automatic or manual cleanup criteria depending on the desired policy.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;Important reminder: deleted versions are not recovered from the Recycle Bin. Treat batch&amp;nbsp;delete&amp;nbsp;jobs as permanent cleanup operations.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL start="7"&gt;
&lt;LI aria-level="3"&gt;
&lt;H5&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt; Monitor batch&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;delete&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;job status&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:240,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;After cleanup jobs are created, admins need to know whether they completed and how much storage was released.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;The tool can check batch&amp;nbsp;delete&amp;nbsp;job status across sites, including&amp;nbsp;completion&amp;nbsp;state and storage released where available.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;This closes the loop from planning to execution.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H1 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Tenant-level defaults vs. existing content&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;One important distinction in SharePoint version management is the difference between tenant-level defaults and existing content.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Tenant-level settings affect new&amp;nbsp;sites&amp;nbsp;or new libraries going forward. Existing sites and existing file versions may need&amp;nbsp;additional&amp;nbsp;steps.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft's guidance describes multiple approaches:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Scenario&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;What it means&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Apply defaults to new libraries only&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Least&amp;nbsp;disruptive; existing settings and versions&amp;nbsp;remain&amp;nbsp;unchanged.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Update existing library settings without trimming versions&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Future versions follow the new policy, but existing versions are not&amp;nbsp;deleted.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Update settings and trim existing versions&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Aligns current and future&amp;nbsp;behavior but&amp;nbsp;requires careful planning and&amp;nbsp;cleanup jobs.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:0,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:276}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This tool helps with the third scenario, where admins need to understand and manage existing&amp;nbsp;version&amp;nbsp;storage across sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;A practical rollout approach&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;For most tenants, I would not recommend starting with the entire environment.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;A safer rollout looks like this:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Phase&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Action&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Phase 1: Baseline&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Get current version policies across a small set of sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Phase 2: Report&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Generate version history reports for pilot sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Phase 3: What-If&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Estimate storage recovery under automatic or manual policies.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Phase 4: Decide&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Choose default policy and&amp;nbsp;identify&amp;nbsp;exceptions.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Phase 5: Apply&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Apply policy to selected pilot sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Phase 6: Cleanup&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Queue batch&amp;nbsp;delete&amp;nbsp;jobs only after review.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Phase 7: Monitor&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Check job status and storage&amp;nbsp;released.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Phase 8: Expand&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Repeat across&amp;nbsp;additional&amp;nbsp;sites or workloads.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This creates a defensible admin process instead of a one-time cleanup event.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Where this helps most&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This tool is especially useful in tenants with:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Large document libraries&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Heavy collaboration sites&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Long-running project sites&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Migration history&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Large Office files with frequent edits&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Storage pressure&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="7" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Inconsistent site-level version policies&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="8" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Need for tenant-wide governance reporting&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;It can also help organizations that want to move toward automatic trimming but need to understand the impact first.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Permissions and prerequisites&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The tool uses PnP PowerShell and interactive authentication.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Typical prerequisites include:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;PowerShell 5.1 or later&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;PnP.PowerShell&amp;nbsp;3.1.0 or later&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;SharePoint Administrator role&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Entra ID app registration&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Delegated SharePoint permissions&amp;nbsp;required&amp;nbsp;for version policy and report operations&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Important:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Ensure that the account running this tool has site collection admin rights on all sites&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;SPAN data-contrast="auto"&gt;If you need to add your Admin account to all OneDrive and SPO sites, check out&amp;nbsp;this scripts:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;A href="https://github.com/mikelee1313/Add-GroupToSites/blob/main/Add-GroupToSPOSites.ps1" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Add-GroupToSPOSites.ps1&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;A href="https://github.com/mikelee1313/Add-GroupToSites/blob/main/Add-GroupToOneDriveSites.ps1" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Add-GroupToOneDriveSites.ps1&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4&gt;&lt;SPAN data-contrast="auto"&gt;The repository README includes setup details and permission guidance:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;A href="https://github.com/mikelee1313/SPOVersions-ApplicationTools" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;Apply-SPOVersions-Tool README&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;As always, review permissions carefully before using any tenant-wide admin automation.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Safety notes&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Version cleanup can permanently remove version history.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Before creating cleanup jobs:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Run reports first.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Run What-If analysis.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Start with pilot sites.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Review business requirements.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Identify&amp;nbsp;exceptions.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Communicate expected behavior to site owners.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="7" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Keep exported results for audit and planning.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="8" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Avoid opening or&amp;nbsp;modifying&amp;nbsp;report CSV files while report jobs are still running.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The tool is designed to support safe planning, but admins still need to make policy decisions carefully.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Why this belongs in your governance toolkit&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;SharePoint storage management is not just about quota.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Version history touches:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;User recovery expectations&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Records and retention requirements&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Collaboration patterns&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Site lifecycle&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Migration cleanup&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Storage forecasting&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="●" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;●&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="7" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Governance consistency&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559737&amp;quot;:0,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:80,&amp;quot;335559740&amp;quot;:276,&amp;quot;335559991&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If version history is unmanaged, storage growth can feel mysterious. Once you report on it, it becomes something you can plan and control.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;That is the point of this tool: help admins move from guessing to measuring, then from measuring to controlled action.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Final thoughts&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559738&amp;quot;:320,&amp;quot;335559739&amp;quot;:120}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;SharePoint version history is valuable, but it needs governance at scale.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft provides flexible version storage options, including automatic trimming and manual limits.&amp;nbsp;The challenge for admins is understanding what exists today and how much storage could be recovered before applying changes.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Apply-SPOVersions-Tool.ps1&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;helps with that process by combining policy discovery, report generation, What-If analysis, policy application, cleanup jobs, and job&amp;nbsp;monitoring&amp;nbsp;into a single admin workflow.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN data-contrast="auto"&gt;More Information&lt;/SPAN&gt;&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;You can find the tool here:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt; &amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://github.com/mikelee1313/SPOVersions-ApplicationTools" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;SPOVersions-ApplicationTools&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Microsoft's official planning guidance is here:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt; &amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/sharepoint/plan-version-storage" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;Plan version storage for document libraries in SharePoint&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559739&amp;quot;:160}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Suggested Reading for More&amp;nbsp;Information:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt; &amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/sharepoint-automatic-version-history-cleanup-intelligent-versioning/4514011" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;SharePoint Automatic Version History Cleanup (Intelligent Versioning)&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Fri, 04 Sep 2026 18:11:38 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/managing-sharepoint-online-version-history-at-scale-to-recover/ba-p/4553571</guid>
      <dc:creator>mikeleemsft</dc:creator>
      <dc:date>2026-09-04T18:11:38Z</dc:date>
    </item>
    <item>
      <title>AI Just Joined Your Code Reviews: GitHub Copilot Comes to Azure Repos</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/ai-just-joined-your-code-reviews-github-copilot-comes-to-azure/ba-p/4552795</link>
      <description>&lt;H3&gt;&lt;U&gt;Overview&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;Every engineering team runs into the same wall: the code is written, the tests are green, and then the pull request sits, waiting for a human to find time. Review is where good work can queue. GitHub Copilot code review for Azure Repos is currently in limited preview. It can take a first pass at a pull request and return feedback after a few moments, depending on the repository and the size of the change.&lt;/P&gt;
&lt;P&gt;Here is how it works, how to switch it on, what it is genuinely good at, and where you should keep a human firmly in the loop.&lt;/P&gt;
&lt;P&gt;GitHub Copilot acts as an automated reviewer on Azure Repos pull requests. When requested, it posts inline comments and one-click suggested edits before a human reviewer signs off.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Best fit: &lt;/STRONG&gt;Early feedback on correctness, security, maintainability, and testability.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Human review retained: &lt;/STRONG&gt;Domain, architecture, compliance, and required code-owner approvals.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Workflow: &lt;/STRONG&gt;Treat findings like any pull request comment, validate, then fix, discuss, or resolve.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Review jobs run on an Azure Pipelines agent, so nothing is installed on developer machines.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;The one thing to remember&amp;nbsp; &lt;/STRONG&gt;Copilot only &lt;STRONG&gt;comments&lt;/STRONG&gt;. It never approves a pull request and never requests changes, so it cannot satisfy a required reviewer or block a merge on its own. Humans stay in control of the merge button, by design.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;&lt;U&gt;Prerequisites&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;Check these prerequisites before you begin.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Requirement&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Platform &amp;amp; repo&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Azure DevOps Services with an Azure Repos Git repository. TFVC is not supported.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Permissions&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Project Collection Administrator&lt;/STRONG&gt; (org), &lt;STRONG&gt;Project Administrator&lt;/STRONG&gt; (project), and &lt;STRONG&gt;repository owner/administrator&lt;/STRONG&gt; (repo).&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Billing&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;An Azure subscription linked to your organization. Usage is metered through Azure Cost Management. For details, see&amp;nbsp;&lt;A href="https://learn.microsoft.com/en-us/azure/devops/repos/git/copilot-code-reviews?view=azure-devops#billing" target="_blank"&gt;Billing&lt;/A&gt;.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Compute&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;A supported Microsoft-hosted Azure Pipelines agent pool, or a Managed DevOps Pool using the latest Ubuntu Server image. Windows images and self-hosted agent pools are not supported.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Enable Copilot code review&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;Access is layered across three scopes; enable the organization first. Use Enable all at the org or project level to cover everything at once.&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;STRONG&gt;Organization: &lt;/STRONG&gt;Organization settings &amp;gt; Repos &amp;gt; Repositories &amp;gt; &lt;STRONG&gt;Allow repositories in this organization to use Copilot code review&lt;/STRONG&gt; = On.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;STRONG&gt;Project (optional): &lt;/STRONG&gt;Project settings &amp;gt; Repos &amp;gt; Repositories, enable or restrict per project.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;STRONG&gt;Repository: &lt;/STRONG&gt;select the repo &amp;gt; &lt;STRONG&gt;Settings&lt;/STRONG&gt; tab &amp;gt; &lt;STRONG&gt;Enable Copilot code review for pull requests in this repository&lt;/STRONG&gt; = On.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;To verify, open any pull request - &lt;STRONG&gt;GitHub Copilot&lt;/STRONG&gt; should appear in the &lt;STRONG&gt;Reviewers&lt;/STRONG&gt; list.&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Configure reviews&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Default review effort&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table style="height: 172px;"&gt;&lt;tbody&gt;&lt;tr style="height: 38.6667px;"&gt;&lt;td style="height: 38.6667px;"&gt;
&lt;P&gt;&lt;STRONG&gt;Effort&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.6667px;"&gt;
&lt;P&gt;&lt;STRONG&gt;When to use&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 38.6667px;"&gt;
&lt;P&gt;&lt;STRONG&gt;Relative cost&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;STRONG&gt;Lite&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Routine changes, small fixes, docs, low-risk updates.&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Fewer tokens&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 66.6667px;"&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;&lt;STRONG&gt;Balanced&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;Complex, cross-cutting, or security-sensitive changes.&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 66.6667px;"&gt;
&lt;P&gt;More tokens&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;EM&gt;Naming note: you may see Lite/Balanced or Low/Medium/High(not yet released); higher effort costs more.&lt;/EM&gt;&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Automatic reviews &amp;amp; instructions&lt;/U&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Automatic review: &lt;/STRONG&gt;configure a policy at project or repository level to review new pull requests on creation.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Custom instructions: &lt;/STRONG&gt;tailor feedback via .github/copilot-instructions.md or .azuredevops/copilot-instructions.md on the PR's target branch, or org/project settings. &lt;A href="https://docs.github.com/en/copilot/tutorials/customize-code-review" target="_blank"&gt;Using custom instructions to unlock the power of Copilot code review - GitHub Docs&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;U&gt;Request and use a review&lt;/U&gt;&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt; &lt;/STRONG&gt;Next to &lt;STRONG&gt;GitHub Copilot&lt;/STRONG&gt; in Reviewers, select &lt;STRONG&gt;Request&lt;/STRONG&gt; (or pick an effort from the menu).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; &lt;/STRONG&gt;Wait for &lt;STRONG&gt;Review completed&lt;/STRONG&gt;, then validate each comment before acting.&lt;/LI&gt;
&lt;/OL&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Comment-only: &lt;/STRONG&gt;Copilot never approves or requests changes, so it doesn't satisfy required reviewers or block merges.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Interactive: &lt;/STRONG&gt;reply, resolve, or hide comments. Copilot doesn't read replies or follow up.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Re-review / cancel: &lt;/STRONG&gt;it doesn't re-review after new commits, select Request again; an in-progress review can be cancelled. To automatically request re-reviews on every push, enable automatic code review. For more information, see&amp;nbsp;&lt;A href="https://docs.github.com/en/copilot/how-tos/copilot-on-github/set-up-copilot/configure-automatic-review#configuring-automatic-code-review-for-repositories-in-an-organization" target="_blank"&gt;Configuring code review by GitHub Copilot&lt;/A&gt;.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;U&gt;Scope and limits&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;Copilot reviews many languages but skips dependency, log, SVG, and vendor/generated files (package-lock.json, yarn.lock, etc.); admins can exclude more paths. Results depend on the difference, so runtime, architecture, and business rules may be missed; always validate.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Requirement / limit&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Value&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Pull request status&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Active, no merge conflicts&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Repository size / changed files&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;≤ 10 GB / ≤ 100 files&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Concurrent reviews (org / user / PR)&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;5 / 2 / 1&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3&gt;&lt;U&gt;Billing&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;Reviews are token-based (1 GitHub AI credit = US$0.01), charged to the linked Azure subscription as a separate meter in Azure Cost Management, not from Copilot plan credits. Effort, PR size, and instructions drive cost; charges can take 48 hours to appear.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Monitor: &lt;/STRONG&gt;Cost Management &amp;gt; Cost analysis, filter by product; project tags enable per-project reporting.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Budget alerts: &lt;/STRONG&gt;filter to product “GitHub Copilot for AzDO”. Alerts notify only; they don't stop reviews. Pilot on a repo or two to estimate cost before scaling.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;A href="https://docs.github.com/en/copilot/reference/copilot-billing/models-and-pricing" target="_blank"&gt;Github Copilot billing&lt;/A&gt;&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Recommended practices&lt;/U&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Keep pull requests small; retain branch policies and required human reviewers.&lt;/LI&gt;
&lt;LI&gt;Fix valid findings; reply to explain false positives. Keep secrets out of source control.&lt;/LI&gt;
&lt;LI&gt;Encode recurring standards in custom instructions, tests, and linters; choose effort deliberately.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;&lt;U&gt;Troubleshooting&lt;/U&gt;&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Symptom&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Check&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Copilot not offered as reviewer&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Enablement, permissions, linked subscription/billing, repo type, Preview-features opt-in.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Review stalls or fails&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Service health and agent pool; failed runs post a log link. Request again.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;A file wasn't reviewed&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Excluded type, content-exclusion path, or evaluated as low-risk.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Visual walkthrough&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Step-by-step: turn it on&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Enablement is layered across organization, project, and repository settings. Enable the organization first, then decide whether to enable all projects and repositories or configure them selectively.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 1 - Enable at the organization&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Go to Organization settings &amp;gt; Repos &amp;gt; Repositories, and under GitHub Copilot code review turn on Allow repositories in this organization to use Copilot code review. Select the Compute pool that will run the review jobs and, if needed, add organization-wide custom instructions.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Organization settings: the master toggle, Compute pool, and organization-wide review instructions.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 2 - Enable the repository and set the default effort&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In &lt;STRONG&gt;Project settings &amp;gt; Repos &amp;gt; Repositories&lt;/STRONG&gt;, pick the repository, open the &lt;STRONG&gt;Settings&lt;/STRONG&gt; tab, and turn on &lt;STRONG&gt;Enable Copilot code review for pull requests in this repository&lt;/STRONG&gt;. Choose a default effort level - more on that below.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Repository settings: Copilot enabled for pull requests, with its default review effort.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 3 - Request a review on a pull request&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Open any pull request. GitHub Copilot now appears in the Reviewers panel. Select Request, or choose a specific effort from the menu. After the review finishes, the status changes to Review completed. Prefer it hands-off? Configure the policy that requests a Copilot review whenever a new pull request is created.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Copilot listed among the reviewers, with its completed review posted to the timeline.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Step 4 - Review and resolve the findings&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Copilot posts each finding inline on the line it applies to and, where possible, includes a one-click suggested change. Validate each finding, then apply the suggestion, reply, react, or resolve the thread. Copilot does not read replies or follow up, and it does not automatically re-review after new commits, select Request again for a fresh review.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Inline findings on the changed code - each ready to validate, address, discuss, or resolve.&lt;/EM&gt;&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Choosing a review effort&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;The effort level controls the depth of the review and the amount of token usage.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Lite - the default option for fast, targeted feedback on common issues such as bugs, security vulnerabilities, and style inconsistencies.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Balanced - routes the pull request to a higher-reasoning model for longer analysis of complex logic, security-sensitive code, and subtle interactions. It generally consumes more tokens.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;EM&gt;The documented options are Lite and Balanced. Higher effort generally analyzes more context and consumes more tokens; pull request size and custom instructions can also affect usage.&lt;/EM&gt;&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;The honest scorecard&lt;/U&gt;&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;✓&amp;nbsp; Strengths&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;⚠&amp;nbsp; Watch-outs&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Fast first-pass feedback after a few moments, depending on the repository and the number of changes.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Comment-only; it never blocks a merge, so you still need required human reviewers.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Catches common issues such as bugs, security vulnerabilities, and style inconsistencies.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;It is not guaranteed to spot every problem and can make mistakes; always validate its feedback with human review.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Inline comments and, where possible, one-click suggested changes for code in any language.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Excludes dependency, log, SVG, vendor, generated, and other documented file patterns.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Works on demand or automatically on Pull requests.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Consumes tokens; an ongoing cost that scales with effort and PR size.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Tunable with organization, project, and repository-level custom instructions.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Preview: no SLA, may change, and data residency may not match your Azure DevOps boundaries.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;The bottom line&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;Copilot code review is not here to replace your reviewers - and the product behavior makes that clear. It can take the first, more mechanical pass at a pull request so issues surface earlier and people can focus on context, design, and business impact. In a busy repository, that can reduce review friction without giving up human control.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;U&gt;Sources and further reading&lt;/U&gt;&lt;/H3&gt;
&lt;P&gt;Microsoft Learn - Get started with Copilot code review for pull requests (updated August 27, 2026): &lt;A class="lia-external-url" href="https://learn.microsoft.com/en-us/azure/devops/repos/git/copilot-code-reviews?view=azure-devops" target="_blank"&gt;https://learn.microsoft.com/en-us/azure/devops/repos/git/copilot-code-reviews?view=azure-devops&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;GitHub Docs - About GitHub Copilot code review: &lt;A class="lia-external-url" href="https://docs.github.com/en/copilot/concepts/agents/code-review" target="_blank"&gt;https://docs.github.com/en/copilot/concepts/agents/code-review&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;GitHub Docs - Files excluded from GitHub Copilot code review: &lt;A class="lia-external-url" href="https://docs.github.com/en/copilot/reference/review-excluded-files" target="_blank"&gt;https://docs.github.com/en/copilot/reference/review-excluded-files&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 03 Sep 2026 13:31:18 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/ai-just-joined-your-code-reviews-github-copilot-comes-to-azure/ba-p/4552795</guid>
      <dc:creator>Shdsouza</dc:creator>
      <dc:date>2026-09-03T13:31:18Z</dc:date>
    </item>
    <item>
      <title>The new sharing experience is coming to SharePoint Online: What admins need to know</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/the-new-sharing-experience-is-coming-to-sharepoint-online-what/ba-p/4539859</link>
      <description>&lt;P&gt;Microsoft is introducing a new sharing experience for Microsoft 365 that is designed to simplify collaboration and make link-based access easier to manage. At the center of this update is the &lt;STRONG&gt;hero link&lt;/STRONG&gt;: a single sharing link for a file that is reused across common sharing actions such as copying a link, sharing by email, or using the file URL.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Roadmap ID:&lt;/STRONG&gt; &lt;A href="https://www.microsoft.com/en-us/microsoft-365/roadmap?id=492622" target="_blank" rel="noopener"&gt;492622&lt;/A&gt;&lt;BR /&gt;&lt;STRONG&gt;Rollout start:&lt;/STRONG&gt; June 2026&lt;/P&gt;
&lt;P&gt;This post is intended for Microsoft 365 and SharePoint Online administrators who want to understand what is changing in the new sharing experience, how the interface differs from the current experience, and how to prepare end users as rollout continues.&lt;/P&gt;
&lt;H2&gt;Meet the hero link&lt;/H2&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;Hero sharing visual&lt;/img&gt;
&lt;P&gt;The hero link is the core change in the new sharing model. Each file uses a single sharing link that controls access, whether a user selects&amp;nbsp;&lt;STRONG&gt;Copy link&lt;/STRONG&gt;, shares by email, or copies the file URL from the browser.&lt;/P&gt;
&lt;P&gt;This reduces the need to create and manage multiple links for the same item and makes sharing behavior more consistent.&lt;/P&gt;
&lt;H2&gt;What changes in the sharing interface&lt;/H2&gt;
&lt;P&gt;The screenshots below highlight some of the most noticeable differences between the classic sharing experience and the new sharing experience. They are intended to help admins and support teams quickly understand where familiar actions have moved and how behavior changes in the new model.&lt;/P&gt;
&lt;H3&gt;Sharing UI&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Classic sharing experience:&lt;/STRONG&gt; More settings are exposed up front, which gives flexibility but can feel busier and harder to scan.&lt;/P&gt;
&lt;img&gt;Classic SharePoint Online sharing UI&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;New sharing experience:&lt;/STRONG&gt; The experience is simpler and more guided, helping users share faster with less decision friction.&lt;/P&gt;
&lt;img&gt;New sharing UI&lt;/img&gt;
&lt;H3&gt;Sharing settings&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Classic sharing experience:&lt;/STRONG&gt; Link options and permission settings can feel more fragmented, requiring users to interpret multiple choices.&lt;/P&gt;
&lt;img&gt;Classic link settings&lt;/img&gt;
&lt;P&gt;&lt;STRONG&gt;New sharing experience:&lt;/STRONG&gt;&amp;nbsp;Settings are more streamlined around the hero link, making access management easier to understand and reuse.&lt;/P&gt;
&lt;img&gt;New link settings&lt;/img&gt;
&lt;H3&gt;Link scope&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Classic sharing experience:&lt;/STRONG&gt; Classic sharing relies more on separate link choices and less flexible scope adjustments.&lt;/P&gt;
&lt;img&gt;Classic link scope options&lt;/img&gt;
&lt;P&gt;&lt;STRONG&gt;New sharing experience:&lt;/STRONG&gt; The new link scope experience lets users change permission scope while continuing to use the same link, making sharing more flexible without creating separate links.&lt;/P&gt;
&lt;img&gt;New link scope options&lt;/img&gt;
&lt;H3&gt;Expiration links&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Classic sharing experience:&lt;/STRONG&gt; Creating links with expiration dates is built into the main link settings, so users can configure expiration as part of the standard sharing flow.&lt;/P&gt;
&lt;img&gt;Classic expiration link settings&lt;/img&gt;
&lt;P&gt;&lt;STRONG&gt;New sharing experience:&lt;/STRONG&gt; Creating expiration links is not yet fully incorporated into the main flow. Users must click the gear icon and choose &lt;STRONG&gt;Create new sharing link&lt;/STRONG&gt; to create a link with expiration settings.&lt;/P&gt;
&lt;img&gt;Menu option to access new link settings&lt;/img&gt;&lt;img&gt;New expiration link settings&lt;/img&gt;
&lt;H3&gt;Stop sharing&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Classic sharing experience:&lt;/STRONG&gt; Stop sharing is accessed from &lt;STRONG&gt;Manage Access&lt;/STRONG&gt;. Stopping sharing removes all unique permissions from the item and causes it to inherit permissions from the top-level object again.&lt;/P&gt;
&lt;img&gt;Classic stop sharing options&lt;/img&gt;
&lt;P&gt;&lt;STRONG&gt;New sharing experience:&lt;/STRONG&gt; Stop sharing is accessed from &lt;STRONG&gt;Sharing settings&lt;/STRONG&gt;. Stopping sharing removes all access from the item and leaves only the Owners group in the permission list for that object.&lt;/P&gt;
&lt;img&gt;New stop sharing options&lt;/img&gt;
&lt;H3&gt;Manage Access&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Classic sharing experience:&lt;/STRONG&gt; Manage Access separates sharing details into different tabs for People, Groups, and Links. From there, users can review existing access, remove members or links, and open advanced settings for deeper permission management.&lt;/P&gt;
&lt;img&gt;Classic Manage Access experience&lt;/img&gt;
&lt;P&gt;&lt;STRONG&gt;New sharing experience:&lt;/STRONG&gt; Manage Access is a single unified view where users can see people, groups, and links together. This makes it easier to add or remove access without switching between separate tabs, and advanced settings are available from the gear icon.&lt;/P&gt;
&lt;img&gt;New Manage Access experience&lt;/img&gt;
&lt;H3&gt;Advanced settings&lt;/H3&gt;
&lt;P&gt;&lt;STRONG&gt;Classic sharing experience:&lt;/STRONG&gt; Advanced settings are reached from Manage Access by clicking the More options button.&lt;/P&gt;
&lt;img&gt;Classic advanced settings&lt;/img&gt;
&lt;P&gt;&lt;STRONG&gt;New sharing experience:&lt;/STRONG&gt; Advanced settings are available from the main sharing link properties by clicking the gear icon.&lt;/P&gt;
&lt;img&gt;New advanced settings&lt;/img&gt;
&lt;H2&gt;Key takeaways for end users&lt;/H2&gt;
&lt;P&gt;For end users, the main change is not what sharing can do, but how sharing is presented and managed.&lt;/P&gt;
&lt;P&gt;The new experience is built around a single reusable sharing link, so actions such as &lt;STRONG&gt;Copy link&lt;/STRONG&gt;, sharing by email, and using the file URL are more consistent than before. Users will also notice that some familiar actions have moved. Manage Access is now a unified view, advanced settings are accessed from the gear icon, and tasks such as creating expiration links follow a slightly different flow than they do in the classic experience.&lt;/P&gt;
&lt;P&gt;The result is a simpler interface that may require a short adjustment period for users who are familiar with the classic layout.&lt;/P&gt;
&lt;H2&gt;First-run experience&lt;/H2&gt;
&lt;P&gt;To help users adjust to the new sharing model, Microsoft has added a first-run experience that appears the first time a user opens the Share dialog. It introduces the main parts of the new experience and explains how the hero link works.&lt;/P&gt;
&lt;P&gt;The first-run experience guides users through the core components of the dialog and helps them learn how to get the most out of the hero link.&lt;/P&gt;
&lt;P&gt;If users want a refresher later, they can click the ellipsis and select &lt;STRONG&gt;View tutorial&lt;/STRONG&gt; to launch the walkthrough again.&lt;/P&gt;
&lt;img&gt;First-run experience View tutorial option&lt;/img&gt;&lt;img&gt;First-run experience tutorial walkthrough&lt;/img&gt;
&lt;H2&gt;Customer communications&lt;/H2&gt;
&lt;P&gt;Before rollout reaches your tenant, admins should review the updated sharing flow, validate internal help content, brief support teams on where key controls have moved, and prepare a short user communication for frequent sharers and site owners.&lt;/P&gt;
&lt;P&gt;Here is a sample communication you can adapt for your organization:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Hello team,&lt;/P&gt;
&lt;P&gt;We want to let you know about an upcoming update to the SharePoint Online and OneDrive sharing experience. This update introduces a simpler sharing experience centered around a single sharing link for each file, helping make sharing more consistent and easier to manage. Existing links and permissions will continue to work, so no action is required for files that have already been shared.&lt;/P&gt;
&lt;P&gt;As part of this change, some sharing options will appear in different places than they do today. For example, users may notice updates to Sharing settings, Manage Access, Stop sharing, and how expiration links are created. The overall goal is to simplify the experience, reduce link sprawl, and make access management easier to understand.&lt;/P&gt;
&lt;P&gt;Before this reaches our tenant, we recommend that site owners, frequent content sharers, and support staff review the updated experience so they are familiar with the new layout and behavior. We will share more guidance and screenshots before rollout is complete.&lt;/P&gt;
&lt;P&gt;If you have questions after the new experience appears, please contact your SharePoint or Microsoft 365 support team.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;More information&lt;/H2&gt;
&lt;P&gt;This new experience was demonstrated during the SharePoint 25th Birthday event. You can watch the full event playlist here: &lt;A href="https://www.youtube.com/playlist?list=PLR9nK3mnD-OVYITAJebVCcvE_LLKVLYNY" target="_blank" rel="noopener"&gt;SharePoint at 25 | Birthday Celebration Event&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;You can also read the Product Group blog post: &lt;A href="https://techcommunity.microsoft.com/blog/onedriveblog/simple-smart-and-secure-the-next-step-in-sharing-files-in-microsoft-365/4411655" target="_blank" rel="noopener"&gt;Simple, Smart, and Secure: The next step in sharing files in Microsoft 365&lt;/A&gt;.&lt;/P&gt;
&lt;H2&gt;Known issues and current limitations&lt;/H2&gt;
&lt;P&gt;Word, Excel, and PowerPoint apps on Mac currently use an older version of the Share dialog and therefore do not yet have the new experience. This is expected to roll out shortly.&lt;/P&gt;
&lt;H2&gt;FAQ&lt;/H2&gt;
&lt;H3&gt;What’s changing with sharing?&lt;/H3&gt;
&lt;P&gt;SharePoint Online and OneDrive are moving to a single canonical sharing link per file or folder. Whether a user selects &lt;STRONG&gt;Copy link&lt;/STRONG&gt;, shares by email, or copies the file URL, the same link is reused instead of creating multiple separate links for the same item.&lt;/P&gt;
&lt;H3&gt;What problem does it solve?&lt;/H3&gt;
&lt;P&gt;Today, sharing can create a different URL almost every time. The new model replaces that sprawl with one stable link per item, so links embedded in emails, chats, and documents stop breaking when you adjust who has access.&lt;/P&gt;
&lt;H3&gt;How does the new sharing link change my governance model?&lt;/H3&gt;
&lt;P&gt;There is less link sprawl to govern. One canonical link per item replaces multiple parallel links with independent lifecycles. Policy, audit, and lifecycle decisions now attach to a single object per file or folder instead of a fan-out of link variants.&lt;/P&gt;
&lt;H3&gt;Will any existing links or permissions break during rollout?&lt;/H3&gt;
&lt;P&gt;No. Existing sharing links and permissions will continue to work during rollout, so users do not need to reshare content or recreate access that is already in place.&lt;/P&gt;
&lt;H3&gt;What if a link leaks?&lt;/H3&gt;
&lt;P&gt;You can invalidate it. The old URL stops working, and a new sharing link is issued for the file. Direct permissions on the item are not touched; only the link is rotated.&lt;/P&gt;
&lt;H3&gt;How does this interact with information barriers?&lt;/H3&gt;
&lt;P&gt;Information barriers continue to prevent sharing across segmented groups. The new sharing link cannot be used to grant access in violation of an information barrier policy.&lt;/P&gt;
&lt;H3&gt;Why does the new sharing link matter for Copilot?&lt;/H3&gt;
&lt;P&gt;Copilot grounds its answers in content that a user already has access to. The more intentional your sharing posture is, the easier it is to understand who can access what content and the lower the risk of oversharing.&lt;/P&gt;
&lt;P&gt;By reducing link sprawl and consolidating sharing around a single canonical link per item, the new model gives admins a clearer view of access that supports Copilot readiness.&lt;/P&gt;
&lt;H3&gt;Does the new sharing link reduce oversharing risk for Copilot?&lt;/H3&gt;
&lt;P&gt;Indirectly, yes. Today, multiple parallel links per item with independent lifecycles make it hard to see and remediate oversharing. One canonical link with explicit scope and re-share controls makes over-permissioning easier to detect and clean up before turning on Copilot more broadly.&lt;/P&gt;
&lt;H2&gt;Final takeaway&lt;/H2&gt;
&lt;P&gt;The new sharing experience simplifies how links are created, reused, and governed in SharePoint Online and OneDrive. For admins, the main preparation work is straightforward: understand the hero link model, review the UI differences called out in this post, and proactively communicate the changes to users before rollout reaches your tenant.&lt;/P&gt;
&lt;P&gt;Existing links and permissions continue to work, but the user experience will change enough that a short readiness plan is worth putting in place now.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Document Contributors: Mike Lee | Mariel Williams&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 04 Sep 2026 18:12:24 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/the-new-sharing-experience-is-coming-to-sharepoint-online-what/ba-p/4539859</guid>
      <dc:creator>mikeleemsft</dc:creator>
      <dc:date>2026-09-04T18:12:24Z</dc:date>
    </item>
    <item>
      <title>Your on-call rotation has a new member: 10 production incidents, end to end, with Azure SRE Agent</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/your-on-call-rotation-has-a-new-member-10-production-incidents/ba-p/4545187</link>
      <description>&lt;DIV class="mce-toc"&gt;
&lt;H2&gt;Table of Contents&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_1" target="_self"&gt;TL;DR&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_2" target="_self"&gt;1. Why the "investigation" half is the real prize&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_3" target="_self"&gt;2. What Azure SRE Agent actually does&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_4" target="_self"&gt;The three primary use cases&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_5" target="_self"&gt;The five extension primitives&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_6" target="_self"&gt;Integrations you can assume&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_7" target="_self"&gt;Skills vs. custom agents vs. knowledge files&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_8" target="_self"&gt;3. Anatomy of an agent-run incident&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_9" target="_self"&gt;4. Build the demo lab&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_10" target="_self"&gt;4.1 Resource group and agent&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_11" target="_self"&gt;4.2 Choose a permission level deliberately&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_12" target="_self"&gt;4.3 Connect ServiceNow&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_13" target="_self"&gt;4.4 Connect deployment correlation&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_14" target="_self"&gt;4.5 Create the demo resources&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_15" target="_self"&gt;4.6 One custom agent per domain&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_16" target="_self"&gt;4.7 Response plans&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_17" target="_self"&gt;5. Set your guardrails before your first incident&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_18" target="_self"&gt;5.1 Run modes&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_19" target="_self"&gt;5.2 What the product blocks for you&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_20" target="_self"&gt;5.3 Hooks: the guardrail you write yourself&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_21" target="_self"&gt;5.4 The recommended production policy&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_22" target="_self"&gt;6. The ten use cases&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_23" target="_self"&gt;Use case #1 — App Service: HTTP 500 after deployment&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_24" target="_self"&gt;Use case #2 — AKS: pods in CrashLoopBackOff&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_25" target="_self"&gt;Use case #3 — Azure SQL Database: CPU saturation and timeouts&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_26" target="_self"&gt;Use case #4 — Azure Cosmos DB: HTTP 429 throttling&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_27" target="_self"&gt;Use case #5 — Azure VM: OS/root disk full&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_28" target="_self"&gt;Use case #6 — Linux VM: anomalous CPU saturation&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_29" target="_self"&gt;Use case #7 — Windows VM with IIS: memory leak&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_30" target="_self"&gt;Use case #8 — Virtual Machine Scale Set: unhealthy instance&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_31" target="_self"&gt;Use case #9 — Application Gateway: HTTP 502 from unhealthy backends&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_32" target="_self"&gt;Use case #10 — Azure Service Bus: queue and dead-letter backlog&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_33" target="_self"&gt;7. The ITSM integration model&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_34" target="_self"&gt;Recommended incident fields&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_35" target="_self"&gt;Recommended agent-generated timeline&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_36" target="_self"&gt;Deduplication strategy&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_37" target="_self"&gt;Record responsibilities&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_38" target="_self"&gt;8. Reality check: where you have to build&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_39" target="_self"&gt;9. Approval and autonomy policy&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_40" target="_self"&gt;10. Cross-cutting security controls&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_41" target="_self"&gt;What the platform gives you for free&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_42" target="_self"&gt;The audit trail&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_43" target="_self"&gt;11. A 30/60/90 pilot that survives contact with your CAB&lt;/A&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_44" target="_self"&gt;The best first five candidates&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_45" target="_self"&gt;What to measure in week one&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_46" target="_self"&gt;12. Measuring whether it's actually working&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_47" target="_self"&gt;13. Resources&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-mcetoc_blog_48" target="_self"&gt;Closing&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/DIV&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;What this post is.&lt;/STRONG&gt; A hands-on, reproducible walkthrough of ten real production failure modes — App Service, AKS, Azure SQL, Cosmos DB, VMs, VM Scale Sets, Application Gateway, and Service Bus — each one driven end to end by Azure SRE Agent: detection, hypothesis-driven investigation, ITSM ticketing, bounded remediation, recovery validation, and follow-up records.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What this post is not.&lt;/STRONG&gt; A claim that you install SRE Agent and all of this happens on day one. Every workflow below needs telemetry, scoped RBAC, a response plan, an approved action surface, and an ITSM integration. I'll be explicit about which parts are documented product behavior and which parts you have to wire yourself — because that distinction is the difference between a demo that works on stage and one that works at 3 AM.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_1"&gt;TL;DR&lt;/H2&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;The pattern&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Alert → agent investigates read-only → agent opens/updates the ticket with evidence → agent proposes a &lt;STRONG&gt;bounded&lt;/STRONG&gt; action → human approves → agent executes → agent validates recovery → agent files the follow-up record&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;The unlock&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Not "AI fixes prod." The unlock is that &lt;EM&gt;investigation&lt;/EM&gt; — the 20 minutes of tab-switching between Azure Monitor, App Insights, deployment history, and Activity Log — is fully automated and consistent, and the fix arrives pre-justified with an evidence chain&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;The guardrail&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Read-only automatic. Ticketing automatic. Production writes in &lt;STRONG&gt;Review&lt;/STRONG&gt; mode. Guest-OS work through fixed-purpose runbooks, never a shell prompt&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;The reality check&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;SRE Agent hard-blocks &lt;CODE&gt;delete&lt;/CODE&gt;/&lt;CODE&gt;remove&lt;/CODE&gt; and all &lt;CODE&gt;az keyvault&lt;/CODE&gt; commands, respects Azure management locks, and only one incident platform can be active at a time. Several patterns in this post need a custom tool or MCP server to complete the loop&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Time to first value&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;One resource group, one alert rule, one response plan. You can reproduce use case #1 in an afternoon&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_2"&gt;1. Why the "investigation" half is the real prize&lt;/H2&gt;
&lt;P&gt;Every conversation about AI in operations goes straight to remediation. "Will it restart my app?" That's the least interesting question, and it's the one with the most downside risk.&lt;/P&gt;
&lt;P&gt;Think about what actually consumes the minutes during a Sev1. The alert fires. Someone acknowledges. Then:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Open Azure Monitor, confirm the metric is real and not a probe artifact&lt;/LI&gt;
&lt;LI&gt;Open Application Insights, find the dominant exception&lt;/LI&gt;
&lt;LI&gt;Open the deployment pipeline, find what shipped and when&lt;/LI&gt;
&lt;LI&gt;Open Activity Log, check whether someone changed configuration&lt;/LI&gt;
&lt;LI&gt;Open Resource Health, rule out a platform incident&lt;/LI&gt;
&lt;LI&gt;Open the &lt;EM&gt;other&lt;/EM&gt; environment, confirm the previous version is healthy&lt;/LI&gt;
&lt;LI&gt;Assemble all of that into a sentence a human can act on&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;That's twenty minutes of context assembly performed by a tired human, differently every time, with quality that depends entirely on who happens to be on call. It is the single most automatable part of incident response and the part nobody automates, because scripts can't reason about which of six hypotheses fits the evidence.&lt;/P&gt;
&lt;P&gt;This is exactly what &lt;A href="https://learn.microsoft.com/azure/sre-agent/root-cause-analysis" target="_blank" rel="noopener"&gt;root cause analysis in SRE Agent&lt;/A&gt; is designed for. The agent doesn't grep logs — it forms hypotheses and invalidates them:&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;HYPOTHESIS 1: Recent deployment broke something ├─ Checked: Last deployment was 3 days ago ├─ Evidence: Error rate stable until 30 minutes ago └─ Result: INVALIDATED HYPOTHESIS 2: Database overloaded ├─ Checked: Azure SQL metrics (CPU, DTU, connections) ├─ Evidence: DTU at 98%, query duration 4x normal ├─ Traced: SELECT * FROM orders WHERE... taking 8.2s └─ Result: VALIDATED ROOT CAUSE: Orders table missing index on customer_id column. Query plan shows full table scan on 2.1M rows. RECOMMENDED ACTION: Add index on orders.customer_id Similar fix applied in INC-2341 (3 weeks ago)&lt;/LI-CODE&gt;
&lt;P&gt;That last line — recalling a similar incident from three weeks ago — is the compounding part. Every thread produces a &lt;A href="https://learn.microsoft.com/azure/sre-agent/memory" target="_blank" rel="noopener"&gt;session insight&lt;/A&gt;: symptoms observed, steps that worked, root cause, and pitfalls to avoid. Thirty minutes after a thread goes quiet, the agent indexes those learnings. Next time the same resource misbehaves, that history surfaces first.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;So the framing for the rest of this post:&lt;/STRONG&gt; remediation is the punchline, but investigation is the product. Every one of the ten use cases below has a large read-only phase you can turn on tomorrow with zero write permissions, and a small write phase you should gate behind approval for a long time.&lt;/P&gt;
&lt;HR /&gt;&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 id="mcetoc_blog_3"&gt;2. What Azure SRE Agent actually does&lt;/H2&gt;
&lt;P&gt;Before the use cases, here is the honest capability map, drawn from the product documentation rather than from a keynote.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_4"&gt;The three primary use cases&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Use case&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;What it means&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Automate incidents&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Alert fires → agent queries monitoring tools, correlates signals across systems, identifies probable root cause, proposes mitigations&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Automate scheduled workflows&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Proactive health checks, compliance sweeps, and routine tasks on a schedule, with results routed to your incident platform or notification channel&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Investigate and advise&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Natural-language questions — "what changed in the last hour?" — answered with grounded citations&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H3 id="mcetoc_blog_5"&gt;The five extension primitives&lt;/H3&gt;
&lt;P&gt;Everything you customize sits in one of five buckets:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Primitive&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;What it is&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;When you reach for it&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Skills&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Procedural guidance (&lt;CODE&gt;SKILL.md&lt;/CODE&gt;) plus optional attached tools; auto-loaded when relevant&lt;/td&gt;&lt;td&gt;Team troubleshooting runbooks that should also &lt;EM&gt;execute&lt;/EM&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Subagents / custom agents&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Purpose-built specialists invoked via &lt;CODE&gt;/agent&lt;/CODE&gt; or routed to by a response plan&lt;/td&gt;&lt;td&gt;A &lt;CODE&gt;DatabaseExpert&lt;/CODE&gt; that owns every SQL incident&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Python tools&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Custom logic, transformations, API calls&lt;/td&gt;&lt;td&gt;Anything that needs code, e.g. writing to the ServiceNow Table API&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;MCP servers&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;40+ managed connectors (Datadog, New Relic, Splunk, Elastic, Dynatrace…) plus any custom MCP tool&lt;/td&gt;&lt;td&gt;Bringing your non-Azure telemetry and your ITSM write surface into the loop&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Agent hooks&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Event-triggered automations at &lt;CODE&gt;Stop&lt;/CODE&gt; and &lt;CODE&gt;PostToolUse&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Policy enforcement, audit emission, blocking risky commands&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Six generic subagents ship built in — &lt;STRONG&gt;Explore, Plan, CodeReview, Bash, Verification, GeneralPurpose&lt;/STRONG&gt; — and the agent can parallelize investigation, planning, review, shell, and verification work across them.&lt;/P&gt;
&lt;P&gt;A &lt;STRONG&gt;permission gate&lt;/STRONG&gt; sits in front of all five primitives and evaluates every proposed tool call &lt;EM&gt;before&lt;/EM&gt; it runs.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_6"&gt;Integrations you can assume&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Category&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Supported&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Monitoring&lt;/td&gt;&lt;td&gt;Azure Monitor (metrics, logs, alerts, workbooks), Application Insights, Log Analytics, Grafana&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Incident platforms&lt;/td&gt;&lt;td&gt;Azure Monitor Alerts, PagerDuty, ServiceNow — &lt;STRONG&gt;only one active at a time&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Source control / CI&lt;/td&gt;&lt;td&gt;GitHub (repos, issues), Azure DevOps (repos, work items)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Data&lt;/td&gt;&lt;td&gt;Azure Data Explorer (Kusto), MCP servers&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Comms&lt;/td&gt;&lt;td&gt;Slack, Microsoft Teams&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;⚠️ &lt;STRONG&gt;Design constraint worth internalizing early.&lt;/STRONG&gt; Only one incident platform can be active at a time, and switching disconnects the current one. If your org runs PagerDuty for paging &lt;EM&gt;and&lt;/EM&gt; ServiceNow for records of truth, you must pick which one the agent is bound to and reach the other through a connector or custom tool. Every use case below assumes &lt;STRONG&gt;ServiceNow is the bound platform&lt;/STRONG&gt;.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="mcetoc_blog_7"&gt;Skills vs. custom agents vs. knowledge files&lt;/H3&gt;
&lt;P&gt;The three are constantly confused. This table settles it:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Skills&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Custom agents&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Knowledge files&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Access&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Automatic when relevant&lt;/td&gt;&lt;td&gt;Explicit (&lt;CODE&gt;/agent&lt;/CODE&gt;) or routed by response plan&lt;/td&gt;&lt;td&gt;Automatic search&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Tools&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Can attach&lt;/td&gt;&lt;td&gt;Has its own&lt;/td&gt;&lt;td&gt;None&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Context&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Uses thread context&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Shares&lt;/STRONG&gt; thread context (no clean slate)&lt;/td&gt;&lt;td&gt;Reference only&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Best for&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Team procedures with execution&lt;/td&gt;&lt;td&gt;Domain specialists&lt;/td&gt;&lt;td&gt;Runbooks, architecture docs&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Practical limits: a maximum of &lt;STRONG&gt;five concurrent active skills&lt;/STRONG&gt; (oldest auto-unloads), knowledge base uploads up to &lt;STRONG&gt;16 MB per file&lt;/STRONG&gt;, and custom agent knowledge bases up to &lt;STRONG&gt;1,000 files&lt;/STRONG&gt;.&lt;/P&gt;
&lt;HR /&gt;&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 id="mcetoc_blog_8"&gt;3. Anatomy of an agent-run incident&lt;/H2&gt;
&lt;P&gt;Every use case in section 6 is an instance of this one shape. Learn it once.&lt;/P&gt;
&lt;P&gt;[[INCIDENT_FLOW_IMAGE]]&lt;/P&gt;
&lt;P&gt;Five properties make this shape safe, and they're worth stating as rules:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;The read phase has no blast radius.&lt;/STRONG&gt; Turn it on everywhere, immediately, with &lt;CODE&gt;Reader&lt;/CODE&gt;.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;One action per incident.&lt;/STRONG&gt; Not "roll back and scale and restart." One bounded, reversible step, then re-measure.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;The proposed action is always the smallest reversible one.&lt;/STRONG&gt; Swap a slot, don't redeploy. Bump one service tier, don't resize the cluster.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Validation is a first-class phase, not a vibe.&lt;/STRONG&gt; Define the metric, the threshold, and the duration before you approve.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Technical recovery ≠ business recovery.&lt;/STRONG&gt; Use case #10 makes this painfully clear.&lt;/LI&gt;
&lt;/OL&gt;
&lt;HR /&gt;&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;H2 id="mcetoc_blog_9"&gt;4. Build the demo lab&lt;/H2&gt;
&lt;P&gt;Everything below runs in a single throwaway resource group. Nothing here should touch a subscription you care about.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;🧪 &lt;STRONG&gt;Lab hygiene.&lt;/STRONG&gt; Create it, demo it, delete it. &lt;CODE&gt;az group delete -n rg-sre-agent-demo --yes --no-wait&lt;/CODE&gt; when you're done. Several of these use cases deliberately break things.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="mcetoc_blog_10"&gt;4.1 Resource group and agent&lt;/H3&gt;
&lt;LI-CODE lang="bash"&gt;LOC=eastus2 RG=rg-sre-agent-demo az group create -n $RG -l $LOC&lt;/LI-CODE&gt;
&lt;P&gt;Create the SRE Agent from the Azure portal and point it at &lt;CODE&gt;$RG&lt;/CODE&gt;. Three things are created for you automatically:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;an &lt;STRONG&gt;Application Insights&lt;/STRONG&gt; instance (this is where your audit trail lands),&lt;/LI&gt;
&lt;LI&gt;a &lt;STRONG&gt;Log Analytics workspace&lt;/STRONG&gt;,&lt;/LI&gt;
&lt;LI&gt;a &lt;STRONG&gt;user-assigned managed identity (UAMI)&lt;/STRONG&gt; — the identity every action runs as.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="mcetoc_blog_11"&gt;4.2 Choose a permission level deliberately&lt;/H3&gt;
&lt;P&gt;At creation you pick one of two levels:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Level&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Grants&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Use it when&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Reader&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Core monitoring roles + resource-type reader roles. Prompts for temporary elevation via on-behalf-of when it needs to act&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Start here.&lt;/STRONG&gt; Production. Weeks 1–4 of any pilot&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Privileged&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Core monitoring roles + resource-type &lt;STRONG&gt;contributor&lt;/STRONG&gt; roles&lt;/td&gt;&lt;td&gt;Non-production, or after a proven pilot&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Regardless of level, these are always assigned:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Role&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Scope&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Why&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Reader&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Resource group&lt;/td&gt;&lt;td&gt;See resources and properties&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Log Analytics Reader&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Resource group&lt;/td&gt;&lt;td&gt;Query logs and workspaces&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Monitoring Reader&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Resource group&lt;/td&gt;&lt;td&gt;Read metrics&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Monitoring Contributor&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Subscription&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Acknowledge and close Azure Monitor alerts&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Grant additional access explicitly and narrowly:&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;SUB=$(az account show --query id -o tsv) AGENT_MI=&amp;lt;agent-managed-identity-principal-id&amp;gt; # Read everywhere you want visibility az role assignment create \ --assignee $AGENT_MI \ --role "Reader" \ --scope "/subscriptions/$SUB" # Write ONLY where you intend the agent to act az role assignment create \ --assignee $AGENT_MI \ --role "Website Contributor" \ --scope "/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.Web/sites/app-checkout-demo"&amp;lt;/agent-managed-identity-principal-id&amp;gt;&lt;/LI-CODE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;📌 &lt;STRONG&gt;A sharp edge.&lt;/STRONG&gt; You can't remove individual permissions from an agent — only entire resource groups. Removing a resource group from the agent's scope revokes all access to it. Plan your resource group boundaries as your &lt;EM&gt;blast-radius&lt;/EM&gt; boundaries, because that's exactly what they are.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="mcetoc_blog_12"&gt;4.3 Connect ServiceNow&lt;/H3&gt;
&lt;P&gt;Use a &lt;STRONG&gt;dedicated, least-privileged integration user&lt;/STRONG&gt; — not a shared admin account.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Method&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;When&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;What you need&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Basic auth&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Quick setup, PDI, testing&lt;/td&gt;&lt;td&gt;Username + password, &lt;CODE&gt;itil&lt;/CODE&gt; or &lt;CODE&gt;admin&lt;/CODE&gt; role&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;OAuth 2.0&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Production&lt;/td&gt;&lt;td&gt;ServiceNow OAuth app (client ID + secret); register redirect &lt;CODE&gt;https://logic-apis-{region}.consent.azure-apim.net/redirect&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Scope the connection so you don't drown:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Assignment group&lt;/STRONG&gt; — essential on a shared enterprise instance&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Priority&lt;/STRONG&gt; — Critical through Planning&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Category&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Scanner defaults worth knowing:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Setting&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Value&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Scan interval&lt;/td&gt;&lt;td&gt;1 minute&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Incidents per page&lt;/td&gt;&lt;td&gt;20&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Max incidents per cycle&lt;/td&gt;&lt;td&gt;220 (11 pages)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Initial lookback&lt;/td&gt;&lt;td&gt;30 days&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Setup performs a &lt;STRONG&gt;real connectivity check&lt;/STRONG&gt; by fetching an actual incident, so credential and endpoint mistakes surface immediately instead of six hours later when nothing syncs.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;🚨 &lt;STRONG&gt;Delete the quickstart plan.&lt;/STRONG&gt; Connecting an incident platform auto-creates a &lt;CODE&gt;quickstart_handler&lt;/CODE&gt; response plan that runs in &lt;STRONG&gt;fully autonomous&lt;/STRONG&gt; mode across all impacted services. If you then build your own plans, incidents get routed twice or to the wrong agent. Go to &lt;STRONG&gt;Builder → Incident response plans → Table view&lt;/STRONG&gt; and delete it before you do anything else.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="mcetoc_blog_13"&gt;4.4 Connect deployment correlation&lt;/H3&gt;
&lt;P&gt;Half the use cases below hinge on "what shipped three minutes before the spike." That correlation requires a source control connector:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;GitHub&lt;/STRONG&gt; — repositories and issues&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Azure DevOps&lt;/STRONG&gt; — repos and work items&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Connect one. Without it, the agent can still read Azure Activity Log and deployment history, but it can't reach commits, PRs, or work items.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_14"&gt;4.5 Create the demo resources&lt;/H3&gt;
&lt;LI-CODE lang="bash"&gt;# 1 · App Service with a staging slot (use cases 1) az appservice plan create -g $RG -n plan-demo --sku P1V3 --is-linux az webapp create -g $RG -p plan-demo -n app-checkout-demo --runtime "DOTNETCORE:8.0" az webapp deployment slot create -g $RG -n app-checkout-demo --slot previous # 2 · AKS (use case 2) az aks create -g $RG -n aks-demo --node-count 3 --generate-ssh-keys --enable-addons monitoring # 3 · Azure SQL (use case 3) az sql server create -g $RG -n sqlsrv-sre-demo -u sqladmin -p "&amp;lt;use-a-generated-password&amp;gt;" az sql db create -g $RG -s sqlsrv-sre-demo -n db-customer --service-objective S1 # 4 · Cosmos DB (use case 4) az cosmosdb create -g $RG -n cosmos-sre-demo az cosmosdb sql database create -g $RG -a cosmos-sre-demo -n catalog az cosmosdb sql container create -g $RG -a cosmos-sre-demo -d catalog \ -n products --partition-key-path /category --throughput 400 # 5–7 · VMs (use cases 5, 6, 7) az vm create -g $RG -n vm-payments-linux --image Ubuntu2204 --size Standard_B2s --generate-ssh-keys az vm create -g $RG -n vm-claims-win --image Win2022Datacenter --size Standard_B2ms \ --admin-username azureadmin --admin-password "&amp;lt;use-a-generated-password&amp;gt;" # 8 · VM Scale Set (use case 8) az vmss create -g $RG -n vmss-api-demo --image Ubuntu2204 --instance-count 12 \ --upgrade-policy-mode automatic --generate-ssh-keys # 10 · Service Bus (use case 10) az servicebus namespace create -g $RG -n sb-sre-demo --sku Standard az servicebus queue create -g $RG --namespace-name sb-sre-demo -n order-events \ --enable-dead-lettering-on-message-expiration true&amp;lt;/use-a-generated-password&amp;gt;&amp;lt;/use-a-generated-password&amp;gt;&lt;/LI-CODE&gt;
&lt;P&gt;Install the &lt;STRONG&gt;Azure Monitor Agent&lt;/STRONG&gt; on the VMs and associate a data collection rule — without guest telemetry, use cases 5, 6, and 7 have nothing to detect.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_15"&gt;4.6 One custom agent per domain&lt;/H3&gt;
&lt;P&gt;Don't build a single mega-agent. Build specialists and let response plans route to them:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Custom agent&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Owns&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Attached tools&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;DeploymentAnalyzer&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;App Service, AKS, anything release-correlated&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;RunAzCliReadCommands&lt;/CODE&gt;, GitHub connector, Kusto&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;DatabaseExpert&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Azure SQL, Cosmos DB&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;RunAzCliReadCommands&lt;/CODE&gt;, Kusto, read-only SQL diagnostics tool&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;GuestOSResponder&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;VM / VMSS / IIS&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;RunAzCliReadCommands&lt;/CODE&gt;, &lt;STRONG&gt;fixed-purpose runbook tools only&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;NetworkPathExpert&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Application Gateway, NSG, DNS, TLS&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;RunAzCliReadCommands&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;IntegrationExpert&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Service Bus, Event Hubs&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;RunAzCliReadCommands&lt;/CODE&gt;, Kusto&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;A custom agent definition is small:&lt;/P&gt;
&lt;LI-CODE lang="yaml"&gt;name: database_expert system_prompt: | You are a database specialist for this estate. Analyze query performance, diagnose connection and saturation issues, and recommend the smallest reversible mitigation. Never propose schema changes, index changes, plan forcing, or session termination — those are DBA-owned and require a change record. handoff_description: Handles Azure SQL and Cosmos DB troubleshooting tools: - execute_kusto_query - RunAzCliReadCommands allowed_skills: - azure-sql-saturation-runbook - cosmos-throughput-runbook&lt;/LI-CODE&gt;
&lt;P&gt;Note what that &lt;CODE&gt;system_prompt&lt;/CODE&gt; is really doing: it is &lt;STRONG&gt;narrowing the action space&lt;/STRONG&gt;. Half of production safety with an agent is telling it, in plain English, which categories of fix are off the table.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_16"&gt;4.7 Response plans&lt;/H3&gt;
&lt;P&gt;Create one plan per domain, all starting in &lt;STRONG&gt;Review&lt;/STRONG&gt;:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Plan&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Filter&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Custom agent&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Mode&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;appsvc-p1&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Priority 1 + 2, service &lt;CODE&gt;checkout&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;DeploymentAnalyzer&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Review&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;aks-p1&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Priority 1, service &lt;CODE&gt;orders-api&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;DeploymentAnalyzer&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Review&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;db-critical&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Priority 1 + 2, service &lt;CODE&gt;customer-api&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;DatabaseExpert&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Review&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;vm-guest&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Priority 1 + 2, title contains &lt;CODE&gt;disk&lt;/CODE&gt;, &lt;CODE&gt;memory&lt;/CODE&gt;, &lt;CODE&gt;CPU&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;GuestOSResponder&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Review&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;network-p1&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Priority 1, title contains &lt;CODE&gt;502&lt;/CODE&gt;, &lt;CODE&gt;backend&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;NetworkPathExpert&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Review&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;integration-p1&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Priority 1, service &lt;CODE&gt;fulfillment&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;IntegrationExpert&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Review&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Filters available: &lt;STRONG&gt;severity/priority&lt;/STRONG&gt; (multiselect), &lt;STRONG&gt;impacted service&lt;/STRONG&gt;, &lt;STRONG&gt;incident type&lt;/STRONG&gt;, and &lt;STRONG&gt;title contains&lt;/STRONG&gt;. Plans can be turned &lt;STRONG&gt;off&lt;/STRONG&gt; without deleting them, which is exactly what you want during maintenance windows.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_17"&gt;5. Set your guardrails before your first incident&lt;/H2&gt;
&lt;P&gt;If you read only one section of this post, read this one. The guardrails are not paperwork; they are the reason this is deployable.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_18"&gt;5.1 Run modes&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Mode&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Behavior&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Default&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Review&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Agent proposes; you approve or deny&lt;/td&gt;&lt;td&gt;Agent-level default&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Autonomous&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Agent executes immediately and reports&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Per-plan and per-task default&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Two subtleties that bite people:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Run modes are set per response plan and per scheduled task&lt;/STRONG&gt;, not globally. The agent-level setting is only a fallback. And per-plan the default is &lt;EM&gt;Autonomous&lt;/EM&gt; — so if you don't set it, you get autonomy.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Review mode shows Approve/Deny only for Azure infrastructure operations&lt;/STRONG&gt; (Azure CLI, ARM writes). Sending an email, posting to Teams, or querying an external source proceeds based on the agent's reasoning. To gate &lt;EM&gt;those&lt;/EM&gt;, you need &lt;A href="https://learn.microsoft.com/azure/sre-agent/agent-hooks" target="_blank" rel="noopener"&gt;hooks&lt;/A&gt; or tool access policies.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;Only users holding the &lt;STRONG&gt;SRE Agent Administrator&lt;/STRONG&gt; role can approve. Standard users cannot, and personal Microsoft accounts can't authorize on-behalf-of at all — it requires a work or school (Entra ID) account.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_19"&gt;5.2 What the product blocks for you&lt;/H3&gt;
&lt;P&gt;These are enforced at the command level, independent of your RBAC:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Guardrail&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Behavior&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Delete operations&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;The agent never runs &lt;CODE&gt;delete&lt;/CODE&gt; or &lt;CODE&gt;remove&lt;/CODE&gt; commands. It returns an error pointing you at the portal&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Key Vault&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;All &lt;CODE&gt;az keyvault&lt;/CODE&gt; commands are blocked, to prevent credential exposure&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Management locks&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Resources with &lt;CODE&gt;ReadOnly&lt;/CODE&gt; locks can't be modified, regardless of permissions or run mode&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Subscription validation&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Subscription IDs are validated as well-formed GUIDs before execution&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;💡 &lt;STRONG&gt;Use the delete block architecturally.&lt;/STRONG&gt; Put a &lt;CODE&gt;ReadOnly&lt;/CODE&gt; management lock on anything that must never change during an incident — your Key Vaults, your production databases, your golden images. That lock is respected before every modification, which gives you a control that survives RBAC drift and misconfigured response plans.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="mcetoc_blog_20"&gt;5.3 Hooks: the guardrail you write yourself&lt;/H3&gt;
&lt;P&gt;Two events are supported — &lt;CODE&gt;Stop&lt;/CODE&gt; (agent about to return a final response) and &lt;CODE&gt;PostToolUse&lt;/CODE&gt; (a tool finished). Hooks run as an LLM &lt;STRONG&gt;prompt&lt;/STRONG&gt; or a sandboxed &lt;STRONG&gt;command&lt;/STRONG&gt; script.&lt;/P&gt;
&lt;P&gt;Here is the single most useful hook for this entire post — a deterministic policy gate on shell execution:&lt;/P&gt;
&lt;LI-CODE lang="yaml"&gt;hooks: PostToolUse: - type: command matcher: "Bash|ExecuteShellCommand" timeout: 30 failMode: block script: | #!/usr/bin/env python3 import sys, json, re context = json.load(sys.stdin) command = context.get('tool_input', {}).get('command', '') dangerous = [ r'\brm\s+-rf\b', r'\bsudo\b', r'\bchmod\s+777\b', r'\bmkfs\b', r'\bdd\s+if=', r'\btruncate\b', r'\bDROP\s+TABLE\b', ] for pattern in dangerous: if re.search(pattern, command, re.IGNORECASE): print(json.dumps({"decision": "block", "reason": f"Blocked by policy: {pattern}"})) sys.exit(0) print(json.dumps({"decision": "allow"}))&lt;/LI-CODE&gt;
&lt;P&gt;And a &lt;CODE&gt;Stop&lt;/CODE&gt; hook that refuses to let the agent declare victory without evidence:&lt;/P&gt;
&lt;LI-CODE lang="yaml"&gt;hooks: Stop: - type: prompt model: ReasoningFast timeout: 30 prompt: | Review the agent's final response. $ARGUMENTS It is only acceptable if it contains ALL of: 1. The specific resource acted upon (full name or resource ID) 2. Metric values BEFORE and AFTER the action 3. The observation window over which recovery was confirmed 4. Who approved the action and at what UTC timestamp Respond with: {"ok": true} {"ok": false, "reason": "&amp;lt;what is="" missing=""&amp;gt;"}&amp;lt;/what&amp;gt;&lt;/LI-CODE&gt;
&lt;P&gt;Hook mechanics you'll want on hand:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Setting&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Default&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Range / notes&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;timeout&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;30s&lt;/td&gt;&lt;td&gt;1–300s&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;failMode&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;allow&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;allow&lt;/CODE&gt; or &lt;CODE&gt;block&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;maxRejections&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;1–25; prompt-type &lt;CODE&gt;Stop&lt;/CODE&gt; hooks only&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;matcher&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;—&lt;/td&gt;&lt;td&gt;Regex, anchored &lt;CODE&gt;^(pattern)$&lt;/CODE&gt;, case-sensitive; &lt;CODE&gt;*&lt;/CODE&gt; matches all&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Script size&lt;/td&gt;&lt;td&gt;—&lt;/td&gt;&lt;td&gt;64 KB max&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Shebangs&lt;/td&gt;&lt;td&gt;—&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;#!/bin/bash&lt;/CODE&gt;, &lt;CODE&gt;#!/usr/bin/env python3&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;⚠️ &lt;STRONG&gt;The footgun:&lt;/STRONG&gt; for &lt;CODE&gt;Stop&lt;/CODE&gt; hooks, a rejection &lt;STRONG&gt;without a &lt;CODE&gt;reason&lt;/CODE&gt; field is treated as approval&lt;/STRONG&gt;. Always populate &lt;CODE&gt;reason&lt;/CODE&gt;.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Agent-level hooks and custom-agent-level hooks both run when both match; agent-level fires first.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_21"&gt;5.4 The recommended production policy&lt;/H3&gt;
&lt;P&gt;This is the policy I'd put in front of a change board:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Allow &lt;STRONG&gt;read-only investigation&lt;/STRONG&gt; automatically, everywhere.&lt;/LI&gt;
&lt;LI&gt;Allow &lt;STRONG&gt;automatic incident creation and work-note updates&lt;/STRONG&gt; — after sanitization.&lt;/LI&gt;
&lt;LI&gt;Use &lt;STRONG&gt;Review mode for all production remediation&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Require &lt;STRONG&gt;human approval for every production write&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Use &lt;STRONG&gt;fixed-purpose runbooks&lt;/STRONG&gt; instead of unrestricted VM shell access.&lt;/LI&gt;
&lt;LI&gt;Require &lt;STRONG&gt;separate approval&lt;/STRONG&gt; for destructive or data-affecting actions.&lt;/LI&gt;
&lt;LI&gt;Initially require &lt;STRONG&gt;human confirmation before resolving&lt;/STRONG&gt; an incident.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_22"&gt;6. The ten use cases&lt;/H2&gt;
&lt;P&gt;Each use case follows the same seven-part structure so you can skim to the one you're firefighting:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What happened&lt;/STRONG&gt; → &lt;STRONG&gt;How Azure Monitor detected it&lt;/STRONG&gt; → &lt;STRONG&gt;How the agent found the cause&lt;/STRONG&gt; → &lt;STRONG&gt;Agent action table&lt;/STRONG&gt; → &lt;STRONG&gt;Recovery note&lt;/STRONG&gt; → &lt;STRONG&gt;Try it yourself&lt;/STRONG&gt; → &lt;STRONG&gt;Guardrails&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;In the action tables, &lt;CODE&gt;Type&lt;/CODE&gt; is one of:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Meaning&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Read&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;No blast radius. Safe to run automatically&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Decision&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Agent reasoning or an approval gate. No resource change&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Write (ITSM)&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Ticket create/update. Sanitized&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Write (Azure)&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Azure control-plane change. &lt;STRONG&gt;Approval required in production&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Write (Guest OS)&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Inside the VM, via a fixed-purpose runbook. &lt;STRONG&gt;Approval required&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Write (K8s/DevOps)&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Cluster or pipeline change. &lt;STRONG&gt;Approval required&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;CODE&gt;Validation&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;Post-action measurement against defined thresholds&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_23"&gt;Use case #1 — App Service: HTTP 500 after deployment&lt;/H3&gt;
&lt;P&gt;&lt;EM&gt;The one you should build first. Clean trigger, bounded action, unambiguous validation.&lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;Release &lt;CODE&gt;2026.03.12.4&lt;/CODE&gt; was deployed to a production checkout App Service. The new code referenced an application setting that was never defined in the production slot. The application started fine — which is what makes this class of failure nasty — but every checkout operation that touched that setting returned HTTP 500.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;P&gt;Azure Monitor and Application Insights fired on a composite condition, not a single metric:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;HTTP 5xx rate above the operational threshold&lt;/LI&gt;
&lt;LI&gt;Failed availability tests&lt;/LI&gt;
&lt;LI&gt;Increased application exceptions&lt;/LI&gt;
&lt;LI&gt;Increased dependency failures&lt;/LI&gt;
&lt;LI&gt;Request latency above baseline&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P1 – Checkout App Service returning elevated HTTP 500 responses&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Identified the affected App Service and slot.&lt;/LI&gt;
&lt;LI&gt;Queried HTTP response and latency metrics.&lt;/LI&gt;
&lt;LI&gt;Queried Application Insights failed requests and exceptions.&lt;/LI&gt;
&lt;LI&gt;Identified the missing-setting exception as the dominant failure.&lt;/LI&gt;
&lt;LI&gt;Reviewed deployment history and Azure Activity Log.&lt;/LI&gt;
&lt;LI&gt;Correlated the error increase with release &lt;CODE&gt;2026.03.12.4&lt;/CODE&gt;.&lt;/LI&gt;
&lt;LI&gt;Compared production against the previous deployment slot.&lt;/LI&gt;
&lt;LI&gt;Confirmed the previous slot remained healthy.&lt;/LI&gt;
&lt;LI&gt;Confirmed no matching Azure platform incident.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;HTTP 500 responses increased from 0.4% to 18% within three minutes of release 2026.03.12.4. Most failures reference a missing application setting. The previous deployment slot passes availability and dependency checks.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Notice the shape of that sentence: a &lt;STRONG&gt;delta&lt;/STRONG&gt;, a &lt;STRONG&gt;time correlation&lt;/STRONG&gt;, and a &lt;STRONG&gt;known-good comparison&lt;/STRONG&gt;. That's what makes it actionable rather than merely true.&lt;/P&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Investigate alert&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Reads HTTP 5xx rate, failed requests, latency, availability-test results&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Analyze exceptions&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Identifies missing-configuration exception as dominant failure&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Correlate deployment&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Finds release 2026.03.12.4 deployed three minutes before the spike&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Compare slots&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Confirms previous slot healthy while production is failing&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Rule out platform issue&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Checks Azure Resource Health and dependency health&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Assess blast radius&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Determines checkout affected, unrelated services healthy&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P1 against the Checkout CI, assigned to Application Operations&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Adds exceptions, deployment correlation, resource links, affected operations&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Classify response&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Classifies as deployment-caused; selects rollback&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Pause release&lt;/td&gt;&lt;td&gt;Write (DevOps)&lt;/td&gt;&lt;td&gt;Pauses the failed release pipeline&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Requests approval to swap the previous healthy slot into production&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Swap slot&lt;/td&gt;&lt;td&gt;Write (Azure)&lt;/td&gt;&lt;td&gt;Performs the approved swap &lt;STRONG&gt;only&lt;/STRONG&gt; on the named App Service&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Validate recovery&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;Confirms 5xx, latency, exceptions, dependencies, availability recover&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Update/resolve INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Records approval, rollback, timestamps, recovery evidence&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Create SNOW PRB&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Problem record for configuration-validation improvements&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Production was reverted to the previous healthy deployment slot at 14:26 UTC. HTTP 500 responses declined from 18% to below 1%, and availability tests passed for 15 consecutive minutes. Preliminary cause: missing production configuration in release 2026.03.12.4.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Break it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;# Put a healthy build in the 'previous' slot first, then break production # by deploying code that reads an app setting which only exists in staging. az webapp config appsettings delete -g $RG -n app-checkout-demo \ --setting-names Checkout__PaymentProviderKey az webapp restart -g $RG -n app-checkout-demo&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Alert it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az monitor metrics alert create -g $RG -n "alert-checkout-5xx" \ --scopes "/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.Web/sites/app-checkout-demo" \ --condition "total Http5xx &amp;gt; 20" \ --window-size 5m --evaluation-frequency 1m --severity 1 \ --description "P1 – Checkout App Service returning elevated HTTP 500 responses"&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it (before the alert, to see the read phase in isolation):&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;app-checkout-demo is returning HTTP 500s. Do not change anything. Investigate and tell me: 1. the dominant exception and its share of total failures 2. what deployed in the 30 minutes before the error rate changed 3. whether the 'previous' slot is healthy right now 4. whether Azure Resource Health shows a platform issue Give me the evidence chain and the smallest reversible mitigation.&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Expect it to propose:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;Proposed action: Swap slot 'previous' into production on app-checkout-demo Risk: brief connection drain (~10s). Fully reversible by swapping back. Validation: Http5xx &amp;lt; 1% and availability test passing for 15 minutes. [Approve] [Deny]&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Verify it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="kusto"&gt;requests | where timestamp &amp;gt; ago(1h) | summarize failed = countif(success == false), total = count() by bin(timestamp, 1m) | extend failureRate = 100.0 * failed / total | render timechart&lt;/LI-CODE&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;🎬 &lt;STRONG&gt;Best thing to record for a demo:&lt;/STRONG&gt; the moment the Approve button appears with the evidence already attached. That single screen is the whole value proposition.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Scope write permissions to the &lt;STRONG&gt;named App Service&lt;/STRONG&gt;, not the resource group.&lt;/LI&gt;
&lt;LI&gt;Verify the previous slot is healthy &lt;STRONG&gt;before&lt;/STRONG&gt; swapping — a swap into a broken slot doubles the outage.&lt;/LI&gt;
&lt;LI&gt;Require human approval for production slot swaps.&lt;/LI&gt;
&lt;LI&gt;Preserve the failed deployment for analysis; don't let the pipeline overwrite it.&lt;/LI&gt;
&lt;LI&gt;Never grant subscription-level Contributor or Owner.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_24"&gt;Use case #2 — AKS: pods in CrashLoopBackOff&lt;/H3&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;Image &lt;CODE&gt;orders-api:4.18.0&lt;/CODE&gt; referenced a configuration key that didn't exist in the production namespace. Eight of ten pods entered &lt;CODE&gt;CrashLoopBackOff&lt;/CODE&gt;. The two survivors couldn't carry production traffic, producing latency and ingress 5xx.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;P&gt;Managed Prometheus / Container Insights detected:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Unavailable replicas&lt;/LI&gt;
&lt;LI&gt;Increasing container restart count&lt;/LI&gt;
&lt;LI&gt;&lt;CODE&gt;CrashLoopBackOff&lt;/CODE&gt; pod state&lt;/LI&gt;
&lt;LI&gt;Failed readiness and liveness checks&lt;/LI&gt;
&lt;LI&gt;Elevated ingress HTTP 5xx&lt;/LI&gt;
&lt;LI&gt;Reduced successful-request rate&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P1 – Orders API unavailable replicas in production AKS&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Identified the cluster, namespace, and deployment.&lt;/LI&gt;
&lt;LI&gt;Reviewed deployment availability and pod states.&lt;/LI&gt;
&lt;LI&gt;Examined logs from failing containers.&lt;/LI&gt;
&lt;LI&gt;Reviewed Kubernetes warning events.&lt;/LI&gt;
&lt;LI&gt;Compared current and previous ReplicaSets.&lt;/LI&gt;
&lt;LI&gt;Correlated the failure with revision 42.&lt;/LI&gt;
&lt;LI&gt;Identified the missing configuration key.&lt;/LI&gt;
&lt;LI&gt;Confirmed revision 41 was previously healthy.&lt;/LI&gt;
&lt;LI&gt;Checked node CPU, memory, storage, networking, status.&lt;/LI&gt;
&lt;LI&gt;Determined AKS infrastructure was healthy.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Eight of ten Orders API pods entered CrashLoopBackOff during rollout of revision 42. Container logs show a missing configuration key. Revision 41, using image 4.17.6, was healthy.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Step 10 is the one people skip. "Rule out the infrastructure" is what stops you from spending an hour on a node pool that was never the problem.&lt;/P&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Investigate workload&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Deployment status, unavailable replicas, readiness, restart counts&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Analyze pod logs&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Startup failure from a missing configuration key&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Analyze events&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Image pulls, mounts, scheduling, probes, container events&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Correlate rollout&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Revision 42 deployed immediately before failure&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Compare ReplicaSets&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Revision 41 was the previous healthy workload&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Rule out infrastructure&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Nodes, memory, CPU, networking, storage healthy&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Assess blast radius&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Eight of ten replicas unavailable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P1 against the Orders API CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Namespace, image, revision, errors, rollout correlation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Classify response&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Application/configuration-caused&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Approval to pause and roll back revision 42&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Pause failed rollout&lt;/td&gt;&lt;td&gt;Write (K8s/DevOps)&lt;/td&gt;&lt;td&gt;Prevents the release progressing or being reapplied&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Roll back deployment&lt;/td&gt;&lt;td&gt;Write (K8s)&lt;/td&gt;&lt;td&gt;Rolls back &lt;STRONG&gt;only&lt;/STRONG&gt; the named deployment to revision 41&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Validate replicas&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;All expected replicas ready and stable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Validate application&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;Ingress errors decline; synthetic orders succeed&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Update/resolve INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Revision, approval, rollback, recovery evidence&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Create defect/task&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Add configuration validation to CI/CD&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Orders API was rolled back from revision 42 to revision 41. All ten replicas are ready, restart counts have stabilized, ingress HTTP 5xx responses are below threshold, and synthetic order transactions are succeeding.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Break it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az aks get-credentials -g $RG -n aks-demo kubectl create namespace orders kubectl create deployment orders-api -n orders --image=nginx:1.25 --replicas=10 kubectl rollout status deployment/orders-api -n orders # revision 41 equivalent, healthy # Now break it: point at an image whose entrypoint requires a missing env var kubectl set image deployment/orders-api -n orders orders-api=busybox:1.36 kubectl patch deployment orders-api -n orders --type=json -p='[ {"op":"add","path":"/spec/template/spec/containers/0/command", "value":["sh","-c","test -n \"$ORDERS_CONFIG_KEY\" || (echo \"FATAL: missing ORDERS_CONFIG_KEY\" &amp;gt;&amp;amp;2; exit 1); sleep 3600"]} ]'&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Watch it break:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;kubectl get pods -n orders -w kubectl rollout history deployment/orders-api -n orders&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;Pods in namespace 'orders' on aks-demo are crash looping. Read-only. Tell me: which revision introduced it, the exact container error, whether the node pool is healthy, and how many replicas are actually serving. Then tell me the last known-good revision and why you believe it was healthy.&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Expect it to propose:&lt;/STRONG&gt; &lt;CODE&gt;kubectl rollout undo deployment/orders-api -n orders --to-revision=&lt;/CODE&gt; scoped to that single deployment.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Verify it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;kubectl get deployment orders-api -n orders \ -o jsonpath='{.status.readyReplicas}/{.status.replicas}{"\n"}' kubectl get pods -n orders --no-headers | awk '{print $4}' | sort | uniq -c&lt;/LI-CODE&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Restrict access to the required &lt;STRONG&gt;cluster, namespace, and deployment&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Do &lt;STRONG&gt;not&lt;/STRONG&gt; grant &lt;CODE&gt;cluster-admin&lt;/CODE&gt;.&lt;/LI&gt;
&lt;LI&gt;Require approval for rollback.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Coordinate with GitOps reconciliation.&lt;/STRONG&gt; If Flux or Argo owns that deployment, a &lt;CODE&gt;kubectl rollout undo&lt;/CODE&gt; gets reverted within minutes and you've created a flapping outage. Either pause reconciliation first or roll back through Git.&lt;/LI&gt;
&lt;LI&gt;Do not permit namespace, persistent-volume, or cluster deletion.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_25"&gt;Use case #3 — Azure SQL Database: CPU saturation and timeouts&lt;/H3&gt;
&lt;P&gt;&lt;EM&gt;The use case where the agent's job is to buy time, not to fix the problem.&lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;A query execution plan changed after an application release. The new plan consumed substantially more CPU and workers. The database saturated, producing SQL dependency timeouts and failed customer requests.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Sustained CPU saturation&lt;/LI&gt;
&lt;LI&gt;Worker or session pressure&lt;/LI&gt;
&lt;LI&gt;Increased connection failures&lt;/LI&gt;
&lt;LI&gt;SQL dependency timeouts&lt;/LI&gt;
&lt;LI&gt;Query-duration deviation from baseline&lt;/LI&gt;
&lt;LI&gt;Degraded customer API success rate&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P1 – Customer API database saturation causing request timeouts&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Reviewed database CPU, workers, sessions, connections.&lt;/LI&gt;
&lt;LI&gt;Reviewed application SQL dependency failures.&lt;/LI&gt;
&lt;LI&gt;Checked for blocking and deadlocks.&lt;/LI&gt;
&lt;LI&gt;Ran approved &lt;STRONG&gt;read-only&lt;/STRONG&gt; Query Store diagnostics.&lt;/LI&gt;
&lt;LI&gt;Identified the primary CPU-consuming query.&lt;/LI&gt;
&lt;LI&gt;Detected a recent execution-plan change.&lt;/LI&gt;
&lt;LI&gt;Correlated with an application release.&lt;/LI&gt;
&lt;LI&gt;Ruled out Azure service health and storage issues.&lt;/LI&gt;
&lt;LI&gt;Determined a temporary scale operation could restore service.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Left permanent query remediation to the DBA team.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Database CPU has remained saturated for 17 minutes. One query accounts for most recent CPU consumption and changed execution plan shortly before the incident. Application SQL dependency timeout rate is 23%.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Step 10 is the design decision that makes this safe. The agent correctly diagnoses a plan regression and then &lt;EM&gt;deliberately does not fix it&lt;/EM&gt;, because forcing a plan or dropping an index is a permanent, DBA-owned, change-controlled action. It buys capacity instead.&lt;/P&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Investigate database&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;CPU, workers, sessions, connections, storage, availability&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Analyze app impact&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;SQL dependency latency, failures, affected API operations&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Check blocking&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Approved diagnostics for blocking, deadlocks, connection growth&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Analyze Query Store&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Highest-impact query and recent plan change&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Correlate changes&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Recent application and database deployments&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Rule out platform issue&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Service health, storage, database availability&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Assess blast radius&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Affected applications; other databases healthy&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P1 against the production database CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Utilization, query ID, timeouts, change correlation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Classify response&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Scaling is mitigation; query changes remain DBA-owned&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Calculate bounded scale&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Selects the &lt;STRONG&gt;smallest&lt;/STRONG&gt; pre-approved capacity increase&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Database owner or incident commander&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Scale database&lt;/td&gt;&lt;td&gt;Write (Azure)&lt;/td&gt;&lt;td&gt;Increases the affected database by one approved service step&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Validate recovery&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;CPU, workers, timeouts, application success recover&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Update INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Previous/new capacity, approval, timing, results&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Create SNOW PRB&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Permanent query-remediation work&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Create scale-down task&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Task/change to restore normal capacity after stability&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Azure SQL capacity was temporarily increased by one approved service step. CPU declined from sustained saturation to 54%, and SQL dependency timeouts returned to baseline. Query Store indicates a probable execution-plan regression requiring permanent DBA remediation.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Break it&lt;/STRONG&gt; — generate a saturating workload against &lt;CODE&gt;db-customer&lt;/CODE&gt; (an unindexed &lt;CODE&gt;LIKE '%...%'&lt;/CODE&gt; scan in a tight loop from a container in the same region works fine on an S1).&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Alert it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az monitor metrics alert create -g $RG -n "alert-sql-cpu" \ --scopes "/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.Sql/servers/sqlsrv-sre-demo/databases/db-customer" \ --condition "avg cpu_percent &amp;gt; 90" \ --window-size 5m --evaluation-frequency 1m --severity 1 \ --description "P1 – Customer API database saturation causing request timeouts"&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;db-customer is saturated. Read-only investigation. Identify the top CPU-consuming query, whether its plan changed recently, and what application release correlates. Do NOT propose index, schema, plan-forcing, or session-kill actions. Propose only the smallest temporary capacity step that restores service, and tell me what it costs per day and when we should scale back down.&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Read-only Query Store diagnostics the agent should run:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="sql"&gt;SELECT TOP 10 qsq.query_id, qsp.plan_id, qsp.last_execution_time, SUM(qsrs.count_executions) AS executions, SUM(qsrs.avg_cpu_time * qsrs.count_executions) AS total_cpu_us FROM sys.query_store_query AS qsq JOIN sys.query_store_plan AS qsp ON qsp.query_id = qsq.query_id JOIN sys.query_store_runtime_stats AS qsrs ON qsrs.plan_id = qsp.plan_id JOIN sys.query_store_runtime_stats_interval AS qsrsi ON qsrsi.runtime_stats_interval_id = qsrs.runtime_stats_interval_id WHERE qsrsi.start_time &amp;gt; DATEADD(hour, -2, GETUTCDATE()) GROUP BY qsq.query_id, qsp.plan_id, qsp.last_execution_time ORDER BY total_cpu_us DESC;&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Expect it to propose:&lt;/STRONG&gt; &lt;CODE&gt;az sql db update -g $RG -s sqlsrv-sre-demo -n db-customer --service-objective S2&lt;/CODE&gt; — exactly one step, on exactly that database.&lt;/P&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Restrict scaling to the &lt;STRONG&gt;named database&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Define minimum and maximum capacity.&lt;/LI&gt;
&lt;LI&gt;Require approval for scale-up &lt;STRONG&gt;and&lt;/STRONG&gt; scale-down.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Time-limit temporary capacity&lt;/STRONG&gt; — an un-reversed emergency scale-up is how a P1 becomes a budget incident.&lt;/LI&gt;
&lt;LI&gt;Do not autonomously force plans, terminate sessions, modify indexes, or change schema.&lt;/LI&gt;
&lt;LI&gt;Track the temporary cost impact with an Azure Cost Management alert.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_26"&gt;Use case #4 — Azure Cosmos DB: HTTP 429 throttling&lt;/H3&gt;
&lt;P&gt;&lt;EM&gt;The one where the correct root cause is "we're succeeding."&lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;A marketing campaign increased Product Catalog traffic by roughly 40%. The Cosmos DB container hit its provisioned throughput ceiling. HTTP 429s increased, and client retries amplified application latency.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;High normalized RU consumption&lt;/LI&gt;
&lt;LI&gt;Increased HTTP 429 responses&lt;/LI&gt;
&lt;LI&gt;Elevated server-side latency&lt;/LI&gt;
&lt;LI&gt;Application dependency failures&lt;/LI&gt;
&lt;LI&gt;Sustained operation near the throughput limit&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P2 – Cosmos DB throttling affecting Product Catalog requests&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Reviewed normalized RU consumption and throttled requests.&lt;/LI&gt;
&lt;LI&gt;Identified the affected database and container.&lt;/LI&gt;
&lt;LI&gt;Reviewed regional and partition behavior.&lt;/LI&gt;
&lt;LI&gt;Checked for hot-partition evidence.&lt;/LI&gt;
&lt;LI&gt;Reviewed application retry telemetry.&lt;/LI&gt;
&lt;LI&gt;Compared current traffic with the historical baseline.&lt;/LI&gt;
&lt;LI&gt;Correlated demand with the marketing campaign.&lt;/LI&gt;
&lt;LI&gt;Checked recent application deployments.&lt;/LI&gt;
&lt;LI&gt;Checked Azure service health.&lt;/LI&gt;
&lt;LI&gt;Determined the primary cause was &lt;STRONG&gt;legitimate demand&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The Product Catalog container is at its configured throughput ceiling, and 21% of requests are being throttled. Traffic increased by approximately 40% following a campaign launch. No deployment or regional platform issue correlates with the event.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Step 4 is the fork in the road. If consumption is uneven across partitions, more RU/s is money set on fire — the correct answer is an architecture change, not a scale-up. The agent has to check before it recommends.&lt;/P&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Investigate throttling&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;RU consumption, 429 rate, latency, requests, availability&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Identify scope&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Account, database, container, operations, regions&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Analyze demand&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Compares traffic and RU consumption with historical patterns&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Check partitions&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Looks for uneven partition consumption where telemetry permits&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Analyze retries&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Determines whether client retries are amplifying the incident&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Correlate events&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Links demand to campaign traffic; excludes release/platform issues&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Assess blast radius&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Affected catalog operations; unaffected containers&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P2 against the Product Catalog CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;RU, throttling, latency, traffic, partition evidence&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Classify response&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Demand-driven &lt;STRONG&gt;unless&lt;/STRONG&gt; hot-partition evidence exists&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Calculate throughput&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Smallest increase within the cost ceiling&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Approval for a temporary throughput increase&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Increase throughput&lt;/td&gt;&lt;td&gt;Write (Azure)&lt;/td&gt;&lt;td&gt;Raises throughput only to the approved maximum&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Validate recovery&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;429 rate and latency recover&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Update/resolve INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Throughput, approval, cost implication, recovery&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Create capacity task&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Work to return throughput to normal&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Create SNOW PRB&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Partition or retry improvements, if required&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Provisioned throughput was increased within the approved production limit. HTTP 429 responses declined from 21% to below 1%, and Product Catalog latency returned to baseline. The increase is temporary and will be reviewed after campaign traffic subsides.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Break it:&lt;/STRONG&gt; the container was created at 400 RU/s. Drive a few hundred reads per second at it and you'll be throttled within seconds.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Alert it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az monitor metrics alert create -g $RG -n "alert-cosmos-429" \ --scopes "/subscriptions/$SUB/resourceGroups/$RG/providers/Microsoft.DocumentDB/databaseAccounts/cosmos-sre-demo" \ --condition "total TotalRequests where StatusCode == 429 &amp;gt; 100" \ --window-size 5m --evaluation-frequency 1m --severity 2 \ --description "P2 – Cosmos DB throttling affecting Product Catalog requests"&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;cosmos-sre-demo container 'products' is throttling. Read-only. Before recommending anything, tell me whether RU consumption is EVEN across physical partitions or concentrated. If it is concentrated, do not recommend a throughput increase — recommend an architecture problem record instead. If it is even, tell me the smallest RU/s that clears throttling and the daily cost delta.&lt;/LI-CODE&gt;
&lt;P&gt;That prompt is the whole use case. Getting the agent to &lt;EM&gt;refuse&lt;/EM&gt; the easy answer under a stated condition is the skill.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Verify it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="kusto"&gt;AzureDiagnostics | where ResourceProvider == "MICROSOFT.DOCUMENTDB" | where Category == "DataPlaneRequests" | summarize throttled = countif(statusCode_s == "429"), total = count() by bin(TimeGenerated, 1m) | extend throttleRate = 100.0 * throttled / total | render timechart&lt;/LI-CODE&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Define a &lt;STRONG&gt;maximum throughput ceiling&lt;/STRONG&gt; the agent may not exceed.&lt;/LI&gt;
&lt;LI&gt;Restrict changes to the &lt;STRONG&gt;named container&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Require approval for increases &lt;EM&gt;and&lt;/EM&gt; reductions.&lt;/LI&gt;
&lt;LI&gt;Do not permit deletion, consistency-level changes, or region changes.&lt;/LI&gt;
&lt;LI&gt;Create cost alerts for prolonged increased throughput.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Treat persistent hot partitions as an architecture issue&lt;/STRONG&gt;, never as a scaling issue.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_27"&gt;Use case #5 — Azure VM: OS/root disk full&lt;/H3&gt;
&lt;P&gt;&lt;EM&gt;The most operationally dangerous use case in this post, and the one with the most interesting guardrail design.&lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;A legacy payment application generated excessive trace logs. Log rotation stopped working and the root filesystem filled. The VM stayed available at the Azure platform layer — heartbeat green, Resource Health fine — but the application stopped, because it could no longer write to disk.&lt;/P&gt;
&lt;P&gt;This is the classic "green dashboard, dead service" failure. Platform-layer monitoring alone will never catch it.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;P&gt;Azure Monitor Agent and guest telemetry detected:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Critically low filesystem free space&lt;/LI&gt;
&lt;LI&gt;Rapid filesystem consumption&lt;/LI&gt;
&lt;LI&gt;Application process stopped&lt;/LI&gt;
&lt;LI&gt;Failed availability tests&lt;/LI&gt;
&lt;LI&gt;Elevated HTTP 5xx&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Healthy VM heartbeat but unhealthy application&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P1 – Legacy payment application unavailable due to full VM OS disk&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Confirmed the VM was online.&lt;/LI&gt;
&lt;LI&gt;Confirmed Azure Monitor Agent heartbeat.&lt;/LI&gt;
&lt;LI&gt;Identified the affected root/OS filesystem.&lt;/LI&gt;
&lt;LI&gt;Reviewed the free-space trend.&lt;/LI&gt;
&lt;LI&gt;Correlated application failure with disk exhaustion.&lt;/LI&gt;
&lt;LI&gt;Found 86 GB of growth in the application trace directory.&lt;/LI&gt;
&lt;LI&gt;Reviewed recent deployments and logging changes.&lt;/LI&gt;
&lt;LI&gt;Checked log-rotation status.&lt;/LI&gt;
&lt;LI&gt;Confirmed the files matched the approved cleanup policy.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Excluded customer data, database files, audit logs, and system files.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The VM is healthy at the Azure platform layer, but the OS volume has less than 1% free space. The approved application trace directory grew by 86 GB in six hours. The payment service stopped when it could no longer write to disk.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Investigate VM&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;VM, agent heartbeat, Azure platform health&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Analyze filesystem&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Root volume and free-space trend&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Correlate app failure&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Service stopped after disk exhaustion&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Identify disk consumer&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Abnormal growth in an approved trace directory&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Check changes&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Deployments, logging changes, rotation, scheduled tasks&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Validate cleanup scope&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Candidate files meet approved path, type, and age rules&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Protect data&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Excludes databases, customer data, security logs, unknown files&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P1 against the payment VM/application CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Disk usage, growth timeline, service impact, cleanup scope&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Approval for the restricted recovery runbook&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Archive logs&lt;/td&gt;&lt;td&gt;Write (Guest OS)&lt;/td&gt;&lt;td&gt;Archives eligible files to protected Azure Storage&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Remove eligible files&lt;/td&gt;&lt;td&gt;Write (Guest OS)&lt;/td&gt;&lt;td&gt;Removes &lt;STRONG&gt;only&lt;/STRONG&gt; successfully archived, allowlisted files&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Run log rotation&lt;/td&gt;&lt;td&gt;Write (Guest OS)&lt;/td&gt;&lt;td&gt;Executes the approved rotation operation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Restart service&lt;/td&gt;&lt;td&gt;Write (Guest OS)&lt;/td&gt;&lt;td&gt;Restarts &lt;STRONG&gt;only&lt;/STRONG&gt; the named payment service if necessary&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Validate recovery&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;Disk, application, archive, availability, growth stabilization&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Update/resolve INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Bytes processed, exclusions, approval, results&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Create SNOW PRB&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Permanent logging and rotation remediation&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The approved recovery runbook archived and removed 82 GB of eligible application trace files. OS-volume free space is now 31%. The payment service was restarted and has passed health checks for 15 minutes. No database, customer, security, or system files were modified.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;That last sentence is not decoration. It is the sentence your auditor will read.&lt;/P&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Break it&lt;/STRONG&gt; &lt;EM&gt;(lab VM only — this fills the root disk)&lt;/EM&gt;:&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az vm run-command invoke -g $RG -n vm-payments-linux \ --command-id RunShellScript --scripts " mkdir -p /var/log/payments/trace fallocate -l 24G /var/log/payments/trace/trace-$(date +%s).log df -h / "&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;vm-payments-linux root filesystem is nearly full and the payment service is down. Read-only first. Tell me: - exactly which directory grew, by how much, over what window - whether log rotation is configured and when it last ran - what changed in the last 24 hours that would explain it Then tell me which files are inside the approved cleanup allowlist (/var/log/payments/trace/*.log, older than 2h) and which are NOT, and confirm no database, audit, or customer data files are in scope. Do not delete anything.&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;The critical design point.&lt;/STRONG&gt; SRE Agent &lt;STRONG&gt;blocks &lt;CODE&gt;delete&lt;/CODE&gt; and &lt;CODE&gt;remove&lt;/CODE&gt; commands outright&lt;/STRONG&gt;. You cannot have it &lt;CODE&gt;rm&lt;/CODE&gt; those files through its Azure CLI surface, and you should be glad. The correct implementation is a &lt;STRONG&gt;fixed-purpose, version-controlled runbook&lt;/STRONG&gt; that the agent &lt;EM&gt;invokes&lt;/EM&gt; with tightly bounded parameters:&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;# What the agent is allowed to call — one runbook, allowlisted parameters, nothing else az automation runbook start \ -g $RG --automation-account-name aa-sre-runbooks \ -n "Reclaim-TraceDiskSpace" \ --parameters vmName=vm-payments-linux \ allowedPath=/var/log/payments/trace \ pattern='*.log' \ minAgeHours=2 \ maxBytes=90000000000 \ archiveToContainer=payments-trace-archive \ requireArchiveBeforeDelete=true \ dryRun=false&lt;/LI-CODE&gt;
&lt;P&gt;The runbook — not the agent — owns the destructive logic, and it enforces:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;path allowlist (refuse anything outside &lt;CODE&gt;allowedPath&lt;/CODE&gt;)&lt;/LI&gt;
&lt;LI&gt;filename pattern allowlist&lt;/LI&gt;
&lt;LI&gt;minimum file age&lt;/LI&gt;
&lt;LI&gt;maximum total bytes per execution&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;successful archive verified before any deletion&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;hard-refuse if any candidate file is unknown, or matches a protected pattern (&lt;CODE&gt;*.mdf&lt;/CODE&gt;, &lt;CODE&gt;*.bak&lt;/CODE&gt;, &lt;CODE&gt;/var/log/audit/*&lt;/CODE&gt;, &lt;CODE&gt;*.key&lt;/CODE&gt;, &lt;CODE&gt;*.pem&lt;/CODE&gt;)&lt;/LI&gt;
&lt;LI&gt;a cooldown that prevents re-execution within N hours&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Verify it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az vm run-command invoke -g $RG -n vm-payments-linux \ --command-id RunShellScript \ --scripts "df -h /; systemctl is-active payments.service; ls -la /var/log/payments/trace | head"&lt;/LI-CODE&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Do not give SRE Agent unrestricted SSH or shell access.&lt;/STRONG&gt; Ever. This is the single highest-leverage rule in this post.&lt;/LI&gt;
&lt;LI&gt;Use a version-controlled, fixed-purpose runbook.&lt;/LI&gt;
&lt;LI&gt;Allowlist paths, patterns, file ages, and maximum cleanup size.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Stop if the responsible files are unknown.&lt;/STRONG&gt; A disk filled by something you can't identify is a security event until proven otherwise.&lt;/LI&gt;
&lt;LI&gt;Require successful archival before deletion.&lt;/LI&gt;
&lt;LI&gt;Prevent repeated execution with a cooldown.&lt;/LI&gt;
&lt;LI&gt;Treat cleanup as &lt;STRONG&gt;temporary mitigation&lt;/STRONG&gt; — the problem record is the fix.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_28"&gt;Use case #6 — Linux VM: anomalous CPU saturation&lt;/H3&gt;
&lt;P&gt;&lt;EM&gt;Where "anomalous" is doing all the work.&lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;Release 7.3.1 introduced an immediate retry loop when an inventory dependency failed. The application retried continuously without backoff, consuming nearly all VM CPU and causing request timeouts.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;P&gt;The alert deliberately combined conditions rather than firing on a threshold:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;CPU significantly outside the &lt;STRONG&gt;historical baseline&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Persistent saturation over multiple evaluations&lt;/LI&gt;
&lt;LI&gt;Increased request latency&lt;/LI&gt;
&lt;LI&gt;Increased dependency failures&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;No approved maintenance or batch workload active&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P1 – Production order-processing Linux VM experiencing anomalous CPU saturation&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;A static "CPU &amp;gt; 90%" rule on a batch-processing VM is a pager that everyone learns to ignore. The composite condition is what makes the alert worth waking someone — or an agent — for.&lt;/P&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Confirmed the VM was online.&lt;/LI&gt;
&lt;LI&gt;Compared current CPU with historical behavior.&lt;/LI&gt;
&lt;LI&gt;Identified the order-processing service as the main CPU consumer.&lt;/LI&gt;
&lt;LI&gt;Reviewed application request latency.&lt;/LI&gt;
&lt;LI&gt;Reviewed downstream dependency failures.&lt;/LI&gt;
&lt;LI&gt;Analyzed application retry logs.&lt;/LI&gt;
&lt;LI&gt;Correlated CPU growth with release 7.3.1.&lt;/LI&gt;
&lt;LI&gt;Excluded expected batch jobs.&lt;/LI&gt;
&lt;LI&gt;Excluded Azure maintenance or platform issues.&lt;/LI&gt;
&lt;LI&gt;Confirmed other application instances had sufficient capacity.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;CPU increased from a normal range of 35–50% to 98% four minutes after deployment 7.3.1. The order-processing service is repeatedly calling a failed dependency without backoff. No expected batch job or platform maintenance is active.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Confirm anomaly&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Compares current CPU with the historical baseline&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Analyze impact&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Latency, timeouts, availability, dependencies&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Identify process&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Named order service is the primary CPU consumer&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Correlate deployment&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Release 7.3.1, four minutes before saturation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Analyze logs&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Dependency retry loop without backoff&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Rule out expected work&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Excludes batch, backup, maintenance, scheduled processing&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Assess blast radius&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Traffic and available capacity on other instances&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P1 against the Order Processing CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;CPU, process, dependency, release, customer impact&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Classify response&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Rollback, &lt;STRONG&gt;not&lt;/STRONG&gt; VM resize or arbitrary process termination&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Approval to drain, roll back, restart the service&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Drain VM&lt;/td&gt;&lt;td&gt;Write (Azure)&lt;/td&gt;&lt;td&gt;Removes the VM from load-balancer rotation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Restore prior release&lt;/td&gt;&lt;td&gt;Write (Guest OS/DevOps)&lt;/td&gt;&lt;td&gt;Restores known-good version or configuration&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Restart named service&lt;/td&gt;&lt;td&gt;Write (Guest OS)&lt;/td&gt;&lt;td&gt;Restarts &lt;STRONG&gt;only&lt;/STRONG&gt; &lt;CODE&gt;orders-service&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Validate recovery&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;CPU, retries, latency, dependencies, health recover&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Return to rotation&lt;/td&gt;&lt;td&gt;Write (Azure)&lt;/td&gt;&lt;td&gt;Restores traffic &lt;STRONG&gt;only after&lt;/STRONG&gt; successful validation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Update/resolve INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Drain, rollback, restart, approval, results&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;/td&gt;&lt;td&gt;Create defect&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Retry, backoff, and circuit-breaker remediation&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Steps 12 and 16 are the pattern to steal: &lt;STRONG&gt;drain before you touch, restore traffic only after validation passes.&lt;/STRONG&gt; Most homegrown automation restarts a service while it's still taking traffic and turns a degradation into an outage.&lt;/P&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Release 7.3.1 introduced a retry loop when the inventory dependency failed. After approval, the VM was drained, the previous release was restored, and orders-service was restarted. CPU declined from 98% to 43%, and application latency returned to baseline.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Break it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az vm run-command invoke -g $RG -n vm-payments-linux \ --command-id RunShellScript --scripts " nohup bash -c 'while true; do curl -s -m 1 http://127.0.0.1:9/inventory &amp;gt;/dev/null 2&amp;gt;&amp;amp;1; done' &amp;amp; nohup bash -c 'while true; do :; done' &amp;amp; echo started "&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;CPU on vm-payments-linux is at 98%. Read-only. First: is this actually anomalous, or is it consistent with this VM's historical pattern for this hour and day of week? Show me the baseline. If anomalous: which process, which dependency is it calling, at what rate, and what deployed immediately before? Do NOT propose killing the top process or resizing the VM.&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Expect it to propose&lt;/STRONG&gt; a drain → restore → restart sequence, with the drain step as a separate approval from the restart.&lt;/P&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Do not automatically terminate the highest-CPU process.&lt;/STRONG&gt; It is very often a legitimate workload, and occasionally it's a security incident you just destroyed the evidence for.&lt;/LI&gt;
&lt;LI&gt;Allow operations only for &lt;STRONG&gt;named services&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Drain before service restart where possible.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Escalate unknown or suspicious processes to security&lt;/STRONG&gt; rather than remediating them.&lt;/LI&gt;
&lt;LI&gt;Limit restart attempts.&lt;/LI&gt;
&lt;LI&gt;Do not permanently resize the VM when the evidence points to faulty code. Resizing to survive a retry storm is buying hardware to host a bug.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_29"&gt;Use case #7 — Windows VM with IIS: memory leak&lt;/H3&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;Release ClaimsPortal 5.9.0 introduced a memory leak in the Claims IIS application pool. Memory consumption climbed over several hours, paging began, request queues grew, and IIS returned HTTP 503.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;P&gt;Azure Monitor Agent collected available memory, committed bytes, paging activity, process working set, IIS request queues, HTTP 500/503 responses, and availability-test results. The alert required &lt;STRONG&gt;sustained abnormal growth&lt;/STRONG&gt;, not a brief spike.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P1 – Memory exhaustion affecting production IIS application&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Confirmed the VM and monitoring agent were healthy.&lt;/LI&gt;
&lt;LI&gt;Compared memory behavior with the historical baseline.&lt;/LI&gt;
&lt;LI&gt;Identified the relevant &lt;CODE&gt;w3wp.exe&lt;/CODE&gt; process.&lt;/LI&gt;
&lt;LI&gt;Mapped it to the Claims application pool.&lt;/LI&gt;
&lt;LI&gt;Reviewed paging and request queues.&lt;/LI&gt;
&lt;LI&gt;Correlated HTTP 503 errors with low available memory.&lt;/LI&gt;
&lt;LI&gt;Reviewed Windows Event Logs.&lt;/LI&gt;
&lt;LI&gt;Correlated the growth with release 5.9.0.&lt;/LI&gt;
&lt;LI&gt;Excluded antivirus and scheduled-reporting activity.&lt;/LI&gt;
&lt;LI&gt;Confirmed another instance could carry traffic.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Available memory declined from 42% to 4% over three hours. The Claims application pool grew from 1.8 GB to 11.6 GB without releasing memory after traffic normalized. Paging and HTTP 503 errors followed. The pattern began after release 5.9.0.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;"Without releasing memory after traffic normalized" is the sentence that distinguishes a leak from load. Cache growth under load is normal; failure to return afterwards is not.&lt;/P&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Confirm anomaly&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Memory, committed bytes, paging vs. baseline&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Identify process&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Maps growing &lt;CODE&gt;w3wp.exe&lt;/CODE&gt; to the Claims pool&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Analyze IIS health&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Pools, queues, HTTP errors, availability&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Correlate release&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Links sustained growth to release 5.9.0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Rule out other causes&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Excludes scheduled jobs, antivirus, maintenance&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Assess capacity&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Confirms another instance can serve traffic&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P1 against the Claims Portal CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Memory, paging, pool, release, HTTP impact&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Classify response&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Targeted recycling&lt;/STRONG&gt;, not a full VM restart&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Approval to drain and recycle the named pool&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Drain VM&lt;/td&gt;&lt;td&gt;Write (Azure)&lt;/td&gt;&lt;td&gt;Removes VM from load-balancer rotation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Capture diagnostics&lt;/td&gt;&lt;td&gt;Write (Guest OS)&lt;/td&gt;&lt;td&gt;Captures approved diagnostics to a protected location&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Recycle app pool&lt;/td&gt;&lt;td&gt;Write (Guest OS)&lt;/td&gt;&lt;td&gt;Recycles &lt;STRONG&gt;only&lt;/STRONG&gt; the Claims application pool&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Validate recovery&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;Memory, paging, queues, HTTP errors, availability recover&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Return to rotation&lt;/td&gt;&lt;td&gt;Write (Azure)&lt;/td&gt;&lt;td&gt;Restores traffic after health checks pass&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Update/resolve INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Memory before/after, approval, stability&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Create SNOW PRB&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Memory-leak remediation&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Step 12 before step 13 matters: recycling the pool destroys the evidence. Capture first.&lt;/P&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Abnormal memory growth was isolated to the Claims application pool following release 5.9.0. The VM was drained, the approved application pool was recycled, and health checks passed before traffic was restored. Available memory increased from 4% to 61%, and HTTP 503 responses stopped.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Break it&lt;/STRONG&gt; &lt;EM&gt;(lab VM only)&lt;/EM&gt;:&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;az vm run-command invoke -g $RG -n vm-claims-win ` --command-id RunPowerShellScript --scripts " Install-WindowsFeature Web-Server -IncludeManagementTools New-WebAppPool -Name 'ClaimsPool' # Simulate the leak \$leak = New-Object System.Collections.ArrayList 1..40 | ForEach-Object { [void]\$leak.Add((New-Object byte[] 100MB)) ; Start-Sleep -Milliseconds 200 } "&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;vm-claims-win available memory is at 4%. Read-only. Map the growing process to an IIS application pool. Show me the memory curve for the last 6 hours and tell me whether memory was released after traffic dropped. Correlate with deployment history. Then propose the most targeted possible mitigation — I do not want a VM restart.&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Expect it to propose:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="powershell"&gt;Restart-WebAppPool -Name "ClaimsPool"&lt;/LI-CODE&gt;
&lt;P&gt;…and nothing else on that machine.&lt;/P&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Recycle &lt;STRONG&gt;only the named application pool&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Avoid full VM restart as the first response — it's a bigger hammer with a longer outage and it destroys the leak evidence.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Do not copy memory dumps into ServiceNow.&lt;/STRONG&gt; They contain credentials, tokens, and customer data.&lt;/LI&gt;
&lt;LI&gt;Store diagnostics in a secured location; put the &lt;EM&gt;link&lt;/EM&gt; in the ticket.&lt;/LI&gt;
&lt;LI&gt;Prevent repeated automatic recycling — a pool that needs recycling every 40 minutes is an incident, not a routine.&lt;/LI&gt;
&lt;LI&gt;Escalate if the leak returns during the observation period.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_30"&gt;Use case #8 — Virtual Machine Scale Set: unhealthy instance&lt;/H3&gt;
&lt;P&gt;&lt;EM&gt;The most autonomy-ready use case in the list, and the reason is stateless workloads.&lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;A configuration extension failed while VMSS instance 17 was being provisioned. The VM was running but its application service never started. The instance failed application health probes and caused intermittent errors.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Reduced healthy backend count&lt;/LI&gt;
&lt;LI&gt;Application Health extension failure&lt;/LI&gt;
&lt;LI&gt;Backend health-probe failure&lt;/LI&gt;
&lt;LI&gt;VM extension provisioning failure&lt;/LI&gt;
&lt;LI&gt;Instance-specific errors&lt;/LI&gt;
&lt;LI&gt;Elevated &lt;STRONG&gt;intermittent&lt;/STRONG&gt; HTTP 5xx&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P2 – Unhealthy VM Scale Set instance causing intermittent API failures&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Reviewed the VMSS healthy-instance count.&lt;/LI&gt;
&lt;LI&gt;Identified instance 17 as the only unhealthy instance.&lt;/LI&gt;
&lt;LI&gt;Reviewed backend health.&lt;/LI&gt;
&lt;LI&gt;Compared instance 17 with healthy instances.&lt;/LI&gt;
&lt;LI&gt;Checked the image and VMSS model.&lt;/LI&gt;
&lt;LI&gt;Reviewed VM extension state.&lt;/LI&gt;
&lt;LI&gt;Found the configuration extension failure.&lt;/LI&gt;
&lt;LI&gt;Reviewed boot and application diagnostics.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Confirmed the workload was stateless.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Confirmed eleven instances could carry production traffic.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Instance 17 is the only unhealthy member of the 12-instance scale set. Its application health probe has failed since 09:18 UTC. The configuration extension failed during provisioning, and the application service never started. Eleven healthy instances can maintain service.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Investigate VMSS&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Instance health, provisioning state, healthy count&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Identify instance&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Instance 17 is the only unhealthy member&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Analyze backend health&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Confirms the instance fails application probes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Compare instances&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Image, model, extensions, configuration&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Find extension failure&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Locates the failed configuration extension&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Review diagnostics&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Boot, extension, and application diagnostics&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Assess safe capacity&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Eleven instances can carry traffic&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Confirm statelessness&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Replacement won't destroy required local state&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P2 against the VMSS/application CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Instance, extension error, health, capacity evidence&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Classify response&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Replacement or reimage per approved procedure&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Approval to isolate and replace instance 17&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Isolate instance&lt;/td&gt;&lt;td&gt;Write (Azure)&lt;/td&gt;&lt;td&gt;Ensures the instance receives no production traffic&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Preserve evidence&lt;/td&gt;&lt;td&gt;Read/Write&lt;/td&gt;&lt;td&gt;Stores approved diagnostic evidence securely&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Replace instance&lt;/td&gt;&lt;td&gt;Write (Azure)&lt;/td&gt;&lt;td&gt;Reimages or replaces &lt;STRONG&gt;only&lt;/STRONG&gt; instance 17&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Validate provisioning&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;Image, model, and extensions deploy successfully&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Validate service&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;Backend health, capacity, customer errors recover&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;/td&gt;&lt;td&gt;Update/resolve INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Replacement, approval, diagnostics, recovery&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;/td&gt;&lt;td&gt;Create SNOW PRB&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Extension and image-validation improvement work&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Steps 8 and 7 are the gate. Replacing a stateless instance with eleven healthy peers is genuinely low risk. Replacing a &lt;EM&gt;stateful&lt;/EM&gt; instance, or replacing one when you're already at minimum capacity, is an outage. Both must be &lt;EM&gt;confirmed&lt;/EM&gt;, not assumed.&lt;/P&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;VMSS instance 17 was isolated after its configuration extension failed and the application service did not start. Diagnostic evidence was captured, and the instance was replaced after approval. The replacement passed extension, application, and backend health checks. The scale set has returned to 12 healthy instances.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Break it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;INSTANCE_ID=$(az vmss list-instances -g $RG -n vmss-api-demo \ --query "[5].instanceId" -o tsv) az vmss extension set -g $RG --vmss-name vmss-api-demo \ --name CustomScript --publisher Microsoft.Azure.Extensions \ --settings '{"commandToExecute":"exit 1"}'&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;vmss-api-demo has an unhealthy instance. Read-only. Identify which instance, since when, and the specific extension error. Confirm for me: (a) the workload is stateless, (b) how many healthy instances remain, and (c) whether remaining capacity can carry current traffic with 20% headroom. Only if all three are satisfied, propose a reimage of that single instance. Capture diagnostics before proposing anything.&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Expect it to propose:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az vmss reimage -g $RG -n vmss-api-demo --instance-id $INSTANCE_ID&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Verify it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az vmss get-instance-view -g $RG -n vmss-api-demo --instance-id $INSTANCE_ID \ --query "vmHealth.status.code" az vmss list-instances -g $RG -n vmss-api-demo -o table&lt;/LI-CODE&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Confirm the workload is stateless&lt;/STRONG&gt; before any replacement.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Confirm sufficient healthy capacity first.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Preserve diagnostic evidence before replacement — the instance is your only copy of the failure.&lt;/LI&gt;
&lt;LI&gt;Restrict permissions to the named VMSS.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Limit simultaneous replacements.&lt;/STRONG&gt; One at a time. An agent that reimages six instances because six probes failed has just caused the outage it was investigating.&lt;/LI&gt;
&lt;LI&gt;Do not permit deletion of the entire scale set.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_31"&gt;Use case #9 — Application Gateway: HTTP 502 from unhealthy backends&lt;/H3&gt;
&lt;P&gt;&lt;EM&gt;The cross-component change nobody coordinated.&lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;Customer Portal release 9.2 changed the backend listener from port 443 to 8443. Application Gateway remained configured to connect on 443. All backend probes failed and customers received HTTP 502.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Increased Application Gateway HTTP 502 responses&lt;/LI&gt;
&lt;LI&gt;Increased failed requests&lt;/LI&gt;
&lt;LI&gt;Four unhealthy backends&lt;/LI&gt;
&lt;LI&gt;Reduced healthy-host count&lt;/LI&gt;
&lt;LI&gt;Failed synthetic availability tests&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P1 – Application Gateway returning HTTP 502 due to unhealthy backends&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Reviewed Application Gateway metrics.&lt;/LI&gt;
&lt;LI&gt;Retrieved backend health.&lt;/LI&gt;
&lt;LI&gt;Identified the affected pool.&lt;/LI&gt;
&lt;LI&gt;Reviewed probe path, protocol, host header, and port.&lt;/LI&gt;
&lt;LI&gt;Reviewed backend settings.&lt;/LI&gt;
&lt;LI&gt;Confirmed the application responded on 8443.&lt;/LI&gt;
&lt;LI&gt;Confirmed the gateway used 443.&lt;/LI&gt;
&lt;LI&gt;Correlated the mismatch with release 9.2.&lt;/LI&gt;
&lt;LI&gt;Reviewed NSG, route, DNS, certificate, and WAF changes.&lt;/LI&gt;
&lt;LI&gt;Excluded networking, certificate, and platform-health issues.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;HTTP 502 responses began at 16:07 UTC. All four Customer Portal backends are unhealthy. Release 9.2 changed the backend listener to port 8443, while Application Gateway continues to use port 443. No NSG, routing, or certificate issue correlates with the incident.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Step 9 is what separates a real investigation from a lucky guess. A 502 has at least six plausible causes — NSG, UDR, DNS, expired cert, WAF rule, backend down. The agent has to &lt;EM&gt;exclude&lt;/EM&gt; them, in writing, before you trust the conclusion.&lt;/P&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Investigate gateway&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;HTTP 502, failed requests, latency, backend counts&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Inspect backend health&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Identifies four unhealthy Customer Portal backends&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Review configuration&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Settings, probes, protocol, port, TLS, routing&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Test backend state&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;App responds on 8443 while gateway uses 443&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Correlate changes&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Links mismatch to Customer Portal release 9.2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Rule out networking&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;NSGs, routes, DNS, TLS, WAF, platform health&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Assess blast radius&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Confirms the Customer Portal pool is unavailable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P1 against the portal/gateway CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;502s, backend, port, deployment, known-good configuration&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Classify response&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Restore the known-good backend listener&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Approval to restore source-controlled configuration&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Restore listener&lt;/td&gt;&lt;td&gt;Write (Application)&lt;/td&gt;&lt;td&gt;Restores the application listener to approved port 443&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Validate backend health&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;All four backends become healthy&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Validate application&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;HTTP 502 declines; synthetic transactions pass&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Verify controls&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Confirms no WAF, TLS, routing, or NSG control was weakened&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Update/resolve INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Cause, restoration, approval, recovery&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Create SNOW CHG&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Coordinated change for the intended port migration&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;/td&gt;&lt;td&gt;Create SNOW PRB&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Cross-component deployment-validation work&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Step 12 is a genuinely important choice. There were two ways to fix this: change the &lt;EM&gt;application&lt;/EM&gt; back to 443, or change the &lt;EM&gt;gateway&lt;/EM&gt; to 8443. The agent restores the &lt;STRONG&gt;application to the known-good, source-controlled state&lt;/STRONG&gt; rather than mutating the gateway to match an unapproved change. One of those is a rollback; the other is ratifying an unreviewed change during an outage. Then step 17 files a proper change record for the migration the team clearly &lt;EM&gt;intended&lt;/EM&gt; to do.&lt;/P&gt;
&lt;P&gt;Step 15 exists because the fastest way to make a 502 disappear is to disable TLS validation. The agent must prove it didn't take the fast way.&lt;/P&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Customer Portal release 9.2 changed the backend listener from port 443 to 8443 without a coordinated gateway change. The application listener was restored to the previous configuration. All four backends are healthy, HTTP 502 responses returned to baseline, and synthetic login tests passed for 15 minutes.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;appgw-portal is returning 502s and all backends are unhealthy. Read-only. Walk me through the exclusion, explicitly, for each of: NSG, UDR/route table, DNS resolution, backend TLS certificate, WAF rule blocking, backend process down, and probe configuration mismatch. State which you ruled out and the evidence for each. Then tell me the known-good configuration and where it is source-controlled.&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Verify it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az network application-gateway show-backend-health \ -g $RG -n appgw-portal \ --query "backendAddressPools[].backendHttpSettingsCollection[].servers[].{addr:address,health:health}" -o table&lt;/LI-CODE&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Do not disable TLS validation.&lt;/STRONG&gt; Not to test, not temporarily, not "just to confirm."&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Do not weaken NSGs or WAF policies&lt;/STRONG&gt; as a mitigation.&lt;/LI&gt;
&lt;LI&gt;Use source-controlled configuration as the definition of "known-good."&lt;/LI&gt;
&lt;LI&gt;Restore a known-good state during the incident; migrate through a change record afterwards.&lt;/LI&gt;
&lt;LI&gt;Require approval for gateway or backend changes.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Validate full application transactions, not just health probes.&lt;/STRONG&gt; A probe returning 200 on &lt;CODE&gt;/health&lt;/CODE&gt; proves very little.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H3 id="mcetoc_blog_32"&gt;Use case #10 — Azure Service Bus: queue and dead-letter backlog&lt;/H3&gt;
&lt;P&gt;&lt;EM&gt;The one that teaches the most important lesson in the entire post.&lt;/EM&gt;&lt;/P&gt;
&lt;H4&gt;What happened&lt;/H4&gt;
&lt;P&gt;Release &lt;CODE&gt;fulfillment-worker:6.4.0&lt;/CODE&gt; couldn't deserialize messages containing a new &lt;CODE&gt;deliveryWindow&lt;/CODE&gt; field. Consumer throughput dropped by 92%. The active backlog grew rapidly, and incompatible messages entered the dead-letter queue.&lt;/P&gt;
&lt;H4&gt;How Azure Monitor detected it&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;Increasing active-message count&lt;/LI&gt;
&lt;LI&gt;Increasing oldest-message age&lt;/LI&gt;
&lt;LI&gt;Dead-letter growth&lt;/LI&gt;
&lt;LI&gt;Reduced completed-message rate&lt;/LI&gt;
&lt;LI&gt;Consumer application errors&lt;/LI&gt;
&lt;LI&gt;Delayed downstream business processing&lt;/LI&gt;
&lt;/UL&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;P1 – Production order-event backlog delaying fulfillment&lt;/STRONG&gt;&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;How the agent found the cause&lt;/H4&gt;
&lt;OL&gt;
&lt;LI&gt;Reviewed active, incoming, outgoing, and dead-letter counts.&lt;/LI&gt;
&lt;LI&gt;Calculated message arrival and completion rates.&lt;/LI&gt;
&lt;LI&gt;Confirmed the backlog was growing.&lt;/LI&gt;
&lt;LI&gt;Reviewed consumer instance health.&lt;/LI&gt;
&lt;LI&gt;Reviewed consumer errors and restarts.&lt;/LI&gt;
&lt;LI&gt;Checked downstream dependency health.&lt;/LI&gt;
&lt;LI&gt;Checked Service Bus authentication and authorization.&lt;/LI&gt;
&lt;LI&gt;Correlated the throughput decline with release 6.4.0.&lt;/LI&gt;
&lt;LI&gt;Found deserialization errors for the new field.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Determined scaling more broken consumers would amplify failures.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Agent finding:&lt;/STRONG&gt;&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The order-events queue grew from 3,000 to 185,000 active messages in 35 minutes. Consumer throughput dropped by 92% immediately after release fulfillment-worker:6.4.0. Application logs show deserialization failures involving the new &lt;CODE&gt;deliveryWindow&lt;/CODE&gt; field.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Step 10 is the whole reason to use a reasoning agent instead of an autoscale rule. Every metric here screams "scale out the consumers." An HPA would have done exactly that, and every new replica would have dead-lettered messages faster.&lt;/P&gt;
&lt;H4&gt;Agent action table&lt;/H4&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Action&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Type&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Detail&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Investigate queue&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Active, incoming, outgoing, scheduled, DLQ counts&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Calculate flow rates&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Confirms arrival exceeds completion; backlog growing&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Inspect consumers&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Health, instance count, scaling, errors, dependencies&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Analyze failures&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Deserialization exceptions involving the new field&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Correlate release&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Links the 92% throughput reduction to release 6.4.0&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Rule out Service Bus&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Health, authorization, throttling, networking, service status&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Assess blast radius&lt;/td&gt;&lt;td&gt;Read&lt;/td&gt;&lt;td&gt;Backlog age and fulfillment impact&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Protect message data&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Prevents payloads or personal data entering ServiceNow&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Create SNOW INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;P1 against the fulfillment integration CI&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Update INC evidence&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Backlog, age, flow, exception, release, business impact&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;/td&gt;&lt;td&gt;Classify response&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Rollback, not scaling broken consumers&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;/td&gt;&lt;td&gt;Request approval&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;Approval to restore consumer 6.3.7&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;/td&gt;&lt;td&gt;Roll back consumer&lt;/td&gt;&lt;td&gt;Write (Azure/K8s)&lt;/td&gt;&lt;td&gt;Rolls back through the approved deployment platform&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;/td&gt;&lt;td&gt;Restore capacity&lt;/td&gt;&lt;td&gt;Write (Azure/K8s)&lt;/td&gt;&lt;td&gt;Restores approved consumer instance count&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;/td&gt;&lt;td&gt;Validate processing&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;Consumer and downstream health&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;/td&gt;&lt;td&gt;Validate backlog&lt;/td&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;Completion exceeds arrival; DLQ growth stops&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;/td&gt;&lt;td&gt;Update INC&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Rollback, rates, estimated drain time, approval&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;/td&gt;&lt;td&gt;Maintain incident&lt;/td&gt;&lt;td&gt;Decision&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Keeps the incident open until backlog age meets the objective&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;/td&gt;&lt;td&gt;Create SNOW CHG&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Separate controlled change for DLQ replay&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;/td&gt;&lt;td&gt;Create SNOW PRB&lt;/td&gt;&lt;td&gt;Write (ITSM)&lt;/td&gt;&lt;td&gt;Message-contract compatibility remediation&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H4&gt;Recovery note&lt;/H4&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Consumer release 6.4.0 could not deserialize messages containing the new &lt;CODE&gt;deliveryWindow&lt;/CODE&gt; field. The fulfillment worker was rolled back to 6.3.7. Consumer throughput recovered, new dead-letter growth stopped, and the active backlog is draining at approximately 7,500 messages per minute. Dead-letter replay requires a separately approved procedure.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H4&gt;The lesson: technical recovery is not business recovery&lt;/H4&gt;
&lt;P&gt;Step 18 is the most important row in this entire post.&lt;/P&gt;
&lt;P&gt;At the moment of rollback, every technical signal is green. Consumers are healthy. Throughput has recovered. The DLQ has stopped growing. An agent optimizing for metrics would resolve the incident right there and go back to sleep.&lt;/P&gt;
&lt;P&gt;But there are still 185,000 unshipped orders and a dead-letter queue full of messages that need a &lt;EM&gt;separately approved&lt;/EM&gt; replay procedure. Customers are still affected. &lt;STRONG&gt;The incident stays open until backlog age meets the business objective&lt;/STRONG&gt;, not until the graphs look nice.&lt;/P&gt;
&lt;P&gt;Encode this in the response plan explicitly:&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;Do not resolve this incident when consumer health recovers. Resolution criteria: 1. Completion rate exceeds arrival rate for 15 consecutive minutes, AND 2. Oldest active message age is under 5 minutes, AND 3. Dead-letter count has not increased for 30 minutes. DLQ replay is out of scope for this incident. File a separate change record.&lt;/LI-CODE&gt;
&lt;H4&gt;Try it yourself&lt;/H4&gt;
&lt;P&gt;&lt;STRONG&gt;Break it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;# Flood the queue while no consumer is running for i in $(seq 1 5000); do az servicebus queue message send -g $RG --namespace-name sb-sre-demo \ -q order-events --body "{\"orderId\":$i,\"deliveryWindow\":\"2026-08-09T10:00Z\"}" 2&amp;gt;/dev/null done az servicebus queue show -g $RG --namespace-name sb-sre-demo -n order-events \ --query "countDetails" -o json&lt;/LI-CODE&gt;
&lt;P&gt;&lt;STRONG&gt;Ask it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;order-events on sb-sre-demo has a growing backlog. Read-only. Give me: arrival rate, completion rate, current active count, oldest message age, DLQ count and DLQ growth rate, and the projected drain time at current rates. Then tell me why scaling out consumers is or is not the correct action here. Do not include any message payloads or customer data in your answer.&lt;/LI-CODE&gt;
&lt;P&gt;That last line is not optional. Message bodies routinely contain names, addresses, and payment references — and everything the agent writes goes into a ticket.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Verify it:&lt;/STRONG&gt;&lt;/P&gt;
&lt;LI-CODE lang="bash"&gt;az servicebus queue show -g $RG --namespace-name sb-sre-demo -n order-events \ --query "{active:countDetails.activeMessageCount, dlq:countDetails.deadLetterMessageCount}" -o json&lt;/LI-CODE&gt;
&lt;H4&gt;Guardrails&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Never automatically purge queues.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Do not automatically replay dead-letter messages.&lt;/STRONG&gt; Replay without idempotency guarantees means duplicate charges and duplicate shipments.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Do not place message payloads in ServiceNow.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Confirm idempotency before replay.&lt;/LI&gt;
&lt;LI&gt;Scale consumers &lt;STRONG&gt;only when the processing path is healthy&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Require separate approval for replay or queue configuration changes.&lt;/LI&gt;
&lt;LI&gt;Keep the incident open until &lt;STRONG&gt;business&lt;/STRONG&gt; recovery is confirmed.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_33"&gt;7. The ITSM integration model&lt;/H2&gt;
&lt;H3 id="mcetoc_blog_34"&gt;Recommended incident fields&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Field&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Example&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Short description&lt;/td&gt;&lt;td&gt;Production Orders API pods failing after deployment&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Configuration item&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;prod-aks-orders-api&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Assignment group&lt;/td&gt;&lt;td&gt;Container Platform Operations&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Impact&lt;/td&gt;&lt;td&gt;High&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Urgency&lt;/td&gt;&lt;td&gt;High&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Environment&lt;/td&gt;&lt;td&gt;Production&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Azure resource ID&lt;/td&gt;&lt;td&gt;Full affected Azure resource ID&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Azure alert ID&lt;/td&gt;&lt;td&gt;Azure Monitor alert correlation identifier&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;SRE investigation&lt;/td&gt;&lt;td&gt;Link to the SRE Agent investigation thread&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Current impact&lt;/td&gt;&lt;td&gt;Eight of ten replicas unavailable&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Probable cause&lt;/td&gt;&lt;td&gt;Missing configuration in latest release&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Confidence&lt;/td&gt;&lt;td&gt;High&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Proposed action&lt;/td&gt;&lt;td&gt;Roll back to revision 41&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Approval&lt;/td&gt;&lt;td&gt;Approver and UTC timestamp&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;Ten replicas ready and synthetic tests passing&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Resolution&lt;/td&gt;&lt;td&gt;Service restored through rollback&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;The &lt;STRONG&gt;Confidence&lt;/STRONG&gt; field earns its place. An agent that says "probable cause: missing configuration (confidence: low)" is far more useful than one that always sounds certain, because it tells the human how much to verify before approving.&lt;/P&gt;
&lt;P&gt;Fields the agent can set directly (&lt;STRONG&gt;preview&lt;/STRONG&gt;): &lt;CODE&gt;assignment_group&lt;/CODE&gt;, &lt;CODE&gt;category&lt;/CODE&gt;, &lt;CODE&gt;subcategory&lt;/CODE&gt;, &lt;CODE&gt;impact&lt;/CODE&gt;, &lt;CODE&gt;urgency&lt;/CODE&gt;, &lt;CODE&gt;priority&lt;/CODE&gt;, &lt;CODE&gt;short_description&lt;/CODE&gt;, and any custom &lt;CODE&gt;u_*&lt;/CODE&gt; field. It &lt;STRONG&gt;cannot&lt;/STRONG&gt; change incident state through field updates — acknowledge and resolve are separate, dedicated tools.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_35"&gt;Recommended agent-generated timeline&lt;/H3&gt;
&lt;P&gt;Every work note should carry:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Element&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Example&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Timestamp&lt;/td&gt;&lt;td&gt;&lt;CODE&gt;2026-03-18 14:26 UTC&lt;/CODE&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Observation&lt;/td&gt;&lt;td&gt;HTTP 500 rate increased to 18%&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Evidence&lt;/td&gt;&lt;td&gt;Link to the Application Insights query&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Change correlation&lt;/td&gt;&lt;td&gt;Incident started three minutes after deployment&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Probable cause&lt;/td&gt;&lt;td&gt;Missing production application setting&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Confidence&lt;/td&gt;&lt;td&gt;High&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Proposed action&lt;/td&gt;&lt;td&gt;Swap to previous healthy slot&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Risk&lt;/td&gt;&lt;td&gt;Temporary deployment rollback&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Approval&lt;/td&gt;&lt;td&gt;Incident commander and timestamp&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Execution&lt;/td&gt;&lt;td&gt;Slot-swap operation and result&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Validation&lt;/td&gt;&lt;td&gt;5xx below 1% for 15 minutes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Follow-up&lt;/td&gt;&lt;td&gt;Problem record for configuration validation&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Note that &lt;STRONG&gt;Evidence is a link, not a paste&lt;/STRONG&gt;. This is a deliberate data-protection pattern: the ticket carries a pointer to the query, and the query results stay in the system that already has the right access controls.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_36"&gt;Deduplication strategy&lt;/H3&gt;
&lt;P&gt;Do &lt;STRONG&gt;not&lt;/STRONG&gt; create one incident per alert, pod, queue, or VMSS instance. Correlate on:&lt;/P&gt;
&lt;LI-CODE lang="text"&gt;application/business service + Azure resource ID + environment (production) + alert-rule family + active incident time window&lt;/LI-CODE&gt;
&lt;P&gt;Related alerts attach to the existing incident as evidence or child alerts. Azure Monitor already merges recurring alerts into a single thread when it's the bound platform; for ServiceNow, this correlation key is yours to implement.&lt;/P&gt;
&lt;P&gt;Get this wrong and your first AKS incident produces eight incidents, eight investigations, and eight rollback proposals for the same deployment.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_37"&gt;Record responsibilities&lt;/H3&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Record&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Purpose&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Example&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Incident (INC)&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Restore service quickly and safely&lt;/td&gt;&lt;td&gt;App Service HTTP 500 outage&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Problem (PRB)&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Identify and remove the underlying cause&lt;/td&gt;&lt;td&gt;Missing deployment configuration validation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Change (CHG)&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Govern permanent or higher-risk production changes&lt;/td&gt;&lt;td&gt;Coordinated Application Gateway port migration&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Engineering defect/task&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Correct application or automation behavior&lt;/td&gt;&lt;td&gt;Add retry backoff to the Linux application&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;The agent must clearly distinguish &lt;STRONG&gt;temporary mitigation&lt;/STRONG&gt; from &lt;STRONG&gt;permanent correction&lt;/STRONG&gt;. Every single use case above ends with a follow-up record, and that's not bureaucratic theatre — an agent that mitigates flawlessly and never files a problem record is an agent that lets the same outage recur forever while making the metrics look great.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_38"&gt;8. Reality check: where you have to build&lt;/H2&gt;
&lt;P&gt;This is the section that will save you a month.&lt;/P&gt;
&lt;P&gt;The PDF this post is built from is explicit that these are &lt;STRONG&gt;target response patterns, not guaranteed zero-configuration behavior&lt;/STRONG&gt;. Having now checked each pattern against the product documentation, here is exactly where the gaps are and what fills them.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;#&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;The pattern assumes&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;What's actually documented&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;What you must build&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Agent &lt;STRONG&gt;creates&lt;/STRONG&gt; a ServiceNow INC&lt;/td&gt;&lt;td&gt;ServiceNow is an &lt;EM&gt;inbound&lt;/EM&gt; platform. Documented writes: &lt;STRONG&gt;post discussion entries, acknowledge, resolve&lt;/STRONG&gt;, plus field updates (preview)&lt;/td&gt;&lt;td&gt;Incidents should originate in ServiceNow (via its own Azure Monitor integration) and flow &lt;EM&gt;in&lt;/EM&gt;. If you truly need agent-initiated creation, add a &lt;STRONG&gt;Python tool or MCP server&lt;/STRONG&gt; against the ServiceNow Table API&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Agent creates &lt;STRONG&gt;PRB / CHG / defect&lt;/STRONG&gt; records&lt;/td&gt;&lt;td&gt;Not a documented first-class ServiceNow action&lt;/td&gt;&lt;td&gt;Same: a custom tool against &lt;CODE&gt;/api/now/table/problem&lt;/CODE&gt; and &lt;CODE&gt;/change_request&lt;/CODE&gt;. This is ~30 lines of Python and worth doing properly, with a least-privileged integration user&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;ServiceNow &lt;EM&gt;and&lt;/EM&gt; PagerDuty both connected&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Only one incident platform active at a time&lt;/STRONG&gt;; switching disconnects the other&lt;/td&gt;&lt;td&gt;Bind the agent to your system of record (ServiceNow). Reach the pager through a connector, Teams/Slack, or a webhook&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Agent runs guest-OS cleanup (&lt;CODE&gt;rm&lt;/CODE&gt;, rotate, restart)&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;&lt;CODE&gt;delete&lt;/CODE&gt; and &lt;CODE&gt;remove&lt;/CODE&gt; commands are blocked outright.&lt;/STRONG&gt; &lt;CODE&gt;az keyvault&lt;/CODE&gt; blocked. Management locks respected&lt;/td&gt;&lt;td&gt;Wrap all guest-OS work in &lt;STRONG&gt;fixed-purpose Azure Automation runbooks&lt;/STRONG&gt; or a constrained &lt;CODE&gt;az vm run-command&lt;/CODE&gt; script, invoked with allowlisted parameters. See use case #5&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;Agent "pauses the release pipeline"&lt;/td&gt;&lt;td&gt;Requires the GitHub or Azure DevOps connector, plus permissions on that pipeline&lt;/td&gt;&lt;td&gt;Connect source control; grant pipeline permissions explicitly; test the pause path before you need it&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Approval gate on &lt;EM&gt;every&lt;/EM&gt; action&lt;/td&gt;&lt;td&gt;Review mode shows Approve/Deny &lt;STRONG&gt;only for Azure infrastructure operations&lt;/STRONG&gt;. Emails, Teams posts, and external queries proceed on the agent's reasoning&lt;/td&gt;&lt;td&gt;Use &lt;STRONG&gt;hooks&lt;/STRONG&gt; or &lt;STRONG&gt;tool access policies&lt;/STRONG&gt; to gate non-Azure actions&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Agent resolves incidents&lt;/td&gt;&lt;td&gt;Supported — but during a pilot you don't want it&lt;/td&gt;&lt;td&gt;Require human confirmation before resolve. Encode it in the response plan and enforce it with a &lt;CODE&gt;Stop&lt;/CODE&gt; hook&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;One agent handles everything&lt;/td&gt;&lt;td&gt;Response plans route to &lt;STRONG&gt;custom agents&lt;/STRONG&gt;; skills cap at &lt;STRONG&gt;five concurrent active&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Build domain specialists (§4.6). A single mega-agent thrashes its skill budget&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Autonomous mode by default is fine&lt;/td&gt;&lt;td&gt;Per-plan default &lt;STRONG&gt;is&lt;/STRONG&gt; Autonomous, and connecting a platform auto-creates an autonomous &lt;CODE&gt;quickstart_handler&lt;/CODE&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Delete the quickstart plan.&lt;/STRONG&gt; Set every plan to Review explicitly&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;Agent has broad subscription rights&lt;/td&gt;&lt;td&gt;You can't remove individual permissions — only whole resource groups&lt;/td&gt;&lt;td&gt;Design resource groups as blast-radius boundaries &lt;STRONG&gt;before&lt;/STRONG&gt; onboarding&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;None of these are blockers. All of them are a week of work you'd rather discover now than during your pilot readout.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_39"&gt;9. Approval and autonomy policy&lt;/H2&gt;
&lt;P&gt;The policy I would actually ship:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Action category&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Recommended initial policy&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Read metrics, logs, traces, resource health&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Automatic&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Correlate deployments and configuration changes&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Automatic&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Create a ServiceNow incident&lt;/td&gt;&lt;td&gt;Automatic after deduplication&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Add sanitized work notes&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Automatic&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Prepare a remediation plan&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Automatic&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Create a draft ServiceNow change&lt;/td&gt;&lt;td&gt;Automatic, but &lt;STRONG&gt;not&lt;/STRONG&gt; approve it&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Modify an Azure production resource&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Human approval required&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Execute a VM guest runbook&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Human approval required&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Roll back an application&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Human approval required&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Delete or replace a stateless VMSS instance&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Human approval required&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Resolve a ServiceNow incident&lt;/td&gt;&lt;td&gt;Human confirmation during the pilot&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Delete data, purge queues, replay DLQ messages&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Separate explicit approval&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Autonomous remediation&lt;/td&gt;&lt;td&gt;Only after a proven, bounded pilot&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Two notes on making this real:&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Start in Review and stay there longer than feels necessary.&lt;/STRONG&gt; The documented recommendation is to observe for two to four weeks and then promote &lt;EM&gt;specific&lt;/EM&gt; triggers you consistently approve. Not the agent — the triggers. Promotion should be per-response-plan and evidence-based: "we approved this exact rollback proposal eleven times without modification" is a reason to go autonomous. "It seems good" is not.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Autonomy should be earned per action type, not per environment.&lt;/STRONG&gt; "Autonomous in staging" is a fine starting rule, but the durable version is "autonomous for VMSS single-instance reimage where the workload is stateless and healthy capacity exceeds 80%" — a narrow, well-characterized action with a mechanical precondition.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_40"&gt;10. Cross-cutting security controls&lt;/H2&gt;
&lt;OL&gt;
&lt;LI&gt;Use a &lt;STRONG&gt;dedicated managed identity&lt;/STRONG&gt; for SRE Agent.&lt;/LI&gt;
&lt;LI&gt;Scope Azure roles to selected &lt;STRONG&gt;resources or resource groups&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Avoid broad &lt;STRONG&gt;Contributor&lt;/STRONG&gt; and &lt;STRONG&gt;Owner&lt;/STRONG&gt; assignments.&lt;/LI&gt;
&lt;LI&gt;Use &lt;STRONG&gt;fixed-purpose Automation runbooks&lt;/STRONG&gt; for guest operations.&lt;/LI&gt;
&lt;LI&gt;Do &lt;STRONG&gt;not&lt;/STRONG&gt; provide unrestricted SSH, shell, or PowerShell execution.&lt;/LI&gt;
&lt;LI&gt;Use a dedicated &lt;STRONG&gt;least-privileged ServiceNow integration identity&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Prefer &lt;STRONG&gt;OAuth&lt;/STRONG&gt; or a managed connector over stored credentials.&lt;/LI&gt;
&lt;LI&gt;Store required secrets in &lt;STRONG&gt;Key Vault&lt;/STRONG&gt; — never in prompts. (The agent blocks &lt;CODE&gt;az keyvault&lt;/CODE&gt; commands entirely, which helps.)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Sanitize logs&lt;/STRONG&gt; before posting them into ServiceNow.&lt;/LI&gt;
&lt;LI&gt;Do not post &lt;STRONG&gt;tokens, personal data, SQL text, message payloads, or memory dumps&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Record &lt;STRONG&gt;every approval and production action&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Define &lt;STRONG&gt;remediation cooldowns&lt;/STRONG&gt; and maximum retry counts.&lt;/LI&gt;
&lt;LI&gt;Require &lt;STRONG&gt;post-action application validation&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;Retain existing &lt;STRONG&gt;manual runbooks&lt;/STRONG&gt; as fallback.&lt;/LI&gt;
&lt;LI&gt;Use &lt;STRONG&gt;Azure Cost Management alerts&lt;/STRONG&gt; for temporary scaling actions.&lt;/LI&gt;
&lt;/OL&gt;
&lt;H3 id="mcetoc_blog_41"&gt;What the platform gives you for free&lt;/H3&gt;
&lt;P&gt;Worth knowing so you don't rebuild it:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Layer&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Isolation model&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Compute&lt;/td&gt;&lt;td&gt;Dedicated sandbox (micro VM) per agent; tool execution separate from the reasoning loop&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Database&lt;/td&gt;&lt;td&gt;Separate database per agent&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Blob storage&lt;/td&gt;&lt;td&gt;Separate blob storage per agent&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Network&lt;/td&gt;&lt;td&gt;Per-agent proxy instance validating every outbound request&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Credentials&lt;/td&gt;&lt;td&gt;Identity sidecar issues short-lived, per-call tokens; &lt;STRONG&gt;credentials never enter the reasoning context&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Token lifetimes: managed identity ~1 hour (auto-refreshed), OAuth refreshed 20 minutes before expiry, per-tool-call action tokens are single-use, blob SAS 1 hour refreshed at 45 minutes. Each tool invocation launches a fresh process whose entire tree terminates on completion — there are no persistent process pools, so one tool call cannot see another's environment.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_42"&gt;The audit trail&lt;/H3&gt;
&lt;P&gt;Every &lt;CODE&gt;az&lt;/CODE&gt; command is logged to &lt;STRONG&gt;your&lt;/STRONG&gt; Application Insights as an &lt;CODE&gt;AgentAzCliExecution&lt;/CODE&gt; custom event. This is your evidence for change management:&lt;/P&gt;
&lt;LI-CODE lang="kusto"&gt;customEvents | where name == "AgentAzCliExecution" | where timestamp &amp;gt; ago(30d) | project timestamp, command = tostring(customDimensions.command), resource = tostring(customDimensions.resourceId), succeeded = tostring(customDimensions.success), thread = tostring(customDimensions.threadId) | order by timestamp desc&lt;/LI-CODE&gt;
&lt;P&gt;Run that query in front of your auditor once and most of the "but can we prove what it did" conversation ends.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_43"&gt;11. A 30/60/90 pilot that survives contact with your CAB&lt;/H2&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Phase&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Enabled capability&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;Detect Azure Monitor alerts&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Create or correlate ServiceNow incidents&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Perform &lt;STRONG&gt;read-only&lt;/STRONG&gt; investigation&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;/td&gt;&lt;td&gt;Add sanitized findings to ServiceNow&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Recommend&lt;/STRONG&gt; remediation without execution&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;/td&gt;&lt;td&gt;Execute bounded actions after approval in Review mode&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;/td&gt;&lt;td&gt;Validate technical &lt;STRONG&gt;and business&lt;/STRONG&gt; recovery&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Prepare incident resolution and follow-up records&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;/td&gt;&lt;td&gt;Consider autonomy only for proven low-risk actions&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Phases 1–5 have &lt;STRONG&gt;zero production write risk&lt;/STRONG&gt; and deliver most of the MTTR reduction. Do not rush past them to get to the demo-friendly part.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_44"&gt;The best first five candidates&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;App Service deployment-slot rollback&lt;/STRONG&gt; — clean trigger, reversible action, unambiguous validation&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;AKS deployment rollback&lt;/STRONG&gt; — same shape, one GitOps caveat&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;VMSS unhealthy-instance replacement&lt;/STRONG&gt; — stateless, bounded, easy precondition check&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Restricted VM disk-recovery runbook&lt;/STRONG&gt; — high toil, high value, forces you to build the runbook pattern properly&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Automatic ServiceNow incident creation and timeline updates&lt;/STRONG&gt; — the compounding one; every incident from here on is better documented than any incident before it&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;These five share the properties you want: clear triggers, tightly bounded actions, measurable validation criteria, and practical escalation paths.&lt;/P&gt;
&lt;H3 id="mcetoc_blog_45"&gt;What to measure in week one&lt;/H3&gt;
&lt;P&gt;Before you enable a single write action, capture your baseline:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Median time from alert to &lt;STRONG&gt;first accurate human diagnosis&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;Percentage of incidents where the first hypothesis was wrong&lt;/LI&gt;
&lt;LI&gt;Median time from diagnosis to mitigation&lt;/LI&gt;
&lt;LI&gt;Percentage of incidents with a complete timeline in the ticket&lt;/LI&gt;
&lt;LI&gt;Percentage of incidents that produced a follow-up problem record&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The read-only phase moves the first, second, and fourth of those immediately. If it doesn't, your telemetry is the problem, not the agent — and that's a genuinely useful thing to discover in week one rather than week twelve.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_46"&gt;12. Measuring whether it's actually working&lt;/H2&gt;
&lt;P&gt;Under &lt;STRONG&gt;Monitor → Incident metrics&lt;/STRONG&gt;:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Metric&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;What it shows&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Incidents reviewed&lt;/td&gt;&lt;td&gt;Total incidents the agent processes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Mitigated by agent&lt;/td&gt;&lt;td&gt;Resolved autonomously&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Assisted by agent&lt;/td&gt;&lt;td&gt;Agent helped; a human completed it&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Mitigated by user&lt;/td&gt;&lt;td&gt;Human resolved using agent-provided information&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pending user action&lt;/td&gt;&lt;td&gt;Waiting on a human&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;The counter-intuitive read: &lt;STRONG&gt;"Assisted by agent" and "Mitigated by user" are the healthy numbers during a pilot.&lt;/STRONG&gt; A high "Mitigated by agent" count in month one means someone left autonomy on.&lt;/P&gt;
&lt;P&gt;Watch &lt;STRONG&gt;Pending user action&lt;/STRONG&gt; closely. A growing queue there means either your approval routing is broken or the agent is proposing things nobody is comfortable approving — both are important signals, and both are invisible without this dashboard.&lt;/P&gt;
&lt;P&gt;Also check &lt;STRONG&gt;Monitor → Session insights&lt;/STRONG&gt; periodically. Each insight card links back to the thread that generated it, so you can trace any learned pattern to its origin. If the agent has learned something wrong, this is where you find it — and &lt;CODE&gt;#forget&lt;/CODE&gt; is how you fix it.&lt;/P&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_47"&gt;13. Resources&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;Core documentation&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/overview" target="_blank" rel="noopener"&gt;Overview of Azure SRE Agent&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/security-overview" target="_blank" rel="noopener"&gt;Security and trust model&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/permissions" target="_blank" rel="noopener"&gt;Agent permissions&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/run-modes" target="_blank" rel="noopener"&gt;Run modes&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Incident response&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/incident-platforms" target="_blank" rel="noopener"&gt;Incident management platforms&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/incident-response-plans" target="_blank" rel="noopener"&gt;Incident response plans&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/servicenow-incidents" target="_blank" rel="noopener"&gt;ServiceNow incident indexing&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/root-cause-analysis" target="_blank" rel="noopener"&gt;Root cause analysis&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/execute-mitigations" target="_blank" rel="noopener"&gt;Execute mitigations&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Extensibility&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/sub-agents" target="_blank" rel="noopener"&gt;Custom agents&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/skills" target="_blank" rel="noopener"&gt;Skills&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/agent-hooks" target="_blank" rel="noopener"&gt;Agent hooks&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/scheduled-tasks" target="_blank" rel="noopener"&gt;Scheduled tasks&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/sre-agent/memory" target="_blank" rel="noopener"&gt;Memory and knowledge&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR /&gt;
&lt;H2 id="mcetoc_blog_48"&gt;Closing&lt;/H2&gt;
&lt;P&gt;The framing that makes this work isn't "AI runs my production." It's this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;STRONG&gt;Your agent is the most junior person on the rotation — and the most thorough.&lt;/STRONG&gt; It will never skip the Resource Health check. It will never forget to compare against the previous slot. It will never write "restarted it, seems fine" in a work note at 4 AM. And it will never, ever be allowed to &lt;CODE&gt;rm -rf&lt;/CODE&gt; anything.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Every guardrail in this post exists to keep it in that role. Scope the identity to resource groups. Keep production writes in Review. Wrap guest-OS work in runbooks with allowlists. Never let it purge a queue or replay a dead-letter message on its own. Keep the incident open until customers are actually served, not until the graphs look nice.&lt;/P&gt;
&lt;P&gt;Do that, and the ten workflows above stop being a slide deck and start being your Tuesday.&lt;/P&gt;
&lt;P&gt;Start with use case #1. One App Service, one slot, one alert rule, one response plan in Review mode. Watch it assemble an evidence chain you'd have spent twenty minutes building by hand, and then decide how much further you want to go.&lt;/P&gt;
&lt;HR /&gt;
&lt;P&gt;&lt;EM&gt;The ten scenarios in this post are target response patterns. Each one requires appropriate telemetry, scoped Azure RBAC, response-plan instructions, approved remediation tooling, and ITSM integration. Confirm current Azure SRE Agent and ServiceNow connector capabilities against Microsoft documentation before implementing — the product is moving quickly, and several capabilities referenced here are in preview.&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Fri, 28 Aug 2026 16:14:08 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/your-on-call-rotation-has-a-new-member-10-production-incidents/ba-p/4545187</guid>
      <dc:creator>zmustafa</dc:creator>
      <dc:date>2026-08-28T16:14:08Z</dc:date>
    </item>
    <item>
      <title>Stop paying for idle VMs — safely: ringed start/stop waves for your Azure estate</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/stop-paying-for-idle-vms-safely-ringed-start-stop-waves-for-your/ba-p/4542066</link>
      <description>&lt;P&gt;&lt;EM&gt;Turning non-production VMs off at night is the easiest Azure saving there is. Doing it without causing an outage is the part nobody writes about. This is an open-source scheduler that takes that saving as an&amp;nbsp;&lt;STRONG&gt;application&lt;/STRONG&gt;, in&amp;nbsp;&lt;STRONG&gt;ordered rings&lt;/STRONG&gt;, with&amp;nbsp;&lt;STRONG&gt;two independent safety gates&lt;/STRONG&gt;&amp;nbsp;between you and a real power action — and it runs entirely in your own subscription.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It is 3am. Somewhere in your subscription, a dev estate is fully powered and doing absolutely nothing. Nobody has logged in since 18:40. The bill does not care.&lt;/P&gt;
&lt;P&gt;The fix looks trivial for about ten minutes. Write a script, stop everything at 19:00, start everything at 07:00, collect the applause. Then someone runs it against an environment where the database tier and the app tier are just two more entries in the same resource group, the app tier comes up first, spends four minutes failing its health probe, and the platform team spends the morning explaining why the cost-saving initiative caused an incident.&lt;/P&gt;
&lt;P&gt;The saving is easy.&amp;nbsp;&lt;STRONG&gt;The sequencing is what breaks.&lt;/STRONG&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;The whole application, end to end. Everything you are about to see runs against the built-in demo estate with both safety gates off — note the mock-mode banners.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://github.com/zmustafa/AzureVMScheduler" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Azure VM Scheduler&lt;/STRONG&gt;&lt;/A&gt;&amp;nbsp;is an open-source, MIT-licensed scheduler that models your estate the way you actually talk about it —&amp;nbsp;&lt;EM&gt;applications hold rings, rings hold virtual machines&lt;/EM&gt;&amp;nbsp;— and fans every scheduled occurrence out into an&amp;nbsp;&lt;STRONG&gt;ordered, staggered wave&lt;/STRONG&gt;&amp;nbsp;of per-VM actions. Starts walk the rings forward. Stops unwind them in reverse. And until you deliberately flip two separate switches, none of it touches a real machine.&lt;/P&gt;
&lt;H2&gt;Two problems, not one&lt;/H2&gt;
&lt;H3&gt;The money&lt;/H3&gt;
&lt;P&gt;Deallocating a VM stops the compute meter. That is the whole trick, and it is a good one: a machine that only needs to run 07:00–19:00 on weekdays is genuinely needed for&amp;nbsp;&lt;STRONG&gt;60 of the 168 hours in a week — about 36%&lt;/STRONG&gt;. The other 64% is compute you are buying and nobody is using.&lt;/P&gt;
&lt;P&gt;Be precise about what you keep paying for, because this is where "we'll save 64%" quietly becomes a credibility problem in your next FinOps review:&amp;nbsp;&lt;STRONG&gt;deallocation stops compute charges, not storage&lt;/STRONG&gt;. Managed disks keep billing whether the VM is running or not, as do reserved public IP addresses and anything else with its own meter. The saving is real and it is large, but it is a saving on the compute line, not on the invoice total.&lt;/P&gt;
&lt;H3&gt;The shape&lt;/H3&gt;
&lt;P&gt;Azure already gives you several ways to turn a machine off on a timer, and they work. The catch is that they are shaped like a&amp;nbsp;&lt;EM&gt;machine&lt;/EM&gt;, or like a&amp;nbsp;&lt;EM&gt;tag&lt;/EM&gt;, and applications are not shaped like either. An application has an order. The data tier comes up before the app tier; the front door comes up last; and on the way down it all has to happen in reverse. A canary ring exists precisely so that it is the&amp;nbsp;&lt;EM&gt;first&lt;/EM&gt;&amp;nbsp;thing to come up and the&amp;nbsp;&lt;EM&gt;last&lt;/EM&gt;&amp;nbsp;thing to go down.&lt;/P&gt;
&lt;P&gt;None of that is expressible as "shut this VM down at 19:00", because the unit is wrong. What a large estate needs is a scheduler whose unit of scheduling is the&amp;nbsp;&lt;STRONG&gt;application&lt;/STRONG&gt;, with ordered stages inside it — and that is a modelling problem, sitting on top of primitives Azure already exposes very well.&lt;/P&gt;
&lt;H2&gt;Where this fits alongside what Azure already gives you&lt;/H2&gt;
&lt;P&gt;Azure is not short of building blocks here. Azure Resource Graph will tell you what is deployed across every subscription you can see. Azure Resource Manager exposes&amp;nbsp;start,&amp;nbsp;deallocate&amp;nbsp;and&amp;nbsp;powerOff&amp;nbsp;as first-class operations with proper RBAC around them. Azure Policy, Azure Automation and the platform's own auto-shutdown all sit on that same foundation. This project is not an alternative to any of that — it is a client of it. Discovery goes through Azure Resource Graph, power actions go through ARM, and identity goes through Microsoft Entra ID.&lt;/P&gt;
&lt;P&gt;What it adds is a shape:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Tool&lt;/th&gt;&lt;th&gt;Designed for&lt;/th&gt;&lt;th&gt;Unit of action&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;VM / DevTest Labs&amp;nbsp;&lt;STRONG&gt;Auto-shutdown&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;A single VM's daily shutdown time&lt;/td&gt;&lt;td&gt;One VM&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Azure Automation&lt;/STRONG&gt;&amp;nbsp;runbooks&lt;/td&gt;&lt;td&gt;Arbitrary automation you author and maintain&lt;/td&gt;&lt;td&gt;Whatever you script&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Start/Stop VMs v2&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Scheduled, sequenced and CPU-triggered start-stop across whole scopes&lt;/td&gt;&lt;td&gt;Subscription, resource group or VM list&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Azure VM Scheduler&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Ordered, application-aware start/stop waves with per-action safety gates&lt;/td&gt;&lt;td&gt;Application → ring → VM&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Read that table honestly.&amp;nbsp;&lt;STRONG&gt;If a resource group is a good enough boundary for your estate, use the built-in option&lt;/STRONG&gt;&amp;nbsp;— it is less to run, less to patch and less to explain to your auditor. Plenty of dev estates genuinely are flat, and for those this project is over-engineering.&lt;/P&gt;
&lt;P&gt;This exists for the estates where it isn't. Where boot order matters, where a canary ring means something, where "stop everything in&amp;nbsp;rg-dev" would take down the one machine that runs overnight settlement, and where the blast radius of a scheduling mistake is measured in incidents rather than in dollars.&lt;/P&gt;
&lt;H3&gt;A closer look at Start/Stop VMs v2&lt;/H3&gt;
&lt;P&gt;Of the built-in options,&amp;nbsp;&lt;A href="https://learn.microsoft.com/azure/azure-functions/start-stop-v2/overview" target="_blank" rel="noopener"&gt;Start/Stop VMs v2&lt;/A&gt;&amp;nbsp;is the nearest neighbour, so it deserves a proper description rather than a table row. It is a Microsoft-published solution you deploy into your own subscription: an Azure Functions app holding a managed identity in Microsoft Entra ID, five Azure Logic Apps that carry the schedules and call that app with a JSON payload, Azure Storage for execution metadata and queues, and Application Insights behind a shared Azure dashboard with optional email through an action group. Each action is scoped to one or more subscriptions, resource groups, or an explicit VM list — with wildcard exclusions — and machines are ordered within a scope by tagging them&amp;nbsp;sequencestart&amp;nbsp;and&amp;nbsp;sequencestop&amp;nbsp;with values from 1 to N. It also does something this project does not:&amp;nbsp;&lt;STRONG&gt;AutoStop&lt;/STRONG&gt;&amp;nbsp;watches CPU utilisation and stops idle machines via an alert.&lt;/P&gt;
&lt;P&gt;One thing to know if you are choosing today: Microsoft's guidance states that no further development or enhancements are planned for Start/Stop VMs v2 beyond what is needed to keep its components on supported versions. That is ordinary platform evolution, not a warning — it still deploys, it was moved to the .NET 8 isolated worker model in 2024, and it still does what it does well.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&amp;nbsp;&lt;/th&gt;&lt;th&gt;Start/Stop VMs v2&lt;/th&gt;&lt;th&gt;Azure VM Scheduler&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Where the schedule lives&lt;/td&gt;&lt;td&gt;Azure Logic Apps you deploy and manage&lt;/td&gt;&lt;td&gt;The application's own database, edited in a UI or over its API&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;How machines are grouped&lt;/td&gt;&lt;td&gt;Subscriptions, resource groups or a VM list, with wildcard exclusions&lt;/td&gt;&lt;td&gt;Application → ring → VM, inherited down the tree&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;How order is expressed&lt;/td&gt;&lt;td&gt;A&amp;nbsp;sequencestart&amp;nbsp;/&amp;nbsp;sequencestop&amp;nbsp;tag per machine, processed in ascending order&lt;/td&gt;&lt;td&gt;The ring's sequence, inherited by every machine in it&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Where results land&lt;/td&gt;&lt;td&gt;Application Insights, a shared Azure dashboard and action-group email&lt;/td&gt;&lt;td&gt;Per-run and per-attempt records in the app, with per-attempt retry&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Where it runs&lt;/td&gt;&lt;td&gt;Azure&lt;/td&gt;&lt;td&gt;Azure, or a laptop on SQLite&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Three differences follow from that, and they are differences of design centre rather than of quality.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Grouping is modelled, not enumerated.&lt;/STRONG&gt;&amp;nbsp;A scope in Start/Stop VMs v2 is written into the payload of the Logic App that owns it. Here the scope is a thing in the model: schedule the application and every ring and machine underneath inherits it, so adding a VM to a ring puts it in the right wave with nothing else to edit and no tag to remember.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Order and overlap are properties of that model.&lt;/STRONG&gt;&amp;nbsp;Sequencing tags are processed in ascending order for both directions, so a reverse-order shutdown is something you author machine by machine in the&amp;nbsp;sequencestop&amp;nbsp;values. Here reverse&amp;nbsp;&lt;EM&gt;is&lt;/EM&gt;&amp;nbsp;the default for stops — the wave diagram further down this post is two rows of the same list read in opposite directions. And because schedules can be inherited, they can overlap, which is why resolution is per action and nearest-wins: a property you need only once inheritance exists.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The guards are sized to the unit.&lt;/STRONG&gt;&amp;nbsp;When the thing you point a schedule at is an entire application, a mistake is proportionally bigger — so the stop path gets two independent gates,&amp;nbsp;never_stop&amp;nbsp;that a machine inherits from any ancestor rather than an exclusion list per schedule, and an exact-count confirmation. That machinery is the price of the larger scoping unit, not a criticism of a smaller one.&lt;/P&gt;
&lt;P&gt;So: if you want CPU-triggered auto-stop, availability in the US Government cloud, a Microsoft support path, or simply nothing extra to run beyond Azure resources themselves, Start/Stop VMs v2 is the better answer. This project is for the estates where ordering, inheritance and blast radius are the hard part.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;Start/Stop VMs v2 details verified against its&amp;nbsp;&lt;A href="https://learn.microsoft.com/azure/azure-functions/start-stop-v2/overview" target="_blank" rel="noopener"&gt;overview documentation&lt;/A&gt;, July 2026.&lt;/EM&gt;&lt;/P&gt;
&lt;H2&gt;Model the estate the way you talk about it&lt;/H2&gt;
&lt;P&gt;The hierarchy is deliberately, aggressively shallow:&amp;nbsp;&lt;STRONG&gt;an application holds rings, a ring holds virtual machines, and that is the entire tree.&lt;/STRONG&gt;&amp;nbsp;Exactly two levels, enforced everywhere — on create, on move, on CSV import, on settings import. There is no way to end up with a ring inside a ring inside a ring, which means there is never a debate about what a given schedule actually covers.&lt;/P&gt;
&lt;P&gt;The built-in demo estate shows the idea in about thirty seconds.&amp;nbsp;&lt;STRONG&gt;Zava Commerce&lt;/STRONG&gt;&amp;nbsp;has three rings —&amp;nbsp;Canary&amp;nbsp;(one VM),&amp;nbsp;Pilot&amp;nbsp;(two),&amp;nbsp;Production&amp;nbsp;(four).&amp;nbsp;&lt;STRONG&gt;Zava Analytics&lt;/STRONG&gt;&amp;nbsp;has&amp;nbsp;Batch&amp;nbsp;and&amp;nbsp;Interactive.&amp;nbsp;&lt;STRONG&gt;Zava Intranet&lt;/STRONG&gt;&amp;nbsp;has&amp;nbsp;Pilot&amp;nbsp;and&amp;nbsp;Production. If your estate is tiered rather than ringed, name them&amp;nbsp;Data,&amp;nbsp;App&amp;nbsp;and&amp;nbsp;Web&amp;nbsp;instead; the model does not care what a stage is called, only that stages are&amp;nbsp;&lt;EM&gt;ordered&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;Attach a schedule to the application and every ring inherits it. Override one ring and only that ring changes. Override a single VM and only that machine changes. That is the whole inheritance story, and it is short on purpose.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The ring board for one application. The sequence number on each ring is the whole ordering model — there is nothing else to configure.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;Waves: what actually happens at 06:30&lt;/H2&gt;
&lt;P&gt;One occurrence produces one&amp;nbsp;&lt;STRONG&gt;run&lt;/STRONG&gt;. One run fans out into one&amp;nbsp;&lt;STRONG&gt;attempt per virtual machine&lt;/STRONG&gt;, ordered by ring sequence, with a configurable&amp;nbsp;&lt;STRONG&gt;stagger&lt;/STRONG&gt;&amp;nbsp;between machines so you never hand ARM several hundred simultaneous power requests and watch it start throttling you.&lt;/P&gt;
&lt;P&gt;Zava Commerce's start wave fires at&amp;nbsp;&lt;STRONG&gt;06:30&lt;/STRONG&gt;&amp;nbsp;with a&amp;nbsp;&lt;STRONG&gt;60-second stagger&lt;/STRONG&gt;. The canary machine goes first. A minute later the two pilot machines. A minute after that the four production machines, one per minute. Seven machines, seven attempts, in a defined order, each recorded.&lt;/P&gt;
&lt;P&gt;The stop wave at&amp;nbsp;&lt;STRONG&gt;20:00&lt;/STRONG&gt;&amp;nbsp;does the same thing backwards.&amp;nbsp;&lt;STRONG&gt;Stops default to&amp;nbsp;reverse&lt;/STRONG&gt;&amp;nbsp;— the last ring in the sequence is the first one down, and the canary ring, which came up first, goes down last. That default is not a convenience; it is the single most important behaviour in the product, because reverse-order shutdown is exactly what a hand-rolled script forgets.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;One application, two waves. Read the stop row right to left and you have the start row — that is the point. If you only take one picture from this post, take this one.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Nearest schedule wins — per action&lt;/H3&gt;
&lt;P&gt;Here is the guarantee that makes overlapping schedules safe to live with. For&amp;nbsp;&lt;STRONG&gt;each action independently&lt;/STRONG&gt;, a VM is acted on by the&amp;nbsp;&lt;EM&gt;nearest&lt;/EM&gt;&amp;nbsp;schedule that targets it: a schedule on the VM beats one on its ring, which beats one on its application. Deeper shadows shallower.&lt;/P&gt;
&lt;P&gt;Because start and stop are resolved separately, a machine ends up with&amp;nbsp;&lt;STRONG&gt;at most one effective start and at most one effective stop&lt;/STRONG&gt;. Stack an application-wide 06:30 start, a ring-level 07:15 start and a per-VM 05:00 start on the same machine and it still starts exactly once, at 05:00. It cannot be started twice. It cannot be stopped twice. That property holds no matter how many schedules sit above it, which is what lets you layer overrides without keeping a mental model of the whole tree.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;A wave running. Each row appears as its machine's turn comes up, in ring order, one stagger interval apart.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Every wave leaves a paper trail&lt;/H3&gt;
&lt;P&gt;Every wave is fully reconstructable afterwards. A run carries a rolled-up status —&amp;nbsp;succeeded,&amp;nbsp;partially_failed,&amp;nbsp;failed,&amp;nbsp;timed_out&amp;nbsp;or&amp;nbsp;cancelled&amp;nbsp;— and each attempt records its own status, whether it ran in real or mock mode, a message, its attempt number, its sequence position and a correlation id. When someone asks "what happened at 06:30 on Tuesday", the answer is a page, not an investigation. Failed attempts can be retried individually, or the whole run can be retried and it will pick up only the ones that failed.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;One wave, after the fact: the mode it ran in, the correlation id, the roll-up, and every machine it touched. This page is the answer to "what happened at 06:30 on Tuesday".&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;Recurrence you can check before you trust it&lt;/H2&gt;
&lt;P&gt;Schedules come in four flavours:&amp;nbsp;&lt;STRONG&gt;one-time&lt;/STRONG&gt;,&amp;nbsp;&lt;STRONG&gt;daily&lt;/STRONG&gt;,&amp;nbsp;&lt;STRONG&gt;weekly&lt;/STRONG&gt;&amp;nbsp;and full&amp;nbsp;&lt;STRONG&gt;five-field cron&lt;/STRONG&gt;&amp;nbsp;— lists, ranges, steps, month and day names, Sunday as 0. Daily and weekly are stored as friendly fields and translated to cron behind the scenes, so there is exactly one occurrence engine in the codebase rather than one engine and three special cases that disagree at the edges.&lt;/P&gt;
&lt;P&gt;Everything is timezone-aware and stored against an IANA zone (the demo estate runs on&amp;nbsp;America/New_York). Times are&amp;nbsp;&lt;STRONG&gt;wall-clock&lt;/STRONG&gt;: 08:00 stays 08:00 across a daylight-saving change, which is what an operations team means when they say "eight in the morning". And an occurrence that lands in a spring-forward gap — an 02:30 job on the morning the clocks jump from 02:00 to 03:00 — is&amp;nbsp;&lt;STRONG&gt;skipped, not silently shifted&lt;/STRONG&gt;&amp;nbsp;to 03:30. That is a decision, made once, applied consistently, and covered by tests.&lt;/P&gt;
&lt;H3&gt;The preview is the point&lt;/H3&gt;
&lt;P&gt;Cron is where scheduling bugs live. Everybody has confidently written&amp;nbsp;0 0 * * 0&amp;nbsp;and then argued about which day that is.&lt;/P&gt;
&lt;P&gt;So the editor does not ask you to trust it. On every keystroke it asks the&amp;nbsp;&lt;STRONG&gt;server&lt;/STRONG&gt;&amp;nbsp;to describe the recurrence in plain English and return its&amp;nbsp;&lt;STRONG&gt;next five occurrences&lt;/STRONG&gt;&amp;nbsp;— and the server answers using the same engine that will actually fire the schedule. Not a browser re-implementation of cron that agrees with the backend most of the time. The same code path. What the editor shows you is, by construction, what the scheduler will do.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Watch the right-hand panel as the cron expression is typed. That description and those five dates come back from the server on every keystroke — from the same engine that fires the schedule.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Schedules that know when to stop&lt;/H3&gt;
&lt;P&gt;A schedule can carry&amp;nbsp;start_date&amp;nbsp;and&amp;nbsp;end_date&amp;nbsp;as local calendar bounds, and a&amp;nbsp;run_limit&amp;nbsp;budget. When the budget is spent or the end date passes, the schedule flips to status&amp;nbsp;completed&amp;nbsp;and stops producing a next run — rather than sitting there looking enabled while silently never firing again, which is the failure mode that has you debugging a scheduler that is working perfectly. Manual runs do not consume the budget; only scheduler-triggered ones do.&lt;/P&gt;
&lt;H2&gt;Why you can point this at production without flinching&lt;/H2&gt;
&lt;P&gt;This is the section the rest of the post exists for. Seven guarantees, each one a mechanism rather than a promise.&lt;/P&gt;
&lt;H3&gt;The gates&lt;/H3&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt; Two independent gates.&lt;/STRONG&gt;A real Azure start requires the globalENABLE_REAL_AZURE_STARTS&amp;nbsp;setting&amp;nbsp;&lt;STRONG&gt;and&lt;/STRONG&gt;&amp;nbsp;the target tenant's&amp;nbsp;allow_vm_start&amp;nbsp;permission. A real stop requires&amp;nbsp;ENABLE_REAL_AZURE_STOPS&amp;nbsp;&lt;STRONG&gt;and&lt;/STRONG&gt;&amp;nbsp;allow_vm_stop. They are entirely separate. Turning on starts does not, and cannot, enable stops.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Re-evaluated on every single attempt.&lt;/STRONG&gt;The permission decision is deliberately kept apart from the expensive work of building an ARM credential. Adapters get cached because acquiring a token is costly; the&lt;EM&gt;decision&lt;/EM&gt;&amp;nbsp;is remade for every attempt. Revoke a tenant's stop permission while a stop wave is halfway through and the remaining attempts stop being real — immediately, not whenever a cached adapter happens to expire.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Mock-first.&lt;/STRONG&gt;Until both switches are on, every wave runs against a deterministic mock adapter that records a simulated result. You can build an entire estate, wire up every schedule, preview the next month of occurrences, run the waves, inspect the attempts and show the whole thing to your change board without touching a single machine. A fresh deployment&lt;STRONG&gt;arrives inert&lt;/STRONG&gt;&amp;nbsp;— both gates ship&amp;nbsp;false.&lt;/LI&gt;
&lt;/OL&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;The gates are a visible posture, not a buried environment variable. This is what a fresh deployment looks like, and it is what it keeps looking like until somebody changes it.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;The guards&lt;/H3&gt;
&lt;OL start="4"&gt;
&lt;LI&gt;&lt;STRONG&gt;never_stop.&lt;/STRONG&gt;Set it on a VM, or on any ancestor, and that machine is removed from every stop wave and every on-demand stop. Zava Payments demonstrates it: its&amp;nbsp;Production&amp;nbsp;ring runs overnight settlement, so it is marked&amp;nbsp;never_stop&amp;nbsp;and the application has a start wave but no stop wave at all. Nothing you do to the parent schedule can pull those machines into a shutdown.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Exact-count confirmation.&lt;/STRONG&gt;Selecting machines and pressing&lt;STRONG&gt;Stop now&lt;/STRONG&gt;&amp;nbsp;stops nothing. The dialog names the tenant, states whether it will deallocate or power off, and refuses to arm until you type the machine count back. It is unglamorous and it has saved somebody's afternoon.&lt;/LI&gt;
&lt;/OL&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Eighteen machines selected, but the dialog offers to stop sixteen — two are&amp;nbsp;never_stop&amp;nbsp;and it says so. The confirm button stays dead until&amp;nbsp;16&amp;nbsp;is typed. Three of the seven guarantees, in one dialog.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;OL start="6"&gt;
&lt;LI&gt;&lt;STRONG&gt; Conflict guard.&lt;/STRONG&gt;The scheduler skips an attempt whose VM already has an opposite-action attempt in flight. If a start wave is still working on a machine, a stop wave will not race it.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Read-only tenants can never power anything.&lt;/STRONG&gt;A connection marked read-only refuses start and stop outright, gate or no gate, and a disabled connection refuses everything.stop_mode&amp;nbsp;is&amp;nbsp;deallocate&amp;nbsp;by default — the one that actually stops the compute meter — with&amp;nbsp;power_off&amp;nbsp;available per schedule when you need the machine halted but not released.&lt;/LI&gt;
&lt;/OL&gt;
&lt;H2&gt;Coverage gaps: the report you didn't know you needed&lt;/H2&gt;
&lt;P&gt;Any scheduling system's second-order failure is&amp;nbsp;&lt;EM&gt;partial&lt;/EM&gt;&amp;nbsp;coverage. Not "the scheduler broke" — the scheduler is fine — but "eleven machines quietly fell outside it". So the overview goes looking for exactly that, in both directions:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Starts but never stops&lt;/STRONG&gt;&amp;nbsp;— machines with an effective start wave and no effective stop wave. These come up every morning and never go down. They are the ones burning money while everyone congratulates themselves on the savings.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Stops but never starts&lt;/STRONG&gt;&amp;nbsp;— the inverse, and the more expensive mistake. These go down tonight and stay down, and you find out at 09:00 tomorrow.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Stop protected&lt;/STRONG&gt;&amp;nbsp;— machines excluded by&amp;nbsp;never_stop, listed explicitly so the exclusion is a visible decision rather than something you rediscover during an incident.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;It also flags start and stop waves that&amp;nbsp;&lt;STRONG&gt;overlap in time&lt;/STRONG&gt;, including the stagger tail, so you find out at design time that your 20:00 stop wave for a forty-machine application is still running when the 20:30 start wave for something else begins.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Gaps in both directions, named machine by machine. The middle one — three machines that stop tonight and are never started again — is the one that ruins a Monday.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The same page carries the pre-flight readiness checks (both global gates, tenants that are read-only or missing the permission a live schedule needs, credentials approaching expiry), windowed KPIs with a previous-period delta, a fourteen-bucket trend, the next-24-hours strip, the rollout plan, an application health matrix and reliability statistics.&lt;/P&gt;
&lt;H2&gt;Getting a real estate in without a spreadsheet&lt;/H2&gt;
&lt;P&gt;Nobody types four hundred resource IDs. Three routes in.&lt;/P&gt;
&lt;H3&gt;Paste bare VM names&lt;/H3&gt;
&lt;P&gt;Give it&amp;nbsp;vm-commerce-prod-01&amp;nbsp;and it resolves the subscription and resource group for you through Azure Resource Graph. If a name is ambiguous across subscriptions, it surfaces the candidates and asks you to pick rather than guessing. Duplicates are blocked. You can also&amp;nbsp;&lt;STRONG&gt;browse a subscription&lt;/STRONG&gt;&amp;nbsp;and select machines directly, or&amp;nbsp;&lt;STRONG&gt;paste full resource IDs&lt;/STRONG&gt;&amp;nbsp;if you already have them.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Four names in. Three are already filed and it tells you exactly which ring holds each; the fourth is unknown and gets offered a tenant to resolve against.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Import VMs&lt;/H3&gt;
&lt;P&gt;Point it at a UTF-8 inventory CSV and it runs a validating preview that reports exactly what would be created, updated and skipped before anything is written. The preview is bound to an encrypted, expiring token, and the commit is atomic — a stale or tampered preview is rejected rather than half-applied. The simplest valid file is a single column of VM names.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Nothing is written during a preview. The commit is all-or-nothing, and a preview that has gone stale is refused rather than partly applied.&lt;/P&gt;
&lt;H2&gt;Who gets to press the button&lt;/H2&gt;
&lt;P&gt;Access control is capability-based, and it is enforced on the API rather than hidden in the UI.&lt;/P&gt;
&lt;P&gt;Users hold roles directly&amp;nbsp;&lt;STRONG&gt;or&lt;/STRONG&gt;&amp;nbsp;through access groups; their effective permissions are the union of both, resolved once per request. Five roles ship built in —&amp;nbsp;admin,&amp;nbsp;operator,&amp;nbsp;auditor,&amp;nbsp;viewer,&amp;nbsp;noaccess&amp;nbsp;— and they are re-seeded on every start, so a capability added in a new version is never left unusable on an existing deployment. Custom roles are free-form on top.&lt;/P&gt;
&lt;P&gt;Sign-in is local, or SSO, or both. SSO is multi-provider: any number of OIDC issuers configured from their discovery documents (Microsoft Entra ID is just the case where the issuer is derived from a directory id), and SAML 2.0 verified with&amp;nbsp;signxml&amp;nbsp;— where the code reads&amp;nbsp;&lt;STRONG&gt;only the signed subtree&lt;/STRONG&gt;&amp;nbsp;the library returns, never the raw document, which is how a whole family of SAML signature-wrapping attacks stops being interesting.&lt;/P&gt;
&lt;P&gt;Three walls are enforced for every request: a&amp;nbsp;noaccess&amp;nbsp;allowlist, a forced-password-change allowlist, and a database-backed per-IP brute-force throttle that catches one attacker spraying many usernames rather than only many attempts at one account. Two lock-out guards return&amp;nbsp;409&amp;nbsp;rather than letting you strand yourself: you cannot remove the last enabled account that can manage users, and you cannot disable local sign-in when no SSO provider is enabled.&lt;/P&gt;
&lt;P&gt;Every action lands in an audit log.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Users, roles, access groups, live sessions, sign-in policy and the SSO providers — one page, one permission to reach it.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H2&gt;Where it runs&lt;/H2&gt;
&lt;P&gt;One container image. The built single-page app is served by FastAPI at the same origin, so there is no CORS story, no second container and no reverse-proxy configuration to get wrong. The static mount is registered last, so it can never shadow the API.&lt;/P&gt;
&lt;P&gt;The&amp;nbsp;&lt;A href="https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fzmustafa%2FAzureVMScheduler%2Fmain%2Fdeploy%2Fmain.json" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Deploy to Azure&lt;/STRONG&gt;&lt;/A&gt;&amp;nbsp;button provisions, in your subscription: a&amp;nbsp;&lt;STRONG&gt;Container App&lt;/STRONG&gt;&amp;nbsp;running the public image,&amp;nbsp;&lt;STRONG&gt;Azure Database for PostgreSQL flexible server&lt;/STRONG&gt;&amp;nbsp;(Burstable B1ms), an&amp;nbsp;&lt;STRONG&gt;Azure Files&lt;/STRONG&gt;&amp;nbsp;share mounted at&amp;nbsp;/app/.data&amp;nbsp;for the encryption key and connection registry, a Container Apps environment and a Log Analytics workspace. Replicas are pinned to one, because the scheduler is in-process by design. Setting&amp;nbsp;privateNetworking&amp;nbsp;at create time injects the environment into a VNet and puts both the database and the storage account behind Private Endpoints with public access disabled.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Everything one deployment creates. The private-networking switch is create-time only — an existing public deployment has to be redeployed, not flipped.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3&gt;Connecting Azure without storing a secret&lt;/H3&gt;
&lt;P&gt;The Container App gets a&amp;nbsp;&lt;STRONG&gt;system-assigned managed identity&lt;/STRONG&gt;. Grant it Reader on the scope you want to manage plus&amp;nbsp;start&amp;nbsp;/&amp;nbsp;deallocate&amp;nbsp;/&amp;nbsp;powerOff&amp;nbsp;on the target VMs, add a tenant in the app using the&amp;nbsp;default_chain&amp;nbsp;auth method, and&amp;nbsp;&lt;STRONG&gt;no credential is stored anywhere at all&lt;/STRONG&gt;. Where you do store client secrets, they are Fernet-encrypted at rest and never leave the host.&lt;/P&gt;
&lt;img /&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Two tenants, one writable and one read-only, both authenticating as the host identity. The per-tenant permissions are the second half of every gate.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Or run the whole thing on a laptop against SQLite.&amp;nbsp;DATABASE_URL&amp;nbsp;picks the engine; nothing else about the application changes.&lt;/P&gt;
&lt;H2&gt;How it's judged&lt;/H2&gt;
&lt;P&gt;The claims above are mechanisms, and each one is testable:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;BLOCKQUOTE&gt;A VM is never started twice nor stopped twice, whatever the schedule overlap — resolution is per action, and the nearest schedule wins.&lt;/BLOCKQUOTE&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;BLOCKQUOTE&gt;The recurrence preview is produced by the&amp;nbsp;&lt;STRONG&gt;same&lt;/STRONG&gt;&amp;nbsp;engine that fires the schedule, so what the editor shows is what the scheduler does.&lt;/BLOCKQUOTE&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;BLOCKQUOTE&gt;An occurrence in a DST spring-forward gap is skipped, never silently shifted.&lt;/BLOCKQUOTE&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;BLOCKQUOTE&gt;A real Azure power action requires two independent switches, re-checked on&amp;nbsp;&lt;STRONG&gt;every&lt;/STRONG&gt;&amp;nbsp;attempt — so revoking a permission halts a wave already in progress.&lt;/BLOCKQUOTE&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;BLOCKQUOTE&gt;never_stop&amp;nbsp;is honoured by scheduled stops and on-demand stops alike.&lt;/BLOCKQUOTE&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;BLOCKQUOTE&gt;Every wave is reconstructable after the fact: run status, per-VM attempt, mode, message, attempt number, sequence position and correlation id.&lt;/BLOCKQUOTE&gt;
&lt;/LI&gt;
&lt;LI&gt;
&lt;BLOCKQUOTE&gt;A fresh deployment cannot touch Azure until a human deliberately arms it.&lt;/BLOCKQUOTE&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;What it deliberately isn't&lt;/H2&gt;
&lt;P&gt;Worth knowing before you invest an afternoon:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Single-replica by design.&lt;/STRONG&gt;&amp;nbsp;The scheduler runs in-process and the Bicep pins replicas to 1/1. That is a conscious trade — no leader election, no distributed lock, no split-brain — but it does mean this is not a highly-available control plane.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Virtual machines only.&lt;/STRONG&gt;&amp;nbsp;Not scale sets, not AKS node pools, not App Service plans, not SQL.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Not a cost tool.&lt;/STRONG&gt;&amp;nbsp;It will not price your savings, forecast them or chargeback them. It turns machines off; your existing cost tooling reports on the result.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Two levels, permanently.&lt;/STRONG&gt;&amp;nbsp;If you need a five-deep hierarchy, this is the wrong shape and no amount of configuration will change that.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Try it&lt;/H2&gt;
&lt;P&gt;The fastest honest test is to run it against nothing. Deploy it with the button below — it arrives with both action gates off, so it physically cannot touch a machine — then open&amp;nbsp;&lt;STRONG&gt;Settings → Demo data&lt;/STRONG&gt;&amp;nbsp;and load the sample&amp;nbsp;&lt;STRONG&gt;Zava&lt;/STRONG&gt;&amp;nbsp;estate: four applications, nine rings, eighteen virtual machines and seven start/stop waves, complete with a&amp;nbsp;never_stop&amp;nbsp;ring and an application that starts but never stops, so the coverage-gap detection has something to find. It loads in one click and removes exactly what it created.&lt;/P&gt;
&lt;P&gt;Build your real rollout on top of that, rehearse every wave against the mock adapter, and only then decide whether to arm anything.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;Let GitHub Copilot do the setup&lt;/H3&gt;
&lt;P&gt;Open an empty folder, put Copilot Chat in&amp;nbsp;&lt;STRONG&gt;agent mode&lt;/STRONG&gt;, and hand it the repository:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Clone&amp;nbsp;https://github.com/zmustafa/AzureVMScheduler&amp;nbsp;into this folder, set it up for local development, then start the backend and the frontend.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P&gt;That is enough. The repository ships a README with the setup steps and VS Code tasks for both servers, so the agent has something to follow rather than a command line to invent. The API comes up on&amp;nbsp;127.0.0.1:8000&amp;nbsp;and Vite on&amp;nbsp;127.0.0.1:5173&amp;nbsp;proxying&amp;nbsp;/api&amp;nbsp;to it; with no&amp;nbsp;DATABASE_URL&amp;nbsp;set, the whole thing runs on a SQLite file under&amp;nbsp;.data/&amp;nbsp;with nothing else to install. Sign in as&amp;nbsp;admin, change the password when it makes you, and load&amp;nbsp;&lt;STRONG&gt;Settings → Demo data&lt;/STRONG&gt;.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Repository:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://github.com/zmustafa/AzureVMScheduler" target="_blank" rel="noopener"&gt;https://github.com/zmustafa/AzureVMScheduler&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Container image:&lt;/STRONG&gt;&amp;nbsp;&lt;A href="https://hub.docker.com/r/zmustafa/azure-vm-scheduler" target="_blank" rel="noopener"&gt;https://hub.docker.com/r/zmustafa/azure-vm-scheduler&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Licence:&lt;/STRONG&gt;&amp;nbsp;MIT — issues and pull requests welcome&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If you try it, I would genuinely like to hear which part of the safety model you found excessive and which part you found insufficient. That is the argument worth having.&lt;/P&gt;
&lt;P&gt;&lt;A class="lia-external-url" href="https://zeeshan.net/stop-paying-for-idle-vms-safely-ringed-start-stop-waves-for-your-azure-estate" target="_blank" rel="noopener"&gt;Original post&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;This is a community open-source project and is not affiliated with or endorsed by Microsoft.&lt;/EM&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 26 Aug 2026 14:49:01 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/stop-paying-for-idle-vms-safely-ringed-start-stop-waves-for-your/ba-p/4542066</guid>
      <dc:creator>zmustafa</dc:creator>
      <dc:date>2026-08-26T14:49:01Z</dc:date>
    </item>
    <item>
      <title>Navigating the Azure Databricks CSP Mandate</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/navigating-the-azure-databricks-csp-mandate/ba-p/4550172</link>
      <description>&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Mandatory Deadline:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; The Compliance Security Profile (CSP) becomes mandatory for processing&amp;nbsp;HIPAA, HITRUST, and IRAP regulated data on Azure Databricks by &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;September 1, 2026&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Permanent Change:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; Enabling CSP is an irreversible, workspace-level configuration. Reversion requires&amp;nbsp;deleting&amp;nbsp;and recreating the workspace, emphasizing the need for meticulous pre-enablement testing.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;Architectural Impact:&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; CSP introduces significant changes, notably requiring&amp;nbsp;VNet&amp;nbsp;encryption which can disrupt existing on-premises connections, and disabling partner-powered AI features by default.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The evolving regulatory landscape demands rigorous security and compliance measures for data processing in the cloud. For organizations&amp;nbsp;leveraging&amp;nbsp;Azure Databricks, the introduction and upcoming mandatory enforcement of the Compliance Security Profile (CSP) represent a pivotal shift. This profile is not merely a feature toggle;&amp;nbsp;it's&amp;nbsp;a foundational architectural commitment designed to harden your Databricks environment against stringent compliance standards.&amp;nbsp;Understanding its implications and preparing proactively is crucial to ensure uninterrupted operations and continued regulatory adherence.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Why CSP Matters&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The Compliance Security Profile (CSP) is a robust, platform-hardening configuration applied at the workspace level within Azure Databricks. Its primary&amp;nbsp;objective&amp;nbsp;is to&amp;nbsp;facilitate&amp;nbsp;adherence to a broad spectrum of compliance standards by enforcing&amp;nbsp;additional&amp;nbsp;monitoring,&amp;nbsp;utilizing&amp;nbsp;hardened compute images, ensuring inter-node encryption with specific instance types, and implementing stricter controls across Databricks workspaces. This provides a secure baseline for the data plane, incorporating enhanced security monitoring capabilities.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;For organizations handling sensitive data, such as Protected Health Information (PHI) under HIPAA, or data subject to HITRUST and IRAP regulations, CSP is not just beneficial—it is becoming mandatory. Starting &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;September 1, 2026&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, all Azure Databricks workspaces&amp;nbsp;processing data under HIPAA, HITRUST, or IRAP will&amp;nbsp;be required&amp;nbsp;to have CSP enabled. Failure to&amp;nbsp;comply&amp;nbsp;will impede the ability to process such regulated workloads.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img&gt;&lt;SPAN data-contrast="auto"&gt;Conceptual diagram illustrating data protection and complianceonDatabricks.&lt;/SPAN&gt;&lt;/img&gt;
&lt;H4 aria-level="4"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;Key Compliance Standards Supported by CSP&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:80,&amp;quot;335559739&amp;quot;:40}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The compliance security profile supports or is&amp;nbsp;required&amp;nbsp;for processing data under a wide array of global and industry-specific compliance standards. This comprehensive coverage underscores its importance for organizations&amp;nbsp;operating&amp;nbsp;in highly regulated sectors:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;C5&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;CCCS Medium (Protected B)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;FedRAMP&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;HIPAA (Health Insurance Portability and Accountability Act)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;HITRUST (Health Information Trust Alliance)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;IRAP (Infosec Registered Assessors Program)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;ISMAP&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Korean Financial Security Institute (K-FSI)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;PCI-DSS (Payment Card Industry Data Security Standard)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;TISAX&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;UK Cyber Essentials Plus&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Understanding CSP's Architectural Implications&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;One of the most critical aspects of CSP to grasp is its permanence. Once enabled on a workspace, or once any regulated data has been processed within a CSP-enabled workspace, the profile cannot be simply toggled off. To revert to a non-CSP state, you would need to&amp;nbsp;delete&amp;nbsp;the existing workspace and provision a new one without the CSP activated. This irreversible nature&amp;nbsp;necessitates&amp;nbsp;a thorough planning and validation phase before implementing CSP in production environments.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4 aria-level="4"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;Cost Considerations: The Enhanced Security &amp;amp; Compliance Add-on&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:80,&amp;quot;335559739&amp;quot;:40}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Enabling CSP automatically activates the "Enhanced Security and Compliance add-on" billing, which will incur&amp;nbsp;additional&amp;nbsp;costs. Organizations must factor these increased expenditures into their budgeting and financial planning.&amp;nbsp;Reviewing the Azure Databricks pricing page is essential to understand the full financial impact.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4 aria-level="4"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;Networking Challenges:&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;VNet&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;&amp;nbsp;Encryption and On-Premises Connectivity&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:80,&amp;quot;335559739&amp;quot;:40}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;A significant "gotcha" highlighted in various sources is the impact of CSP on network architecture. CSP enforces stricter network security policies, often requiring&amp;nbsp;VNet&amp;nbsp;encryption. If your Azure Databricks workspaces utilize&amp;nbsp;VNet&amp;nbsp;Injection and connect to on-premises systems via ExpressRoute or VPN, this&amp;nbsp;VNet&amp;nbsp;encryption can&amp;nbsp;potentially disrupt existing connections. This&amp;nbsp;necessitates&amp;nbsp;close collaboration with networking teams to verify compatibility, test connectivity in pre-production environments, and potentially reconfigure network components such as routing tables, security groups, or&amp;nbsp;firewall&amp;nbsp;rules.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4 aria-level="4"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;Feature Impact: AI Assist and Public Preview Limitations&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:80,&amp;quot;335559739&amp;quot;:40}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;To&amp;nbsp;maintain&amp;nbsp;stringent compliance boundaries, CSP workspaces alter default behaviors and restrict certain features:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Partner-powered AI Features:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; By default, "Partner-powered AI features," which include some AI-powered coding assistants like Genie Code, are disabled in CSP workspaces. While Databricks-hosted models may power Genie Code in CSP workspaces for specific compliance standards (e.g., HIPAA, FedRAMP Moderate, PCI-DSS, HITRUST) in certain regions, organizations relying on these features should assess alternatives or plan for explicit enablement, understanding the potential constraints.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/databricks/security/privacy/security-profile" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Preview Features&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="auto"&gt;:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; Only a&amp;nbsp;limited&amp;nbsp;set of Public Preview features are supported in CSP workspaces. Workloads dependent on unsupported preview features may face limitations or require adjustments.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Preparing for the CSP Mandate&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;To ensure a smooth transition to CSP, a detailed and phased approach is recommended. This involves thorough assessment, strategic planning, rigorous testing, and clear communication across various teams.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The radar chart above visualizes the current readiness level (Pre-CSP Readiness) versus the desired target state (Post-CSP Target State) across critical preparation areas for the Compliance Security Profile. It underscores the significant effort required in areas like network reconfiguration and thorough testing to achieve full compliance and operational stability.&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;SPAN style="color: rgb(30, 30, 30); font-size: 24px;"&gt;Inventory and Assessment&lt;/SPAN&gt;
&lt;UL&gt;
&lt;LI&gt;Identify Regulated Workspaces:&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; Catalogue all existing Azure Databricks workspaces.&amp;nbsp;Determine&amp;nbsp;which ones currently process, or are planned to process, data subject to HIPAA, HITRUST, or IRAP.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{}"&gt; &lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;Review Data Pipelines:&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; Map out all data ingress and egress points for these identified workspaces, including connections to on-premises data sources, other cloud services, and external APIs. This helps&amp;nbsp;identify&amp;nbsp;potential network impacts.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;OL start="2"&gt;
&lt;LI aria-level="4"&gt;
&lt;H4&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt; Network Architecture Review&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Evaluate&amp;nbsp;VNet&amp;nbsp;Encryption:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; If your workspace uses&amp;nbsp;VNet&amp;nbsp;Injection and has private connectivity to an on-premises network (e.g., via ExpressRoute or VPN), verify that these connections will remain functional under CSP's new encryption requirements.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;Plan for Reconfiguration:&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; Allocate resources for potential network re-architecting, including updating routing tables, security groups, or&amp;nbsp;firewall&amp;nbsp;rules to accommodate encrypted traffic flows.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;OL start="3"&gt;
&lt;LI aria-level="4"&gt;
&lt;H4&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt; Feature Impact Analysis&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;AI &amp;amp; Assist Features:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; Assess the reliance of your development teams on "Partner-powered AI features" like&amp;nbsp;Genie&amp;nbsp;Code.&amp;nbsp;Determine&amp;nbsp;if Databricks-hosted alternatives meet their needs or if explicit enablement (and its associated compliance considerations) is&amp;nbsp;required.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;Preview Features:&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; Consult official documentation to check for limitations on Public Preview features in CSP workspaces and plan accordingly if your workloads depend on any unsupported features.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;OL start="4"&gt;
&lt;LI aria-level="4"&gt;
&lt;H4&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt; Data Handling Responsibilities&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Sensitive Information Fields:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; Implement policies to prevent sensitive data from being entered into customer-defined input fields (e.g., workspace names, compute resource names, tags, job names, URLs), as these might be stored or processed outside the compliance boundary.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;Encryption at Rest:&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; Verify that all data&amp;nbsp;containing&amp;nbsp;PHI or other regulated information is encrypted at rest in any storage location interacting with Databricks, including workspace storage accounts.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;OL start="5"&gt;
&lt;LI aria-level="4"&gt;
&lt;H4&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt; Execution and Validation Plan&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;/LI&gt;
&lt;/OL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Staging Environment First:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; Always enable CSP on a clone of your production environment in a staging subscription before rolling out to production.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;Thorough Testing:&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; Conduct comprehensive end-to-end tests on the staging workspace to&amp;nbsp;validate&amp;nbsp;data pipelines, network connectivity, user workflows, and performance.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{}"&gt; &lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;Enablement Method:&lt;SPAN style="color: rgb(30, 30, 30);" data-contrast="auto"&gt; Choose the&amp;nbsp;appropriate tooling&amp;nbsp;for enablement—Azure Portal, Azure CLI, PowerShell, ARM templates, or&amp;nbsp;Terraform—to ensure consistency and automation.&lt;/SPAN&gt;&lt;SPAN style="color: rgb(30, 30, 30);" data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Detailed Enablement Methods&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Enabling CSP can be done for both new and existing workspaces using various Azure management tools. Regardless of the method chosen,&amp;nbsp;it's&amp;nbsp;crucial to select the applicable compliance standards during enablement.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4 aria-level="4"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;Enabling CSP on New Workspaces&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:80,&amp;quot;335559739&amp;quot;:40}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;For new workspaces, the compliance security profile settings at the account level can control whether&amp;nbsp;it's&amp;nbsp;enabled by default. Account administrators can enable CSP individually during deployment using:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Azure Portal&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Azure CLI (e.g., az&amp;nbsp;databricks&amp;nbsp;workspace create --enable-compliance-security-profile --compliance-standards '["HIPAA"]')&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;PowerShell&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;ARM templates&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Terraform (using&amp;nbsp;the databricks_compliance_security_profile_workspace_setting resource)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H4 aria-level="4"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;Enabling CSP on Existing Workspaces&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:80,&amp;quot;335559739&amp;quot;:40}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Existing workspaces can also have CSP enabled through similar methods:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Azure Portal:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; Navigate to Workspace &amp;gt; Settings &amp;gt; Security &amp;amp; compliance &amp;gt; Enable compliance security profile; select standards and save.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Azure CLI / PowerShell / ARM templates / Terraform:&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; Utilize&amp;nbsp;these tools to&amp;nbsp;modify&amp;nbsp;the workspace settings and enable CSP, specifying the relevant compliance standards.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Understanding Key Technical Considerations&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Beyond the general planning, specific technical details must be understood and addressed to ensure a successful CSP implementation.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H4 aria-level="4"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;Account-Level Requirements&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:80,&amp;quot;335559739&amp;quot;:40}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Before enabling CSP, ensure your Databricks account meets these prerequisites:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Your Databricks account must include the Enhanced Security and Compliance add-on.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;Your Databricks workspace needs to be on the&amp;nbsp;Premium&amp;nbsp;pricing tier.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H4 aria-level="4"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 4"&gt;Security Configuration Table&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:80,&amp;quot;335559739&amp;quot;:40}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H4&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The table below summarizes critical security configuration aspects influenced by CSP:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Security Aspect&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Pre-CSP State&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Post-CSP State&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Preparation Action&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Compute Images&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Standard images&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Hardened compute images&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;No direct action&amp;nbsp;required, platform handles.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Inter-node Encryption&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Configurable/Optional&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Enforced (for specific instance types)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Ensure use of supported instance types.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Network Encryption (VNet)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Standard&amp;nbsp;VNet&amp;nbsp;configuration&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;VNet&amp;nbsp;encryption&amp;nbsp;required&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Test on-premises connectivity, reconfigure network routes/firewalls if needed.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;AI Assist Features&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;"Partner-powered AI features" typically enabled&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;"Partner-powered AI features" disabled by default&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Assess reliance, plan explicit&amp;nbsp;enablement&amp;nbsp;or alternative Databricks-hosted models.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Monitoring&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Standard monitoring&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Enhanced security monitoring,&amp;nbsp;additional&amp;nbsp;agents&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Familiarize with new monitoring capabilities and data.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Compliance Scope&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Self-managed controls&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Platform-enforced controls for selected standards&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Select&amp;nbsp;appropriate compliance&amp;nbsp;standards during CSP enablement.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN data-ccp-props="{}"&gt;&lt;SPAN data-contrast="auto"&gt;To further understand the broader context of security and compliance on Databricks, including how CSP fits into the larger ecosystem, watch this video from Databricks:&lt;/SPAN&gt; &lt;/SPAN&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;&lt;A class="lia-external-url" href="https://youtu.be/I9lxH6pzask?si=oXkOgR3o05PJtKYM" target="_blank" rel="noopener"&gt;Databricks Security &amp;amp; Compliance&lt;/A&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Re&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;ferences&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Compliance security profile:&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/databricks/security/privacy/security-profile" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://learn.microsoft.com/en-us/azure/databricks/security/privacy/security-profile&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;Configure enhanced security and compliance settings:&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/databricks/security/privacy/enhanced-security-compliance" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://learn.microsoft.com/en-us/azure/databricks/security/privacy/enhanced-security-compliance&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;HIPAA, Azure Databricks, Microsoft Learn:&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/databricks/security/privacy/hipaa" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://learn.microsoft.com/en-us/azure/databricks/security/privacy/hipaa&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-contrast="none"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="none"&gt;What is Azure Virtual Network encryption:&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-encryption-overview" target="_blank" rel="noopener"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;https://learn.microsoft.com/en-us/azure/virtual-network/virtual-network-encryption-overview&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:false,&amp;quot;134233118&amp;quot;:false,&amp;quot;335551550&amp;quot;:1,&amp;quot;335551620&amp;quot;:1,&amp;quot;335557856&amp;quot;:16777215,&amp;quot;335559738&amp;quot;:0,&amp;quot;335559739&amp;quot;:0}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Wed, 26 Aug 2026 14:47:42 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/navigating-the-azure-databricks-csp-mandate/ba-p/4550172</guid>
      <dc:creator>anishekkamal</dc:creator>
      <dc:date>2026-08-26T14:47:42Z</dc:date>
    </item>
    <item>
      <title>Building an AI Azure Ops Workbench — Part 3: Reverse engineer Azure Architecture Diagrams</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/building-an-ai-azure-ops-workbench-part-3-reverse-engineer-azure/ba-p/4541741</link>
      <description>&lt;P data-line="115"&gt;&lt;EM&gt;In&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-1-from-reactive-tickets-to-a-proactive/4534569" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-1-from-reactive-tickets-to-a-proactive/4534569"&gt;Part 1&lt;/A&gt;&amp;nbsp;we made the case for an operations copilot that runs inside your own tenant. In&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765"&gt;Part 2&lt;/A&gt;, the&amp;nbsp;&lt;STRONG&gt;Azure Support Agent&lt;/STRONG&gt;'s war room of specialist agents root-caused a live 5xx in about ninety seconds. But every one of those specialists had to be pointed at something first — and defining that "something" is the problem this post solves. Welcome to the second pillar:&amp;nbsp;&lt;STRONG&gt;Map&lt;/STRONG&gt;.&lt;/EM&gt;&lt;/P&gt;
&lt;HR /&gt;
&lt;P data-line="123"&gt;Here's a question that sounds trivial and almost never is:&amp;nbsp;&lt;STRONG&gt;which resources make up your application?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P data-line="126"&gt;Azure knows. It exposes the answer generously, too — Azure Resource Graph will return every resource in the tenant, with full properties, from a single KQL query. The Portal shows every relationship if you click far enough down. Azure Monitor holds the metrics, Microsoft Entra ID holds the identities. Very little about your estate is genuinely hidden.&lt;/P&gt;
&lt;P data-line="131"&gt;What's scarce isn't data. It's&amp;nbsp;&lt;STRONG&gt;time&lt;/STRONG&gt;. Nobody has a spare afternoon each week to re-derive which forty of your eleven hundred resources constitute "the checkout app," redraw the diagram, and write down&amp;nbsp;&lt;EM&gt;why&lt;/EM&gt;&amp;nbsp;the private endpoint is there. So the map drifts out of date — not because the information went missing, but because keeping it current is work that never wins against a sprint. That's a bandwidth problem, and bandwidth problems are exactly the kind of thing you can hand to an agent that never gets bored.&lt;/P&gt;
&lt;P data-line="138"&gt;So the Azure Support Agent builds the map for you and keeps it alive. Five pieces, each feeding the next:&amp;nbsp;&lt;STRONG&gt;Workloads&lt;/STRONG&gt;&amp;nbsp;that mean something, a live&amp;nbsp;&lt;STRONG&gt;architecture diagram&lt;/STRONG&gt;&amp;nbsp;reverse-engineered from what's actually deployed, an&amp;nbsp;&lt;STRONG&gt;Architecture Memory&lt;/STRONG&gt;&amp;nbsp;that remembers design intent, a&amp;nbsp;&lt;STRONG&gt;Know-Me doc&lt;/STRONG&gt;&amp;nbsp;your on-call can read at 3 a.m., and an&amp;nbsp;&lt;STRONG&gt;Estate Graph&lt;/STRONG&gt;&amp;nbsp;that renders the whole tenant as one navigable picture.&lt;/P&gt;
&lt;P data-line="144"&gt;One promise up front, because it shapes every design decision below:&amp;nbsp;&lt;STRONG&gt;mapping your estate never changes it.&lt;/STRONG&gt;&amp;nbsp;Every feature in this post is read-only against Azure.&lt;/P&gt;
&lt;P data-line="147"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="154"&gt;Part one — Workloads&lt;/H2&gt;
&lt;H3 data-line="156"&gt;A unit of scope that actually means something&lt;/H3&gt;
&lt;P data-line="158"&gt;A subscription is an accounting boundary. A resource group is a lifecycle boundary. Neither one reliably equals "an application." So the workbench introduces one that does: the&amp;nbsp;&lt;STRONG&gt;Workload&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P data-line="161"&gt;A workload is a named set of scopes, and it can mix all four levels Azure gives you — a&amp;nbsp;&lt;STRONG&gt;management group&lt;/STRONG&gt;, a&amp;nbsp;&lt;STRONG&gt;subscription&lt;/STRONG&gt;, a&amp;nbsp;&lt;STRONG&gt;resource group&lt;/STRONG&gt;, or an&amp;nbsp;&lt;STRONG&gt;individual resource ID&lt;/STRONG&gt;. Real estates are untidy, so membership is subtractive as well as additive: every scope carries an&amp;nbsp;excludes&amp;nbsp;list, which lets you express "this entire resource group&amp;nbsp;&lt;EM&gt;except&lt;/EM&gt;&amp;nbsp;that one legacy VM" without hand-listing thirty-nine resource IDs and re-listing them next month.&lt;/P&gt;
&lt;P data-line="167"&gt;Alongside its scopes, a workload carries the metadata that everything downstream reasons about: workload type, environment, business criticality, data classification and free-form tags. That metadata isn't decoration — the fleet views pivot on it, and the assessments in Part 4 weight their findings by it.&lt;/P&gt;
&lt;P data-line="172"&gt;This layer matters more than it first appears, because&amp;nbsp;&lt;STRONG&gt;the workload is the unit of scope for the entire product&lt;/STRONG&gt;. Every assessment, every coverage report, every architecture diagram in this post, and every deep investigation from&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765"&gt;Part 2&lt;/A&gt;&amp;nbsp;is scoped to one. Get this right and everything downstream inherits it. Get it wrong and you're running beautiful analysis on the wrong set of resources.&lt;/P&gt;
&lt;H3 data-line="178"&gt;Autopilot: let the AI propose the boundaries&lt;/H3&gt;
&lt;P data-line="180"&gt;Defining workloads by hand is perfectly fine for five of them. It does not survive eleven hundred resources, and it&amp;nbsp;&lt;EM&gt;really&lt;/EM&gt;&amp;nbsp;doesn't survive an estate somebody else built.&lt;/P&gt;
&lt;P data-line="183"&gt;&lt;STRONG&gt;Autopilot&lt;/STRONG&gt;&amp;nbsp;reads the estate and proposes the groupings, reasoning over exactly the signals an experienced engineer would use: tag values, naming conventions, resource-group boundaries, and which resources actually sit together. It's built for real tenants rather than demos — a discovery pass handles up to&amp;nbsp;&lt;STRONG&gt;5,000 resources&lt;/STRONG&gt;&amp;nbsp;(and tells you when it truncated rather than silently sampling), feeding the model in&amp;nbsp;&lt;STRONG&gt;batches of 500&lt;/STRONG&gt;&amp;nbsp;in a map-reduce pattern so a large estate never has to fit inside one context window.&lt;/P&gt;
&lt;P data-line="190"&gt;The important part is what happens next:&amp;nbsp;&lt;STRONG&gt;nothing is saved behind your back.&lt;/STRONG&gt;&amp;nbsp;Autopilot streams out candidate workloads, each with its reasoning, a confidence level, and a breakdown of what's inside it — and then it stops. Those candidates are proposals until you explicitly save them. You can rename, merge, split, or bin them. This is the same posture as the Launch gate in&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765"&gt;Part 2&lt;/A&gt;: the AI proposes, a human disposes.&lt;/P&gt;
&lt;P data-line="196"&gt;Each Autopilot-born workload also remembers its&amp;nbsp;origin&amp;nbsp;— the management group or subscription it was discovered from — which powers a one-click&amp;nbsp;&lt;STRONG&gt;Refresh&lt;/STRONG&gt;&amp;nbsp;when the estate moves on, instead of making you re-run discovery from scratch and reconcile by hand.&lt;/P&gt;
&lt;P data-line="200"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="203"&gt;Groups, for when one app is really five&lt;/H3&gt;
&lt;P data-line="205"&gt;Most real applications exist several times over:&amp;nbsp;CRM PROD,&amp;nbsp;CRM DEV,&amp;nbsp;CRM DR. Treating those as three unrelated workloads is technically correct and practically useless.&lt;/P&gt;
&lt;P data-line="208"&gt;&lt;STRONG&gt;Groups&lt;/STRONG&gt;&amp;nbsp;are a non-destructive association on top of workloads — members keep their own identity, their own scopes and their own health score, but you can see them as one family. And because the naming pattern is so consistent in practice, the workbench will suggest the groupings for you: the suggestion pass strips environment tokens (prod,&amp;nbsp;dev,&amp;nbsp;stg,&amp;nbsp;test,&amp;nbsp;dr,&amp;nbsp;shared,&amp;nbsp;sandbox) from workload names and groups whatever stems match.&amp;nbsp;CRM PROD&amp;nbsp;and&amp;nbsp;CRM DEV&amp;nbsp;both stem to&amp;nbsp;CRM, so they're offered as a group.&lt;/P&gt;
&lt;P data-line="215"&gt;It's a small feature that does something disproportionately useful: it lets you ask "is&amp;nbsp;&lt;EM&gt;this application&lt;/EM&gt;&amp;nbsp;healthy?" rather than "is this one environment of it healthy?"&lt;/P&gt;
&lt;H3 data-line="218"&gt;A health score you're allowed to argue with&lt;/H3&gt;
&lt;P data-line="220"&gt;Each workload the Azure Support Agent tracks carries a composite health score out of 100. The interesting part isn't the number — it's that you can take the number apart.&lt;/P&gt;
&lt;P data-line="223"&gt;The score is a weighted average of&amp;nbsp;&lt;STRONG&gt;seven signals&lt;/STRONG&gt;, and they are deliberately not weighted equally:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Signal&lt;/th&gt;&lt;th&gt;Weight&lt;/th&gt;&lt;th&gt;Why&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Monitoring&lt;/td&gt;&lt;td&gt;1.0&lt;/td&gt;&lt;td&gt;Are the right alerts in place?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Telemetry&lt;/td&gt;&lt;td&gt;1.0&lt;/td&gt;&lt;td&gt;Are logs and metrics actually being collected?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Backup / DR&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;1.5&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;An unrecoverable workload is the worst failure mode on the list&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Performance&lt;/td&gt;&lt;td&gt;1.0&lt;/td&gt;&lt;td&gt;Is anything saturating or trending at its limits?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Ownership&lt;/td&gt;&lt;td&gt;1.0&lt;/td&gt;&lt;td&gt;Does a human own this?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Policy&lt;/td&gt;&lt;td&gt;1.0&lt;/td&gt;&lt;td&gt;Is it governed and compliant?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Tags&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;0.5&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Untagged is untidy, not unsafe&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="236"&gt;Bands are plain:&amp;nbsp;&lt;STRONG&gt;80 and above is good&lt;/STRONG&gt;,&amp;nbsp;&lt;STRONG&gt;50 and above is a warning&lt;/STRONG&gt;, below 50 is poor, and a workload with no analyzed signals at all reads&amp;nbsp;&lt;EM&gt;unknown&lt;/EM&gt;&amp;nbsp;rather than zero.&lt;/P&gt;
&lt;P data-line="239"&gt;Three design decisions are worth pulling out, because they're what make the number usable rather than decorative.&lt;/P&gt;
&lt;P data-line="242"&gt;&lt;STRONG&gt;First, it explains itself.&lt;/STRONG&gt;&amp;nbsp;The API doesn't return a bare score; it returns the&amp;nbsp;contributing&amp;nbsp;signals, the&amp;nbsp;missing&amp;nbsp;ones, and the weights actually applied. "Why is this 62?" has a real answer you can put on a slide, not a shrug.&lt;/P&gt;
&lt;P data-line="246"&gt;&lt;STRONG&gt;Second, unmeasured never masquerades as bad.&lt;/STRONG&gt;&amp;nbsp;Signals you haven't analyzed yet are excluded from the denominator entirely — a workload is never punished for a backup assessment nobody has run yet. It's marked unknown and the score is computed from what's actually known. A score that quietly conflates "bad" with "not yet measured" is a score people learn, correctly, to ignore.&lt;/P&gt;
&lt;P data-line="251"&gt;&lt;STRONG&gt;Third, you can disagree.&lt;/STRONG&gt;&amp;nbsp;The weights are an admin setting. If your organisation's risk appetite says tags matter more than that, change it — the score is a tool for your judgement, not a replacement for it.&lt;/P&gt;
&lt;P data-line="255"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="260"&gt;The board, the table and the cockpit&lt;/H3&gt;
&lt;P data-line="262"&gt;Fleet views tend to fail in one of two directions: a wall of rows nobody reads, or a dashboard so abstract it says nothing. The workbench offers three deliberately different lenses.&lt;/P&gt;
&lt;P data-line="265"&gt;The&amp;nbsp;&lt;STRONG&gt;table&lt;/STRONG&gt;&amp;nbsp;is the working view — one row per workload with environment pills, the score badge, the individual health signals broken out, resource counts and a risk column that folds in retirements and critical findings. It's what you scan on a Monday.&lt;/P&gt;
&lt;P data-line="269"&gt;The&amp;nbsp;&lt;STRONG&gt;board&lt;/STRONG&gt;&amp;nbsp;is a Kanban-style swimlane view grouped by environment — production, staging, development, test, DR, shared, unknown — which is the fastest way to spot the thing everyone dreads: something sitting in&amp;nbsp;production&amp;nbsp;with a health score in the reds.&lt;/P&gt;
&lt;P data-line="273"&gt;The&amp;nbsp;&lt;STRONG&gt;cockpit&lt;/STRONG&gt;&amp;nbsp;is the strip across the top: health distribution across the fleet, a composition treemap, an environment × criticality matrix, and a risk ticker. Four small pictures, each answering "where should I be looking?"&lt;/P&gt;
&lt;P data-line="277"&gt;Underneath the visuals sits a shared&amp;nbsp;&lt;STRONG&gt;resource taxonomy&lt;/STRONG&gt;&amp;nbsp;— every Azure resource type is classified into a category (compute, web, containers, data, storage, networking, security, integration, AI/ML, analytics, monitoring, management) and an architectural layer (edge, presentation, application, integration, data, networking, security, monitoring, shared). That single classification is what lets a donut chart, a treemap and an architecture diagram all speak the same language about the same estate.&lt;/P&gt;
&lt;P data-line="284"&gt;And the charts themselves are honest little things: a&amp;nbsp;&lt;STRONG&gt;composition donut&lt;/STRONG&gt;&amp;nbsp;by category, a&amp;nbsp;&lt;STRONG&gt;seven-axis health radar&lt;/STRONG&gt;&amp;nbsp;(one axis per signal, so a lopsided workload looks lopsided), a&amp;nbsp;&lt;STRONG&gt;sparkline&lt;/STRONG&gt;&amp;nbsp;of score trend, and a&amp;nbsp;&lt;STRONG&gt;treemap&lt;/STRONG&gt;&amp;nbsp;of resource categories by weight. Click into a single workload and you get an Overview tab — at-a-glance, health and coverage, watchers, security, lifecycle — plus a full resource table, with chips that jump you straight to that workload's architecture, its retirement radar, its policy view.&lt;/P&gt;
&lt;P data-line="291"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="294"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="296"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="300"&gt;Part two — The Azure Support Agent's Architecture Designer&lt;/H2&gt;
&lt;H3 data-line="302"&gt;Now draw it, from what's actually deployed&lt;/H3&gt;
&lt;P data-line="304"&gt;This is the part that tends to make people sit up in a demo, so it's worth going through properly.&lt;/P&gt;
&lt;P data-line="307"&gt;Point the workbench at a workload, press&amp;nbsp;&lt;STRONG&gt;Generate&lt;/STRONG&gt;, and it reverse-engineers an interactive architecture diagram from live Azure data. What follows isn't one big AI call — it's a pipeline with a deliberate division of labour:&amp;nbsp;&lt;STRONG&gt;Azure supplies the facts, the model supplies the reading of them, and code enforces the truth.&lt;/STRONG&gt;&amp;nbsp;That split is the whole reason the output is worth trusting.&lt;/P&gt;
&lt;H3 data-line="313"&gt;Step one: read the estate, twice&lt;/H3&gt;
&lt;P data-line="315"&gt;The workbench resolves the workload's scopes into a set of subscriptions, resource groups and resource IDs, then queries Azure Resource Graph in&amp;nbsp;&lt;STRONG&gt;two passes&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P data-line="318"&gt;The first pass is deliberately cheap — a lightweight inventory projecting only what it needs to identify things:&amp;nbsp;id,&amp;nbsp;name,&amp;nbsp;type,&amp;nbsp;kind,&amp;nbsp;location,&amp;nbsp;resourceGroup,&amp;nbsp;subscriptionId,&amp;nbsp;sku,&amp;nbsp;identity,&amp;nbsp;zones&amp;nbsp;and&amp;nbsp;tags, plus the resource groups themselves.&lt;/P&gt;
&lt;P data-line="322"&gt;The second pass goes back for the interesting part:&amp;nbsp;&lt;STRONG&gt;properties&lt;/STRONG&gt;, fetched in chunks of 30 resources at a time. Properties are where the actual topology hides — but they're also enormous and mostly irrelevant, so they're filtered before they ever reach the model. The filter keeps keys that carry relationships and drops the rest:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P data-line="327"&gt;networkProfile&amp;nbsp;·&amp;nbsp;ipConfigurations&amp;nbsp;·&amp;nbsp;subnet&amp;nbsp;·&amp;nbsp;privateLinkServiceConnections&amp;nbsp;·&amp;nbsp;serverFarmId&amp;nbsp;·&amp;nbsp;storageProfile&amp;nbsp;·&amp;nbsp;agentPoolProfiles&amp;nbsp;·&amp;nbsp;vnetSubnetID&amp;nbsp;·&amp;nbsp;backendPools&amp;nbsp;·&amp;nbsp;routingRules&amp;nbsp;·&amp;nbsp;keyVaultProperties&amp;nbsp;·&amp;nbsp;connectionStrings&amp;nbsp;·&amp;nbsp;siteConfig&amp;nbsp;·&amp;nbsp;hostNames&amp;nbsp;·&amp;nbsp;primaryEndpoints&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;P data-line="332"&gt;Two budgets bound the whole thing: roughly&amp;nbsp;&lt;STRONG&gt;6,000 characters per resource&lt;/STRONG&gt;&amp;nbsp;against a&amp;nbsp;&lt;STRONG&gt;120,000-character total&lt;/STRONG&gt;. When the budget runs out, the remaining resources are explicitly marked as omitted rather than silently dropped — the pipeline would rather tell you it ran out of room than quietly draw you an incomplete picture. A sprawling workload degrades gracefully instead of blowing the context window, which is the difference between a feature that works on your estate and one that only works in a screenshot.&lt;/P&gt;
&lt;P data-line="339"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="341"&gt;Step two: what the model is actually asked to do&lt;/H3&gt;
&lt;P data-line="343"&gt;The model receives the workload name, the resource count, and a compact JSON array of resources with their trimmed properties. The instruction that matters most is this one:&amp;nbsp;&lt;STRONG&gt;infer relationships from the properties, not from what you know about Azure in general.&lt;/STRONG&gt;&amp;nbsp;A model asked "how do App Services usually connect to SQL?" will confabulate a plausible architecture. A model asked "here is&amp;nbsp;serverFarmId&amp;nbsp;and here is&amp;nbsp;privateLinkServiceConnections[], what do they tell you?" is doing evidence-based reading.&lt;/P&gt;
&lt;P data-line="350"&gt;It's asked to return a strict JSON contract — a name, a description,&amp;nbsp;nodes[],&amp;nbsp;edges[],&amp;nbsp;groups[], a short&amp;nbsp;&lt;STRONG&gt;rationale&lt;/STRONG&gt;, and a&amp;nbsp;&lt;STRONG&gt;confidence&lt;/STRONG&gt;&amp;nbsp;value. Nodes carry an&amp;nbsp;arm_id&amp;nbsp;tying them to a real resource. It's permitted&amp;nbsp;&lt;STRONG&gt;at most a couple of conceptual nodes without an ARM ID&lt;/STRONG&gt;&amp;nbsp;— "Users", "Internet" — because a diagram with no origin for the traffic is harder to read, and that's a bounded, honest exception rather than a licence to invent.&lt;/P&gt;
&lt;P data-line="356"&gt;The call is given generous headroom (16,000 tokens) so a large estate doesn't produce a diagram truncated mid-JSON, and if the model returns nothing it retries once before reporting failure rather than showing you an empty canvas.&lt;/P&gt;
&lt;H3 data-line="360"&gt;Step three: the validation pass, where trust is actually won&lt;/H3&gt;
&lt;P data-line="362"&gt;This is the least glamorous stage and the most important one. Everything the model returns is treated as a&amp;nbsp;&lt;EM&gt;proposal&lt;/EM&gt;&amp;nbsp;and put through normalization before it's allowed near your screen:&lt;/P&gt;
&lt;UL data-line="365"&gt;
&lt;LI data-line="365"&gt;&lt;STRONG&gt;Groups&lt;/STRONG&gt;&amp;nbsp;are de-duplicated, and their&amp;nbsp;kind&amp;nbsp;is clamped to the permitted set — subscription, resource group, VNet, tier, custom.&lt;/LI&gt;
&lt;LI data-line="367"&gt;&lt;STRONG&gt;Nodes&lt;/STRONG&gt;&amp;nbsp;are de-duplicated, and each&amp;nbsp;arm_id&amp;nbsp;is&amp;nbsp;&lt;STRONG&gt;cross-referenced against the real inventory&lt;/STRONG&gt;. Category and layer are re-derived from the actual ARM type rather than trusted from the model. Node metadata is capped at six key–value pairs with length limits, so nobody can stuff an essay into a diagram label. Group references that point at a group that doesn't exist are cleared.&lt;/LI&gt;
&lt;LI data-line="372"&gt;&lt;STRONG&gt;Edges&lt;/STRONG&gt;&amp;nbsp;get the strictest treatment: any edge pointing at a node that doesn't exist is&amp;nbsp;&lt;STRONG&gt;dropped&lt;/STRONG&gt;, self-edges are dropped, duplicate source→target pairs collapse, and&amp;nbsp;kind&amp;nbsp;is clamped to the six permitted values. Logical relationships (identity, monitoring, dependency) are automatically drawn dashed so you can tell a network path from a conceptual one at a glance.&lt;/LI&gt;
&lt;LI data-line="376"&gt;&lt;STRONG&gt;Layout&lt;/STRONG&gt;&amp;nbsp;is applied automatically when the model hasn't produced usable coordinates — if fewer than half the nodes have real positions, the diagram is laid out by tier.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="379"&gt;The net effect is a rule that's easy to state and easy to audit:&amp;nbsp;&lt;STRONG&gt;a model can suggest a relationship, but it cannot invent a resource.&lt;/STRONG&gt;&amp;nbsp;If a node doesn't correspond to something that genuinely exists in your tenant, it doesn't survive to the canvas.&lt;/P&gt;
&lt;H3 data-line="383"&gt;It's a graph, not a picture&lt;/H3&gt;
&lt;P data-line="385"&gt;What lands is a typed model, not an image.&lt;/P&gt;
&lt;P data-line="387"&gt;&lt;STRONG&gt;Edges carry meaning&lt;/STRONG&gt;&amp;nbsp;— six kinds, so the diagram expresses&amp;nbsp;&lt;EM&gt;how&lt;/EM&gt;&amp;nbsp;two things relate rather than merely that they do:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Edge kind&lt;/th&gt;&lt;th&gt;Means&lt;/th&gt;&lt;th&gt;Drawn&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;depends_on&lt;/td&gt;&lt;td&gt;A needs B to function&lt;/td&gt;&lt;td&gt;dashed&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;connects_to&lt;/td&gt;&lt;td&gt;A talks to B&lt;/td&gt;&lt;td&gt;solid&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;data_flow&lt;/td&gt;&lt;td&gt;Data moves from A to B&lt;/td&gt;&lt;td&gt;solid&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;network&lt;/td&gt;&lt;td&gt;A network-level path (peering, subnet membership)&lt;/td&gt;&lt;td&gt;solid&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;identity&lt;/td&gt;&lt;td&gt;An authentication / managed-identity relationship&lt;/td&gt;&lt;td&gt;dashed&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;monitors&lt;/td&gt;&lt;td&gt;A observes B&lt;/td&gt;&lt;td&gt;dashed&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="399"&gt;&lt;STRONG&gt;Nodes are classified&lt;/STRONG&gt;&amp;nbsp;into twelve categories — Web &amp;amp; API, Compute, Containers, Databases, Storage, Integration, Networking, Security &amp;amp; Identity, AI &amp;amp; ML, Monitoring, Analytics, Other — each with its own colour, and into nine architectural layers that run&amp;nbsp;&lt;STRONG&gt;edge → presentation → application → integration → data → networking → security → monitoring → shared&lt;/STRONG&gt;. That layering is what lets the canvas arrange itself in tiers like a diagram a human would draw, instead of a hairball.&lt;/P&gt;
&lt;P data-line="406"&gt;&lt;STRONG&gt;Groups&lt;/STRONG&gt;&amp;nbsp;wrap nodes by subscription, resource group, VNet or tier, which is what makes forty resources legible at all.&lt;/P&gt;
&lt;H3 data-line="409"&gt;Reading the estate back to you&lt;/H3&gt;
&lt;P data-line="411"&gt;Each node renders as a card that carries rather more than a label. Alongside the name and a category-coloured Azure icon, it can show the&amp;nbsp;&lt;STRONG&gt;hosting model&lt;/STRONG&gt;&amp;nbsp;(IaaS / PaaS / SaaS), a rough&amp;nbsp;&lt;STRONG&gt;monthly cost estimate&lt;/STRONG&gt;&amp;nbsp;derived from type and SKU, and whether the resource is&amp;nbsp;&lt;STRONG&gt;publicly or privately reachable&lt;/STRONG&gt;&amp;nbsp;— three questions an architect asks about every box on a whiteboard, answered on the box itself.&lt;/P&gt;
&lt;P data-line="417"&gt;Nodes can also carry badges from two other systems:&amp;nbsp;&lt;STRONG&gt;best-practice lint&lt;/STRONG&gt;&amp;nbsp;(single points of failure, missing redundancy) and&amp;nbsp;&lt;STRONG&gt;assessment findings&lt;/STRONG&gt;&amp;nbsp;with their severity, so once you've run the Part 4 assessments the diagram becomes a heat map of where your problems physically live. Treat the cost figure as a sizing hint that tells you which corner of the diagram is expensive — not as a bill. Reconciled cost, against Cost Management, belongs to a later post.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="425"&gt;The same diagram, six different questions&lt;/H3&gt;
&lt;P data-line="427"&gt;Because the diagram is a typed model rather than an image, it can be&amp;nbsp;&lt;EM&gt;re-read&lt;/EM&gt;&amp;nbsp;without being redrawn. This is the part that surprises people in a demo, and it's where a live canvas pulls decisively ahead of a Visio file.&lt;/P&gt;
&lt;P data-line="431"&gt;&lt;STRONG&gt;Azure view&lt;/STRONG&gt;&amp;nbsp;turns on the shared-responsibility lens: every node picks up an&amp;nbsp;&lt;STRONG&gt;IaaS / PaaS / SaaS / Net&lt;/STRONG&gt;&amp;nbsp;badge, a globe or padlock for whether it's&amp;nbsp;&lt;STRONG&gt;publicly or privately reachable&lt;/STRONG&gt;, its indicative cost, and peering and private-link edges. Anything publicly reachable gains a red ring. It answers "what's exposed here?" in one toggle, on a diagram you didn't have to annotate.&lt;/P&gt;
&lt;P data-line="436"&gt;&lt;STRONG&gt;WAF tint&lt;/STRONG&gt;&amp;nbsp;recolours the diagram by a failing&amp;nbsp;&lt;STRONG&gt;Well-Architected pillar&lt;/STRONG&gt;&amp;nbsp;— Security, Reliability, Cost, Operations, Performance. Switch pillar and the highlight moves. Combined with the live assessment badge in the toolbar, the diagram becomes a map of&amp;nbsp;&lt;EM&gt;where your findings physically live&lt;/EM&gt;&amp;nbsp;rather than a list of resource IDs in a report.&lt;/P&gt;
&lt;P data-line="441"&gt;&lt;STRONG&gt;Boundary boxes&lt;/STRONG&gt;&amp;nbsp;regroup the whole diagram on demand: no boundaries, or by&amp;nbsp;&lt;STRONG&gt;resource group, subscription, VNet, subnet or region&lt;/STRONG&gt;. Watching the same twenty-odd resources rearrange from a flat application view into a subnet view is the fastest way to explain a network design to someone who's never seen it — and it's the clearest possible proof that this is a model, not a picture.&lt;/P&gt;
&lt;P data-line="446"&gt;&lt;STRONG&gt;Hosting filter&lt;/STRONG&gt;&amp;nbsp;narrows to just IaaS, PaaS, SaaS or network plumbing, which is how you find the three VMs hiding in an otherwise serverless estate.&lt;/P&gt;
&lt;P data-line="449"&gt;&lt;STRONG&gt;Impact&lt;/STRONG&gt;&amp;nbsp;is blast radius on the diagram: select a node and everything connected upstream and downstream lights up while the rest dims.&amp;nbsp;&lt;STRONG&gt;Path&lt;/STRONG&gt;&amp;nbsp;traces the directed request path north-to-south through the system. Between them they answer the two questions every incident starts with —&amp;nbsp;&lt;EM&gt;what does this depend on&lt;/EM&gt;, and&amp;nbsp;&lt;EM&gt;what breaks if it goes&lt;/EM&gt;.&lt;/P&gt;
&lt;P data-line="454"&gt;&lt;STRONG&gt;Review&lt;/STRONG&gt;&amp;nbsp;collects the best-practice lint into a numbered panel, and the findings also render on the nodes themselves — a Cosmos account with no private endpoint gets flagged in place, next to the resource, not in a spreadsheet.&lt;/P&gt;
&lt;P data-line="458"&gt;None of these change the diagram. They're lenses over the same validated model, which is exactly why they're cheap to switch between.&lt;/P&gt;
&lt;img /&gt;&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="469"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="471"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="473"&gt;A canvas you can actually work with&lt;/H3&gt;
&lt;P data-line="475"&gt;The diagram renders on a real graph canvas, so it behaves the way you'd expect rather than like a static export. Pan, zoom, drag nodes into a shape that matches how&amp;nbsp;&lt;EM&gt;you&lt;/EM&gt;&amp;nbsp;think about the system, multi-select, and use the minimap when a diagram outgrows the viewport.&lt;/P&gt;
&lt;P data-line="479"&gt;It's a genuine editor, not a read-only render:&lt;/P&gt;
&lt;UL data-line="481"&gt;
&lt;LI data-line="481"&gt;&lt;STRONG&gt;Add resources&lt;/STRONG&gt;&amp;nbsp;by dragging from a categorised palette of Azure types.&lt;/LI&gt;
&lt;LI data-line="482"&gt;&lt;STRONG&gt;Draw edges&lt;/STRONG&gt;&amp;nbsp;by dragging from one node's handle to another.&lt;/LI&gt;
&lt;LI data-line="483"&gt;&lt;STRONG&gt;Edit anything&lt;/STRONG&gt;&amp;nbsp;in the inspector — a node's name, type, category, layer and metadata; an edge's label, kind and dashed/solid style; a group's name and kind.&lt;/LI&gt;
&lt;LI data-line="485"&gt;&lt;STRONG&gt;Add groups&lt;/STRONG&gt;&amp;nbsp;to carve the diagram into subscriptions, resource groups or tiers.&lt;/LI&gt;
&lt;LI data-line="486"&gt;&lt;STRONG&gt;Add sticky notes&lt;/STRONG&gt;&amp;nbsp;for the annotations every real diagram accumulates.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="488"&gt;And when your manual dragging has made a mess,&amp;nbsp;&lt;STRONG&gt;six layout algorithms&lt;/STRONG&gt;&amp;nbsp;are one click away: top-down hierarchical, left-right hierarchical, tier-layered, grid, radial and force-directed. Watching a diagram reorganise itself between them is genuinely the fastest way to find the view that makes a given system make sense.&lt;/P&gt;
&lt;P data-line="493"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="497"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="499"&gt;Enhance, rebuild, and check for drift&lt;/H3&gt;
&lt;P data-line="501"&gt;Three buttons keep a diagram alive after the first generation.&lt;/P&gt;
&lt;P data-line="503"&gt;&lt;STRONG&gt;Enhance&lt;/STRONG&gt;&amp;nbsp;is goal-directed AI refinement: tell it what to improve — "group these by tier", "show the data flows more clearly" — and it revises the existing diagram while preserving what's already correct, running through the same validation pass as a fresh generation.&lt;/P&gt;
&lt;P data-line="507"&gt;&lt;STRONG&gt;Rebuild&lt;/STRONG&gt;&amp;nbsp;re-reads the live estate and regenerates. Generation runs as a&amp;nbsp;&lt;STRONG&gt;background job&lt;/STRONG&gt;, not a frozen browser tab: you get a phase and a percentage —&amp;nbsp;scope&amp;nbsp;→&amp;nbsp;query&amp;nbsp;→&amp;nbsp;ai&amp;nbsp;→&amp;nbsp;save&amp;nbsp;→&amp;nbsp;done&amp;nbsp;— so a big workload taking a couple of minutes looks like progress rather than a hang. Jobs are capped at three concurrent so a bulk rebuild can't stampede your model provider.&lt;/P&gt;
&lt;P data-line="512"&gt;&lt;STRONG&gt;Drift&lt;/STRONG&gt;&amp;nbsp;compares the diagram against live Azure on demand — the mechanics are in the next section, but it's worth noting it's right there in the toolbar, one click from the picture it's checking.&lt;/P&gt;
&lt;P data-line="516"&gt;Two more keep the diagram connected to the rest of the workbench.&amp;nbsp;&lt;STRONG&gt;Ask AI&lt;/STRONG&gt;&amp;nbsp;puts a question box against this specific diagram, so "why is this Cosmos account reachable from the internet?" is answered with the architecture already in context. And&amp;nbsp;&lt;STRONG&gt;Investigate&lt;/STRONG&gt;&amp;nbsp;hands the whole thing — diagram&amp;nbsp;&lt;EM&gt;and&lt;/EM&gt;&amp;nbsp;its memory — straight into a&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765"&gt;Part 2&lt;/A&gt;&amp;nbsp;deep investigation, which is the loop this series has been building toward: the map you generated in ninety seconds becomes the context a war room reasons over.&lt;/P&gt;
&lt;P data-line="523"&gt;Everything is undoable, and each diagram keeps an&amp;nbsp;&lt;STRONG&gt;Activity&lt;/STRONG&gt;&amp;nbsp;log and a&amp;nbsp;&lt;STRONG&gt;History&lt;/STRONG&gt;&amp;nbsp;of revisions, so an edit made in a hurry is never a one-way door.&lt;/P&gt;
&lt;P data-line="526"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="528"&gt;Getting it back out again&lt;/H3&gt;
&lt;P data-line="530"&gt;A diagram trapped in a tool is a diagram that won't be used, so export is deliberately broad:&lt;/P&gt;
&lt;UL data-line="532"&gt;
&lt;LI data-line="532"&gt;&lt;STRONG&gt;PNG&lt;/STRONG&gt;&amp;nbsp;and&amp;nbsp;&lt;STRONG&gt;SVG&lt;/STRONG&gt;&amp;nbsp;for design docs, change requests and slide decks.&lt;/LI&gt;
&lt;LI data-line="533"&gt;&lt;STRONG&gt;Mermaid&lt;/STRONG&gt;&amp;nbsp;to paste straight into a README or a wiki — and it round-trips: you can&amp;nbsp;&lt;STRONG&gt;import&lt;/STRONG&gt;&amp;nbsp;an existing Mermaid flowchart back onto the canvas.&lt;/LI&gt;
&lt;LI data-line="535"&gt;&lt;STRONG&gt;JSON&lt;/STRONG&gt;&amp;nbsp;for the full model, if you want to do something else with it entirely.&lt;/LI&gt;
&lt;LI data-line="536"&gt;&lt;STRONG&gt;Bicep&lt;/STRONG&gt;&amp;nbsp;and&amp;nbsp;&lt;STRONG&gt;Terraform&lt;/STRONG&gt;&amp;nbsp;&lt;EM&gt;skeletons&lt;/EM&gt;&amp;nbsp;— scaffolding derived from the diagram. They're a starting point, not a deployable module, and the product says so.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="539"&gt;There's also a&amp;nbsp;&lt;STRONG&gt;Present&lt;/STRONG&gt;&amp;nbsp;mode that takes the diagram fullscreen, which turns out to be what people actually reach for in an architecture review.&lt;/P&gt;
&lt;P data-line="542"&gt;Diagrams have a lifecycle —&amp;nbsp;&lt;STRONG&gt;draft → in review → ready&lt;/STRONG&gt;, plus archive — and can be organised into&amp;nbsp;&lt;STRONG&gt;collections&lt;/STRONG&gt;, so a tenant with sixty diagrams doesn't become its own navigation problem. Every save snapshots a revision, and deletion is a recoverable Trash rather than an ending.&lt;/P&gt;
&lt;P data-line="546"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P data-line="548"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="550"&gt;Honest about what it is&lt;/H3&gt;
&lt;P data-line="552"&gt;Two caveats the product is upfront about, and so should this post be.&lt;/P&gt;
&lt;P data-line="554"&gt;&lt;STRONG&gt;The confidence value is declared by the model, not computed by the system.&lt;/STRONG&gt;&amp;nbsp;It's a useful signal about how sure the model was, not an independent measurement of correctness. The thing you should actually trust is the structural guarantee underneath it: every node maps to a real ARM ID, because that part is enforced in code rather than requested in a prompt.&lt;/P&gt;
&lt;P data-line="559"&gt;&lt;STRONG&gt;A first pass is a first draft.&lt;/STRONG&gt;&amp;nbsp;Inference from properties is very good at the relationships Azure records explicitly — network paths, hosting plans, private endpoints, disks — and weaker at the ones that only exist at runtime, like an app calling an external API by URL. That's exactly why the canvas is editable and why Architecture Memory exists: the generated diagram gets you ninety percent of the way in ninety seconds, and you spend ten minutes adding what only your team knows.&lt;/P&gt;
&lt;H2 data-line="568"&gt;Part three — Memory, drift, and the doc your on-call reads&lt;/H2&gt;
&lt;H3 data-line="570"&gt;Architecture Memory — the intent behind the diagram&lt;/H3&gt;
&lt;P data-line="572"&gt;A diagram tells you&amp;nbsp;&lt;EM&gt;what is deployed&lt;/EM&gt;. What it can't carry is what your team&amp;nbsp;&lt;STRONG&gt;intended&lt;/STRONG&gt;&amp;nbsp;— that the second region is deliberately warm-standby rather than half-finished, that the public IP is a known and accepted risk, that when this app misbehaves you check Front Door before you touch the database. Historically that knowledge lives in one senior engineer's head and leaves when they do.&lt;/P&gt;
&lt;P data-line="577"&gt;&lt;STRONG&gt;Architecture Memory&lt;/STRONG&gt;&amp;nbsp;is a structured document attached to each architecture, spanning&amp;nbsp;&lt;STRONG&gt;20 sections across six groups&lt;/STRONG&gt;:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Group&lt;/th&gt;&lt;th&gt;Sections&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Purpose &amp;amp; shape&lt;/td&gt;&lt;td&gt;Overview, architecture pattern, expected flow, components &amp;amp; responsibilities, dependencies&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Topology &amp;amp; access&lt;/td&gt;&lt;td&gt;Network topology, identity &amp;amp; access, data &amp;amp; storage&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Security &amp;amp; compliance&lt;/td&gt;&lt;td&gt;Security model, compliance &amp;amp; governance&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Resilience &amp;amp; performance&lt;/td&gt;&lt;td&gt;Resiliency targets, scaling &amp;amp; performance, critical thresholds &amp;amp; SLIs&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Operations&lt;/td&gt;&lt;td&gt;Observability, runbook / operational notes, change management, cost &amp;amp; sizing notes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Risk &amp;amp; diagnostics&lt;/td&gt;&lt;td&gt;Known gaps &amp;amp; risks, known issues &amp;amp; past incidents, diagnostic hints&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="589"&gt;A brand-new memory is pre-seeded with the&amp;nbsp;&lt;STRONG&gt;seven highest-signal sections&lt;/STRONG&gt;&amp;nbsp;rather than twenty empty boxes, and the AI will draft them from the live architecture for you to correct — which is a much easier job than writing from nothing. Every save snapshots a revision (capped at 50 per document, de-duplicated by content signature), so the design history is recoverable.&lt;/P&gt;
&lt;P data-line="594"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="597"&gt;Where the two pillars snap together&lt;/H3&gt;
&lt;P data-line="599"&gt;Here's the payoff, and it's the reason Map is worth doing before Assess.&lt;/P&gt;
&lt;P data-line="601"&gt;&lt;STRONG&gt;Architecture Memory is injected into the&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765"&gt;Part 2&lt;/A&gt;&amp;nbsp;War Room as expert context.&lt;/STRONG&gt;&amp;nbsp;When a deep investigation has to fit inside a prompt budget, the memory is trimmed by an explicit priority order — expected flow first, then diagnostic hints, known gaps, critical thresholds, security model, resiliency targets, dependencies, components, network topology, observability, known issues. Eleven sections, ranked by operational value, so the most useful knowledge is the&amp;nbsp;&lt;STRONG&gt;last&lt;/STRONG&gt;&amp;nbsp;thing to fall out of the prompt rather than the first.&lt;/P&gt;
&lt;P data-line="608"&gt;Which means the note you wrote in a calm Tuesday afternoon —&amp;nbsp;&lt;EM&gt;"check Front Door health before you look at the database"&lt;/EM&gt;&amp;nbsp;— is what a specialist agent reads at 2 a.m. while you're asleep. Documenting your architecture stops being a chore you do for auditors and becomes something that measurably improves the next incident.&lt;/P&gt;
&lt;H3 data-line="613"&gt;Drift: when reality wanders off&lt;/H3&gt;
&lt;P data-line="615"&gt;Once you have a documented design&amp;nbsp;&lt;EM&gt;and&lt;/EM&gt;&amp;nbsp;live inventory, comparing them costs almost nothing — so the workbench does it continuously.&lt;/P&gt;
&lt;P data-line="618"&gt;&lt;STRONG&gt;Drift detection&lt;/STRONG&gt;&amp;nbsp;matches documented resources against live ones by ARM ID and sorts every resource into one of four states:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;State&lt;/th&gt;&lt;th&gt;Meaning&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;ok&lt;/td&gt;&lt;td&gt;Present in both the design and the live estate&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;documented_missing&lt;/td&gt;&lt;td&gt;In the architecture, no longer live&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;live_uncontrolled&lt;/td&gt;&lt;td&gt;Running in your tenant, in nobody's design&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;inferred&lt;/td&gt;&lt;td&gt;An edge the architecture asserts without a live pair&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="628"&gt;It produces a drift score — simply the share of resources that reconcile — and if a workload has no architecture at all, the score is null and everything live is flagged uncontrolled, which is itself a finding worth acting on.&lt;/P&gt;
&lt;P data-line="632"&gt;live_uncontrolled&amp;nbsp;is usually the column people stare at. That's the resource somebody spun up in a hurry during an incident eight months ago that nobody has thought about since.&lt;/P&gt;
&lt;P data-line="635"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="639"&gt;The Know-Me doc — and a refusal to make things up&lt;/H3&gt;
&lt;P data-line="641"&gt;Diagrams serve architects. On-call needs prose: what is this thing, who owns it, what's the SLA, who do I wake up, and what usually breaks.&lt;/P&gt;
&lt;P data-line="644"&gt;The workbench generates that&amp;nbsp;&lt;STRONG&gt;Know-Me doc&lt;/STRONG&gt;&amp;nbsp;from the architecture and its memory —&amp;nbsp;&lt;STRONG&gt;13 sections&lt;/STRONG&gt;&amp;nbsp;covering the workload overview, the solution architecture, the Azure services and subscriptions in scope, diagnostics and first-look triage, critical thresholds and SLIs, resiliency and DR posture, known issues and proactive callouts, security posture, support and escalation handling, contacts, and data/compliance/cost notes.&lt;/P&gt;
&lt;P data-line="650"&gt;The thirteenth section is the one I'd point a sceptic at, because it's a list of everything the AI&amp;nbsp;&lt;STRONG&gt;refused to invent&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P data-line="653"&gt;The generator is explicitly forbidden from fabricating the facts that matter most: people, SLAs, RTO and RPO values, on-call rotations, customer names, subscription GUIDs, contract and schedule IDs. It doesn't guess and it doesn't produce a plausible-looking placeholder that reads like a fact. It emits a typed marker in the literal form&amp;nbsp;⟦TODO: &amp;lt;label&amp;gt; | key=&amp;lt;field&amp;gt;⟧, and every one of those markers is collected into that final checklist section for a human to complete. What Azure&amp;nbsp;&lt;EM&gt;does&lt;/EM&gt;&amp;nbsp;know — subscriptions, regions, real scope — is auto-filled and labelled as platform-sourced, so you can see at a glance which facts came from the platform, which were AI-suggested and editable, and which are waiting on you.&lt;/P&gt;
&lt;P data-line="662"&gt;Filling them in is deliberately low-friction. Fields render as the right control for their type — segmented buttons for small strict sets like Critical/High/Medium/Low, a typeahead combobox for larger sets like subscriptions or regions, a plain input for free text — and a&amp;nbsp;&lt;STRONG&gt;Guided Fill&lt;/STRONG&gt;&amp;nbsp;mode walks you through every incomplete field one at a time, keyboard-driven, so completing a doc is a five-minute pass rather than an afternoon of hunting.&lt;/P&gt;
&lt;P data-line="668"&gt;&lt;STRONG&gt;And the refusal is enforced at the door.&lt;/STRONG&gt;&amp;nbsp;A doc moves through&amp;nbsp;&lt;STRONG&gt;draft → in review → published&lt;/STRONG&gt;, and publishing is&amp;nbsp;&lt;STRONG&gt;blocked&lt;/STRONG&gt;&amp;nbsp;until all five required groups have at least one real answer: escalation, resiliency, SLA, contract, and contacts. You cannot publish a runbook whose escalation path is still a placeholder. An on-call document that confidently states a fabricated RTO is worse than no document at all — it's a document someone will&amp;nbsp;&lt;EM&gt;believe&lt;/EM&gt;&amp;nbsp;at 3 a.m. The gate exists so nobody discovers the gap during an incident.&lt;/P&gt;
&lt;P data-line="675"&gt;Finished docs export to Markdown or a branded PDF, support inline images, keep revisions, and go to a recoverable Trash rather than vanishing.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="685"&gt;Part four — The Estate Graph&lt;/H2&gt;
&lt;H3 data-line="687"&gt;Zoom all the way out&lt;/H3&gt;
&lt;P data-line="689"&gt;Per-workload diagrams answer "how does this application hang together?" The&amp;nbsp;&lt;STRONG&gt;Estate Graph&lt;/STRONG&gt;&amp;nbsp;answers the larger question:&amp;nbsp;&lt;EM&gt;how does all of it hang together?&lt;/EM&gt;&lt;/P&gt;
&lt;P data-line="692"&gt;It assembles the whole tenant into one interactive graph —&amp;nbsp;&lt;STRONG&gt;15 node kinds&lt;/STRONG&gt;&amp;nbsp;and&amp;nbsp;&lt;STRONG&gt;14 edge kinds&lt;/STRONG&gt;. Nodes run from the tenant connection through management groups, subscriptions and resource groups, down to resources, and across to the artifacts you've built: workloads, architectures, memories and assessment findings. Edges carry the structure (contains,&amp;nbsp;member_of,&amp;nbsp;belongs_to), the modelling relationships (models,&amp;nbsp;documents,&amp;nbsp;has_finding) and the dependency relationships (depends_on,&amp;nbsp;connects_to,&amp;nbsp;data_flow).&lt;/P&gt;
&lt;P data-line="699"&gt;It's&amp;nbsp;&lt;STRONG&gt;workload-first&lt;/STRONG&gt;&amp;nbsp;by design. You navigate applications, with raw resources underneath, which is the opposite of how most inventory tools present a tenant and much closer to how teams actually think.&lt;/P&gt;
&lt;H3 data-line="703"&gt;Five overlays, one map&lt;/H3&gt;
&lt;P data-line="705"&gt;Switch on an overlay and the same map answers a different question:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Overlay&lt;/th&gt;&lt;th&gt;Answers&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Cost&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Where is the money?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Retirement&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;What is Azure evolving away from, and by when?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Coverage&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;What's unmonitored, untelemetered or unprotected? (monitoring, telemetry, backup/DR)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;RBAC&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Who holds privileged access where?&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Change&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;What moved recently?&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="715"&gt;That's the argument for a single graph over five separate dashboards: the cost hotspot and the coverage gap and the privileged principal are all&amp;nbsp;&lt;EM&gt;the same node&lt;/EM&gt;, and seeing them on one map is how you notice they're related.&lt;/P&gt;
&lt;P data-line="719"&gt;Because a tenant-wide graph can get genuinely enormous, everything is capped on purpose rather than allowed to melt the browser: findings collapse into a single "⚠ N findings" super-node past 18 per workload, expanding a group loads at most 400 resources, and the overlays are bounded too (12 privileged principals, 20 retirement items, 40 change events). You choose a layout — organic, hierarchy, breadthfirst or concentric — and it persists for your tenant.&lt;/P&gt;
&lt;H3 data-line="725"&gt;Every node is a doorway&lt;/H3&gt;
&lt;P data-line="727"&gt;Select a node and the inspector opens a&amp;nbsp;&lt;STRONG&gt;dossier&lt;/STRONG&gt;: for a workload, its environment, criticality, resource count, linked architecture, risk score and findings; for a resource, its type, SKU, location, owner, cost and the workloads it belongs to; for an architecture, its state, AI confidence and how much of its memory is filled.&lt;/P&gt;
&lt;P data-line="732"&gt;From there you can trace rather than just look — expand a node's neighbours, highlight a&amp;nbsp;&lt;STRONG&gt;blast radius&lt;/STRONG&gt;, or ask for the path between two nodes. And the "open in" actions carry the workload context with you into Inventory, the architecture, its memory, an assessment run, Change Explorer, RBAC, Telemetry, Backup &amp;amp; DR — or straight into a&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765"&gt;Part 2&lt;/A&gt;&amp;nbsp;war-room investigation. You land somewhere useful, already scoped, instead of at the top of another dashboard.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P data-line="741"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="749"&gt;Read-only, and why that's a design constraint rather than a limitation&lt;/H2&gt;
&lt;P data-line="751"&gt;Everything in this post is a read path. Workloads, architectures, memories, Know-Me docs and the Estate Graph all write to the Azure Support Agent's own storage — never to Azure. The reads themselves go straight to Azure Resource Graph and the ARM APIs.&lt;/P&gt;
&lt;P data-line="755"&gt;That's a deliberate boundary. Mapping is the activity you want to be able to run against production on a Friday afternoon without a change request, without a second pair of eyes, and without thinking twice. The moment mapping can mutate, it acquires a blast radius and people stop running it — which defeats the point. Writes exist elsewhere in the workbench (applying owner tags, for instance), and they're approval-gated and audited when they do. They're a later post.&lt;/P&gt;
&lt;P data-line="761"&gt;And if you haven't connected a tenant yet, demo mode seeds the whole pillar with realistic synthetic workloads, architectures and inventory, so you can walk the entire flow before pointing it at anything real.&lt;/P&gt;
&lt;H2 data-line="765"&gt;How it's judged&lt;/H2&gt;
&lt;UL data-line="767"&gt;
&lt;LI data-line="767"&gt;&lt;STRONG&gt;Health scores are composite and explainable.&lt;/STRONG&gt;&amp;nbsp;Seven weighted signals, published bands, and an API that returns which signals contributed, which are missing, and the exact weights used.&lt;/LI&gt;
&lt;LI data-line="769"&gt;&lt;STRONG&gt;Unmeasured never masquerades as bad.&lt;/STRONG&gt;&amp;nbsp;Signals that haven't been analyzed are excluded from the denominator rather than scored as zero, and the weights are yours to tune.&lt;/LI&gt;
&lt;LI data-line="771"&gt;&lt;STRONG&gt;Autopilot is review-before-apply.&lt;/STRONG&gt;&amp;nbsp;Proposals carry reasoning and confidence, and are never persisted without an explicit human save.&lt;/LI&gt;
&lt;LI data-line="773"&gt;&lt;STRONG&gt;Every node maps to a real resource.&lt;/STRONG&gt;&amp;nbsp;Model-emitted ARM IDs are validated against live inventory; duplicates collapse and orphaned edges are dropped before anything renders.&lt;/LI&gt;
&lt;LI data-line="775"&gt;&lt;STRONG&gt;Large estates degrade gracefully.&lt;/STRONG&gt;&amp;nbsp;Discovery caps, property budgets and graph caps are explicit and disclosed rather than silently sampling.&lt;/LI&gt;
&lt;LI data-line="777"&gt;&lt;STRONG&gt;The generator declines to invent.&lt;/STRONG&gt;&amp;nbsp;People, SLAs, RTO/RPO, contacts, GUIDs and contract IDs become explicit ⟦TODO⟧ markers, and publishing is blocked until all five required groups are genuinely complete.&lt;/LI&gt;
&lt;LI data-line="780"&gt;&lt;STRONG&gt;Drift is measured, not asserted.&lt;/STRONG&gt;&amp;nbsp;Documented and live inventory reconcile by ARM ID into four named states with a score you can track over time.&lt;/LI&gt;
&lt;LI data-line="782"&gt;&lt;STRONG&gt;Overlays reflect real data and deep links resolve.&lt;/STRONG&gt;&amp;nbsp;Cost, retirement, coverage, RBAC and change all read live sources, and every node opens the artifact behind it.&lt;/LI&gt;
&lt;LI data-line="784"&gt;&lt;STRONG&gt;Read-only throughout.&lt;/STRONG&gt;&amp;nbsp;Mapping your estate never changes it, and the Azure Support Agent runs in your own Azure Container App against Azure's own APIs.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 data-line="787"&gt;Try it yourself&lt;/H2&gt;
&lt;P data-line="789"&gt;If you've already deployed the&amp;nbsp;&lt;STRONG&gt;Azure Support Agent&lt;/STRONG&gt;, this is the fastest way to feel the difference — about ten minutes:&lt;/P&gt;
&lt;OL data-line="792"&gt;
&lt;LI data-line="792"&gt;Run&amp;nbsp;&lt;STRONG&gt;Autopilot&lt;/STRONG&gt;&amp;nbsp;against one subscription and accept a single proposed workload.&lt;/LI&gt;
&lt;LI data-line="793"&gt;Hit&amp;nbsp;&lt;STRONG&gt;Generate architecture&lt;/STRONG&gt;&amp;nbsp;and watch it assemble. Seeing a correct diagram of something you own build itself out of Azure Resource Graph is the moment this stops being abstract.&lt;/LI&gt;
&lt;LI data-line="795"&gt;Open its&amp;nbsp;&lt;STRONG&gt;Architecture Memory&lt;/STRONG&gt;&amp;nbsp;and write three honest sentences about how it's&amp;nbsp;&lt;EM&gt;supposed&lt;/EM&gt;&amp;nbsp;to work — the expected flow, one known gap, one diagnostic hint.&lt;/LI&gt;
&lt;LI data-line="797"&gt;Now run a&amp;nbsp;&lt;STRONG&gt;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765"&gt;Part 2&lt;/A&gt;&amp;nbsp;deep investigation&lt;/STRONG&gt;&amp;nbsp;against that workload.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P data-line="799"&gt;The difference between the answer you get in step 4 and the answer you'd have got before step 3 is the entire argument for this pillar. The map isn't documentation you produce for someone else's benefit; it's context that makes every other answer better.&lt;/P&gt;
&lt;P data-line="803"&gt;No tenant connected yet? Demo mode runs the same flow on synthetic data, with nothing to risk.&lt;/P&gt;
&lt;P data-line="805"&gt;&lt;STRONG&gt;Next time — Part 4:&amp;nbsp;&lt;EM&gt;Assess — coverage and your real posture.&lt;/EM&gt;&lt;/STRONG&gt;&amp;nbsp;With the map in place, we go looking for trouble on purpose: Azure Monitor baseline alert coverage and whether the alerts you already have would actually fire, telemetry gaps, backup and DR posture with real costs attached, Well-Architected reviews at scale, FMEA risk registers, and who can do what across your estate — each judged against a versioned baseline, and each arriving with the infrastructure-as-code to close the gap.&lt;/P&gt;
&lt;P data-line="814"&gt;It's open source and free to run. Three ways to start, in rising order of commitment:&lt;/P&gt;
&lt;OL data-line="816"&gt;
&lt;LI data-line="816"&gt;&lt;STRONG&gt;Explore demo mode&lt;/STRONG&gt;&amp;nbsp;— synthetic data, no connection required, nothing to risk.&lt;/LI&gt;
&lt;LI data-line="817"&gt;&lt;STRONG&gt;Deploy to your tenant&lt;/STRONG&gt;&amp;nbsp;— one click to Azure Container Apps; private networking; your data never leaves.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="821"&gt;Or main repository&amp;nbsp;&lt;A href="https://github.com/zmustafa/AzureSupportAgent" target="_blank" rel="noopener" data-href="https://github.com/zmustafa/AzureSupportAgent"&gt;https://github.com/zmustafa/AzureSupportAgent&lt;/A&gt;&lt;/P&gt;
&lt;P data-line="823"&gt;&lt;A class="lia-external-url" href="https://zeeshan.net/building-an-ai-azure-ops-workbench-part-3-reverse-engineer-azure-architecture-diagrams/" target="_blank" rel="noopener"&gt;Original post&lt;/A&gt;.&lt;/P&gt;</description>
      <pubDate>Wed, 26 Aug 2026 14:50:20 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/building-an-ai-azure-ops-workbench-part-3-reverse-engineer-azure/ba-p/4541741</guid>
      <dc:creator>zmustafa</dc:creator>
      <dc:date>2026-08-26T14:50:20Z</dc:date>
    </item>
    <item>
      <title>Building Resilient Power Automate Flows That Stay Running</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/building-resilient-power-automate-flows-that-stay-running/ba-p/4542457</link>
      <description>&lt;P&gt;If you've spent any time working with Power Automate in enterprise environments, you've seen it happen. A business-critical flow fails on a Friday afternoon. The person who built it left the company six months ago. Nobody gets an alert. Nobody knows until Monday morning when someone notices the reports didn't run. By then, the blast radius is already bigger than it needed to be.&lt;/P&gt;
&lt;P&gt;Flow failures aren't inevitable, but unplanned ones usually share the same root causes: personal account dependencies, missing error handling, hardcoded configurations, and no visibility into what's actually happening at runtime. The good news is that most of these are solvable with patterns that aren't especially complex, they just require intentionality.&lt;/P&gt;
&lt;P&gt;This post covers 16 recommendations across 5 focus areas that I've found to be the highest-leverage investments for making Power Automate flows more resilient, performant, and easier to operate at scale. I've ordered them roughly by the impact you'll see fastest, with supporting documentation for each section for further reading and implementation guidance.&lt;/P&gt;
&lt;H2&gt;1. Credential and Connection Resilience&lt;/H2&gt;
&lt;P&gt;This is where I always start with customers, because it's the most common source of outages and also one of the easiest to fix systematically.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Migrate high-value flows to service principal ownership.&lt;/STRONG&gt; Flows owned by user accounts fail when passwords change, MFA prompts fire, or the user leaves the organization. A service principal is a non-human identity that represents an application or service and doesn't have any of those human lifecycle problems. The pattern is to register an Azure AD app registration per workload domain, grant it the required API permissions, and bind the flow to it using connection references rather than a personal connection. For connectors that don't yet support service principals (SharePoint, Outlook, Teams), use a hardened service account protected with Privileged Identity Management.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/service-principal-support" target="_blank"&gt;Service principal owned flows&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/service-principal-support" target="_blank"&gt;Service Principal Licensing Requirements&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/troubleshoot/power-platform/power-automate/connections/troubleshoot-broken-connections" target="_blank"&gt;Resolve broken connections&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Use connection references for all connections.&lt;/STRONG&gt; Embedded personal connections break when flows are exported, imported, or the owner changes. If you're building flows inside solutions, there's no good reason not to be using connection references. Create one per connector type used in your solution and bind every flow to the reference rather than a personal connection. When you deploy through environments, you update the binding once rather than hunting through individual flows.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-apps/maker/data-platform/create-connection-reference" target="_blank"&gt;Use connection references in solutions&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/alm/conn-ref-env-variables-build-tools" target="_blank"&gt;Pre-populate connection references for CI/CD&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Store secrets in Azure Key Vault, not flow variables.&lt;/STRONG&gt; Hardcoded API keys or tokens in flow expressions show up in run history and are a real security exposure. The Key Vault connector has a "Get secret" action you can drop at the top of any flow. Restrict access to the service principal only, and when you rotate a secret in Key Vault, the flow picks it up dynamically with no changes needed.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/connectors/keyvault/" target="_blank"&gt;Azure Key Vault connector reference&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-apps/maker/data-platform/environmentvariables-azure-key-vault-secrets" target="_blank"&gt;Key Vault secrets with environment variables&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/use-secure-inputs-outputs-triggers" target="_blank"&gt;Secure data in cloud flows&lt;/A&gt;&lt;/P&gt;
&lt;H2&gt;2. Error Handling and Retry Logic&lt;/H2&gt;
&lt;P&gt;Unhandled errors in Power Automate produce silent failures. The flow shows red, maybe an email goes out if you're lucky, and whoever is on call has to play detective with limited context. Building proper failure boundaries before flows reach production is one of the highest-ROI things you can do.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Wrap every action in a Scope with "Configure run after."&lt;/STRONG&gt; A Scope action groups a logical block of actions and lets you branch on "Has failed." The pattern is straightforward: wrap each logical unit (get data, send notification, write to Dataverse), add a parallel branch configured to run on failure, and in that branch log the error, send an alert, and terminate cleanly. This keeps failure handling isolated and predictable rather than having it bleed across the entire flow.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/scopes" target="_blank"&gt;Use scopes to organize actions&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/create-scopes" target="_blank"&gt;Best practices for using scopes&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/error-handling" target="_blank"&gt;Employ robust error handling&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Enable built-in retry policies on connector actions.&lt;/STRONG&gt; Transient HTTP and connector errors are a fact of life. The retry policy setting on any connector action handles them automatically without custom logic. Exponential interval is generally preferable over fixed. Four retries with a PT10S interval is a reasonable starting point. One important caveat: check for idempotency before enabling retries on Dataverse writes, since a write that partially succeeded before a transient error can create duplicate records if blindly retried.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/error-handling#implement-a-retry-policy" target="_blank"&gt;Implement a retry policy&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/well-architected/reliability/handle-transient-faults" target="_blank"&gt;Handle transient faults (Well-Architected)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/limits-and-config" target="_blank"&gt;Flow limits &amp;amp; config (retry settings)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Use "Do until" loops with exit conditions for polling.&lt;/STRONG&gt; A polling loop without bounds can run indefinitely or silently miss the exit condition it was waiting for. Set a maximum iteration count and a timeout, and make sure your exit condition is the expected success state and not just the absence of error.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-control-flow-loops?tabs=standard" target="_blank"&gt;Until logic documentation&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/limits-and-config" target="_blank"&gt;Flow limits: concurrency &amp;amp; looping&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Capture and surface error details in failure notifications.&lt;/STRONG&gt; Generic failure emails like "Your flow failed" are nearly useless for triage. In the failure branch, use workflow().run.name and actions('ActionName')?['error'] expressions to pull the actual error message, and construct a direct link to the run using the environment name, flow ID, and run ID. Sending this as a Teams adaptive card with structured fields makes triage significantly faster than sifting through the admin center.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/troubleshoot-cloud-flows" target="_blank"&gt;Understand error codes&lt;/A&gt;&lt;/P&gt;
&lt;H2&gt;3. ALM and Environment Strategy&lt;/H2&gt;
&lt;P&gt;Environment drift is sneaky. It builds up over time through ad-hoc edits made directly in production, hardcoded values that break on promotion, and manual export/import processes that are just inconsistent enough to cause problems at the worst times.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Deploy only managed solutions to production.&lt;/STRONG&gt; Unmanaged solutions in production allow anyone with access to make direct edits that bypass your ALM process. The model I recommend is straightforward: build in Dev with unmanaged solutions, export as managed for promotion, validate in Sandbox, and promote to Production through Pipelines. Use the "Block unmanaged customizations" setting in Environment security policies to enforce this at the platform level.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/alm/solution-concepts-alm" target="_blank"&gt;Solution concepts with Power Platform&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/alm/update-solutions-alm" target="_blank"&gt;Create and update custom solutions for ALM in Power Platform&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Use Power Platform Pipelines for automated promotion.&lt;/STRONG&gt; Manual export and import is error-prone and doesn't scale. Pipelines automate the full Dev to Sandbox to Production path, support pre-deployment validation before each promotion, and let you restrict production deployment approvals to designated owners. If you're not using Pipelines yet, this is worth the setup investment.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/alm/pipelines" target="_blank"&gt;Overview of pipelines in Power Platform&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/alm/set-up-pipelines" target="_blank"&gt;Set up pipelines in Power Platform&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/alm/delegated-deployments-setup" target="_blank"&gt;Deploy pipelines as a service principal&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Eliminate hardcoding with Environment Variables.&lt;/STRONG&gt; Flows that reference hardcoded SharePoint site URLs, list names, or IDs break every time they're promoted to a new environment. Replace them with environment variables, set the values at the environment level rather than in the solution itself, and validate bindings as part of your pre-deployment checklist.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-apps/maker/data-platform/environmentvariables" target="_blank"&gt;Environment variables for Power Platform overview&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-apps/maker/data-platform/environmentvariables-power-automate" target="_blank"&gt;Use environment variables in Power Automate solution cloud flows&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Apply DLP policies scoped per environment.&lt;/STRONG&gt; Overly permissive DLP in production is a real risk for data leakage and flow instability. Classify connectors intentionally across Business, Non-Business, and Blocked. Scope policies from the top down, tenant-level first and then environment-level. Use endpoint filtering to restrict rather than wholesale block where possible, and always test DLP policy changes in Sandbox before promoting them to production.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/admin/wp-data-loss-prevention" target="_blank"&gt;Data loss prevention policies overview&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/admin/managed-environment-data-policies" target="_blank"&gt;Data policies for Managed Environments&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/admin/identify-blocked-flows-data-policies" target="_blank"&gt;Identify blocked Power Automate flows from data policies&lt;/A&gt;&lt;/P&gt;
&lt;H2&gt;4. Monitoring and Observability&lt;/H2&gt;
&lt;P&gt;If you don't have visibility into flow health, you're finding out about failures the worst possible way: from users. Most organizations have significantly less monitoring in place for Power Automate than they do for their traditional application workloads.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Enable Power Platform admin center flow analytics.&lt;/STRONG&gt; This is the quickest win in the monitoring category. In the Power Platform admin center, navigate to Analytics and enable flow run history and error reporting at the environment level. From there, set up a regular cadence (weekly is a good start) to review failure rates for flows classified as business-critical. Having that baseline gives you something to measure against when you start making resilience improvements.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-platform/admin/tenant-level-analytics" target="_blank"&gt;Tenant-level analytics&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/monitoring-and-alerting" target="_blank"&gt;Best practices for monitor your flows (analytics)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Integrate with Application Insights for deeper observability.&lt;/STRONG&gt; For environments running Managed Environments, you can configure the Data Export setting in the admin center to push cloud flow runs, triggers, and actions to an Azure Application Insights resource. Once data is flowing, you get full query and visualization capability for run health, custom diagnostics, and alerting. This is the right long-term destination for any organization that takes operational reliability seriously.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/monitoring-and-alerting" target="_blank"&gt;Overview of integration with Application Insights&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/monitoring-and-alerting" target="_blank"&gt;Set up Application Insights with Power Automate&lt;/A&gt;&lt;/P&gt;
&lt;H2&gt;5. Performance and Throttling&lt;/H2&gt;
&lt;P&gt;High-volume flows that aren't tuned for throttling will eventually hit API rate limits and start failing or queuing in ways that are hard to predict. Most of the common patterns here are straightforward to address.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Apply concurrency control on trigger-heavy flows.&lt;/STRONG&gt; By default, Power Automate concurrency is unbounded. A high-volume trigger can spin up thousands of parallel runs simultaneously and hit API limits quickly. Enable concurrency control on the trigger, set the degree of parallelism based on your connector's rate limits (starting between 10 and 25 is reasonable), and monitor queue depth in the Power Automate portal to tune from there.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/understand-limits" target="_blank"&gt;Understand limits &amp;amp; avoid throttling&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/limits-and-config" target="_blank"&gt;Flow limits: concurrency, looping, debatching&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Batch SharePoint and Dataverse operations instead of looping.&lt;/STRONG&gt; An "Apply to each" loop that makes an individual API call per item scales linearly in both API call count and runtime. For SharePoint, use the "Send an HTTP request to SharePoint" action with OData $batch to group reads and writes. For Dataverse, use batch actions or FetchXML to pull multiple records in a single call. As a rough target, if a loop is making more than 50 individual API calls per run, it's a good candidate for batching.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/connectors/sharepointonline/" target="_blank"&gt;Make batch requests with the REST APIs - SharePoint&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/understand-limits" target="_blank"&gt;Execute batch operations by using the Web API - Dataverse&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Use chunking for large file or record sets.&lt;/STRONG&gt; Flows processing large payloads can hit the 100MB message size limit or simply time out. The pattern here is to split large workloads into pages using OData $top and $skip or Dataverse paging cookies, use a parent flow to orchestrate chunked child flows, and log progress state to Dataverse so the parent can resume if a chunk fails.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/logic-apps/logic-apps-handle-large-messages" target="_blank"&gt;Handle large messages in workflows using chunking in Azure Logic Apps (applies to Power Automate)&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://learn.microsoft.com/en-us/power-automate/guidance/coding-guidelines/understand-limits" target="_blank"&gt;Message size limits in Power Automate&lt;/A&gt;&lt;/P&gt;
&lt;H2&gt;Where to Start&lt;/H2&gt;
&lt;P&gt;If you're looking at this list and wondering where to begin, the recommended implementation order is:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Credential and Connection Resilience first.&lt;/STRONG&gt; This eliminates the most common source of outages. Migrate to service principals where supported and harden service accounts with PIM everywhere else.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Error Handling and Retry Logic second.&lt;/STRONG&gt; Low effort relative to the impact. Adding scopes, run-after branches, and retry policies is mostly configuration work, and the payoff is immediate.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;ALM and Environment Strategy third.&lt;/STRONG&gt; Managed solutions in production, Pipelines for promotion, and environment variables in place of hardcoded values.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Monitoring and Observability fourth.&lt;/STRONG&gt; Structured logging and failure alerting gives you quantifiable before-and-after visibility on everything else you're doing.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Performance and Throttling last.&lt;/STRONG&gt; Address this for high-volume flows once the foundational reliability work is in place.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;You don't need to implement all 16 of these at once. Even getting the first two focus areas locked down will materially reduce the failure rate for most enterprise Power Automate implementations. The goal is to build flows that run reliably, fail visibly when something goes wrong, and don't require a forensic investigation every time they do.&lt;/P&gt;
&lt;P&gt;Start there and layer in the rest over time.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Author&lt;/STRONG&gt;: Marc Lotorto &lt;STRONG&gt;Contributors&lt;/STRONG&gt;: Sheldon Dsouza, Ben Kohler&lt;/P&gt;</description>
      <pubDate>Thu, 30 Jul 2026 19:04:54 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/building-resilient-power-automate-flows-that-stay-running/ba-p/4542457</guid>
      <dc:creator>mlotorto</dc:creator>
      <dc:date>2026-07-30T19:04:54Z</dc:date>
    </item>
    <item>
      <title>Microsoft Foundry Models: A Field Guide for Cloud Solution Architects</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/microsoft-foundry-models-a-field-guide-for-cloud-solution/ba-p/4541912</link>
      <description>&lt;P&gt;Which model families matter, what each one is for, and how to choose through the Well-Architected lens.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;July 2026. Views are my own, not Microsoft guidance. Model availability, status tags, and capabilities change fast: everything below is accurate at time of writing. Verify against the live catalog before you commit an architecture.&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;Foundry in one minute&lt;/H1&gt;
&lt;P&gt;Microsoft Foundry is the model platform on Azure: one catalog, one control plane. What that means in practice:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;1,900+ models across OpenAI, Anthropic, Mistral AI, Meta, DeepSeek, xAI, Cohere, NVIDIA, and others (at time of writing)&lt;/LI&gt;
&lt;LI&gt;Two deployment modes: serverless APIs (pay per token, fastest path) and managed compute (your infrastructure, your controls)&lt;/LI&gt;
&lt;LI&gt;One governance plane: Entra ID for identity, Azure billing with existing commitments applying, Azure Monitor for observability, Azure Policy for guardrails&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The implication for architects: adding a model vendor is no longer a procurement cycle. It's a routing decision. That changes how you should design, and it raises the bar on the plumbing: gateway, model service layer, config-driven model names.&lt;/P&gt;
&lt;H1&gt;The lens: five pillars, five questions&lt;/H1&gt;
&lt;P&gt;The Azure Well-Architected Framework gives you five pillars. Applied to model selection, they become five questions:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Cost Optimization: &lt;/STRONG&gt;does this workload need frontier pricing, or is a smaller model good enough?&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Reliability: &lt;/STRONG&gt;what happens when this model retires, throttles, or degrades?&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Performance Efficiency: &lt;/STRONG&gt;what latency does the user experience at p99, not on average?&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Security: &lt;/STRONG&gt;who can call this model, and what filters sit in front of it?&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Operational Excellence: &lt;/STRONG&gt;can you swap this model without an engineering sprint?&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Each vendor section below closes with the pillar notes that matter most for that family.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;[Diagram 1 –&amp;nbsp; The Model Catalogue Toolbox]&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;OpenAI: tiers, not versions&lt;/H1&gt;
&lt;P&gt;The GPT-5 family in Foundry is not one model with version numbers. It's tiers with different jobs (at time of writing):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Deep reasoning (gpt-5.6-sol): &lt;/STRONG&gt;multi-step analysis, complex agentic workflows, hard coding problems. Slowest and most expensive. Use it where being wrong is expensive.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Frontier workhorse (gpt-5.5): &lt;/STRONG&gt;document work, coding, data analysis, 1M-token context. Where most complex production traffic belongs.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Chat tier (gpt-5.5 Instant): &lt;/STRONG&gt;multi-turn assistants, tool orchestration, retrieval-grounded apps. Faster, cheaper, precise enough.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Nano tier (gpt-5 nano): &lt;/STRONG&gt;ultra-low-latency Q&amp;amp;A at volume. When a user is waiting and the task is simple, this is the answer.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H4&gt;WAF notes&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Cost + Performance: &lt;/STRONG&gt;The most common failure mode is routing everything to the biggest model. Users wait longer, the bill grows, and quality doesn't improve because most requests never needed the depth.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Reliability: &lt;/STRONG&gt;Every deployed model has a retirement date. Check it at design time and plan the migration path before you need it.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Operational Excellence: &lt;/STRONG&gt;Abstract model names behind config. A retirement should be a config change, not a sprint.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Anthropic: Claude, now GA on Azure&lt;/H1&gt;
&lt;P&gt;Claude Opus 4.8, Claude Sonnet 5, and Claude Haiku 4.5 are generally available in Foundry hosted on Azure (GA announced June 29, 2026; Sonnet 5 followed in early July). Same Azure billing, same Entra ID, no separate Anthropic contract. Claude Fable 5, Anthropic's frontier agent model, returned to availability on July 1 after an export-control suspension from June 12-30. Mythos-class models remain gated research preview for approved organizations only (at time of writing).&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Opus 4.8: &lt;/STRONG&gt;maximum reasoning depth. Long-horizon agentic runs, hard multi-step analysis, complex coding.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Sonnet 5: &lt;/STRONG&gt;the default for agents and coding work. Strong tool use, large context, handles workloads that used to need Opus-class models.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Haiku 4.5: &lt;/STRONG&gt;the volume tier. Classification, tagging, metadata, simple Q&amp;amp;A at thousands of calls.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H4&gt;WAF notes&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Security: &lt;/STRONG&gt;Unlike Azure OpenAI models, Claude deployments ship with no built-in content filtering at deployment time (at time of writing). Configure Azure AI Content Safety or gateway-level filtering yourself. This is the single most-missed item in reviews.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Reliability: &lt;/STRONG&gt;A safety-flagged request returns stop_reason "refusal" with HTTP 200, not an error status. Handle it in application logic, not in status-code checks.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Operational Excellence: &lt;/STRONG&gt;Foundry does not pass through Anthropic's native rate-limit response headers. Use Azure Monitor for consumption tracking. And verify context-window figures in the portal's deployment pane: public documentation sources have disagreed.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Mistral AI: open weights and specialists&lt;/H1&gt;
&lt;P&gt;Mistral's lineup answers requirements the flagships don't (at time of writing):&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Mistral Large 3: &lt;/STRONG&gt;frontier-class capability with open weights. Tool calling, long context, agentic workflows. Deployable on managed compute when serverless doesn't fit the compliance story.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Mistral Document AI: &lt;/STRONG&gt;OCR and extraction for scanned PDFs, forms, and technical manuals, feeding straight into RAG pipelines.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Codestral: &lt;/STRONG&gt;purpose-built code generation.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Ministral: &lt;/STRONG&gt;small models for edge and low-latency scenarios.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H4&gt;WAF notes&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Security: &lt;/STRONG&gt;Open weights plus deployment control is the answer when data residency or model inspection is a requirement, not a preference.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Cost: &lt;/STRONG&gt;On document pipelines, a dedicated extraction model routinely beats prompting a general model, on both accuracy and price.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;Meta Llama: the open ecosystem&lt;/H1&gt;
&lt;P&gt;Llama spans 1B and 3B small models for edge and on-device inference up to 405B for synthetic data generation and distillation. It has the widest open fine-tuning community, which matters when you need domain adaptation with full control of weights and training data.&lt;/P&gt;
&lt;H4&gt;WAF notes&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Cost + Performance: &lt;/STRONG&gt;Llama SLMs handle classification, extraction, and summarization at a fraction of frontier pricing, and at the edge they remove network latency entirely.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Operational Excellence: &lt;/STRONG&gt;Managed-compute deployments put patching, scaling, and monitoring on your team. Budget for the ops, not just the tokens.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;DeepSeek: reasoning on a budget&lt;/H1&gt;
&lt;P&gt;DeepSeek's family includes reasoning models trained for step-by-step math, science, and coding tasks at aggressive price points. Worth evaluating wherever reasoning depth matters but flagship pricing doesn't fit.&lt;/P&gt;
&lt;H4&gt;WAF notes&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Cost: &lt;/STRONG&gt;Benchmark against your actual reasoning workloads. The price gap to frontier reasoning tiers is large enough to justify the evaluation effort.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Security: &lt;/STRONG&gt;Same rule as all partner models: bring your own content filtering, and check data-handling terms on the model card before production use.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;xAI Grok and Microsoft Phi&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Grok: &lt;/STRONG&gt;reasoning and non-reasoning models aimed at data extraction, coding, summarization, and agentic applications.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Phi: &lt;/STRONG&gt;Microsoft's small-model family, 60M+ downloads (at time of writing). On-device, edge, and high-volume simple tasks.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H4&gt;WAF notes&lt;/H4&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Performance: &lt;/STRONG&gt;Phi at the edge removes the network round trip entirely. For latency-critical simple tasks, no hosted model competes with no network call.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;The selection checklist&lt;/H1&gt;
&lt;P&gt;Before any model earns a production slot, walk it through the five pillars:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Pillar&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;What to check before you commit&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Cost Optimization&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Map the workload to a tier before picking a name. Price the small-model alternative for every high-volume task. Check reservation options for steady traffic.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Reliability&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Find the retirement date before the first deployment. Plan the migration path (blue/green beats in-place for most production workloads). Know the throttling behavior and your overflow lane.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Performance Efficiency&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Benchmark p95/p99 latency with your prompts, not the vendor's. Enable streaming for anything user-facing. Consider edge or SLM options where network latency dominates.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Security&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Verify what content filtering ships by default; for most partner models the answer is none, so configure it. Use Managed Identities, not API keys. Check data-handling terms per model card.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Operational Excellence&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Keep model names in config, never in code. Put a gateway and a model service layer in front. Define promotion gates (evals, latency budgets) before the next version ships.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;The pattern that ties it together&lt;/H1&gt;
&lt;P&gt;Your most expensive model should handle your fewest requests. The hybrid pattern:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Frontier model as the brain: &lt;/STRONG&gt;complex decisions, planning, orchestration. Low volume, high stakes.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Small models as the hands: &lt;/STRONG&gt;Phi or Llama SLMs for classification, extraction, and summarization at volume.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Specialists where they win: &lt;/STRONG&gt;reasoning models for math-heavy tasks, extraction models for documents.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;A router in front: &lt;/STRONG&gt;the gateway decides which request goes where. The application never knows.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The catalog isn't a leaderboard. It's a toolbox. The teams that get cost, latency, and reliability right pick per workload, not per benchmark, and they build the plumbing (gateway, model service layer, config-driven names) that makes multi-model architectures operational instead of aspirational.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [Diagram 2 – The pattern that ties the models together]&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;Cheat sheet: the catalog briefly&lt;/H1&gt;
&lt;P&gt;One row per family. Use it as the 30-second version of everything above (all entries at time of writing).&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Family&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Key models&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Reach for it when&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Watch out for&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;OpenAI GPT-5&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;gpt-5.6-sol, gpt-5.5, gpt-5.5 Instant, gpt-5 nano&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Default frontier lineup; tiered from deep reasoning to low-latency nano&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Routing everything to the flagship; retirement dates; hard-coded names&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Anthropic Claude&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Opus 4.8, Sonnet 5, Haiku 4.5 (GA on Azure); Fable 5&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Agentic and coding workloads; second frontier vendor for resilience&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;No default content filtering; refusals return HTTP 200; no native rate-limit headers&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Mistral AI&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Large 3, Document AI, Codestral, Ministral&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Open weights, data residency, document extraction pipelines&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Managed compute shifts ops burden to your team&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Meta Llama&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;1B-3B SLMs up to 405B&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Fine-tuning with full weight control; edge inference; distillation&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;You own patching, scaling, monitoring on managed compute&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;DeepSeek&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Reasoning model family&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Step-by-step math, science, coding where flagship pricing doesn't fit&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Bring your own filtering; check data-handling terms per card&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;xAI Grok&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Reasoning + non-reasoning models&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Data extraction, summarization, agentic apps&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Same partner-model filtering rule&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Microsoft Phi&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Small-model family&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;On-device and edge; high-volume simple tasks&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Capability ceiling; validate quality before routing volume&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H1&gt;Disclaimer&lt;/H1&gt;
&lt;P&gt;The views expressed in this article are those of the author and do not necessarily reflect the official policy or position of Microsoft. The author is a Microsoft employee.&lt;/P&gt;
&lt;H1&gt;References&lt;/H1&gt;
&lt;P&gt;Microsoft documentation and announcements:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/foundry/concepts/foundry-models-overview" target="_blank"&gt;Microsoft Foundry Models overview:&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/foundry/foundry-models/concepts/models-sold-directly-by-azure" target="_blank"&gt;Foundry Models sold directly by Azure&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/foundry/foundry-models/concepts/models-from-partners" target="_blank"&gt;Foundry Models from partners and community&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/foundry/foundry-models/concepts/claude-models" target="_blank"&gt;Claude models in Microsoft Foundry&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/foundry/openai/how-to/reasoning" target="_blank"&gt;Azure OpenAI reasoning models&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://azure.microsoft.com/blog/gpt-5-in-azure-ai-foundry-the-future-of-ai-apps-and-agents-starts-here/" target="_blank"&gt;GPT-5 in Azure AI Foundry (Azure blog)&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://azure.microsoft.com/blog/introducing-mistral-large-3-in-microsoft-foundry-open-capable-and-ready-for-production-workloads/" target="_blank"&gt;Mistral 3 on Microsoft Foundry (Azure blog)&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/well-architected/pillars" target="_blank"&gt;Azure Well-Architected Framework pillars&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://ai.azure.com/catalog" target="_blank"&gt;Model catalog:&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Vendor announcements:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://www.anthropic.com/news/redeploying-fable-5" target="_blank"&gt;Anthropic, Redeploying Claude Fable 5 (July 2026):&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://www.anthropic.com/news/claude-fable-5-mythos-5" target="_blank"&gt;Anthropic, Claude Fable 5 and Mythos 5 (June-July 2026)&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Wed, 29 Jul 2026 13:06:57 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/microsoft-foundry-models-a-field-guide-for-cloud-solution/ba-p/4541912</guid>
      <dc:creator>luciacasucci</dc:creator>
      <dc:date>2026-07-29T13:06:57Z</dc:date>
    </item>
    <item>
      <title>Building an AI Azure Ops Workbench — Part 2: The War Room — watch AI root-cause a 5xx in 90 seconds</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/building-an-ai-azure-ops-workbench-part-2-the-war-room-watch-ai/ba-p/4540765</link>
      <description>&lt;P&gt;&lt;EM&gt;In&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-1-from-reactive-tickets-to-a-proactive/4534569" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-1-from-reactive-tickets-to-a-proactive/4534569"&gt;Part 1&lt;/A&gt; we made the case for the&amp;nbsp;&lt;STRONG&gt;Azure Support Agent&lt;/STRONG&gt;, an operations copilot that runs in your own tenant and reasons over live evidence through Azure's own APIs. This post opens the first pillar — &lt;STRONG&gt;Converse&lt;/STRONG&gt;&amp;nbsp;— and goes inside the two features that make it real: a chat that actually queries your estate and shows its work, and the marquee act, a&amp;nbsp;&lt;STRONG&gt;War Room&lt;/STRONG&gt;&amp;nbsp;of specialist agents that fan out in parallel to turn "why is the site throwing 5xx?" into a ranked, validated root cause. Let's watch it work.&lt;/EM&gt;&lt;/P&gt;
&lt;HR /&gt;
&lt;P data-line="57"&gt;Every incident starts the same way: a question you can't answer fast enough. The signal you need is almost always already in Azure — the metrics are in Azure Monitor, the topology is in Azure Resource Graph, the recent changes are in the activity log, the expiring secret is in Key Vault. The hard part at 2 a.m. is that the answer is spread across a dozen surfaces and one pair of hands. The Converse pillar is about collapsing that distance: you ask in plain English, and the agent does the querying, correlating and explaining for you — against your &lt;EM&gt;live&lt;/EM&gt; estate, not a training-data guess about how Azure works.&lt;/P&gt;
&lt;P data-line="57"&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="65"&gt;First, a chat that reads your tenant&lt;/H2&gt;
&lt;P data-line="67"&gt;Before we get to the marquee demo, it's worth being precise about what "chat" means here, because it is not a toy wrapped around a language model. When you ask&amp;nbsp;&lt;EM&gt;"Why is the checkout API throwing 5xx?"&lt;/EM&gt;, the Azure Support Agent answers by doing the work — it reaches into your subscription through the official&amp;nbsp;&lt;STRONG&gt;Azure MCP server&lt;/STRONG&gt;&amp;nbsp;(and, when you've connected it, a&amp;nbsp;&lt;STRONG&gt;Microsoft Graph / Entra ID&lt;/STRONG&gt;&amp;nbsp;MCP server), runs read-only queries against&amp;nbsp;&lt;STRONG&gt;Azure Resource Graph&lt;/STRONG&gt;, Monitor and the rest, and streams the whole thing back to you as it goes.&lt;/P&gt;
&lt;P data-line="74"&gt;That streaming detail matters more than it sounds. Answers arrive over&amp;nbsp;&lt;STRONG&gt;Server-Sent Events&lt;/STRONG&gt;, so you don't stare at a spinner — you watch a live&amp;nbsp;&lt;STRONG&gt;timeline&lt;/STRONG&gt;&amp;nbsp;assemble: the model's reasoning as it narrates its plan, then each tool call it makes (the query it ran, how long it took, and a one-line summary of what came back), step by step, until the final answer lands. When it's done, that timeline doesn't vanish. It's persisted with the message, so if you reload the page a week later the reasoning, every tool call, and any screenshots you pasted in are all still there. Nothing about&amp;nbsp;&lt;EM&gt;how&lt;/EM&gt;&amp;nbsp;the agent reached its conclusion is thrown away — which is exactly what you want when you have to defend that conclusion to a change board later.&lt;/P&gt;
&lt;P data-line="83"&gt;A few things make it comfortable to live in day-to-day:&lt;/P&gt;
&lt;UL data-line="85"&gt;
&lt;LI data-line="85"&gt;&lt;STRONG&gt;Multiple sessions, isolated context.&lt;/STRONG&gt;&amp;nbsp;Keep three investigations open at once; each chat carries its own model choice, its own Azure connection, and its own optional workload scope.&lt;/LI&gt;
&lt;LI data-line="87"&gt;&lt;STRONG&gt;Vision input.&lt;/STRONG&gt;&amp;nbsp;Paste a screenshot of a failing blade or an error toast; it's part of the question and it's saved with the turn.&lt;/LI&gt;
&lt;LI data-line="89"&gt;&lt;STRONG&gt;Starter suggestions.&lt;/STRONG&gt;&amp;nbsp;Not sure how to phrase it? Curated prompts, grouped by domain — connectivity, identity, security, compute, performance, cost — get you moving with one click.&lt;/LI&gt;
&lt;LI data-line="91"&gt;&lt;STRONG&gt;Cancel-safe turns.&lt;/STRONG&gt;&amp;nbsp;This is the quietly brilliant part. Hit&amp;nbsp;&lt;STRONG&gt;Stop&lt;/STRONG&gt;, or just close the tab, and the work&amp;nbsp;&lt;STRONG&gt;keeps running server-side&lt;/STRONG&gt;. The turn is decoupled from your browser connection entirely: it finishes, saves its partial or full answer and its timeline, and is waiting for you when you come back. Reconnect and the stream replays what you missed and picks up live. Your investigation is never hostage to a flaky Wi-Fi connection or an accidental refresh. In Deep mode it goes one further: the investigation tree is checkpointed to the database as it builds, so even a mid-flight reconnect picks up every hypothesis already resolved.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="99"&gt;That last point is the difference between a demo and a tool you'd actually trust mid-incident. The work is durable because the&amp;nbsp;&lt;EM&gt;evidence&lt;/EM&gt;&amp;nbsp;is durable.&lt;/P&gt;
&lt;P data-line="102"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="104"&gt;Then, when it's genuinely hard: the Azure Support Agent War Room&lt;/H2&gt;
&lt;P data-line="106"&gt;A single model narrating one line of investigation is perfect for "which NSG is blocking this port?" But real incidents are rarely one line of investigation — they're five plausible theories that each need chasing before you can rule them out. That's more parallel work than one reasoning thread can do well, and it's exactly where a single-threaded chatbot starts guessing.&lt;/P&gt;
&lt;P data-line="111"&gt;So you flip on&amp;nbsp;&lt;STRONG&gt;Deep mode&lt;/STRONG&gt;, and a&amp;nbsp;&lt;STRONG&gt;War Room&lt;/STRONG&gt;&amp;nbsp;convenes.&lt;/P&gt;
&lt;P data-line="113"&gt;Instead of one generalist, the agent fields a bench of&amp;nbsp;&lt;STRONG&gt;eight specialists&lt;/STRONG&gt;, each with its own lens on the estate:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 100%; border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Specialist&lt;/th&gt;&lt;th class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;What it owns&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;🌐 &lt;STRONG&gt;Networking&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;NSGs, routes, DNS, private endpoints, peering, connectivity&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;🔑 &lt;STRONG&gt;Identity &amp;amp; Access&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;RBAC, Entra ID, managed identities, Key Vault, secrets&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;⚡ &lt;STRONG&gt;Compute &amp;amp; Apps&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;VMs, App Service, AKS, Container Apps, Functions, scale sets&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;💾 &lt;STRONG&gt;Storage &amp;amp; Data&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Storage accounts, SQL, Cosmos DB, disks, backups&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;🔐 &lt;STRONG&gt;Security &amp;amp; Exposure&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Public exposure, Defender, open ports, permissive NSG rules&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;📈 &lt;STRONG&gt;Reliability &amp;amp; Performance&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Resource health, availability, metrics, scaling, SLA&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;💰 &lt;STRONG&gt;Cost &amp;amp; Governance&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Spend anomalies, Azure Policy, quotas, tags, budgets&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;📊 &lt;STRONG&gt;Monitoring &amp;amp; Logs&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Activity logs, alerts, Application Insights, Log Analytics&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;P data-line="127"&gt;The point of the bench isn't role-play — it's&amp;nbsp;&lt;EM&gt;parallelism with focus&lt;/EM&gt;. Several specialists research at the same time, each pulling live evidence for its own domain, so a broad question gets broad coverage in the time a single thread would spend on one branch. Here's what that looks like mid-flight — eight specialists working the estate at the same moment, each on its own lane:&lt;/P&gt;
&lt;P data-line="132"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="134"&gt;You pick the bench — or let it pick for you&lt;/H2&gt;
&lt;P data-line="136"&gt;You're not stuck with all eight specialists on every question. Before a Deep investigation runs you can&amp;nbsp;&lt;STRONG&gt;hand-pick the bench&lt;/STRONG&gt;&amp;nbsp;— just Networking and Identity for a connectivity puzzle, say — or let the agent&amp;nbsp;&lt;STRONG&gt;suggest the roster for you&lt;/STRONG&gt;. The suggestion isn't a black box: it proposes a recommended set&amp;nbsp;&lt;EM&gt;with a one-line reason for each pick&lt;/EM&gt;&amp;nbsp;("Identity — the error is a 403 and the app uses a managed identity"), and if the model is ever unsure it falls back to deterministic keyword matching, so you always get a sensible default. Pick none and it staffs the room itself.&lt;/P&gt;
&lt;P data-line="143"&gt;Why bother narrowing it? Focus. A DNS question doesn't need the Cost specialist spending tool calls on spend anomalies. A tighter bench means less noise in the tree, a faster answer and lower token cost — without giving up the parallelism that makes the War Room worth it in the first place.&lt;/P&gt;
&lt;P data-line="147"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="149"&gt;How an investigation actually unfolds&lt;/H3&gt;
&lt;P data-line="151"&gt;Under the hood the War Room runs a disciplined, four-phase play — and because it streams the whole way, you watch each phase happen rather than waiting for a black-box verdict:&lt;/P&gt;
&lt;OL data-line="154"&gt;
&lt;LI data-line="154"&gt;&lt;STRONG&gt;Incident research.&lt;/STRONG&gt;&amp;nbsp;The agent spends a bounded burst of read-only tool calls building context on the live estate, then proposes a short slate of&amp;nbsp;&lt;STRONG&gt;two to three distinct hypotheses&lt;/STRONG&gt;, each attributed to the specialist best suited to test it. No fishing expeditions — the work is time- and iteration-boxed so it converges instead of wandering.&lt;/LI&gt;
&lt;LI data-line="159"&gt;&lt;STRONG&gt;Hypotheses formation.&lt;/STRONG&gt;&amp;nbsp;The candidate root causes are pinned down as a clean set — parallel theories, not a single lucky guess — ready to be tested independently.&lt;/LI&gt;
&lt;LI data-line="162"&gt;&lt;STRONG&gt;Validating hypotheses.&lt;/STRONG&gt;&amp;nbsp;Now the specialists go to work,&amp;nbsp;&lt;STRONG&gt;in parallel&lt;/STRONG&gt;, each running its own read-only investigation to either confirm or kill its assigned theory. Every hypothesis gets a verdict —&amp;nbsp;&lt;STRONG&gt;validated&lt;/STRONG&gt;,&amp;nbsp;&lt;STRONG&gt;invalidated&lt;/STRONG&gt;, or&amp;nbsp;&lt;STRONG&gt;inconclusive&lt;/STRONG&gt;&amp;nbsp;— backed by a paragraph of specific evidence. A theory that survives can spawn one deeper sub-hypothesis, so the investigation drills down where the evidence leads and drops the dead ends. The result is a compact&amp;nbsp;&lt;STRONG&gt;hypothesis tree&lt;/STRONG&gt;&amp;nbsp;(a couple of levels deep, deliberately capped so it stays readable) that records not just what was true but&amp;nbsp;&lt;EM&gt;what was checked and ruled out&lt;/EM&gt;.&lt;/LI&gt;
&lt;LI data-line="170"&gt;&lt;STRONG&gt;Conclusion.&lt;/STRONG&gt;&amp;nbsp;With the tree resolved, the agent streams a plain-English answer — the root cause, the evidence chain that proves it, a severity, and concrete next actions — and attaches a&amp;nbsp;&lt;STRONG&gt;confidence score&lt;/STRONG&gt;. That score is&amp;nbsp;&lt;EM&gt;computed&lt;/EM&gt;, not asserted: three quarters of it comes from how the&amp;nbsp;&lt;STRONG&gt;strongest&lt;/STRONG&gt;&amp;nbsp;hypothesis resolved and one quarter from how the whole slate resolved, so one clean validation outranks three shrugs, and an invalidated theory contributes nothing. A single validated root cause reads very differently from three inconclusive maybes, and the number says so.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P data-line="178"&gt;Two design choices keep that four-phase play fast and honest rather than open-ended:&lt;/P&gt;
&lt;P data-line="180"&gt;&lt;STRONG&gt;It's boxed, not boundless.&lt;/STRONG&gt;&amp;nbsp;Every phase carries both an iteration limit&amp;nbsp;&lt;EM&gt;and&lt;/EM&gt;&amp;nbsp;a wall-clock budget, each agent's tool calls fan out only so wide, and the hypothesis tree is hard-capped in depth, breadth and total nodes. That's deliberate: an investigation that can run forever is one that runs up a bill and wanders. The budgets force it to spend its evidence-gathering where it counts and then&amp;nbsp;&lt;EM&gt;converge&lt;/EM&gt;&amp;nbsp;— you get an answer in about a minute and a half, not a research project.&lt;/P&gt;
&lt;P data-line="186"&gt;Those aren't vibes; they're constants. The guardrails, concretely:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 100%; border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Guardrail&lt;/th&gt;&lt;th class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Value&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Hypotheses formed per investigation&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;2–3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Tree depth&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;2 — a hypothesis, plus at most one sub-hypothesis under it&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Validated nodes across the whole tree&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;5&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Research phase&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;≤ 5 tool-loop iterations, ~55 s wall clock&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Each hypothesis validation&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;≤ 3 iterations, ~40 s wall clock&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Concurrent tool calls inside one turn&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;6&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Hypotheses validated in parallel&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;up to 12 (configurable; parallelism can be turned off entirely)&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="198"&gt;Read that table as a cost control as much as a latency one. A wide parallel search across a live tenant is exactly the kind of thing that quietly burns tokens and API quota, so the ceilings are part of the product, not a tuning afterthought.&lt;/P&gt;
&lt;P data-line="202"&gt;&lt;STRONG&gt;Fast where it's cheap, strong where it counts.&lt;/STRONG&gt;&amp;nbsp;The broad research sweep and the parallel hypothesis validation can run on a fast, inexpensive model, while the final conclusion — the part you actually read and act on — is always written by your strongest configured model. You get the breadth of a wide parallel search without paying premium-model rates for every intermediate tool call. The fast tier is opt-in: name a cheaper provider and model for the intermediate phases and they're used automatically; leave it unset and the whole investigation runs on your primary model.&lt;/P&gt;
&lt;P data-line="209"&gt;Ninety seconds after you asked, you have a conclusion rather than a hunch. Here is that exact claim, unedited, against a live tenant:&amp;nbsp;&lt;EM&gt;one in five requests is failing with a 5xx and nothing was deployed.&lt;/EM&gt;&amp;nbsp;The room convenes, eight specialists fan out, and the verdict comes back that&amp;nbsp;&lt;STRONG&gt;nothing is broken at all&lt;/STRONG&gt;&amp;nbsp;— the 5xx responses are being minted by the Container Apps ingress in front of an app pinned to a single replica, while the loud suspects (crash loop, autoscale churn, database exhaustion, storage) are each cleared with a number attached. And the whole thing — every hypothesis, its verdict, its evidence, the specialist who tested it — is saved as a&amp;nbsp;&lt;STRONG&gt;navigable hypothesis tree&lt;/STRONG&gt;&amp;nbsp;attached to the chat. The next person on call doesn't start from zero; they start from your investigation.&lt;/P&gt;
&lt;img /&gt;
&lt;P data-line="221"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="221"&gt;The rest of this post is about how that happened — and there are three more recorded runs further down, including one with no incident at all.&lt;/P&gt;
&lt;H2 data-line="224"&gt;Specialists don't just read metrics — they run real diagnostics&lt;/H2&gt;
&lt;P data-line="226"&gt;It's tempting to picture the bench as eight things running Resource Graph queries. They do that, but the more interesting part is that a specialist can reach for&amp;nbsp;&lt;STRONG&gt;higher-order diagnostic tools&lt;/STRONG&gt;&amp;nbsp;mid-investigation — the same ones a senior engineer would open — all still strictly read-only:&lt;/P&gt;
&lt;UL data-line="230"&gt;
&lt;LI data-line="230"&gt;&lt;STRONG&gt;Performance Profiler.&lt;/STRONG&gt;&amp;nbsp;A specialist can launch an Azure Monitor-threshold performance profile on a workload and fold the resulting scorecard and ranked bottlenecks straight into the evidence, rather than eyeballing raw metric charts.&lt;/LI&gt;
&lt;LI data-line="233"&gt;&lt;STRONG&gt;Access and ownership lookups.&lt;/STRONG&gt;&amp;nbsp;&lt;EM&gt;"Who can actually reach this resource?"&lt;/EM&gt;&amp;nbsp;and&amp;nbsp;&lt;EM&gt;"who owns it?"&lt;/EM&gt;&amp;nbsp;are answered from the workbench's cached RBAC and ownership scans — real least-privilege evidence, without hammering live Azure mid-incident.&lt;/LI&gt;
&lt;LI data-line="236"&gt;&lt;STRONG&gt;In-guest sandbox checks.&lt;/STRONG&gt;&amp;nbsp;Where a workload has onboarded sandbox VMs and you have the permission, a specialist can run&amp;nbsp;&lt;STRONG&gt;read-only&lt;/STRONG&gt;&amp;nbsp;in-guest diagnostics — resolve a DNS name from inside the subnet, test a connection — the checks you'd normally SSH in to run by hand.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="240"&gt;The point is that the War Room investigates with the same toolbox you would, only in parallel and without the tab-hopping. And because Deep mode is read-only end to end, none of those tools can change a thing — a profiler runs, a VM command reads, but nothing mutates your estate.&lt;/P&gt;
&lt;H2 data-line="244"&gt;Two investigations from the field&lt;/H2&gt;
&lt;P data-line="246"&gt;The single-replica case above is a clean one-liner once you see it. The real value of the War Room shows up when the&amp;nbsp;&lt;EM&gt;obvious&lt;/EM&gt;&amp;nbsp;suspect is innocent and the truth is hiding one layer over. The next two cases are&amp;nbsp;&lt;STRONG&gt;composites&lt;/STRONG&gt;&amp;nbsp;— teaching examples assembled from the shape of incidents I've worked, not transcripts of a single run — chosen because they show that pattern better than any one real investigation does. (If you want unedited runs, they're in the section right after this one.) In both, notice the pattern:&amp;nbsp;&lt;STRONG&gt;every signal was already in Azure.&lt;/STRONG&gt;&amp;nbsp;The win isn't new data; it's several specialists correlating across domains at once, and a tree that records what got&amp;nbsp;&lt;EM&gt;ruled out&lt;/EM&gt;, not just what was true.&lt;/P&gt;
&lt;H3 data-line="255"&gt;Investigation 1 — "The database is slow" (that isn't the database)&lt;/H3&gt;
&lt;P data-line="257"&gt;A checkout API starts returning intermittent 500s and stalling under peak load. On-call's gut says the SQL database is maxed out — so that's the first thing the War Room checks, and it's the first thing it rules&amp;nbsp;&lt;EM&gt;out&lt;/EM&gt;. The symptom points at the data layer; the cause is one layer over, and it only shows itself under load, which is exactly why a quiet repro never reproduces it.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 100%; border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;#&lt;/th&gt;&lt;th class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Specialist&lt;/th&gt;&lt;th class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Hypothesis&lt;/th&gt;&lt;th class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Verdict&lt;/th&gt;&lt;th class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Evidence&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;H1&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;💾 Storage &amp;amp; Data&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Azure SQL DTU/vCore saturation or blocking&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;&lt;STRONG&gt;Invalidated&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;DB sitting at ~30% DTU, no blocking waits, query stats healthy&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;H2&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;📈 Reliability &amp;amp; Perf&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;App Service plan CPU/memory saturation&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;&lt;STRONG&gt;Inconclusive&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;CPU normal — but active connection count is abnormally high&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;H3&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;🌐 Networking&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;&lt;STRONG&gt;SNAT port exhaustion&lt;/STRONG&gt; on outbound connections from App Service&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;&lt;STRONG&gt;Validated&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;&lt;CODE&gt;SnatConnectionCount&lt;/CODE&gt; hits its ceiling exactly when the 500s spike; failed-connection metric climbs under load&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;H3.1&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;🌐 Networking (sub)&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;App opens a fresh connection per request instead of pooling&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;&lt;STRONG&gt;Validated&lt;/STRONG&gt;&lt;/td&gt;&lt;td class="lia-border-color-custom-dcdce4 lia-vertical-align-top lia-border-style-solid" style="border-width: 1px; padding: 8px 11px;"&gt;Outbound connection churn tracks the request rate almost 1:1&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;col style="width: 20.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;P data-line="269"&gt;The conclusion streams back in plain English: the app is exhausting its&amp;nbsp;&lt;STRONG&gt;SNAT ports&lt;/STRONG&gt;&amp;nbsp;because it opens a new outbound connection per request instead of pooling them — so under load it simply runs out of source ports and requests start failing. The database was never the problem. Fixes follow, ranked: enable connection pooling in the app, add a&amp;nbsp;&lt;STRONG&gt;NAT Gateway&lt;/STRONG&gt;&amp;nbsp;for outbound scale, or move SQL behind a&amp;nbsp;&lt;STRONG&gt;private endpoint&lt;/STRONG&gt;&amp;nbsp;so those calls don't consume SNAT at all.&amp;nbsp;&lt;STRONG&gt;Confidence: high&lt;/STRONG&gt;&amp;nbsp;— one cleanly validated chain, and the loud suspect explicitly cleared.&lt;/P&gt;
&lt;P data-line="276"&gt;Here's the part worth sitting with: every number in that table lived in Azure Monitor the whole time. What was missing at 2 a.m. wasn't data — it was someone with the bandwidth to check the data, the compute&amp;nbsp;&lt;EM&gt;and&lt;/EM&gt;&amp;nbsp;the networking layers simultaneously and notice that the SNAT ceiling, not the DB, lined up with the failures. That correlation is the whole job, and it's what the War Room does in parallel.&lt;/P&gt;
&lt;H3 data-line="282"&gt;Investigation 2 — "Random 403s after a harmless change"&lt;/H3&gt;
&lt;P data-line="284"&gt;Overnight, roughly 5% of requests to an internal API start returning&amp;nbsp;&lt;STRONG&gt;403 Forbidden&lt;/STRONG&gt;. It's intermittent, and it only hits&amp;nbsp;&lt;EM&gt;some&lt;/EM&gt;&amp;nbsp;instances — the classic "works on my pod" ghost that resists every local repro. A 403 screams&amp;nbsp;&lt;EM&gt;identity&lt;/EM&gt;, so that's where a single-thread chatbot would dig in and stay. The War Room checks identity too — and clears it in the first pass.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 100%; border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;#&lt;/th&gt;&lt;th&gt;Specialist&lt;/th&gt;&lt;th&gt;Hypothesis&lt;/th&gt;&lt;th&gt;Verdict&lt;/th&gt;&lt;th&gt;Evidence&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;H1&lt;/td&gt;&lt;td&gt;🔑 Identity &amp;amp; Access&lt;/td&gt;&lt;td&gt;App registration secret/cert expired&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Invalidated&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Credential valid for 60+ more days&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;H2&lt;/td&gt;&lt;td&gt;🔐 Security &amp;amp; Exposure&lt;/td&gt;&lt;td&gt;A new NSG / WAF rule is blocking traffic&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Invalidated&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;No matching deny; rule set unchanged in the window&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;H3&lt;/td&gt;&lt;td&gt;📊 Monitoring &amp;amp; Logs&lt;/td&gt;&lt;td&gt;Correlate the 403 onset to a recent change&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Validated (lead)&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Change history shows a Private Endpoint + Private DNS zone added yesterday&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;H4&lt;/td&gt;&lt;td&gt;🌐 Networking&lt;/td&gt;&lt;td&gt;One spoke VNet is&amp;nbsp;&lt;STRONG&gt;unlinked&lt;/STRONG&gt;&amp;nbsp;to the new Private DNS zone, so its instances resolve Key Vault/Storage to the&amp;nbsp;&lt;EM&gt;public&lt;/EM&gt;&amp;nbsp;IP and hit the resource-firewall deny&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;Validated&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;The failing requests map exactly to instances in the unlinked subnet; resource-firewall logs show denied public-IP calls&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 6.67285%" /&gt;&lt;col style="width: 19.3698%" /&gt;&lt;col style="width: 31.1399%" /&gt;&lt;col style="width: 12.1508%" /&gt;&lt;col style="width: 30.6666%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;P data-line="296"&gt;The root cause: a private-endpoint rollout the day before left&amp;nbsp;&lt;STRONG&gt;one spoke VNet unlinked&lt;/STRONG&gt;&amp;nbsp;to the new Private DNS zone. Instances in that subnet keep resolving Key Vault and Storage to their public endpoints, and the resource firewall — correctly — denies them. Everyone else is fine, which is why it looked random. The fix is a single missing&amp;nbsp;&lt;STRONG&gt;VNet link&lt;/STRONG&gt;.&amp;nbsp;&lt;STRONG&gt;Confidence: high&lt;/STRONG&gt;&amp;nbsp;— a change correlated to the onset, and subnet-precise evidence tying the 403s to the gap.&lt;/P&gt;
&lt;P data-line="302"&gt;This is the investigation that takes a human an hour of cross-referencing an activity log against a network diagram. In the War Room the Monitoring specialist surfaced the suspicious change while the Networking specialist proved the DNS gap — at the same time — and the tree shows the two innocent identity and security theories that got cleared along the way, so nobody re-litigates them later.&lt;/P&gt;
&lt;P data-line="308"&gt;It's also a preview of where this series goes. That "intended topology: all spokes linked" is exactly the kind of fact the workbench remembers as&amp;nbsp;&lt;STRONG&gt;Architecture Memory&lt;/STRONG&gt;&amp;nbsp;(Part 3), the missing link is the sort of thing&amp;nbsp;&lt;STRONG&gt;drift detection&lt;/STRONG&gt;&amp;nbsp;flags before it pages anyone, and the "what changed last night" answer is&amp;nbsp;&lt;STRONG&gt;Change Explorer&lt;/STRONG&gt;&amp;nbsp;doing in one query what used to be an hour of log archaeology (Part 5).&lt;/P&gt;
&lt;H2 data-line="314"&gt;Four real investigations, recorded end to end&lt;/H2&gt;
&lt;P data-line="316"&gt;The two cases above are composites. These four are not — they are unedited screen recordings of the workbench running against a live Azure tenant, captured in one sitting. Each clip starts on an empty chat and runs the whole way through: scoping to a workload, switching the turn to Deep investigation, typing the question, the war room assembling,&amp;nbsp;&lt;STRONG&gt;All Hands On Deck&lt;/STRONG&gt;, the launch, the specialists working in parallel, and the written verdict at the end. Nothing is sped up beyond playback rate and nothing is cut.&lt;/P&gt;
&lt;P data-line="323"&gt;You've already seen the first one — the 5xx run at the top of this post. Here's what it actually concluded, and then three more.&lt;/P&gt;
&lt;H3 data-line="326"&gt;1. "One in five requests is failing and nothing was deployed"&lt;/H3&gt;
&lt;P data-line="328"&gt;The question in the title of this post, asked verbatim:&amp;nbsp;&lt;EM&gt;roughly one in five requests to the&amp;nbsp;azsupagent&amp;nbsp;app fails with a 5xx while other users see no problem at all; nothing was deployed.&lt;/EM&gt;&lt;/P&gt;
&lt;P data-line="331"&gt;The verdict is the interesting part, because the answer is&amp;nbsp;&lt;STRONG&gt;nothing is broken&lt;/STRONG&gt;. There is no server-side fault at all — the 5xx responses are generated at the Container Apps&amp;nbsp;&lt;STRONG&gt;ingress&lt;/STRONG&gt;, in front of the app, because the app is pinned to a&amp;nbsp;&lt;STRONG&gt;single replica&lt;/STRONG&gt;&amp;nbsp;(min = max = 1, zero restarts all day). Concurrent requests beyond that one instance's capacity get 502/503/504 while requests already in flight on the same replica finish normally — which is exactly the "one in five fails, the rest are fine at the same moment" shape. Crucially, the loud suspects are&amp;nbsp;&lt;EM&gt;cleared with evidence&lt;/EM&gt;, not skipped: no crash loop (replica count flat at 1.00, restart count 0), no autoscale churn, no Postgres exhaustion (8.88 active connections,&amp;nbsp;&lt;STRONG&gt;0&lt;/STRONG&gt;&amp;nbsp;failed, CPU 8.7%), no storage dependency (100% availability across 24h).&lt;/P&gt;
&lt;P data-line="341"&gt;&lt;EM&gt;(Recording at the top of this post.)&lt;/EM&gt;&lt;/P&gt;
&lt;H3 data-line="343"&gt;2. "It's slow at peak but the database dashboards look fine"&lt;/H3&gt;
&lt;P data-line="345"&gt;Different symptom, different specialists leading,&amp;nbsp;&lt;STRONG&gt;same underlying cause&lt;/STRONG&gt;&amp;nbsp;as the run above — which is a good demonstration that the conclusion follows the evidence rather than the phrasing of the question. Replica count is pinned at 1.00/1.00 across the full seven-day window, so at peak the requests queue in the ingress buffer. That queueing adds seconds of latency that never appears as CPU, memory or database pressure, which is precisely why the DB dashboards look clean and why nobody can reproduce it off-peak.&lt;/P&gt;
&lt;P data-line="352"&gt;Note that the database is&amp;nbsp;&lt;STRONG&gt;actively disproven&lt;/STRONG&gt;&amp;nbsp;rather than merely unexamined:&amp;nbsp;disk_queue_depth&amp;nbsp;is 0 in every one of 96 buckets, peak IOPS is 4 out of a provisioned 240, and active connections peak at 15 with zero failures. That distinction — invalidated vs. not checked — is the whole argument for the hypothesis tree.&lt;/P&gt;
&lt;P data-line="357"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="359"&gt;3. "What changed in the last 48 hours, and could any of it hurt me?"&lt;/H3&gt;
&lt;P data-line="361"&gt;This one shows the War Room used as a&amp;nbsp;&lt;STRONG&gt;change-risk&lt;/STRONG&gt;&amp;nbsp;tool rather than an incident tool, and it found something more uncomfortable than a bad deployment. The riskiest change in the window was not made by a human at all: a&amp;nbsp;&lt;STRONG&gt;service principal holding Contributor at the tenant root management group&lt;/STRONG&gt;&amp;nbsp;created a new, undocumented action group. The object it created is benign in content — email and SMS only, no webhook — so alerting was never broken. The&amp;nbsp;&lt;EM&gt;identity&lt;/EM&gt;&amp;nbsp;is the finding: an unowned, unattributed non-human principal with tenant-wide write authority and root-scope policy rights.&lt;/P&gt;
&lt;P data-line="369"&gt;The secondary finding is independent and equally unglamorous: shared storage account keys were retrieved three times in the small hours on an account that still permits shared-key auth, accepts&amp;nbsp;&lt;STRONG&gt;TLS 1.0&lt;/STRONG&gt;, and has no network restrictions at all. Meanwhile the five human container app deployments in the same window are explicitly cleared of causing instability.&lt;/P&gt;
&lt;P data-line="374"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3 data-line="376"&gt;4. "No incident — just tell me what breaks first"&lt;/H3&gt;
&lt;P data-line="378"&gt;The last one is the proactive case, and it's the one I'd actually run on a Friday afternoon. No symptom, no page, no incident: just&amp;nbsp;&lt;EM&gt;audit this workload end to end and tell me what fails first, how bad the blast radius is, and the single highest-value fix this week.&lt;/EM&gt;&lt;/P&gt;
&lt;P data-line="382"&gt;The answer is the PostgreSQL flexible server, and the audit is specific about why: HA disabled, a single primary pinned to one availability zone, zero read replicas, geo-redundant backup disabled, seven-day retention, and storage auto-grow off. A zone outage — or an ordinary planned maintenance event — takes it fully offline with no failover target and nothing to geo-restore from, so the blast radius is a&amp;nbsp;&lt;STRONG&gt;100% workload outage&lt;/STRONG&gt;&amp;nbsp;with recovery bounded by manual restore time. It also flags something no single-resource check would catch: the database is the only resource in one region while the entire rest of the workload sits in another, so every data path already leaves the app's region for zero resilience benefit.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="399"&gt;Scoped to the workload, scoped to the tenant&lt;/H2&gt;
&lt;P data-line="401"&gt;A War Room investigation doesn't have to boil the ocean. Point it at a&amp;nbsp;&lt;STRONG&gt;Workload&lt;/STRONG&gt; and it's constrained to that application's resources — its subscriptions, resource groups and resource IDs — so it reasons about the thing you care about instead of wandering the whole estate. And because the Azure Support Agent is multi-tenant aware, every investigation carries its &lt;STRONG&gt;tenant and connection context&lt;/STRONG&gt;, so each tool call targets the right subscription in the right directory. One operator can run investigations across several customers' tenants from the same workbench without the signals ever crossing.&lt;/P&gt;
&lt;H2 data-line="409"&gt;You don't have to start in the chat&lt;/H2&gt;
&lt;P data-line="411"&gt;Most investigations don't begin with someone typing a question — they begin somewhere else in the workbench noticing something is off. So the War Room is wired to be&amp;nbsp;&lt;STRONG&gt;handed off to&lt;/STRONG&gt;. When a proactive feature surfaces a risk, it can open a Deep investigation pre-loaded with the right workload and a ready-made prompt:&lt;/P&gt;
&lt;UL data-line="416"&gt;
&lt;LI data-line="416"&gt;&lt;STRONG&gt;Backup/DR coverage&lt;/STRONG&gt;&amp;nbsp;finds a resource with no protection →&amp;nbsp;&lt;EM&gt;"investigate this gap."&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="417"&gt;&lt;STRONG&gt;Change Explorer&lt;/STRONG&gt;&amp;nbsp;flags a risky change →&amp;nbsp;&lt;EM&gt;"investigate this change and its blast radius."&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="418"&gt;&lt;STRONG&gt;Performance Profiler&lt;/STRONG&gt;&amp;nbsp;spots a metric pressing against its Azure Monitor threshold →&amp;nbsp;&lt;EM&gt;"why is this the binding bottleneck?"&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="420"&gt;&lt;STRONG&gt;Retirement Radar&lt;/STRONG&gt;&amp;nbsp;finds a workload in the blast radius of an upcoming Azure retirement →&amp;nbsp;&lt;EM&gt;"investigate this impacted workload."&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="422"&gt;&lt;STRONG&gt;Telemetry Intelligence&lt;/STRONG&gt;&amp;nbsp;sees a failure spike on an operation →&amp;nbsp;&lt;EM&gt;"investigate this spike."&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="423"&gt;&lt;STRONG&gt;Architecture Memory&lt;/STRONG&gt;&amp;nbsp;opens the War Room with that architecture's memory already attached.&lt;/LI&gt;
&lt;LI data-line="424"&gt;&lt;STRONG&gt;Identity findings&lt;/STRONG&gt;&amp;nbsp;and&amp;nbsp;&lt;STRONG&gt;workload cards&lt;/STRONG&gt;&amp;nbsp;stage a scoped chat the same way — the workload card going straight into a deep reliability review.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="427"&gt;Each one hands the War Room its context on a plate: deep mode on, the right workload selected, the prompt already written, the recommended bench loaded. What it deliberately does&amp;nbsp;&lt;STRONG&gt;not&lt;/STRONG&gt;&amp;nbsp;do is start investigating. Every hand-off stops at the specialist-selection gate — nothing is dispatched until you click&amp;nbsp;&lt;STRONG&gt;Launch&lt;/STRONG&gt;. A dashboard can&amp;nbsp;&lt;EM&gt;stage&lt;/EM&gt;&amp;nbsp;an investigation; only a person starts one.&lt;/P&gt;
&lt;P data-line="432"&gt;There's a durable twist worth stealing, too. A browser hand-off is one-shot — it dies on a refresh — so as the War Room opens it mirrors that context into a server-side&amp;nbsp;&lt;STRONG&gt;Case File&lt;/STRONG&gt;, reusing the workload's already-open case (appending a note) instead of piling up duplicates. The investigation is a chat; the case is the record that outlives it.&lt;/P&gt;
&lt;P data-line="437"&gt;A hand-off arrives fully staged — deep mode on, workload scoped, prompt written, bench loaded:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="441"&gt;And then it stops, deliberately, at the gate and waits for a human:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="445"&gt;From one workload to the whole fleet&lt;/H2&gt;
&lt;P data-line="447"&gt;The same machinery scales past a single incident. Select a handful of workloads in the fleet view, hit&amp;nbsp;&lt;STRONG&gt;Deep review&lt;/STRONG&gt;, and the workbench spins up&amp;nbsp;&lt;STRONG&gt;one investigation per workload&lt;/STRONG&gt;&amp;nbsp;— its own chat, titled for the workload, the full eight-specialist bench, and a shared reliability brief:&amp;nbsp;&lt;EM&gt;review this workload across networking, identity, compute, storage, security, monitoring and cost, and name the top risk.&lt;/EM&gt;&amp;nbsp;A whole portfolio gets swept for latent risk in one pass instead of you babysitting workloads one at a time.&lt;/P&gt;
&lt;P data-line="454"&gt;It's throttled on purpose. A batch is capped, and the launches go out through a small concurrency gate rather than all at once — twenty simultaneous eight-specialist investigations would stampede any model provider's rate limits, and an ops tool that DDoSes your own AI quota isn't much of an ops tool. Each workload comes back with its own tree, root cause and confidence, so you can triage the fleet by what the evidence actually says. It's the difference between reacting to the workload that paged you and proactively asking&amp;nbsp;&lt;EM&gt;all&lt;/EM&gt;&amp;nbsp;of them "is anything wrong?" — and it's the bridge to Mission Control and scheduled automations later in the series (Part 5).&lt;/P&gt;
&lt;P data-line="462"&gt;It starts where you'd expect — the fleet view, with the workloads you care about selected:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="466"&gt;What comes out: severity, confidence, and next steps&lt;/H2&gt;
&lt;P data-line="468"&gt;An investigation isn't just a wall of text — it resolves into a&amp;nbsp;&lt;STRONG&gt;structured result&lt;/STRONG&gt;&amp;nbsp;you can route and reuse: a stated&amp;nbsp;&lt;STRONG&gt;root cause&lt;/STRONG&gt;&amp;nbsp;and summary, a&amp;nbsp;&lt;STRONG&gt;severity&lt;/STRONG&gt;&amp;nbsp;(info, warning, error or critical), the&amp;nbsp;&lt;STRONG&gt;evidence chain&lt;/STRONG&gt;&amp;nbsp;behind the verdict, and a ranked list of&amp;nbsp;&lt;STRONG&gt;next actions&lt;/STRONG&gt;. Both lists are capped, so what you get is a shortlist to act on rather than a transcript to wade through. On top sits the&amp;nbsp;&lt;STRONG&gt;confidence score&lt;/STRONG&gt;&amp;nbsp;from earlier — three parts strongest-hypothesis, one part whole-slate — so three inconclusive maybes score low and look exactly as shaky as they are. Because the shape is structured, the same result feeds a Case File, a ticket, or the next investigation without anyone re-typing it.&lt;/P&gt;
&lt;P data-line="477"&gt;Those next actions can include the precise commands to fix the problem — but this is still the Converse pillar, so they stay&amp;nbsp;&lt;STRONG&gt;proposal-first&lt;/STRONG&gt;. The War Room tells you what it would do and why; actually doing it is the approval-gated territory of the Act pillar (Part 5). Nothing runs behind your back.&lt;/P&gt;
&lt;H2 data-line="482"&gt;Grounded, not guessed&lt;/H2&gt;
&lt;P data-line="484"&gt;It's worth saying plainly why this is trustworthy, because "AI incident response" can mean a lot of hand-wavy things. Every phase here runs against&amp;nbsp;&lt;STRONG&gt;live Azure evidence&lt;/STRONG&gt;&amp;nbsp;through MCP tools that are&amp;nbsp;read-only by default — the&amp;nbsp;&lt;STRONG&gt;Azure Support Agent&lt;/STRONG&gt; is investigating, not changing anything. Each tool call and its result is captured in the timeline, so the conclusion is backed by a visible trail of exactly which resources were queried and what they returned. Hypotheses that the evidence contradicts are marked &lt;EM&gt;invalidated&lt;/EM&gt;&amp;nbsp;and kept in the tree rather than quietly dropped — the record shows the roads not taken. That read-only discipline holds even for the heavier tools: the performance profiler reads, the sandbox-VM checks read, and any write-classified tool is filtered out of the toolset the moment Deep mode starts — an investigation is structurally incapable of mutating your estate. This is the same grounding discipline the whole product is built on, and Part 6 is devoted to it in full.&lt;/P&gt;
&lt;H2 data-line="496"&gt;It gets smarter about&amp;nbsp;&lt;EM&gt;your&lt;/EM&gt;&amp;nbsp;estate over time&lt;/H2&gt;
&lt;P data-line="498"&gt;There's one more piece that turns a good investigation into an institutional one. Each architecture you've mapped can carry an&amp;nbsp;&lt;STRONG&gt;Architecture Memory&lt;/STRONG&gt;&amp;nbsp;— the intended design, the security model, known gaps, diagnostic hints — and that context is injected into&amp;nbsp;&lt;STRONG&gt;every phase&lt;/STRONG&gt;&amp;nbsp;of an investigation as expert background. So the War Room doesn't just know generic Azure; it knows&amp;nbsp;&lt;EM&gt;this&lt;/EM&gt;&amp;nbsp;workload's quirks.&lt;/P&gt;
&lt;P data-line="504"&gt;And the loop closes: when an investigation nails a root cause, you can&amp;nbsp;&lt;STRONG&gt;save that RCA back into the architecture's Memory&lt;/STRONG&gt;&amp;nbsp;with a click. The next time something goes sideways on the same workload, the agent recalls what happened last time. Your incidents stop being disposable and start compounding into knowledge — the tribal wisdom that usually lives in one senior engineer's head, captured where the whole team can reuse it.&lt;/P&gt;
&lt;P data-line="510"&gt;And a saved RCA isn't a dead note. It carries its confidence, it's de-duplicated against the exact investigation it came from (save it twice and you still have one entry), and it lands in the memory's&amp;nbsp;&lt;STRONG&gt;known-issues&lt;/STRONG&gt;&amp;nbsp;section — the section that gets injected&amp;nbsp;&lt;EM&gt;first&lt;/EM&gt;&amp;nbsp;when context has to be trimmed to fit. Your estate quietly accumulates its own case law, and the most expensively-learned facts are the last ones to fall out of the prompt. When you want a finding to leave the workbench entirely, one click&amp;nbsp;&lt;STRONG&gt;escalates an investigation into a tracked Case&lt;/STRONG&gt;&amp;nbsp;that back-references the exact chat and message. And every Deep investigation you've run is kept in a searchable&amp;nbsp;&lt;STRONG&gt;history&lt;/STRONG&gt;, each with a digest — root cause, hypothesis counts, confidence — and its full, pinnable tree one click away.&lt;/P&gt;
&lt;P data-line="520"&gt;The whole learning loop is one button at the bottom of a finished investigation:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P data-line="524"&gt;…and the finding reappears in the architecture's known-issues section, ready to be injected into the next investigation on that workload:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="529"&gt;Point it at almost anything&lt;/H2&gt;
&lt;P data-line="531"&gt;Root-causing a 5xx is the headline, but the same parallel-specialist machinery answers a much wider range of questions. A sampling of what people point the War Room at:&lt;/P&gt;
&lt;UL data-line="534"&gt;
&lt;LI data-line="534"&gt;&lt;STRONG&gt;Proactive audits&lt;/STRONG&gt;&amp;nbsp;—&amp;nbsp;&lt;EM&gt;"check every NSG for 0.0.0.0/0 rules"&lt;/EM&gt;&amp;nbsp;(Security &amp;amp; Exposure).&lt;/LI&gt;
&lt;LI data-line="535"&gt;&lt;STRONG&gt;Change correlation&lt;/STRONG&gt;&amp;nbsp;—&amp;nbsp;&lt;EM&gt;"did last night's change cause this?"&lt;/EM&gt;&amp;nbsp;(Monitoring &amp;amp; Logs).&lt;/LI&gt;
&lt;LI data-line="536"&gt;&lt;STRONG&gt;Retirement impact&lt;/STRONG&gt;&amp;nbsp;—&amp;nbsp;&lt;EM&gt;"which workloads does this upcoming retirement hit?"&lt;/EM&gt;&amp;nbsp;(Reliability).&lt;/LI&gt;
&lt;LI data-line="537"&gt;&lt;STRONG&gt;Cost spikes&lt;/STRONG&gt;&amp;nbsp;—&amp;nbsp;&lt;EM&gt;"why did this subscription jump 30% this month?"&lt;/EM&gt;&amp;nbsp;(Cost &amp;amp; Governance).&lt;/LI&gt;
&lt;LI data-line="538"&gt;&lt;STRONG&gt;Performance&lt;/STRONG&gt;&amp;nbsp;—&amp;nbsp;&lt;EM&gt;"what's the binding bottleneck on this workload?"&lt;/EM&gt;&amp;nbsp;(Reliability &amp;amp; Performance).&lt;/LI&gt;
&lt;LI data-line="539"&gt;&lt;STRONG&gt;Security posture&lt;/STRONG&gt;&amp;nbsp;—&amp;nbsp;&lt;EM&gt;"is any storage account publicly reachable?"&lt;/EM&gt;&amp;nbsp;(Security &amp;amp; Exposure).&lt;/LI&gt;
&lt;LI data-line="540"&gt;&lt;STRONG&gt;Connectivity&lt;/STRONG&gt;&amp;nbsp;—&amp;nbsp;&lt;EM&gt;"why can't this subnet reach that private endpoint?"&lt;/EM&gt;&amp;nbsp;(Networking).&lt;/LI&gt;
&lt;LI data-line="541"&gt;&lt;STRONG&gt;Governance&lt;/STRONG&gt;&amp;nbsp;—&amp;nbsp;&lt;EM&gt;"is everything tagged to our taxonomy?"&lt;/EM&gt;&amp;nbsp;(Cost &amp;amp; Governance).&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="543"&gt;Same four phases, same read-only discipline, same navigable tree — pointed at whatever question you have this week.&lt;/P&gt;
&lt;H2 data-line="546"&gt;How it's judged&lt;/H2&gt;
&lt;P data-line="548"&gt;Every post in this series ends with the same honesty check — how you'd know the feature is actually doing its job, not just demoing well:&lt;/P&gt;
&lt;UL data-line="551"&gt;
&lt;LI data-line="551"&gt;&lt;STRONG&gt;Every answer shows its work.&lt;/STRONG&gt;&amp;nbsp;Each turn carries a visible reasoning + tool-call timeline; the conclusion is traceable to the exact Azure queries behind it.&lt;/LI&gt;
&lt;LI data-line="553"&gt;&lt;STRONG&gt;Hypotheses are validated against live evidence.&lt;/STRONG&gt;&amp;nbsp;The tree records what was checked, what was confirmed, and what was ruled out — each verdict tied to specific evidence.&lt;/LI&gt;
&lt;LI data-line="555"&gt;&lt;STRONG&gt;Confidence is earned, not asserted.&lt;/STRONG&gt;&amp;nbsp;The score is computed from how cleanly the hypotheses resolved — weighted toward the strongest one — so a shaky conclusion looks shaky.&lt;/LI&gt;
&lt;LI data-line="557"&gt;&lt;STRONG&gt;Read-only by default.&lt;/STRONG&gt;&amp;nbsp;The whole investigation runs against your estate without changing a thing; any write stays proposal-first and approval-gated.&lt;/LI&gt;
&lt;LI data-line="559"&gt;&lt;STRONG&gt;Nothing launches itself.&lt;/STRONG&gt;&amp;nbsp;Dashboards can stage an investigation with full context, but specialists are only ever dispatched when a human clicks Launch.&lt;/LI&gt;
&lt;LI data-line="561"&gt;&lt;STRONG&gt;Turns are durable.&lt;/STRONG&gt;&amp;nbsp;Cancel a turn or close the tab and the work continues server-side and is saved — evidence and all — so nothing is lost.&lt;/LI&gt;
&lt;LI data-line="563"&gt;&lt;STRONG&gt;You choose the bench, or the AI suggests it.&lt;/STRONG&gt;&amp;nbsp;A focused roster means less noise and lower cost without losing parallel coverage.&lt;/LI&gt;
&lt;LI data-line="565"&gt;&lt;STRONG&gt;Bounded by design.&lt;/STRONG&gt;&amp;nbsp;Published caps on iterations, wall-clock time, tree size and parallelism force convergence, so it lands an answer instead of wandering — and can't quietly run up a bill.&lt;/LI&gt;
&lt;LI data-line="567"&gt;&lt;STRONG&gt;Real diagnostics, still read-only.&lt;/STRONG&gt;&amp;nbsp;Performance profiles, access lookups and in-guest checks all run without the power to change anything.&lt;/LI&gt;
&lt;LI data-line="569"&gt;&lt;STRONG&gt;Reusable output.&lt;/STRONG&gt;&amp;nbsp;Every investigation resolves to severity, confidence and next actions — escalatable to a Case and recalled on the next incident.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 data-line="572"&gt;Try it yourself&lt;/H2&gt;
&lt;P data-line="574"&gt;If you deployed the Azure Support Agent after&amp;nbsp;&lt;A href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-1-from-reactive-tickets-to-a-proactive/4534569" target="_blank" rel="noopener" data-href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-1-from-reactive-tickets-to-a-proactive/4534569"&gt;Part 1&lt;/A&gt;, open a chat, ask it something real about your estate, and watch the timeline build. Then toggle&amp;nbsp;&lt;STRONG&gt;Deep mode&lt;/STRONG&gt;&amp;nbsp;on a genuinely thorny question and let the War Room run — the hypothesis tree is the single best way to&amp;nbsp;&lt;EM&gt;feel&lt;/EM&gt;&amp;nbsp;what an AI ops workbench does that a chatbot can't. No live tenant yet? Demo mode runs the same experience on synthetic data, with nothing to risk.&lt;/P&gt;
&lt;P data-line="581"&gt;&lt;STRONG&gt;&lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-3-reverse-engineer-azure-architecture-/4541741" target="_blank" rel="noopener" data-lia-auto-title="Part 3" data-lia-auto-title-active="0"&gt;Next time — Part 3:&amp;nbsp;&lt;EM&gt;Map your estate — from proliferation to a living picture.&lt;/EM&gt;&lt;/A&gt;&lt;/STRONG&gt;&amp;nbsp;The War Room is only as sharp as its understanding of what's deployed, so next we turn resource proliferation into something you can reason about:&amp;nbsp;&lt;STRONG&gt;Workloads&lt;/STRONG&gt;&amp;nbsp;with explainable health scores,&amp;nbsp;&lt;STRONG&gt;Autopilot&lt;/STRONG&gt;&amp;nbsp;that proposes them for you, live&amp;nbsp;&lt;STRONG&gt;architecture diagrams&lt;/STRONG&gt;&amp;nbsp;reverse-engineered from what's actually running, the&amp;nbsp;&lt;STRONG&gt;Architecture Memory&lt;/STRONG&gt;&amp;nbsp;you just saw feeding investigations, and the whole-tenant&amp;nbsp;&lt;STRONG&gt;Estate Graph&lt;/STRONG&gt;. Mapping is where "proactive" gets its eyes.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It's open source and free to run. Three ways to start, in rising order of commitment:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Explore demo mode&lt;/STRONG&gt;&amp;nbsp;— synthetic data, no connection required, nothing to risk.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Deploy to your tenant&lt;/STRONG&gt; — one click to Azure Container Apps; private networking; your data never leaves.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Or main repository &lt;A href="https://github.com/zmustafa/AzureSupportAgent" target="_blank" rel="noopener"&gt;https://github.com/zmustafa/AzureSupportAgent&lt;/A&gt;&lt;/STRONG&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A class="lia-external-url" href="https://zeeshan.net/azure-support-agent-part-2/" target="_blank" rel="noopener"&gt;Part 2 Original&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 30 Jul 2026 21:20:40 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/building-an-ai-azure-ops-workbench-part-2-the-war-room-watch-ai/ba-p/4540765</guid>
      <dc:creator>zmustafa</dc:creator>
      <dc:date>2026-07-30T21:20:40Z</dc:date>
    </item>
    <item>
      <title>Proactive Resiliency with Azure App Service Auto Heal</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/proactive-resiliency-with-azure-app-service-auto-heal/ba-p/4539836</link>
      <description>&lt;P class="lia-align-justify"&gt;&lt;SPAN data-contrast="auto"&gt;Modern cloud applications are expected to remain resilient -&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;they must observe, protect, recover, and preserve service continuity when workloads begin to behave unpredictably&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. This includes scenarios such as transient faults, memory pressure, dependency timeouts, or sudden spikes in failed requests.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;While traditional monitoring detects these issues, recovery often depends on manual intervention, increasing Mean Time to Recovery (MTTR) and operational overhead.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-align-justify"&gt;&lt;SPAN data-contrast="auto"&gt;In Azure App Service, &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Auto Heal &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;is one of the&amp;nbsp;platform’s&amp;nbsp;bulit-in&amp;nbsp;resiliency controls. It&amp;nbsp;is&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;designed to detect unhealthy application behavior and automatically take corrective action&amp;nbsp;without human intervention.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-align-justify"&gt;&lt;SPAN data-contrast="auto"&gt;This makes Auto Heal less of an operational convenience and more of an &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;infrastructure self-preservation&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;capability&amp;nbsp;aligned with the&amp;nbsp;Azure Well-Architected Framework,&amp;nbsp;helping&amp;nbsp;applications to recover gracefully&amp;nbsp;while&amp;nbsp;preserving availability and diagnostic context.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Why Auto-Heal Matter&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;s and&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Why Infrastructure Needs Self-Preservation&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P class="lia-align-justify"&gt;&lt;SPAN data-contrast="auto"&gt;In mission-critical environments, infrastructure cannot depend entirely on humans noticing every failure pattern in real time. Applications can degrade gradually, dependencies can slow down, memory can grow unexpectedly, and individual instances can enter unhealthy states while the rest of the platform continues operating.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Without automated mitigation, these symptoms often become operational events:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="18" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;A process consumes excessive memory.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="18" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Requests begin taking longer than expected.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="18" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;HTTP failures increase.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="18" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;One instance starts affecting user experience while others remain healthy.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-align-justify"&gt;&lt;SPAN data-contrast="auto"&gt;Auto Heal allows App Service to respond to these conditions using pre-defined rules&amp;nbsp;and it&amp;nbsp;recognize that the workload has crossed a boundary where recovery action is safer than continued degradation.&amp;nbsp;This way it&amp;nbsp;helps maintain application stability in production environments.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335551550&amp;quot;:6,&amp;quot;335551620&amp;quot;:6}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;How Auto-Heal Works&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt; Trigger Conditions (Detecting Unhealthy State)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Auto-Heal monitors application behavior using configurable signals such as:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 79.6296%; height: 184px; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr style="height: 39px;"&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Trigger&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Infrastructure signal&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 39px;"&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Request duration&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The app is responding too slowly or threads may be blocked.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 39px;"&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Request count&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The app should recycle after a controlled amount of traffic.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 39px;"&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;HTTP status codes&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The app is returning repeated failures.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 39px;"&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Memory limit&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td style="height: 39px;"&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;The process or container is approaching unsafe resource consumption.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;These conditions are evaluated over a defined &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;time window and threshold&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, enabling precise detection of abnormal patterns.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL start="2"&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt; Mitigation Actions (Self-Recovery)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;When a trigger condition is met, Auto-Heal executes one or more corrective actions:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Recycle worker process (most common)&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Restarts the application process for the affected instance.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Capture memory or crash dumps&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Preserves diagnostic data for post-incident analysis.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Log events&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Records Auto-Heal activity for auditing and troubleshooting.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="3" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Execute custom actions (Windows / supported Linux scenarios)&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Run scripts or executables for advanced remediation.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;Each action is applied &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;per instance&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, ensuring that other healthy instances continue serving traffic.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL start="3"&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt; Controlled Recovery Behavior&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Auto-Heal works&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;instance-by-instance&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, avoiding full application downtime in scaled environments.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;When combined with&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Health Check&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, unhealthy instances are temporarily removed from load balancing before recovery.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;A configurable&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;startup override window&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;prevents false triggers during application initialization.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5 aria-level="3"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 3"&gt;Key Benefits:&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Improved application availability&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Automatically recovers from transient failures such as HTTP 5xx bursts, slow requests, or memory pressure.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Reduced Mean Time to Recovery (MTTR)&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Eliminates dependency on manual restarts by triggering corrective actions instantly.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Built-in diagnostics at the point of failure&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Captures logs, memory dumps, and telemetry during failure&amp;nbsp;-&amp;nbsp;before state is lost.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Operational efficiency&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Reduces the need for continuous monitoring and manual intervention, especially during off-hours.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="1" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Seamless integration with platform capabilities&lt;/SPAN&gt;&lt;/STRONG&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Works alongside&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Health Check&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;,&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Azure Monitor&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, and&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Application Insights&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;for a comprehensive resiliency strategy.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="lia-align-justify"&gt;&lt;SPAN data-contrast="auto"&gt;Importantly, Auto-Heal is&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;included as part of Azure App Service&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;and does not incur additional cost beyond standard logging and telemetry storage.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-align-justify"&gt;&lt;SPAN data-contrast="auto"&gt;However,&amp;nbsp;Auto Heal should be viewed as a &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;guardrail&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, not a cure. It does not eliminate the root cause of a memory leak, dependency bottleneck, bad release, or application deadlock. Instead, it helps preserve runtime health by taking controlled action when the application reaches an unhealthy state.&amp;nbsp;A resilient platform does not assume failures will never happen. It assumes failures will happen and provides mechanisms to contain, recover, and learn from them.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Hence, validate the following while configuring from a resiliency perspective:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 82.963%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Validation question&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Why it matters&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Are triggers mapped to real failure patterns?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Avoids rules that are too generic or irrelevant.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Are thresholds based on production baselines?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Prevents unnecessary recycling or delayed recovery.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Is startup time accounted for?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Avoids triggering Auto Heal during normal warm-up.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Is the action safe for the workload?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Prevents loss of in-memory state or avoidable user impact.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Are logs and diagnostics enabled?&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Ensures recovery events can be investigated afterward.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Configuring Auto-Heal&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Auto-Heal can be configured using multiple approaches:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;
&lt;H6&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Azure Portal&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H6&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Wingdings" data-listid="20" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Wingdings&amp;quot;,&amp;quot;469769242&amp;quot;:[9642],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Open the App Service resource in the Azure portal.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Wingdings" data-listid="20" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Wingdings&amp;quot;,&amp;quot;469769242&amp;quot;:[9642],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Go to Diagnose and solve problems.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Wingdings" data-listid="20" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Wingdings&amp;quot;,&amp;quot;469769242&amp;quot;:[9642],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Select Diagnostic Tools&amp;nbsp;&amp;gt;&amp;nbsp;Open Auto-Heal.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Wingdings" data-listid="20" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Wingdings&amp;quot;,&amp;quot;469769242&amp;quot;:[9642],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Configure triggers, thresholds, startup delay, and mitigation actions.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;
&lt;H6&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Application configuration (web.config)&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;(Windows)&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/H6&gt;
&lt;SPAN data-contrast="auto"&gt;Enables rule definition alongside application code&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;
&lt;H6&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Infrastructure as Code (IaC)&lt;/SPAN&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/H6&gt;
&lt;SPAN data-contrast="auto"&gt;ARM, Bicep, CLI, or SDK-based configuration for consistency across environments&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;This flexibility allows teams to standardize Auto-Heal policies across workloads.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Validating Auto-Heal in Action&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Operational visibility is critical. Azure provides multiple ways to validate that Auto-Heal has triggered and executed correctly.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt; Azure Portal – Auto-Heal History&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Navigate to:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Diagnose and Solve Problems → Auto-Heal → History&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; This view provides:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Trigger conditions met&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Timestamp of execution&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Actions taken&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Status and outcome&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;OL start="2"&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt; Application Event Logs&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Accessible via:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Portal: Diagnostic Tools → Application Event Logs&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;img /&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Kudu:&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;LogFiles/EventLog.xml&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Look for Auto-Heal related events indicating:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Trigger activation&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Process&amp;nbsp;recycles&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="8" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Success or failure of actions&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;OL start="3"&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt; Kudu Console (Advanced Diagnostics)&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Kudu provides deep runtime visibility:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Process Explorer&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Observe worker process (w3wp) restart via&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;Process ID (PID) changes&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Log Stream&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;View real-time errors leading up to Auto-Heal execution&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;File system access&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Retrieve memory dumps and logs from: D:\home\LogFiles\&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;OL start="4"&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Review Web App Restarted &amp;amp; HTTP Setting Errors&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="23" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;In App Service, Diagnose and Solve Problems, search for Web App Restarted, Filter by time and select Auto-Heal to view status → it will show status same as Auto Heal History&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="23" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;For HTTP error scenarios, check HTTP Setting Errors for HTTPS unavailability and related triggers.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;OL start="5"&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Azure Monitor Metrics&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;Track Auto-Heal activity using:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;WorkerProcessRecycleCount&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;:&amp;nbsp;Indicates how often instances are recycled&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN data-contrast="auto"&gt;HealthCheckStatus&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;:&amp;nbsp;Shows instance recovery lifecycle&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;These metrics can be used to:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Build dashboards&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Configure alerts&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="11" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Correlate with performance degradation&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;OL start="6"&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Application Insights Integration&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;When enabled, Application Insights helps:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Correlate Auto-Heal events with exceptions and dependencies&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Analyze performance trends leading to failures&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="12" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Validate recovery timelines&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Best Practices for Effective Auto-Heal Usage&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;To maximize effectiveness:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Define safe and practical triggers&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Start with conservative thresholds to avoid unnecessary restarts.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Continuously refine rules using diagnostics and production behavior to improve accuracy over time.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Pair Auto-Heal with platform resiliency features&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Use&amp;nbsp;Health Check so traffic is routed away from unhealthy instances during recovery.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Use autoscaling alongside Auto-Heal: Auto-Heal addresses runtime instability, while auto&amp;nbsp;scale responds to load.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Monitor and learn from recovery patterns&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Track&amp;nbsp;frequent&amp;nbsp;events as&amp;nbsp;repeated activations may indicate deeper application issues.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="13" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Enable observability through Azure Monitor and Application Insights for end-to-end visibility.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Key Considerations and Limitations&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;While powerful, Auto-Heal must be used thoughtfully:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Auto Heal is not&amp;nbsp;a substitute for root cause fixes&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Repeated triggers indicate underlying issues that must be addressed&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Overly aggressive rules can cause churn&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Frequent recycles may impact user experience&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Platform differences (Windows vs Linux)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Memory-based triggers are&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;not supported on Linux&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Custom actions have&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;limited support on Linux&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI style="list-style-type: none;"&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Windows provides the most comprehensive feature set&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Single-instance applications experience downtime during&amp;nbsp;recycle&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Scaling to multiple instances is recommended for production workloads&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="14" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Dependency failures are not resolved by Auto-Heal&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Recycling does not fix external service outages.&amp;nbsp;The goal is not to restart applications more often. The goal is to make recovery safer, faster, and more intentional when unhealthy runtime states occur.&amp;nbsp;The dependency failures&amp;nbsp;need&amp;nbsp;to be investigated further.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 aria-level="2"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-parastyle="heading 2"&gt;Bringing It All Together&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134245418&amp;quot;:true,&amp;quot;134245529&amp;quot;:true,&amp;quot;335559738&amp;quot;:160,&amp;quot;335559739&amp;quot;:80}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Auto-Heal is a foundational capability for building&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;resilient, self-recovering applications on Azure App Service&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;. When combined with Health Check, monitoring, and scaling strategies, it enables:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="15" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Faster recovery from runtime faults&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="15" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Improved availability and user experience&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="15" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Reduced operational burden on engineering teams&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;By thoughtfully configuring triggers, validating behavior through diagnostics, and continuously refining rules, organizations can transform Auto-Heal from a simple restart mechanism into a&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;strategic resiliency control&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 22 Jul 2026 20:52:05 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/proactive-resiliency-with-azure-app-service-auto-heal/ba-p/4539836</guid>
      <dc:creator>lakprasad</dc:creator>
      <dc:date>2026-07-22T20:52:05Z</dc:date>
    </item>
    <item>
      <title>Azure Support Agent — Part 1: Building an AI Azure Ops Workbench</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/azure-support-agent-part-1-building-an-ai-azure-ops-workbench/ba-p/4534569</link>
      <description>&lt;P&gt;Picture a busy afternoon: an app starts throwing 5xx, and you go looking for why. The good news is that Azure almost certainly already holds the answer. The Portal has the resource. Azure Resource Graph knows what's actually deployed. Monitor has the metrics, Log Analytics has the logs, Advisor has the recommendations, and the CLI reaches the rest. Azure is remarkably data-rich — very little about your estate is truly hidden. The real challenge at scale is human bandwidth: stitching a dozen surfaces into a single answer while the clock is running.&lt;/P&gt;
&lt;P&gt;There's a second, quieter category of work, too — the things that never prompt you to open a tab in the first place. A database whose backups quietly stopped succeeding. A workload that grew business-critical before anyone gave it a DR pair. A Key Vault secret ticking toward expiry. The signals to catch every one of these already exist in Azure; what's missing is simply someone (or something) with the time to watch all of them, continuously, across the whole estate.&lt;/P&gt;
&lt;P&gt;Now multiply that across a real environment — hundreds of resources, dozens of teams, and a platform that keeps evolving as Azure ships new capabilities and retires older ones. Nobody here is short on skill or data; there's just far more signal than any human can watch at once. And that — always-on, correlate-everything, catch-it-early work — is exactly what AI is good at. It's the gap this workbench is built to fill.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;What if your subscription had a copilot that already knew the answer — and had been watching for the problem before you asked?&lt;/STRONG&gt;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Meet the &lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-1-from-reactive-tickets-to-a-proactive/4534569" target="_blank" rel="noopener" data-lia-auto-title="Azure Support Agent" data-lia-auto-title-active="0"&gt;Azure Support Agent&lt;/A&gt;&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;The&amp;nbsp;&lt;STRONG&gt;Azure Support Agent&lt;/STRONG&gt;&amp;nbsp;is an open-source, AI-driven operations workbench that you deploy into&amp;nbsp;&lt;STRONG&gt;your own tenant&lt;/STRONG&gt;. Point it at a subscription and it discovers your workloads (e.g. find related resources using AI inferencing), reverse-engineers live architecture diagrams (how difficult has it been for you to catch-up with diagrams? how about live+living documentation?), runs Well-Architected-style assessments, and puts a team of specialist AI agents at your disposal to investigate, monitor, and remediate.&lt;/P&gt;
&lt;P&gt;It talks to Azure through the official&amp;nbsp;&lt;STRONG&gt;Azure MCP server&lt;/STRONG&gt;&amp;nbsp;and a&amp;nbsp;&lt;STRONG&gt;Microsoft Graph (Entra ID) MCP server&lt;/STRONG&gt;&amp;nbsp;— the same Model Context Protocol that's quickly becoming the standard way for AI to use real tools. Between them that's over a hundred read-classified tools, so the agent reasons over&amp;nbsp;&lt;EM&gt;live evidence&lt;/EM&gt; from your estate, not a training-data guess about how Azure works. In other words, it doesn't replace any of Azure's tooling — it orchestrates it on your behalf, on top of the platform APIs you already trust.&lt;/P&gt;
&lt;P&gt;And it runs where your data already lives. One click deploys it to&amp;nbsp;&lt;STRONG&gt;Azure Container Apps&lt;/STRONG&gt; in your subscription; nothing about your estate leaves your tenant.&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;the Architecture Designer showing reverse-engineered architecture diagram of your workload with the help of AI, overlay with assessments, launch tools direclty&lt;/P&gt;
&lt;/img&gt;
&lt;H3&gt;&lt;STRONG&gt;Converse — a chat that reads your tenant, and a war room for the hard ones &lt;EM&gt;(Part 2)&lt;/EM&gt;&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;Back to that bad afternoon — except this time you don't open eight tabs. You ask, in plain English:&amp;nbsp;&lt;EM&gt;"Why is the checkout API throwing 5xx?"&lt;/EM&gt;&amp;nbsp;— and the agent answers by&amp;nbsp;&lt;EM&gt;doing the work&lt;/EM&gt;, not by guessing from training data. It queries your live estate through the MCP tools and streams its reasoning and every tool call back to you as it goes, so you can see exactly which resources it looked at. Those turns are durable: reload the page and the timeline is still there, and if you cancel a long answer the work keeps running server-side instead of evaporating. You can keep several investigations going at once, paste in a screenshot of a failing blade, and lean on a starter suggestion when you're not sure what to ask.&lt;/P&gt;
&lt;P&gt;When a question is genuinely hard, you switch on&amp;nbsp;&lt;STRONG&gt;Deep mode&lt;/STRONG&gt;&amp;nbsp;and a&amp;nbsp;&lt;STRONG&gt;War Room&lt;/STRONG&gt;&amp;nbsp;convenes. Instead of one model guessing, a team of specialists goes to work in parallel — a Networking specialist checks NSGs, private endpoints and DNS; an Identity specialist looks at managed identities and expiring secrets; Compute, Storage, Security and Reliability specialists each take their own angle — every one of them pulling live evidence from your estate at the same time. They form hypotheses, throw out the ones the evidence contradicts, and converge. Ninety seconds later you have a conclusion rather than a hunch:&amp;nbsp;&lt;EM&gt;the app's Key Vault secret expired overnight; here's the dependency chain that proves it, and here's the exact command to rotate it.&lt;/EM&gt; The whole investigation is saved as a navigable hypothesis tree attached to the chat, so the next person doesn't start from zero.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Map — turn sprawl into a picture you can actually use &lt;EM&gt;(Part 3)&lt;/EM&gt;&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;You can't reason about resources you can't see, and almost nobody has a current map of their own estate — so the agent builds one for you. It groups raw resources into&amp;nbsp;&lt;STRONG&gt;Workloads&lt;/STRONG&gt;&amp;nbsp;(the resources that actually make up one application) and gives each a composite, explainable health score; if you'd rather not draw those boundaries by hand,&amp;nbsp;&lt;STRONG&gt;Autopilot&lt;/STRONG&gt;&amp;nbsp;studies the estate and proposes the groupings for you to approve.&lt;/P&gt;
&lt;P&gt;Then it gets visual. Point it at a workload and it&amp;nbsp;&lt;A class="lia-external-url" href="https://zmustafa.github.io/AzureSupportAgent/how-to/design-assessment/architectures-know-me/" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;reverse-engineers an interactive architecture diagram&lt;/STRONG&gt;&lt;/A&gt;&amp;nbsp;from what's genuinely deployed, inferring the real relationships — NIC to subnet to VNet, app to plan, private endpoint to target — instead of trusting a stale Visio. It keeps a persistent&amp;nbsp;&lt;STRONG&gt;Architecture Memory&lt;/STRONG&gt;&amp;nbsp;for each design (intended topology, security model, resiliency targets, known gaps) that later feeds those War Room investigations as expert context, and it flags&amp;nbsp;&lt;STRONG&gt;drift&lt;/STRONG&gt;&amp;nbsp;when the live estate wanders from the design. It will even draft the on-call&amp;nbsp;&lt;STRONG&gt;"know-me" doc&lt;/STRONG&gt;&amp;nbsp;for a workload, auto-filling what Azure knows and marking human-only facts — SLAs, escalation paths, RTO/RPO — as explicit TODOs rather than inventing them. Zoom all the way out and the&amp;nbsp;&lt;STRONG&gt;Estate Graph&lt;/STRONG&gt; renders your whole tenant as one searchable, workload-aware map, with cost, retirement and RBAC overlays and deep links straight to the underlying resource.&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;Use AI to discover your Azure workloads from a management group/subscription/rg scopes, then group their resources to perform proactive operations&lt;/P&gt;
&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;A reverse-engineered estate graph of your Azure Workload&lt;/P&gt;
&lt;/img&gt;
&lt;H3&gt;&lt;STRONG&gt;Assess — go looking for trouble before it finds you &lt;EM&gt;(Part 4)&lt;/EM&gt;&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;This is where "proactive" stops being a slogan. Most tooling waits to be asked; the Azure Support Agent runs a battery of assessments that hunt for risk&amp;nbsp;&lt;EM&gt;before&lt;/EM&gt;&amp;nbsp;the ticket exists, each judging your estate against a reviewed, versioned baseline rather than a vibe.&lt;/P&gt;
&lt;P&gt;It starts with&amp;nbsp;&lt;STRONG&gt;coverage&lt;/STRONG&gt;: which resources are missing the&amp;nbsp;&lt;STRONG&gt;Azure Monitor baseline alerts&lt;/STRONG&gt;&amp;nbsp;they ought to have, and which are shipping no diagnostic logs at all — then it hands you ready-to-apply&amp;nbsp;&lt;STRONG&gt;Bicep or Terraform&lt;/STRONG&gt;&amp;nbsp;to close the gaps. It audits&amp;nbsp;&lt;STRONG&gt;backup and DR&lt;/STRONG&gt;&amp;nbsp;the same way: is each resource actually backed up, with adequate retention, an offsite copy and a DR pair that's been drilled — or will you find out during the outage? A&amp;nbsp;&lt;A class="lia-external-url" href="https://zmustafa.github.io/AzureSupportAgent/how-to/design-assessment/performance-profiler/" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Performance Profiler&lt;/STRONG&gt;&lt;/A&gt;&amp;nbsp;reads live metrics and ranks every resource by saturation on a heatmap, naming the workload's binding bottleneck before your users feel it. And for the big picture it scores a workload against the five&amp;nbsp;&lt;STRONG&gt;Well-Architected&lt;/STRONG&gt;&amp;nbsp;pillars with reproducible, deterministic math (never a random number a model made up), turns the architecture into a quantified&amp;nbsp;&lt;STRONG&gt;FMEA&lt;/STRONG&gt;&amp;nbsp;risk register, and gives you a read-only&amp;nbsp;&lt;STRONG&gt;identity and RBAC&lt;/STRONG&gt;&amp;nbsp;posture — expiring credentials, ownerless apps, MFA gaps, and who can&amp;nbsp;&lt;EM&gt;really&lt;/EM&gt; do what. The payoff is a change of timing: you stop discovering that a database was never backed up at the worst possible moment, and start seeing it on a dashboard on a quiet Tuesday.&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;Azure Monitor Baseline Alerts (AMBA) assessment against your Azure Workload - showing where you have/have not configured alerting&lt;/P&gt;
&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;Performance Profiler - unified matrix view of all your resources in an Azure Workload and their performance metrics at a point in time&lt;/P&gt;
&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;AI driven change explorer on what changed in your Azure Workload during a time window&lt;/P&gt;
&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;Conduct AI assisted Failure Mode and Effects Analysis (FMEA) against your Azure Workload&lt;/P&gt;
&lt;/img&gt;
&lt;H3&gt;&lt;STRONG&gt;Act — don't just find it, fix it (safely) &lt;EM&gt;(Part 5)&lt;/EM&gt;&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;Findings that die in a dashboard help no one, so the last pillar is about closing the loop — carefully. You can&amp;nbsp;&lt;STRONG&gt;dry-run an Azure Policy&lt;/STRONG&gt;&amp;nbsp;deny and measure its real&amp;nbsp;&lt;STRONG&gt;blast radius&lt;/STRONG&gt;&amp;nbsp;— exactly which resources it would hit — before you enforce a thing. You can straighten out&amp;nbsp;&lt;STRONG&gt;ownership and tagging&lt;/STRONG&gt;&amp;nbsp;from a single owner directory and tag census, applying corrections as real tags with snapshots and a one-click revert if anything looks off. And&amp;nbsp;&lt;A class="lia-external-url" href="https://zmustafa.github.io/AzureSupportAgent/how-to/estate-intelligence/change-explorer/" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Change Explorer&lt;/STRONG&gt;&lt;/A&gt;&amp;nbsp;tells you, in plain English, what changed across your estate, who changed it, and whether it was risky — the forensics you always wish you had mid-incident.&lt;/P&gt;
&lt;P&gt;From there it helps you get ahead of the calendar and, eventually, take yourself out of the loop.&amp;nbsp;&lt;STRONG&gt;Retirement Radar&lt;/STRONG&gt;&amp;nbsp;maps Azure service retirements and breaking changes to the specific workloads they'll hit, with real deadlines; the&amp;nbsp;&lt;STRONG&gt;Reservations&lt;/STRONG&gt;&amp;nbsp;view tells you whether your commitments are actually paying off or quietly leaking money.&amp;nbsp;&lt;STRONG&gt;Mission Control&lt;/STRONG&gt;&amp;nbsp;runs&amp;nbsp;&lt;EM&gt;every&lt;/EM&gt;&amp;nbsp;analysis on a workload at once for a single go/no-go verdict — which you can then put on a schedule with&amp;nbsp;&lt;STRONG&gt;Automations&lt;/STRONG&gt;, routing results to Teams, Jira or ServiceNow so the whole loop runs without you babysitting it. Everything that writes stays proposal-first: the AI suggests, you approve.&lt;/P&gt;
&lt;img&gt;
&lt;P&gt;Mission Control's per-workload go/no-go verdict, pick a workload, launch and let it warm up&lt;/P&gt;
&lt;/img&gt;&lt;img&gt;Unified view of Azure retirements and breaking changes against your Azure Workload&lt;/img&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Built to be trusted&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;None of this is worth much if you can't hand it the keys with a clear conscience, so the trust model is deliberately conservative. The Azure Support Agent is&amp;nbsp;&lt;STRONG&gt;read-only by default&lt;/STRONG&gt;&amp;nbsp;— every write is&amp;nbsp;&lt;STRONG&gt;approval-gated&lt;/STRONG&gt;&amp;nbsp;and recorded in a&amp;nbsp;&lt;STRONG&gt;full audit log&lt;/STRONG&gt;, that can be sent to Splunk, CrowdStrike NG SIEM, or others. Full EntraID based authentication, It runs in&amp;nbsp;&lt;STRONG&gt;your&lt;/STRONG&gt; Azure Container App with private endpoints intra-service, so nothing about your estate ever leaves your tenant. And the&amp;nbsp;&lt;STRONG&gt;AI is off until you switch it on&lt;/STRONG&gt;: bring your own provider — OpenAI, Azure OpenAI, Anthropic Claude, Google Gemini, GitHub Copilot, Mistral, or a local model via Ollama or LM Studio — and there is zero LLM traffic until you explicitly configure one. This is the difference between a chatbot that answers from memory and a workbench that uses tools against live evidence, shows its working, and leaves you with artifacts you keep. It matters enough that a whole later post is devoted to it —&amp;nbsp;&lt;STRONG&gt;Part 6&lt;/STRONG&gt;&amp;nbsp;— covering the full access model and how the answers stay grounded, reproducible and free of fabrication.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Where this series goes&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;This is Part 1 of a seven-part tour. Each post ahead goes deep on one pillar of the Azure Support Agent, leads with a real screenshot, and stands on its own — so skip to whichever one solves your problem this week:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/MicrosoftMissionCriticalBlog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765" target="_blank" rel="noopener" data-lia-auto-title="Part 2 — The War Room" data-lia-auto-title-active="0"&gt;Part 2 — The War Room&lt;/A&gt;:&lt;/STRONG&gt;&amp;nbsp;watch a team of AI specialists root-cause a 5xx in ninety seconds.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;&lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-3-reverse-engineer-azure-architecture-/4541741" data-lia-auto-title="Map your estate" data-lia-auto-title-active="0" target="_blank"&gt;Part 3 — Map your estate&lt;/A&gt;:&lt;/STRONG&gt;&amp;nbsp;live architecture diagrams, Workloads, know-me docs, the Estate Graph.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Part 4 — Assess before it pages you:&lt;/STRONG&gt;&amp;nbsp;alert/telemetry and backup/DR coverage, Well-Architected scores, FMEA risk registers and identity &amp;amp; RBAC — with the IaC to fix the gaps.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Part 5 — Act: govern, fix, and stay ahead:&lt;/STRONG&gt;&amp;nbsp;Policy dry-runs and blast radius, ownership &amp;amp; tags, change forensics, retirement radar, reservations and Mission Control.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Part 6 — Letting AI into your Azure:&lt;/STRONG&gt;&amp;nbsp;the read-only-by-default access model, grounded and deterministic answers, and bring-your-own-model.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Part 7 — How it's wired:&lt;/STRONG&gt;&amp;nbsp;the agents, the MCP layer, and one-click deploy — for the builders.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Whether you're on-call chasing a root cause, an architect who needs a current diagram, on the security team watching RBAC and secrets, or a FinOps owner hunting waste, there's a part above with your name on it.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;The bottom line&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;The promise of the Azure Support Agent is a shift in posture. Your estate stops being a mystery you interrogate after something breaks, and becomes a system that tells you what's wrong — often before anyone gets paged.&lt;/P&gt;
&lt;P&gt;Picture next Monday. The expiring Key Vault secret shows up on a dashboard the Thursday before, and gets rotated in the quiet — so the 5xx afternoon simply never happens. The database with the failing backups is flagged, with generated Bicep to fix it, a week ahead of the quarterly DR drill instead of during the post-mortem. Nothing about your Azure changed except&amp;nbsp;&lt;EM&gt;when&lt;/EM&gt;&amp;nbsp;you found out.&lt;/P&gt;
&lt;H3&gt;&lt;STRONG&gt;Try it yourself&lt;/STRONG&gt;&lt;/H3&gt;
&lt;P&gt;The Azure Support Agent is open source and free to run. Three ways to start, in rising order of commitment:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Explore demo mode&lt;/STRONG&gt;&amp;nbsp;— synthetic data, no connection required, nothing to risk.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Deploy to your tenant&lt;/STRONG&gt; — one click to Azure Container Apps; private networking; your data never leaves.&lt;/LI&gt;
&lt;/OL&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Or main repository &lt;A class="lia-external-url" href="https://github.com/zmustafa/AzureSupportAgent" target="_blank" rel="noopener"&gt;https://github.com/zmustafa/AzureSupportAgent&lt;/A&gt;&lt;/STRONG&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;A class="lia-internal-link lia-internal-url lia-internal-url-content-type-blog" href="https://techcommunity.microsoft.com/blog/microsoftmissioncriticalblog/building-an-ai-azure-ops-workbench-%E2%80%94-part-2-the-war-room-%E2%80%94-watch-ai-root-cause-a/4540765" target="_blank" rel="noopener" data-lia-auto-title="seconds" data-lia-auto-title-active="0"&gt;Next time — Part 2: &lt;EM&gt;The War Room — watch AI root-cause a 5xx in ninety seconds&lt;/EM&gt;&lt;/A&gt;&lt;EM&gt;.&lt;/EM&gt;&lt;/STRONG&gt; We'll go inside a live Deep-mode investigation: how a team of specialist agents fans out across your estate in parallel, forms and discards hypotheses against real evidence, and converges on a root cause you can navigate — and trust. It's the single best demonstration of what an AI ops workbench actually feels like.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://zeeshan.net/azure-support-agent/" target="_blank" rel="noopener"&gt;Part 1 Original&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 03 Aug 2026 13:11:39 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/azure-support-agent-part-1-building-an-ai-azure-ops-workbench/ba-p/4534569</guid>
      <dc:creator>zmustafa</dc:creator>
      <dc:date>2026-08-03T13:11:39Z</dc:date>
    </item>
    <item>
      <title>Kernels Behind the Wall: Custom Python 3.10-3.14 Jupyter Kernels for Air-Gapped Azure ML</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/kernels-behind-the-wall-custom-python-3-10-3-14-jupyter-kernels/ba-p/4534118</link>
      <description>&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245380"&gt;&lt;/A&gt;Purpose&lt;/H1&gt;
&lt;P&gt;Regulated organizations - banks, insurers, healthcare providers - increasingly run Azure Machine Learning on compute instances that have no outbound internet access. Their data scientists still need modern Python versions and a rich, curated set of libraries. This document exists to close that gap. It captures a repeatable, field-tested pattern for delivering fully loaded Python 3.10-3.14 Jupyter kernels to an air-gapped Azure ML compute - without ever running a package resolver on the locked-down side. The technique itself is version-agnostic: the build, pack, ship, and unpack mechanism works for any Python version that conda can create. This guide uses Python 3.10-3.14 only as a representative range - 3.10 to match the built-in Azure ML kernel and 3.14 as today's ceiling - but the same steps apply equally to 3.9, a future 3.15, or any other version. The only version-dependent part is the package list itself (for example, the Azure ML SDK v1 tops out at Python 3.11).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245381"&gt;&lt;/A&gt;What This Document Is&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;A hands-on runbook for building, packaging, shipping, and installing custom Python 3.10-3.14 Jupyter kernels on an air-gapped Azure ML compute instance.&lt;/LI&gt;
&lt;LI&gt;A build-once, ship-an-artifact pattern that uses conda-pack, an Azure Storage blob reached over a private endpoint, and the compute's managed identity.&lt;/LI&gt;
&lt;LI&gt;A cleaned, ready-to-install package list - tuned per Python version - in which the known traps from the original Azure ML package export have already been fixed (conda internals, a CLI masquerading as a library, and standard-library-shadowing backports removed; wrong package names and duplicates corrected).&lt;/LI&gt;
&lt;LI&gt;A troubleshooting reference for the failures that actually happen: RBAC 403s, the azureml v1 Python ceiling, architecture and glibc mismatches, and conda-pack gotchas.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245382"&gt;&lt;/A&gt;What This Document Is Not&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;Not an introduction to Jupyter, conda, or Python packaging fundamentals.&lt;/LI&gt;
&lt;LI&gt;Not a guide to provisioning Azure ML workspaces, virtual networks, or private endpoints - those are assumed to already exist.&lt;/LI&gt;
&lt;LI&gt;Not for internet-connected computes, where a normal pip install or conda environment is all you need.&lt;/LI&gt;
&lt;LI&gt;Not a Windows or ARM recipe - the build box must be Linux x86_64 that matches the target compute.&lt;/LI&gt;
&lt;LI&gt;Not an official Microsoft product manual; it is a practitioner's field guide.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245383"&gt;&lt;/A&gt;Executive Summary&lt;/H1&gt;
&lt;P&gt;An air-gapped Azure ML compute presents two problems at the same time: it cannot reach PyPI or conda, and it ships with a single built-in Python 3.10 kernel. This guide solves both with one idea - build the environment where internet exists, freeze it into a single self-contained artifact, and ship that artifact across the air gap. The same mechanism works for any Python version conda can build - the 3.10-3.14 range used throughout is only a worked example, not a limit.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Build once on an internet-connected Linux x86_64 box, then conda-pack the environment into a single relocatable tarball.&lt;/LI&gt;
&lt;LI&gt;Upload the tarball to a blob container the compute can reach over a private endpoint; on the compute, install_offline_kernel.py uses the managed identity to download and unpack it - with zero package resolution on the locked-down side.&lt;/LI&gt;
&lt;LI&gt;Clean the raw package list first: strip conda internals, a CLI masquerading as a library, and backports that shadow the standard library.&lt;/LI&gt;
&lt;LI&gt;Keep the azureml SDK v1 for Python 3.10 and 3.11; drop it for 3.12-3.14 and use azure-ai-ml (v2) instead.&lt;/LI&gt;
&lt;LI&gt;Blob upload and download need data-plane roles (Storage Blob Data Contributor or Reader) - control-plane Owner or Contributor is not enough.&lt;/LI&gt;
&lt;LI&gt;Custom kernels persist across compute stop/start; only deleting the compute removes them.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Here is a fun situation I keep running into at regulated customers. A data scientist opens a brand-new Azure ML compute instance inside a locked-down bank network, types pip install pandas, and gets… nothing. No wheels. No index. No error worth reading. Just a cursor blinking back with the quiet confidence of a machine that has &lt;STRONG&gt;never once touched the internet&lt;/STRONG&gt; and does not intend to start now.&lt;/P&gt;
&lt;P&gt;That is the environment we are dealing with: an &lt;STRONG&gt;air-gapped&lt;/STRONG&gt; compute. And air-gapping is only the first of two problems. The second is that Azure ML Studio ships exactly &lt;STRONG&gt;one built-in kernel — Python 3.10&lt;/STRONG&gt;. If you need 3.11, 3.12, 3.13, or 3.14, or you want that 3.10 kernel preloaded with your organisation’s curated data-science stack instead of the bare default, the only supported path is to &lt;STRONG&gt;register your own Jupyter kernel&lt;/STRONG&gt;. On a normal box you’d pip your way there in a coffee break. Here you can’t, for the reason above.&lt;/P&gt;
&lt;P&gt;This post is the pattern I use to solve both at once: build the environment somewhere that &lt;EM&gt;does&lt;/EM&gt; have internet, freeze it into a single self-contained artifact with conda-pack, ship that artifact to a Storage blob the compute can reach over a private endpoint, and unpack it in place. No dependency resolution on the secure side. No firewall exceptions. No six-week change request that ends in “no.”&lt;/P&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245384"&gt;&lt;/A&gt;The short version&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Two constraints, one technique. &lt;/STRONG&gt;Air-gapped compute (no PyPI/conda) &lt;EM&gt;and&lt;/EM&gt; a single built-in 3.10 kernel. Custom kernels solve the version/packages gap; conda-pack solves the no-internet gap.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Build once, ship a tarball. &lt;/STRONG&gt;Create the env on an internet-connected &lt;STRONG&gt;Linux x86_64&lt;/STRONG&gt; box, conda-pack it, upload to blob, download + unpack on the compute. Zero resolver runs on the locked-down side.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Don’t trust the raw package list. &lt;/STRONG&gt;A curated AML image’s package dump contains conda internals, a CLI masquerading as a library, and two backports that shadow the standard library. Clean it first (Section 4).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;azureml SDK v1 caps you at Python 3.11. &lt;/STRONG&gt;Keep azureml-* for 3.10/3.11; drop it on 3.12–3.14 and use azure-ai-ml (v2).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;“Owner” does not grant blob I/O. &lt;/STRONG&gt;Uploads/downloads need a &lt;STRONG&gt;data-plane&lt;/STRONG&gt; role (Storage Blob Data Contributor / Reader), not control-plane Owner or Contributor.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Kernels survive stop/start. &lt;/STRONG&gt;They live on the persistent user disk; only deleting the compute wipes them.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245385"&gt;&lt;/A&gt;Before you start&lt;/H1&gt;
&lt;P&gt;Five things need to be true before any of the commands below will work. Confirm them now, not at Section 6:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;A Linux x86_64 build box with internet — &lt;/STRONG&gt;Ubuntu 22.04 or similar. Must be x86_64 (see the arch note in Section 3) and ideally a similar/older OS than the compute (see the glibc note there too).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;An Azure Storage account reachable from the compute — &lt;/STRONG&gt;over a private endpoint from the compute’s VNet, with a container to hold the tarball.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;A managed identity on the compute instance — &lt;/STRONG&gt;system- or user-assigned, attached to the &lt;EM&gt;compute&lt;/EM&gt; (not just the workspace), with &lt;STRONG&gt;Storage Blob Data Reader&lt;/STRONG&gt; on that account.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Rights to assign RBAC — &lt;/STRONG&gt;Owner or User Access Administrator on the storage account, so you can grant the data-plane roles in Section 6. If you don’t have this, line up whoever does before you begin.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Terminal access to the compute — &lt;/STRONG&gt;via AML Studio, where you’ll run the installer as azureuser.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245386"&gt;&lt;/A&gt;1. Why the obvious approaches don’t work&lt;/H1&gt;
&lt;P&gt;Before the solution, it’s worth being honest about why the easy options fail, because someone on the call will suggest all of them:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;The tempting shortcut&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Why it doesn’t survive contact with an air-gapped compute&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;pip install -r requirements.txt&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;No route to PyPI. DNS or connect timeout. There is nothing to resolve against.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;conda create -n env python=3.12 …&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Can’t reach conda channels, and now also blocks on the Anaconda ToS endpoint it can’t contact.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Just use the built-in kernel&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;It’s Python 3.10 only, with the stock package set. No version choice, no curated stack.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;“Can we open the firewall briefly?”&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;In a regulated tenant, that’s a security review measured in weeks and usually ends in a polite no.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Copy a wheelhouse folder by hand&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Fine for pure-Python, but collapses the moment a package needs a compiled binary the target can’t build.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;STRONG&gt;The insight: &lt;/STRONG&gt;stop trying to make the compute reach &lt;EM&gt;out&lt;/EM&gt;. Build everything &lt;STRONG&gt;outside&lt;/STRONG&gt;, freeze it into one self-contained artifact — interpreter, packages, and native .so files included — and hand it to the compute through the one channel it already trusts: its own VNet’s private endpoint to Azure Storage.&lt;/P&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245387"&gt;&lt;/A&gt;2. The approach: build, pack, ship, unpack&lt;/H1&gt;
&lt;P&gt;Four steps. Assemble the env on a machine with internet, compress it with conda-pack into one .tar.gz, upload it to a blob container, and run a small installer on the compute that downloads, unpacks, and registers the kernel.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;Why conda-pack instead of rebuilding from a&amp;nbsp;&lt;/STRONG&gt;pip freeze&lt;STRONG&gt; on the target? &lt;/STRONG&gt;Because a freeze from a curated AML image is not a clean, reinstallable manifest. That env was assembled by conda plus internal feeds, so its pins are internally contradictory — they will not resolve on a fresh Python. conda-pack sidesteps all of it by shipping the &lt;STRONG&gt;exact binaries that already work&lt;/STRONG&gt;. The target never runs a solver, so there is nothing left to conflict.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;📌&amp;nbsp; Note&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;A conda-pack tarball is a frozen snapshot of a working env — same site-packages, same shared objects, same interpreter. Once conda-unpack rewrites the embedded absolute paths, it runs exactly as if it had been built on the compute. No network, no channels, no ToS prompt.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245388"&gt;&lt;/A&gt;3. Part 1 — Build the environment (Linux x86_64)&lt;/H1&gt;
&lt;P&gt;&lt;STRONG&gt;Where: &lt;/STRONG&gt;an internet-connected Linux x86_64 box (Ubuntu 22.04 or similar). &lt;STRONG&gt;The architecture is not optional. &lt;/STRONG&gt;Build on ARM64 or a Mac and the compute rejects the binary with Exec format error. There is no cross-arch fallback; the interpreter simply won’t run.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;⚠️&amp;nbsp; Gotcha&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Match more than just the CPU. &lt;/STRONG&gt;conda-pack ships compiled binaries, so they link against the build box’s system libraries — glibc in particular. Build on a &lt;EM&gt;newer&lt;/EM&gt; OS than the compute (e.g. Ubuntu 24.04 for an older compute image) and you can hit GLIBC_2.xx not found at import time. Build on an OS that’s the &lt;STRONG&gt;same or older&lt;/STRONG&gt; than the target, and match the Python patch line, to stay safe.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245389"&gt;&lt;/A&gt;3.1 Install Miniconda and accept the ToS (once)&lt;/H2&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 99.0741%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;curl -fSL -o miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh&lt;/P&gt;
&lt;P&gt;bash miniconda.sh -b -p $HOME/miniconda&lt;/P&gt;
&lt;P&gt;source $HOME/miniconda/etc/profile.d/conda.sh&lt;/P&gt;
&lt;P&gt;conda init bash &amp;amp;&amp;amp; exec bash&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;# Accept the ToS HERE, on the box that can actually reach the endpoint:&lt;/P&gt;
&lt;P&gt;conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/main || true&lt;/P&gt;
&lt;P&gt;conda tos accept --override-channels --channel https://repo.anaconda.com/pkgs/r&amp;nbsp;&amp;nbsp;&amp;nbsp; || true&lt;/P&gt;
&lt;P&gt;conda install -n base -c conda-forge conda-pack -y&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245390"&gt;&lt;/A&gt;3.2 Create the env (ipykernel is mandatory)&lt;/H2&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 99.9074%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;# The env name follows through the whole workflow. Pick your version:&lt;/P&gt;
&lt;P&gt;conda create -n aml-py310 -c conda-forge python=3.10 ipykernel pip setuptools wheel -y&lt;/P&gt;
&lt;P&gt;conda create -n aml-py314 -c conda-forge python=3.14 ipykernel pip setuptools wheel -y&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Include ipykernel. The installer on the compute runs a preflight check for it and aborts with a rebuild message if it’s missing. It comes from conda here, which is why it does not appear in the pip requirements files. Leave it out and you’ll do the whole build, upload, and download before finding out nothing registers.&lt;/P&gt;
&lt;H2&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245391"&gt;&lt;/A&gt;3.3 Install the curated package set&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;A note on the requirements file: &lt;/STRONG&gt;there’s no magic requirements-py310.txt attached to this post — it stands in for &lt;EM&gt;your own&lt;/EM&gt; curated package list. Bring whatever set your team needs; Section 4 shows how to sanitise it and Section 5 covers the per-version differences. The one-file-per-Python-version layout below is just how I keep the versions straight.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 99.537%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;conda activate aml-py310&lt;/P&gt;
&lt;P&gt;pip install -r requirements/requirements-py310.txt&lt;/P&gt;
&lt;P&gt;pip check&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # surface residual conflicts BEFORE you pack&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;# Freeze exact versions so a rebuild next month is byte-for-byte repeatable:&lt;/P&gt;
&lt;P&gt;pip freeze &amp;gt; requirements/requirements-py310.lock.txt&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;On 3.12 / 3.13 / 3.14 this set is built around azure-ai-ml (v2); the deprecated azureml-* v1 family is intentionally absent. Section 5 explains why.&lt;/P&gt;
&lt;H2&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245392"&gt;&lt;/A&gt;3.4 Pack it&lt;/H2&gt;
&lt;P&gt;Run this from &lt;STRONG&gt;base&lt;/STRONG&gt; (where conda-pack lives), not from inside the env:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 1072px; height: 388px; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr style="height: 207.562px;"&gt;&lt;td style="height: 207.562px;"&gt;
&lt;P&gt;conda deactivate&lt;/P&gt;
&lt;P&gt;mkdir -p ~/aml-offline &amp;amp;&amp;amp; cd ~/aml-offline&lt;/P&gt;
&lt;P&gt;conda pack -n aml-py310 -o aml-py310.tar.gz --ignore-missing-files&lt;/P&gt;
&lt;P&gt;ls -lh aml-py310.tar.gz&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # ~150 MB minimal … several GB with the full DS stack&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 180.438px;"&gt;&lt;td style="height: 180.438px;"&gt;
&lt;P&gt;&lt;STRONG&gt;⚠️&amp;nbsp; Gotcha&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;--ignore-missing-files is required for these envs. &lt;/STRONG&gt;Because the env mixes conda with a large pip layer, pip upgrades a few conda-installed packages (e.g. packaging) and rewrites their dist-info. Without the flag, conda-pack aborts with CondaPackError: Files managed by conda were found to have been deleted/overwritten. The flag packs what’s actually on disk — the consistent pip versions. Add --force if the output file already exists.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 1071px" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;H2&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245393"&gt;&lt;/A&gt;3.5 Smoke-test before shipping&lt;/H2&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 98.1481%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;mkdir -p /tmp/test &amp;amp;&amp;amp; tar -xzf aml-py310.tar.gz -C /tmp/test&lt;/P&gt;
&lt;P&gt;/tmp/test/bin/conda-unpack&lt;/P&gt;
&lt;P&gt;/tmp/test/bin/python -c "import sys, ipykernel; print(sys.version, ipykernel.__version__)"&lt;/P&gt;
&lt;P&gt;file /tmp/test/bin/python&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # MUST say: ELF 64-bit LSB executable, x86-64&lt;/P&gt;
&lt;P&gt;rm -rf /tmp/test&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;Run the file check every single time. If it doesn’t say x86-64, stop and rebuild now. Shipping it anyway just moves the same failure to the compute, where it takes longer to spot.&lt;/P&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245394"&gt;&lt;/A&gt;4. Cleaning the curated package list – (Depends on the package list , Here we can see some examples)&lt;/H1&gt;
&lt;P&gt;A raw package list dumped from a curated AML image looks fine at a glance. Installed as-is, it either fails the build outright or, worse, silently breaks the env in ways you won’t notice until a notebook misbehaves three weeks later. I’ve hit six recurring problems in these lists. Here they are, with the fix for each.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table style="width: 1075px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Offender&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;The problem&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;The fix&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;conda, conda-content-trust, conda-package-handling, pycosat, boltons, ruamel-yaml-conda&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;These are components of the &lt;STRONG&gt;base conda install&lt;/STRONG&gt;, not project libraries. pycosat needs a C toolchain, and a pip-installed conda can shadow the real one.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Remove all six. Keep ruamel.yaml (the real PyPI build) for YAML.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;azure-cli&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;It’s a &lt;EM&gt;command-line app&lt;/EM&gt;, not a notebook library, and it pins hundreds of exact azure-mgmt-* / azure-storage-* versions. Single biggest source of conflicts.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Remove it. Install the az CLI separately if you need it — don’t let it dictate your SDK versions.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;azureml-core + the azureml-* v1 family&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Deprecated (EOL June 2026) and version-capped. Binary deps (azureml-dataprep-rslex, dotnetcore2) only ship wheels to CPython 3.11.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Keep for 3.10/3.11 only. On 3.12–3.14, drop it and use azure-ai-ml (v2).&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;brotlipy&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;A conda-image artifact superseded by Brotli. On newer Python it often has no wheel and wants a C compiler.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Remove. requests / urllib3 pull in Brotli automatically when needed.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;dataclasses==0.6, uuid==1.30&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Ancient backports that &lt;STRONG&gt;shadow the standard library&lt;/STRONG&gt; on modern Python. These cause real, subtle breakage — not just noise.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Remove on sight.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;azure-storage-filedatalake (and duplicates)&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;That name 404s on PyPI — it’s the &lt;EM&gt;import&lt;/EM&gt; name. azure-identity and databricks-sql-connector also appear twice.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Correct to azure-storage-file-datalake (dashes). Deduplicate the rest.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table style="width: 1071px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;💡&amp;nbsp; Tip&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Do the resolution &lt;STRONG&gt;out in the open&lt;/STRONG&gt;, on the build box, where pip check and error messages are visible and cheap to fix. The whole point of shipping a tarball is that the locked-down compute never runs a solver — so make sure the solver runs cleanly &lt;EM&gt;before&lt;/EM&gt; you pack.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245395"&gt;&lt;/A&gt;5.&lt;SPAN style="color: rgb(30, 30, 30);"&gt;The azureml v1 version ceiling&lt;/SPAN&gt;&lt;/H1&gt;
&lt;P&gt;This one deserves its own section because it silently dictates which Python versions you can even offer. The azureml-* v1 SDK — azureml-core and its binary friends azureml-dataprep-rslex, azureml-dataprep-native, dotnetcore2 — is deprecated (EOL June 2026) and only ships wheels for &lt;STRONG&gt;CPython 3.8–3.11&lt;/STRONG&gt; (rslex reaches 3.12, but not 3.13/3.14). On 3.13/3.14 the install simply cannot resolve. So the strategy is version-aware:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 97.963%; border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Python&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Requirements file&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;azureml-* v1&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Notebook SDK&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;3.10&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;requirements-py310.txt&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Included&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;azureml-core&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;3.11&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;requirements-py311.txt&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Included&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;azureml-core&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;3.12&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;requirements-py312.txt&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Dropped&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;azure-ai-ml&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;3.13&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;requirements-py313.txt&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Dropped&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;azure-ai-ml&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;3.14&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;requirements-py314.txt&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Dropped&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;azure-ai-ml&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.0712%" /&gt;&lt;col style="width: 25.0712%" /&gt;&lt;col style="width: 25.0712%" /&gt;&lt;col style="width: 25.0712%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;The v2 azure-ai-ml SDK is tested on Python 3.8–3.14 and covers workspace, compute, datastore, job, pipeline, and AutoML operations — so notebooks keep working on the newer interpreters without the deprecated stack.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;The filenames in this table are just a per-version naming convention for your own package lists — not files you download from anywhere. Keep one list per Python version and the rest of the workflow is identical.&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245396"&gt;&lt;/A&gt;6. Part 2 — Upload the tarball to blob&lt;/H1&gt;
&lt;P&gt;The tarball is packed and tested. Now drop it in a blob container the compute can reach over its private endpoint. This is where a role-assignment subtlety trips up almost everyone.&lt;/P&gt;
&lt;H2&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245397"&gt;&lt;/A&gt;6.1 Upload options&lt;/H2&gt;
&lt;P&gt;&lt;STRONG&gt;Portal (easiest): &lt;/STRONG&gt;Storage account → Containers → your container → + Add Directory offline-kernels → Upload the .tar.gz. The Portal uses the account key, so it sidesteps the RBAC issue below entirely.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;azcopy with the build VM’s managed identity:&lt;/STRONG&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 97.4074%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;curl -fSL -o azcopy.tar.gz https://aka.ms/downloadazcopy-v10-linux&lt;/P&gt;
&lt;P&gt;tar -xzf azcopy.tar.gz&lt;/P&gt;
&lt;P&gt;sudo cp azcopy_linux_amd64_*/azcopy /usr/local/bin/ &amp;amp;&amp;amp; sudo chmod +x /usr/local/bin/azcopy&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;azcopy login --identity&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # add --identity-client-id &amp;lt;uami&amp;gt; for user-assigned&lt;/P&gt;
&lt;P&gt;azcopy copy "$HOME/aml-offline/aml-py310.tar.gz" \&lt;/P&gt;
&lt;P&gt;&amp;nbsp; "https://&amp;lt;ACCOUNT&amp;gt;.blob.core.windows.net/&amp;lt;CONTAINER&amp;gt;/offline-kernels/aml-py310.tar.gz"&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245398"&gt;&lt;/A&gt;6.2 The 403 that ignores your title&lt;/H2&gt;
&lt;P&gt;You’re a subscription &lt;STRONG&gt;Owner&lt;/STRONG&gt;. Azure is unimpressed ☹. The upload still fails with 403 AuthorizationPermissionMismatch. Owner and Contributor are &lt;STRONG&gt;control-plane&lt;/STRONG&gt; roles; they let you manage the storage &lt;EM&gt;account&lt;/EM&gt;. Reading and writing &lt;EM&gt;blobs&lt;/EM&gt; is a &lt;STRONG&gt;data-plane&lt;/STRONG&gt; operation, and it needs a data-plane role the control-plane ones don’t include.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;I lost most of an afternoon to this during a bank onboarding earlier this year. I was sure the role assignment just hadn’t propagated yet, so I kept re-running the copy and waiting. The real problem was that I’d been granted Contributor on the account and never the data-plane role. About ninety seconds after the right role landed, the upload went through. Check the role before you blame propagation.&lt;/EM&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table style="width: 1064px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Operation&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Role you actually need&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Plane&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Upload the tarball (build side)&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Storage Blob Data Contributor&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Data-plane&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Download the tarball (compute side)&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Storage Blob Data Reader&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Data-plane&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Owner / Contributor&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Manage the account — &lt;STRONG&gt;not sufficient&lt;/STRONG&gt; for blob I/O&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Control-plane&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;sid=$(az storage account show -n &amp;lt;ACCOUNT&amp;gt; --query id -o tsv)&lt;/P&gt;
&lt;P&gt;az role assignment create \&lt;/P&gt;
&lt;P&gt;&amp;nbsp; --assignee &amp;lt;object-id-or-MI-principal-id&amp;gt; \&lt;/P&gt;
&lt;P&gt;&amp;nbsp; --role "Storage Blob Data Contributor" \&lt;/P&gt;
&lt;P&gt;&amp;nbsp; --scope "$sid"&lt;/P&gt;
&lt;P&gt;# wait ~1–2 min for RBAC propagation, then retry the copy&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;⚠️&amp;nbsp; Gotcha&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Whatever account you upload to &lt;STRONG&gt;must&lt;/STRONG&gt; be the same one the installer points at, and the &lt;STRONG&gt;compute’s own managed identity&lt;/STRONG&gt; needs &lt;STRONG&gt;Storage Blob Data Reader&lt;/STRONG&gt; on it. Mismatch the accounts and the download 403s the same way, except now it fails on the compute instead of your build box.&lt;/P&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245399"&gt;&lt;/A&gt;7. Part 3 — Install the kernel on the compute&lt;/H1&gt;
&lt;P&gt;On the compute’s terminal (AML Studio → the compute → Terminal, where you’re azureuser), point install_offline_kernel.py at the right env and run it. The full script is in the &lt;STRONG&gt;Appendix&lt;/STRONG&gt; at the end of this post.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 96.6667%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;# Constants at the top of install_offline_kernel.py:&lt;/P&gt;
&lt;P&gt;STORAGE_ACCOUNT = "&amp;lt;your-account&amp;gt;"&lt;/P&gt;
&lt;P&gt;CONTAINER&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = "data"&lt;/P&gt;
&lt;P&gt;BLOB_PREFIX&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = "offline-kernels"&lt;/P&gt;
&lt;P&gt;ENV_NAME&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; = "aml-py310"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # aml-py311 / py312 / py313 / py314&lt;/P&gt;
&lt;P&gt;DISPLAY_NAME&amp;nbsp;&amp;nbsp;&amp;nbsp; = "Python 3.10 (AML Custom)"&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;# Only for a user-assigned MI, so IMDS knows which identity to use:&lt;/P&gt;
&lt;P&gt;export AZURE_CLIENT_ID="&amp;lt;uami-client-id&amp;gt;"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;python3 install_offline_kernel.py&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;What the script does:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt;Bootstraps the SDK &lt;/STRONG&gt;— installs azure-identity + azure-storage-blob into the user site (~5 MB, one-time). It also supports a local tarball or a SAS URL, so it works with zero Azure auth if you pre-stage the file.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Authenticates &lt;/STRONG&gt;via DefaultAzureCredential — picks up the compute’s managed identity from IMDS.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Downloads &lt;/STRONG&gt;offline-kernels/aml-py310.tar.gz over the private endpoint.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Extracts &lt;/STRONG&gt;into /anaconda/envs/aml-py310 (sudo only if the path isn’t user-writable).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Runs conda-unpack &lt;/STRONG&gt;— rewrites the embedded absolute paths so the env works in its new home.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Preflight-checks &lt;/STRONG&gt;that the env can import ipykernel, and aborts with an exact rebuild command if not.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Registers the kernel &lt;/STRONG&gt;as “Python 3.10 (AML Custom)” for azureuser. Idempotent — it skips the unpack if the env already exists.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;STRONG&gt;Force a clean rebuild &lt;/STRONG&gt;after re-uploading a new tarball:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="width: 96.9444%; border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;sudo rm -rf /anaconda/envs/aml-py310&lt;/P&gt;
&lt;P&gt;rm -rf ~/.local/share/jupyter/kernels/aml-py310&lt;/P&gt;
&lt;P&gt;python3 install_offline_kernel.py&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 100.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;STRONG&gt;Verify: &lt;/STRONG&gt;in AML Studio open a notebook → kernel picker → select “Python 3.10 (AML Custom)” and run import sys; print(sys.version). On 3.12+, reach for the v2 SDK: from azure.ai.ml import MLClient.&lt;/P&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245400"&gt;&lt;/A&gt;8. When it doesn’t work&lt;/H1&gt;
&lt;P&gt;The short list I check first, in order of how often each one is the culprit:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table style="width: 1045px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Symptom&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Cause&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Fix&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Exec format error: …/bin/python&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Tarball built on the wrong arch/OS (ARM64 or macOS).&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Rebuild on Linux x86_64 (Section 3), re-upload, retry.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;ERROR: … cannot import ipykernel&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Env packed without ipykernel.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Recreate the env WITH ipykernel, repack, re-upload, clean-rebuild.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;DefaultAzureCredential failed …&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;No MI on the compute, or MI lacks the data role.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Attach an MI to the &lt;STRONG&gt;compute&lt;/STRONG&gt; (not the workspace) + Storage Blob Data Reader.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;HTTP 403 from blob&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;MI lacks the data-plane role on this account/container.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Add Storage Blob Data Reader on the same account you uploaded to.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;HTTP 404 from blob&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Wrong account/container/blob path in the script.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Re-check the constants against the actual blob path in the Portal.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Multiple identities from IMDS&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;User-assigned MI; the SDK can’t guess which one.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;export AZURE_CLIENT_ID="&amp;lt;uami-client-id&amp;gt;" first.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;STRONG&gt;⚠️&amp;nbsp; Gotcha&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;The single most common face-plant &lt;/STRONG&gt;is the workspace-vs-compute identity mix-up. Granting a role to the AML &lt;EM&gt;workspace&lt;/EM&gt; identity does nothing for IMDS calls coming from the compute. The managed identity must be assigned to the &lt;STRONG&gt;compute instance itself&lt;/STRONG&gt;. Check that before you check anything else.&lt;/P&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245401"&gt;&lt;/A&gt;9. Why this actually works with no internet&lt;/H1&gt;
&lt;P&gt;Four details make the whole thing hold together. They’re also exactly what a security reviewer will ask about, so it helps to have the answers ready.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;IMDS is not the internet. &lt;/STRONG&gt;Managed-identity auth works with zero outbound access because IMDS lives at 169.254.169.254 — a link-local address served by the Azure host, not a public endpoint. The blob download then rides the Storage account’s private endpoint inside the VNet. Nothing touches the public internet.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;No Anaconda ToS prompt on the secure side. &lt;/STRONG&gt;You accepted the ToS on the build box. The compute only ever sees a plain tarball, so no conda channel is ever contacted and the ToS gate never appears.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Workspace MI ≠ compute MI. &lt;/STRONG&gt;RBAC granted to the &lt;EM&gt;workspace&lt;/EM&gt; identity does not authorize IMDS calls from the compute. The identity must live on the &lt;STRONG&gt;compute instance&lt;/STRONG&gt;. This is the top cause of a mysterious 403 — worth repeating.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Kernels persist across stop/start. &lt;/STRONG&gt;The kernelspec and env live on the persistent user disk (~/.local/share/jupyter/kernels/ and /anaconda/envs/). A stop/start keeps them; only &lt;STRONG&gt;deleting&lt;/STRONG&gt; the compute wipes them — at which point you just re-run the installer.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245402"&gt;&lt;/A&gt;10. conda-pack gotchas on the build box&lt;/H1&gt;
&lt;P&gt;The build box has its own small collection of traps. Sharing the scars so you can skip them:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Trap&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;What you see&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;The fix&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;python -m conda_pack …&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;package cannot be directly executed&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;The module has no __main__. Use the console script conda-pack … or the conda pack subcommand.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;conda pack&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;invalid choice: 'pack'&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;conda-pack isn’t installed in that conda. conda install -n base -c conda-forge conda-pack -y.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Packing a mixed conda+pip env&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Files managed by conda … deleted/overwritten&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Add --ignore-missing-files; add --force if the .tar.gz exists.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;conda-pack script missing&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;conda-pack: command not found&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;python -m pip install conda-pack, then hash -r, then conda-pack -p &amp;lt;env-prefix&amp;gt; -o out.tar.gz.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245403"&gt;&lt;/A&gt;Wrapping up&lt;/H1&gt;
&lt;P&gt;You don’t need to punch a hole in the firewall to give a locked-down Azure ML compute a rich, multi-version Python environment. You need to &lt;STRONG&gt;do all the messy dependency resolution outside&lt;/STRONG&gt;, where you can see it, freeze the result with conda-pack, ship one tarball over a private endpoint, and register it as a kernel on the other side. Build once, pack once, upload once, install once.&lt;/P&gt;
&lt;P&gt;The parts that bite are all predictable once you know they’re there: the arch mismatch, the azureml version ceiling, the data-plane 403, and the workspace-vs-compute identity. Now you know, so they should cost you minutes instead of an afternoon.&lt;/P&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245404"&gt;&lt;/A&gt;Appendix — install_offline_kernel.py&lt;/H1&gt;
&lt;P&gt;This is the installer referenced in Section 7 — the only script that runs on the air-gapped compute. It fetches the tarball three ways in priority order (a local file, a SAS URL, or blob download via the compute’s managed identity), unpacks it, runs conda-unpack, preflight-checks ipykernel, and registers the kernel. Set the constants at the top, copy it onto the compute, and run python3 install_offline_kernel.py.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;📌&amp;nbsp; Note&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Replace the placeholders. &lt;/STRONG&gt;The storage account, subscription id, and CLI user below are placeholders — swap in your own values before running. Everything else is ready to use as-is.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table style="width: 1015px; height: 9131px;"&gt;&lt;tbody&gt;&lt;tr style="height: 10px;"&gt;&lt;td style="height: 10px;"&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;tr style="height: 9121px;"&gt;&lt;td style="height: 9121px;"&gt;
&lt;P&gt;#!/usr/bin/env python3&lt;/P&gt;
&lt;P&gt;"""&lt;/P&gt;
&lt;P&gt;Install an offline conda-packed Python kernel on an AML compute instance.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Gets a conda-pack tarball (in priority order):&lt;/P&gt;
&lt;P&gt;&amp;nbsp; 1. a local tarball on this box (LOCAL_TARBALL, or ~/aml-offline/&amp;lt;ENV&amp;gt;.tar.gz,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; or ./&amp;lt;ENV&amp;gt;.tar.gz) - no Azure auth needed,&lt;/P&gt;
&lt;P&gt;&amp;nbsp; 2. a SAS URL (BLOB_SAS_URL) - no RBAC data role needed,&lt;/P&gt;
&lt;P&gt;&amp;nbsp; 3. Azure Blob via DefaultAzureCredential (compute managed identity).&lt;/P&gt;
&lt;P&gt;Then unpacks it and registers it as a Jupyter kernel for the current user.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Prerequisites (only for option 3 - blob download via managed identity):&lt;/P&gt;
&lt;P&gt;&amp;nbsp; - A managed identity (system- or user-assigned) attached to the compute instance.&lt;/P&gt;
&lt;P&gt;&amp;nbsp; - That identity has "Storage Blob Data Reader" on the storage account (DATA-plane&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; role; control-plane Contributor/Owner is NOT sufficient).&lt;/P&gt;
&lt;P&gt;&amp;nbsp; - For user-assigned MI, set env var AZURE_CLIENT_ID to its client id.&lt;/P&gt;
&lt;P&gt;"""&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;from __future__ import annotations&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;import os&lt;/P&gt;
&lt;P&gt;import subprocess&lt;/P&gt;
&lt;P&gt;import sys&lt;/P&gt;
&lt;P&gt;from pathlib import Path&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;# ---- Configuration ---------------------------------------------------------&lt;/P&gt;
&lt;P&gt;STORAGE_ACCOUNT = "&amp;lt;your-account&amp;gt;"&lt;/P&gt;
&lt;P&gt;CONTAINER = "data"&lt;/P&gt;
&lt;P&gt;BLOB_PREFIX = "offline-kernels"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;ENV_NAME = "aml-py310"&lt;/P&gt;
&lt;P&gt;DISPLAY_NAME = "Python 3.10 (AML Custom)"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;# If the tarball is already on this machine (e.g. you built it here), the script&lt;/P&gt;
&lt;P&gt;# uses it and skips the blob download entirely - no Azure auth / RBAC needed.&lt;/P&gt;
&lt;P&gt;# Leave "" to auto-search ~/aml-offline/&amp;lt;ENV_NAME&amp;gt;.tar.gz and the current dir,&lt;/P&gt;
&lt;P&gt;# or set an explicit path.&lt;/P&gt;
&lt;P&gt;LOCAL_TARBALL = ""&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;# Optional full SAS URL to the blob, e.g.&lt;/P&gt;
&lt;P&gt;#&amp;nbsp;&amp;nbsp; https://&amp;lt;acct&amp;gt;.blob.core.windows.net/&amp;lt;cont&amp;gt;/&amp;lt;prefix&amp;gt;/&amp;lt;env&amp;gt;.tar.gz?sv=...&lt;/P&gt;
&lt;P&gt;# If set, it is used instead of DefaultAzureCredential and bypasses the&lt;/P&gt;
&lt;P&gt;# "Storage Blob Data Reader" RBAC requirement. Leave "" for managed-identity auth.&lt;/P&gt;
&lt;P&gt;BLOB_SAS_URL = ""&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;# Azure auth for the blob download (only used if no local tarball and no SAS URL).&lt;/P&gt;
&lt;P&gt;#&amp;nbsp;&amp;nbsp; CREDENTIAL_MODE = "cli"&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -&amp;gt; use your signed-in Azure CLI user; first run:&lt;/P&gt;
&lt;P&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; az login&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # device-code on a compute&lt;/P&gt;
&lt;P&gt;#&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; az account set --subscription $SUBSCRIPTION_ID&lt;/P&gt;
&lt;P&gt;#&amp;nbsp;&amp;nbsp; CREDENTIAL_MODE = "managed" -&amp;gt; use the compute's managed identity&lt;/P&gt;
&lt;P&gt;#&amp;nbsp;&amp;nbsp; CREDENTIAL_MODE = "default" -&amp;gt; DefaultAzureCredential chain (MI, then CLI, ...)&lt;/P&gt;
&lt;P&gt;SUBSCRIPTION_ID = "&amp;lt;your-subscription-id&amp;gt;"&lt;/P&gt;
&lt;P&gt;AZURE_USERNAME = "&amp;lt;your-cli-user&amp;gt;"&amp;nbsp;&amp;nbsp; # expected CLI user (informational)&lt;/P&gt;
&lt;P&gt;CREDENTIAL_MODE = "cli"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;TARGET_DIR = Path(f"/anaconda/envs/{ENV_NAME}")&lt;/P&gt;
&lt;P&gt;TARBALL_PATH = Path(f"/tmp/{ENV_NAME}.tar.gz")&lt;/P&gt;
&lt;P&gt;# ---------------------------------------------------------------------------&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;def run(cmd: list[str], **kwargs) -&amp;gt; None:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Run a subprocess command, streaming output and raising on failure."""&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"+ {' '.join(cmd)}", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; subprocess.run(cmd, check=True, **kwargs)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;def ensure_sdk_packages() -&amp;gt; None:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Install azure-identity and azure-storage-blob into the current interpreter."""&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; import azure.identity&amp;nbsp; # noqa: F401&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; import azure.storage.blob&amp;nbsp; # noqa: F401&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; except ImportError:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pass&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print("Installing azure-identity and azure-storage-blob ...", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; run([&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sys.executable, "-m", "pip", "install", "--quiet", "--user",&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "azure-identity", "azure-storage-blob",&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ])&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;def find_local_tarball() -&amp;gt; Path | None:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Return an existing local tarball to use instead of downloading, or None."""&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; candidates = []&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if LOCAL_TARBALL:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; candidates.append(Path(LOCAL_TARBALL).expanduser())&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; candidates.append(Path.home() / "aml-offline" / f"{ENV_NAME}.tar.gz")&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; candidates.append(Path.cwd() / f"{ENV_NAME}.tar.gz")&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; for c in candidates:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if c.is_file():&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return c&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return None&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;def get_credential():&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Return an Azure credential according to CREDENTIAL_MODE."""&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if CREDENTIAL_MODE == "cli":&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from azure.identity import AzureCliCredential&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Uses the user signed in via `az login` (e.g. &amp;lt;your-cli-user&amp;gt;).&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Using Azure CLI credential (expected user: {AZURE_USERNAME}).", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return AzureCliCredential()&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if CREDENTIAL_MODE == "managed":&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; from azure.identity import ManagedIdentityCredential&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; client_id = os.environ.get("AZURE_CLIENT_ID")&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print("Using the compute's managed identity.", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ManagedIdentityCredential(client_id=client_id) if client_id else ManagedIdentityCredential()&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from azure.identity import DefaultAzureCredential&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print("Using DefaultAzureCredential chain.", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return DefaultAzureCredential()&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;def download_blob(env_name: str, dest: Path) -&amp;gt; None:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Download the conda-pack tarball via SAS URL or an Azure credential."""&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; from azure.storage.blob import BlobClient&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dest.parent.mkdir(parents=True, exist_ok=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if BLOB_SAS_URL:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Downloading via SAS URL -&amp;gt; {dest}", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; client = BlobClient.from_blob_url(BLOB_SAS_URL)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ensure_sdk_packages()&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; credential = get_credential()&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; blob_name = f"{BLOB_PREFIX}/{env_name}.tar.gz"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; url = f"https://{STORAGE_ACCOUNT}.blob.core.windows.net/{CONTAINER}/{blob_name}"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Downloading {url} -&amp;gt; {dest}", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; client = BlobClient.from_blob_url(url, credential=credential)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; with open(dest, "wb") as f:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream = client.download_blob(max_concurrency=4)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; stream.readinto(f)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; except Exception as exc:&amp;nbsp; # noqa: BLE001&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; msg = str(exc)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if "AuthorizationPermissionMismatch" in msg or "not authorized" in msg:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sys.exit(&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "ERROR: 403 AuthorizationPermissionMismatch downloading the tarball.\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"The credential in use (CREDENTIAL_MODE='{CREDENTIAL_MODE}') lacks the\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"DATA-plane role 'Storage Blob Data Reader' on storage account\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"'{STORAGE_ACCOUNT}'. (azcopy login / control-plane Contributor do NOT grant this.)\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Fix ONE of:\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"&amp;nbsp; 1. Grant that role to the principal (e.g. {AZURE_USERNAME} for CLI mode,\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; or the compute's managed identity for managed mode), or\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "&amp;nbsp; 2. Set BLOB_SAS_URL to a SAS link (no RBAC needed), or\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"&amp;nbsp; 3. Put the tarball at ~/aml-offline/{env_name}.tar.gz to skip download.\n\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"Original error:\n{msg}"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; raise&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Downloaded {dest.stat().st_size:,} bytes", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;def ensure_target_dir(target: Path) -&amp;gt; None:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; """Create target dir, using sudo if necessary, and chown to current user."""&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if target.exists():&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; user = os.environ.get("USER", "azureuser")&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; try:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; target.mkdir(parents=True, exist_ok=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; except PermissionError:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Need sudo to create {target}", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; run(["sudo", "mkdir", "-p", str(target)])&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; run(["sudo", "chown", "-R", f"{user}:{user}", str(target)])&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;def install_kernel() -&amp;gt; None:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (TARGET_DIR / "bin").is_dir():&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Env {ENV_NAME} already exists at {TARGET_DIR}, skipping unpack.", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; local = find_local_tarball()&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if local is not None:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Using local tarball {local}; skipping blob download.", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; src = local&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; downloaded = False&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; download_blob(ENV_NAME, TARBALL_PATH)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; src = TARBALL_PATH&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; downloaded = True&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ensure_target_dir(TARGET_DIR)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Extracting {src} -&amp;gt; {TARGET_DIR}", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; run(["tar", "-xzf", str(src), "-C", str(TARGET_DIR)])&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print("Running conda-unpack ...", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; run([str(TARGET_DIR / "bin" / "conda-unpack")])&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Only remove the temp download, never a user-provided local tarball.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if downloaded:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TARBALL_PATH.unlink()&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; except FileNotFoundError:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pass&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Registering Jupyter kernel '{ENV_NAME}' ...", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; env_python = str(TARGET_DIR / "bin" / "python")&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Sanity-check: env must actually contain ipykernel, otherwise the tarball&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # was built without it and needs to be rebuilt on the Linux build box.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; check = subprocess.run(&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [env_python, "-c", "import ipykernel, sys; print(ipykernel.__version__)"],&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; capture_output=True, text=True,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if check.returncode != 0:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sys.exit(&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"ERROR: {env_python} cannot import ipykernel.\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"The conda-pack tarball was built without ipykernel. Rebuild on the Linux box with:\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"&amp;nbsp; conda create -n {ENV_NAME} -c conda-forge python=&amp;lt;major.minor&amp;gt; ipykernel pip setuptools wheel -y\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"&amp;nbsp; conda-pack -n {ENV_NAME} -o {ENV_NAME}.tar.gz --ignore-missing-files\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"then re-upload and clean up: sudo rm -rf {TARGET_DIR}\n\n"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; f"stderr from check:\n{check.stderr}"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"ipykernel {check.stdout.strip()} found in env.", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; run([&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; env_python, "-m", "ipykernel", "install",&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "--user",&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "--name", ENV_NAME,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "--display-name", DISPLAY_NAME,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ])&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;def main() -&amp;gt; int:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"Starting offline {ENV_NAME} kernel setup on AML compute instance ...", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; install_kernel()&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; kernels_dir = Path.home() / ".local" / "share" / "jupyter" / "kernels"&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if kernels_dir.is_dir():&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"\nInstalled kernels in {kernels_dir}:", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for k in sorted(kernels_dir.iterdir()):&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; print(f"&amp;nbsp; - {k.name}")&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; print("\nOffline kernel setup completed.", flush=True)&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;if __name__ == "__main__":&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sys.exit(main())&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;H1&gt;&lt;A class="lia-anchor" target="_blank" name="_Toc234245405"&gt;&lt;/A&gt;References&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://conda.github.io/conda-pack/" target="_blank" rel="noopener"&gt;conda-pack documentation — packaging conda envs into relocatable tarballs.&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/machine-learning/how-to-identity-based-service-authentication" target="_blank" rel="noopener"&gt;Azure ML: identity-based access for compute — attaching a managed identity to the compute instance.&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/storage/blobs/authorize-access-azure-active-directory" target="_blank" rel="noopener"&gt;Authorize access to blobs with Microsoft Entra ID — why data-plane roles, not Owner, grant blob I/O.&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/azure/virtual-machines/instance-metadata-service" target="_blank" rel="noopener"&gt;Azure Instance Metadata Service (IMDS) — the link-local endpoint that makes MI auth work offline.&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/python/api/overview/azure/ai-ml-readme" target="_blank" rel="noopener"&gt;azure-ai-ml (SDK v2) — the supported SDK on Python 3.12–3.14.&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A style="font-style: normal; font-weight: 400; background-color: rgb(255, 255, 255);" href="https://learn.microsoft.com/azure/machine-learning/v1/concept-v2" target="_blank" rel="noopener"&gt;Azure ML CLI/SDK v1 deprecation — background on the v1 version ceiling.&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Tue, 07 Jul 2026 18:28:36 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/kernels-behind-the-wall-custom-python-3-10-3-14-jupyter-kernels/ba-p/4534118</guid>
      <dc:creator>Sabyasachi-Samaddar</dc:creator>
      <dc:date>2026-07-07T18:28:36Z</dc:date>
    </item>
    <item>
      <title>From Downtime Risk to Enterprise Resilience: SAP NetWeaver Java HA Journey with SUSE</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/from-downtime-risk-to-enterprise-resilience-sap-netweaver-java/ba-p/4534580</link>
      <description>&lt;H5&gt;&lt;STRONG&gt;Introduction: &lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;For years, the IT team at a global manufacturing company had relied on SAP NetWeaver 7.50 Java to support critical business processes. The environment handled everything from employee self-service applications to business integrations across multiple regions. While the infrastructure was stable, one concern remained constant: SAP Central Services instance represented a potential single point of failure.&lt;/P&gt;
&lt;P&gt;Every maintenance window required careful planning. Any unexpected server outage could disrupt business operations, impact users worldwide, and create pressure on support teams to restore services as quickly as possible.&lt;/P&gt;
&lt;H5&gt;&lt;STRONG&gt;Challenge: &lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;The SAP landscape was growing, and business stakeholders expected continuous availability. Traditional backup and recovery procedures could restore services, but you could not eliminate the downtime associated with infrastructure failures.&lt;/P&gt;
&lt;P&gt;The architecture team identified SAP Java Central Services as a critical component that needed enhanced protection.&lt;/P&gt;
&lt;P&gt;The objective was simple:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Eliminate single points of failure.&lt;/LI&gt;
&lt;LI&gt;Automate failover during infrastructure issues.&lt;/LI&gt;
&lt;LI&gt;Minimize business disruption.&lt;/LI&gt;
&lt;LI&gt;Improve operational confidence.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5&gt;&lt;STRONG&gt;Solution: &lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;You adopted a SUSE High Availability solution built around clustered architecture. Multiple nodes were configured to work together, continuously monitoring the health of SAP services and infrastructure resources.&lt;/P&gt;
&lt;P&gt;Using SUSE HA, the environment could automatically detect failures and transfer workloads to a healthy node whenever required. Instead of relying on manual intervention, recovery became a coordinated and automated process.&lt;/P&gt;
&lt;P&gt;The architecture provided:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Continuous monitoring of critical SAP components.&lt;/LI&gt;
&lt;LI&gt;Automated failover capabilities.&lt;/LI&gt;
&lt;LI&gt;Resource management through cluster policies.&lt;/LI&gt;
&lt;LI&gt;Improved service continuity during unplanned outages.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5&gt;&lt;STRONG&gt;Implementation: &lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;Deployment required close collaboration between SAP administrators, Linux engineers, and infrastructure architects. You carefully validated cluster configurations, tested failover scenarios, and documented operational procedures.&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;Several disaster recovery simulations were conducted:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Server shutdown tests.&lt;/LI&gt;
&lt;LI&gt;Network interruption scenarios.&lt;/LI&gt;
&lt;LI&gt;Service failure simulations.&lt;/LI&gt;
&lt;LI&gt;Planned maintenance activities.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Each test demonstrated how the cluster could maintain application availability while reducing recovery times.&lt;/P&gt;
&lt;H5&gt;&lt;STRONG&gt;Results: &lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;As the solution moved into production, confidence across the organization increased significantly.&lt;STRONG&gt; &lt;/STRONG&gt;Business users experienced uninterrupted access to critical SAP services, while operations teams gained greater visibility into system health and cluster status.&lt;/P&gt;
&lt;P&gt;The organization realized several key benefits:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Higher platform availability.&lt;/LI&gt;
&lt;LI&gt;Faster recovery from failures.&lt;/LI&gt;
&lt;LI&gt;Reduced operational risk.&lt;/LI&gt;
&lt;LI&gt;Improved maintenance flexibility.&lt;/LI&gt;
&lt;LI&gt;Enhanced business continuity.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5&gt;&lt;STRONG&gt;Lessons Learned:&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;The project reinforced an important principle for enterprise SAP environments:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;High availability is not simply about recovering from failure, it's about designing systems that continue operating when failures occur.&lt;/LI&gt;
&lt;LI&gt;By combining SAP NetWeaver 7.50 Java Central Services with SUSE High Availability technology, the company transformed a potential business risk into a resilient and reliable platform capable of supporting mission-critical operations around the clock.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H6&gt;&lt;STRONG&gt;Key Benefits of SUSE HA for SAP NetWeaver Java Central Services&lt;/STRONG&gt;&lt;/H6&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;STRONG&gt; Elimination of Single Points of Failure&lt;/STRONG&gt;&lt;BR /&gt;SAP NetWeaver Java Central Services (SCS) is a critical component of the SAP Java stack. SUSE High Availability (HA) protects the SCS instance by clustering resources across multiple nodes, reducing the risk of service interruption caused by server failures.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Automated Failover and Faster Recovery&lt;/STRONG&gt;&lt;BR /&gt;When a node or service fails, SUSE Pacemaker automatically detects the issue and transfers SAP services to a healthy node. This minimizes manual intervention and significantly decreases recovery time.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Increased Business Continuity&lt;/STRONG&gt;&lt;BR /&gt;By maintaining service availability during infrastructure outages, SUSE HA helps ensure that business-critical SAP applications remain accessible to users, reducing operational disruptions.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Reduced Downtime During Planned Maintenance&lt;/STRONG&gt;&lt;BR /&gt;Organizations can perform maintenance activities on cluster nodes with minimal impact to SAP services. Workloads can be shifted between nodes, helping ensure uninterrupted operations.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Continuous Monitoring and Health Checks&lt;/STRONG&gt;&lt;BR /&gt;SUSE HA continuously monitors cluster resources, SAP processes, virtual IP addresses, and storage components. Early detection of issues helps improve overall system reliability.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Improved Operational Efficiency&lt;/STRONG&gt;&lt;BR /&gt;Automated resource management reduces the need for manual failover procedures and allows administrators to focus on proactive platform management rather than reactive troubleshooting.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Enhanced System Resilience&lt;/STRONG&gt;&lt;BR /&gt;The cluster architecture is designed to withstand hardware, operating system, network, and service failures, creating a more robust SAP landscape.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Better Disaster Recovery Readiness&lt;/STRONG&gt;&lt;BR /&gt;Regular failover testing and cluster validation capabilities help organizations verify their recovery procedures and improve preparedness for unexpected outages.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt; Enterprise-Grade Reliability for Mission-Critical Workloads&lt;/STRONG&gt;&lt;BR /&gt;For organizations running critical SAP business processes, SUSE HA provides the foundation for achieving high availability and meeting stringent uptime requirements.&lt;/LI&gt;
&lt;/OL&gt;
&lt;H5&gt;&lt;STRONG&gt;Conclusion:&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;In modern SAP landscapes, resilience is a business requirement rather than a technical luxury. SUSE High Availability provides organizations with a robust foundation for protecting SAP NetWeaver Java workloads, reducing downtime, and ensuring that critical business services remain available when they are needed most. SUSE High Availability for SAP NetWeaver 7.50 Java Central Services enables organizations to build a resilient SAP platform by eliminating single points of failure, automating failover, and minimizing downtime. Through continuous monitoring, intelligent resource management, and cluster-based protection, businesses can improve service continuity, simplify operations, and ensure that mission-critical SAP workloads remain available when they are needed most.&lt;/P&gt;
&lt;H5&gt;&lt;STRONG&gt;Reference links:&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://support.scc.suse.com/s/kb/SUSE-HA-for-SAP-NetWeaver-7-50-Java-central-services?language=en_US" target="_blank"&gt;&lt;STRONG&gt;SUSE HA for SAP NetWeaver 7.50 Java central services | SUSE | Support Center&lt;/STRONG&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;For the main cluster configuration and the automatic mounting of shared file systems during startup using entries defined in /etc/fstab, see the "High Availability Cluster with Simple Mount" section at the link below:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.com%2Fv3%2F__https%3A%2Fdocumentation.suse.com%2Fsbp%2Fsap-15%2Fhtml%2FSAP-S4HA10-setupguide-simplemount-sle15%2Findex.html__%3B!!DjNdo6avjEs!qMWAvFd-fK_1YjELAKxSCedpZlEfFYzK2Z9mtoQsUDYWGvHS4_kHVnuNmL9dYMzmZdIv_jJmQ9zouTSTzvpjRQ%24&amp;amp;data=05%7C02%7Cakarnam%40microsoft.com%7C0fbc662a01d14ae9e32508ded0a8a831%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C639177620013201631%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&amp;amp;sdata=dD2r9Nwhh2eF2PsRKsfSwNBenmeDIicq1OEpCcoWUEI%3D&amp;amp;reserved=0" target="_blank"&gt;&lt;STRONG&gt;https://documentation.suse.com/sbp/sap-15/html/SAP-S4HA10-setupguide-simplemount-sle15/index.html&lt;/STRONG&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Refer to the resource groups outlined in the TID, together with the necessary SAP profile file modifications and location constraints documented in the "SAP NetWeaver Enqueue Replication 1 High Availability Cluster – SAP NetWeaver 7.40 and 7.50" guide linked below. These configurations are applicable since the Java SCS instance supports Enqueue Replication 1 (ENSA1) only:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Furldefense.com%2Fv3%2F__https%3A%2Fdocumentation.suse.com%2Fsbp%2Fsap-15%2Fhtml%2FSAP-nw740-sle15-setupguide%2Findex.html__%3B!!DjNdo6avjEs!qMWAvFd-fK_1YjELAKxSCedpZlEfFYzK2Z9mtoQsUDYWGvHS4_kHVnuNmL9dYMzmZdIv_jJmQ9zouTSe1CS0ZA%24&amp;amp;data=05%7C02%7Cakarnam%40microsoft.com%7C0fbc662a01d14ae9e32508ded0a8a831%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C639177620013211990%7CUnknown%7CTWFpbGZsb3d8eyJFbXB0eU1hcGkiOnRydWUsIlYiOiIwLjAuMDAwMCIsIlAiOiJXaW4zMiIsIkFOIjoiTWFpbCIsIldUIjoyfQ%3D%3D%7C0%7C%7C%7C&amp;amp;sdata=PUcTq1PehDsYHS7arEwSOxHwf4mKKNoUFoCCMbajD%2FI%3D&amp;amp;reserved=0" target="_blank"&gt;&lt;STRONG&gt;https://documentation.suse.com/sbp/sap-15/html/SAP-nw740-sle15-setupguide/index.html&lt;/STRONG&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 07 Jul 2026 17:35:51 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/from-downtime-risk-to-enterprise-resilience-sap-netweaver-java/ba-p/4534580</guid>
      <dc:creator>AnuradhaKarnam</dc:creator>
      <dc:date>2026-07-07T17:35:51Z</dc:date>
    </item>
    <item>
      <title>Azure OpenAI Architecture: The Decisions That Actually Matter (Part 3)</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/azure-openai-architecture-the-decisions-that-actually-matter/ba-p/4528901</link>
      <description>&lt;H1&gt;Introduction&lt;/H1&gt;
&lt;P&gt;Part 1 of this series tackled the architectural decisions that shape any Azure OpenAI / Microsoft Foundry Models workload — capacity model, deployment scope, governance layer, grounding strategy, and quota engineering. Part 2 turned those decisions into a Well-Architected Framework discipline. Part 3 looks at the part that makes GenAI architecture genuinely different from a traditional service: the platform itself never stops moving.&lt;/P&gt;
&lt;P&gt;Models are released, promoted to GA, moved to Legacy, deprecated, and eventually retired. New regions come online; certain features (such as Priority Processing) light up only on specific model versions and deployment scopes. Fine-tuned models inherit the lifecycle of their base. Performance characteristics shift between releases. Reliability in this world is not just uptime — it is the ability to absorb continuous change without disrupting production.&lt;/P&gt;
&lt;P&gt;That discipline is GenAIOps: the people, processes, and tooling that turn model upgrades from emergency events into routine operations. Part 2 already covers the core lifecycle mechanics and upgrade policy trade-offs through a Well-Architected lens. Part 3 stays focused on the operational and architectural practices that make change safe: evaluation of pipelines, observability, routing patterns, prompt governance, and abstraction. Where details are time-sensitive — stage thresholds, SLA windows, regional rollout delays, capacity tier eligibility — they are flagged with "At the time of writing". Always confirm current behavior against Microsoft Learn before committing to a design.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Who is this series for?&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Cloud and Solution Architects&lt;/LI&gt;
&lt;LI&gt;Platform and product owners&lt;/LI&gt;
&lt;LI&gt;Senior developers responsible for operating Azure OpenAI workloads in production&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;What you’ll learn in Part 3:&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;How to build an evaluation pipeline that promotes model upgrades the way CI/CD promotes code.&lt;/LI&gt;
&lt;LI&gt;How to instrument full-stack observability so regressions surface early (latency, errors, token trends, quality drift).&lt;/LI&gt;
&lt;LI&gt;How the Model Router pattern, canary releases, and tier-aware fallbacks turn model change into a configuration concern.&lt;/LI&gt;
&lt;LI&gt;How to govern prompts as production artifacts with versioning, feature-flagged rollouts, and regression testing.&lt;/LI&gt;
&lt;LI&gt;How to manage lifecycle-dependent assets (fine-tuned models) and regional rollout realities without firefighting — plus a GenAIOps Decision Matrix you can reuse as a checklist.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;EM&gt;We’ve also included a summary decision matrix at the end of this post for quick reference.&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;1. Model lifecycle (recap)&lt;/H1&gt;
&lt;P&gt;Azure OpenAI/Microsoft Foundry models are living dependencies: new versions are released, promoted from Preview to GA, then eventually move through deprecation toward retirement. To avoid surprises, treat every deployed model version as having an expiration date and design so you can swap versions without rewriting application code. In general, use the Standard deployment auto-upgrade mode that preserves stability but guarantees continuity at retirement, and plan to deliberate blue/green migrations for dedicated (provisioned) capacity where auto-upgrade is not available. For the deeper mechanics (upgrade modes, retirement behavior, and migration playbooks), refer to Part 2’s Reliability section; the rest of this article focuses on the GenAIOps practices that make those upgrades routine.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Figure 1 — Models lifecycle&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H1&gt;2. GenAIOps: Evaluating Before Promoting&lt;/H1&gt;
&lt;P&gt;Upgrading a model should not be a manual, subjective exercise. Azure AI Foundry provides evaluation capabilities that, combined with a regression prompt suite, turn model upgrades into measurable, repeatable decisions:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Side-by-side prompt comparisons across model versions.&lt;/LI&gt;
&lt;LI&gt;Automated quality scoring (relevance, coherence, groundedness, safety, and fluency).&lt;/LI&gt;
&lt;LI&gt;Structured-output validation (JSON conformance, schema validation).&lt;/LI&gt;
&lt;LI&gt;Batch testing across comprehensive prompt libraries representative of real production traffic.&lt;/LI&gt;
&lt;LI&gt;Custom evaluation metrics tailored to your domain.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Architectural best practice:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Maintain a curated regression prompt suite that mirrors real production traffic &lt;/STRONG&gt;— including the long tail.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Run evaluation pipelines against candidate models&lt;/STRONG&gt; before any production cut-over.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Integrate evaluation into CI/CD &lt;/STRONG&gt;using Azure DevOps, GitHub Actions, or similar automation.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Define quality gates that must pass before promotion&lt;/STRONG&gt; (e.g., groundedness ≥ a target threshold, p95 latency under a target budget). Pick numbers that fit your workload, not the article.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Model promotion should require passing the evaluation gates &lt;/STRONG&gt;the same way application code requires passing unit tests. Without automated evaluation, model upgrades become high-risk, low-visibility events that teams avoid until forced by retirement deadlines — the exact pattern that keeps lifecycle work in the "emergency" column instead of the "scheduled" column.&lt;/P&gt;
&lt;P&gt;Example evaluation workflow:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Trigger — a new model version reaches GA, or your migration playbook hits the R-90 step.&lt;/LI&gt;
&lt;LI&gt;Deploy — the candidate model goes to a staging deployment.&lt;/LI&gt;
&lt;LI&gt;Regress — the prompt suite (typically several hundred to several thousand prompts) is run against the candidate.&lt;/LI&gt;
&lt;LI&gt;Compare — the candidate's outputs are scored against the current production model.&lt;/LI&gt;
&lt;LI&gt;Inspect — humans review flagged differences; metrics, latency distributions, and cost-per-request go on the dashboard.&lt;/LI&gt;
&lt;LI&gt;Gate — an approval step (manual or automated) decides whether the candidate proceeds to blue/green production deployment.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Figure 2 — Evaluation Pipeline&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H1&gt;3. Observability: Full-Stack or It Didn't Happen&lt;/H1&gt;
&lt;P&gt;GenAIOps is more than one-time evaluation. Once a candidate's model has been promoted, you need continuous, end-to-end observability across the request path — not just at the model boundary. Without it, you are operating blind during model transitions.&lt;/P&gt;
&lt;P&gt;At a minimum, instrument:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Prompt processing time&lt;/STRONG&gt; (gateway through model invocation).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Model inference latency&lt;/STRONG&gt;, expressed as p50, p95, and p99 — averages hide the experience of the slowest 5% of users.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Token consumption &lt;/STRONG&gt;(prompt tokens, completion tokens, total) trended over time.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Error rates by class&lt;/STRONG&gt; (429 throttling, 503 service unavailable, 400 validation errors, content-filter rejections).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Model version distribution&lt;/STRONG&gt; — which versions are actually serving traffic right now.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;User-satisfaction signals&lt;/STRONG&gt; (thumbs-up/down, explicit feedback, session abandonment).&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Many performance regressions only surface at scale. A model version that performs well in evaluation against a few hundred prompts may behave differently under production traffic patterns. Plan for that.&lt;/P&gt;
&lt;P&gt;A practical metrics architecture on Azure tends to combine:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Application Insights for end-to-end request tracing across the application and gateway.&lt;/LI&gt;
&lt;LI&gt;Azure Monitor for infrastructure, quota, and PTU utilization of metrics.&lt;/LI&gt;
&lt;LI&gt;Custom telemetry for prompt-level success/failure tracking and quality scoring.&lt;/LI&gt;
&lt;LI&gt;Log Analytics for forensic analysis when a regression is suspected.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Drift in model behavior rarely shows up as a single broken request — it surfaces as a slow shift in tail latency, fallback rate, or user-satisfaction signal. Monitoring that only looks at average will miss it.&lt;/P&gt;
&lt;H1&gt;4. The Model Router Pattern&lt;/H1&gt;
&lt;P&gt;As GenAI systems mature, a static single-model architecture becomes both limiting and expensive. A Model Router introduces dynamic, intelligent model selection in front of one or more model deployments.&lt;/P&gt;
&lt;P&gt;Typical responsibilities of a router:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Send simple queries to a smaller, faster model and complex reasoning to a larger one.&lt;/LI&gt;
&lt;LI&gt;Run canary releases of new model versions with percentage-based rollouts.&lt;/LI&gt;
&lt;LI&gt;A/B test model variants to measure quality, latency, and cost differences.&lt;/LI&gt;
&lt;LI&gt;Route to the right capacity tier — including falling back from Provisioned to Standard during migrations or capacity constraints.&lt;/LI&gt;
&lt;LI&gt;Where the workload also needs lower-variance latency on the Standard side, route latency-critical traffic through Priority Processing on a Global Standard or Data Zone Standard (US) deployment, on a model version that supports it. (At the time of writing, Priority Processing is enabled by setting the service_tier attribute on the request and requires a model version released on or after 2025-12-01 — verify both eligibility constraints on Microsoft Learn before depending on it.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Decision logic can be driven by any combination of:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Query complexity (simple heuristics or a lightweight classifier).&lt;/LI&gt;
&lt;LI&gt;User tier (e.g., free vs premium).&lt;/LI&gt;
&lt;LI&gt;Response-time requirements (interactive vs background).&lt;/LI&gt;
&lt;LI&gt;Cost constraints — pick the cheapest model that meets the quality bar.&lt;/LI&gt;
&lt;LI&gt;Regional model availability and capacity.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Implementation options:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Azure API Management &lt;/STRONG&gt;— built-in routing policies, weighted backends, retry policies.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Azure Front Door&lt;/STRONG&gt; — global routing with health probes.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Custom routing service&lt;/STRONG&gt; — maximum flexibility, more operational overhead.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Semantic Kernel or LangChain &lt;/STRONG&gt;— framework-level routing logic embedded in the application.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Beyond cost and performance, the Model Router pattern decouples the application layer from any single model version. That decoupling is what makes lifecycle management tractable: when a model moves to Legacy, you change a router rule, not application code.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Figure 3 — Model Router Architecture vs Blue/Green Deployment&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp;&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;5. Prompt Lifecycle Governance&lt;/H1&gt;
&lt;P&gt;Prompts are not strings embedded in code. They are production artifacts that influence quality, cost, and safety, and they evolve almost as often as the models behind them. Treat them as first-class assets.&lt;/P&gt;
&lt;H3&gt;Prompt templates&lt;/H3&gt;
&lt;P&gt;Separate stable system instructions from dynamic content (user input and retrieved context). This lets you version, test, and audit each layer independently.&lt;/P&gt;
&lt;H3&gt;Version control&lt;/H3&gt;
&lt;P&gt;Store prompts in Git — full history, code review, branching, and tagging. Treat prompt changes the way you treat code changes: pull request, review, and test before merging.&lt;/P&gt;
&lt;H3&gt;Feature-flagged rollouts&lt;/H3&gt;
&lt;P&gt;Roll out prompt changes gradually using feature flags. Monitor the impact on a subset of users before exposing the change broadly. The same observability stack that watches model upgrades should watch prompt rollouts.&lt;/P&gt;
&lt;H3&gt;Regression testing&lt;/H3&gt;
&lt;P&gt;Maintain a regression suite of expected prompt behaviors and run it whenever prompts or models change. The suite reuses the same evaluation pipeline you built in Section 2.&lt;/P&gt;
&lt;H3&gt;Prompt-level metrics&lt;/H3&gt;
&lt;UL&gt;
&lt;LI&gt;Success rate — did the prompt achieve its intended outcome?&lt;/LI&gt;
&lt;LI&gt;Fallback rate — how often did users rephrase or abandon?&lt;/LI&gt;
&lt;LI&gt;Satisfaction score — explicit user feedback.&lt;/LI&gt;
&lt;LI&gt;Token efficiency — average tokens per successful completion (a leading indicator of cost regression).&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;PII and privacy safeguards&lt;/H3&gt;
&lt;P&gt;Customer prompts and completions are not used to train base models. That means logging is safe for debugging — but defense in depth still applies:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Redact PII&lt;/STRONG&gt; (names, emails, phone numbers, addresses) before logs are written.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Apply RBAC &lt;/STRONG&gt;on Log Analytics workspaces so only the right roles can access raw prompt data.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Govern data retention&lt;/STRONG&gt; with automated purging after a defined window.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Keep audit&lt;/STRONG&gt; trails of who accessed which logs and when.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Prompt quality is not a one-time effort. It is an ongoing operational discipline that needs tooling, processing, and measurement, in the same way application code does.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Figure 4 — Prompt Lifecycle Governance&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H1&gt;6. Fine-Tuned Models: The Hidden Retirement Risk&lt;/H1&gt;
&lt;P&gt;Fine-tuned models inherit the lifecycle of their base model. That creates a cascading retirement risk that many teams overlook.&lt;/P&gt;
&lt;P&gt;During base-model deprecation:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;New fine-tuning jobs against that base are blocked — you can no longer create new fine-tuned versions.&lt;/LI&gt;
&lt;LI&gt;Existing fine-tuned deployments continue serving inference, with no immediate impact.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;When the base model is retired:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Fine-tuned deployments stop responding (HTTP 404), exactly like any other deployment pinned to a retired version.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The migration imperative is straightforward: retrain fine-tuned models on the successor base model well before the retirement date, ideally during the predecessor's Legacy or Deprecated stage.&lt;/P&gt;
&lt;P&gt;Architectural considerations:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Track base-model dependencies explicitly in your asset inventory — the same place you track library and runtime versions.&lt;/LI&gt;
&lt;LI&gt;Schedule retraining workflows aligned with base-model lifecycle dates, not with team availability.&lt;/LI&gt;
&lt;LI&gt;Validate fine-tuned model quality on the new base; behavior can shift between base versions.&lt;/LI&gt;
&lt;LI&gt;Keep training datasets in version-controlled storage, so retraining is reproducible.&lt;/LI&gt;
&lt;LI&gt;Re-evaluate whether fine-tuning is still necessary; newer base models, combined with better prompting (few-shot, chain-of-thought, structured outputs), sometimes remove the need entirely.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;EM&gt;Common mistake: investing heavily in fine-tuning without budgeting for the recurring retraining cost and lifecycle overhead. Improved prompting on a newer base model is often the cheaper path.&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;7. Regional Rollouts and Multi-Region Strategy&lt;/H1&gt;
&lt;P&gt;Successor models are not always available in every Azure region simultaneously. Microsoft typically releases a new version in a subset of regions first, with broader rollout following over weeks or months. At the time of writing, the regional rollout schedule is published per model on Microsoft Learn — confirm before assuming a particular region will receive a release on a particular day.&lt;/P&gt;
&lt;H3&gt;Maintain staging deployments in early-release regions&lt;/H3&gt;
&lt;P&gt;Even if production runs elsewhere, maintain a staging deployment in regions that tend to receive new models earliest. That gives you visibility into the successor's behavior before it auto-upgrades into your primary region.&lt;/P&gt;
&lt;H3&gt;Pre-test successor models before primary auto-upgrades&lt;/H3&gt;
&lt;P&gt;If your production deployment uses "Once the current version expires", the upgrade will happen automatically. Pre-testing in an early-release region lets you catch behavioral changes before they hit live traffic.&lt;/P&gt;
&lt;H3&gt;Multi-region routing for lifecycle flexibility&lt;/H3&gt;
&lt;P&gt;Azure Front Door or Azure API Management with multi-region back-ends lets you route based on model availability, capacity headroom (one region may have quota while another is exhausted), and latency. Combined with the Model Router pattern from Section 6, this turns regional staggering from a constraint into an option.&lt;/P&gt;
&lt;H3&gt;Account for capacity-tier eligibility in your routing&lt;/H3&gt;
&lt;P&gt;Some capacity tiers are scoped to specific deployment scopes — Priority Processing, for example, is offered on Global Standard and Data Zone Standard (US) deployments at the time of writing. Bake those eligibility constraints into routing rules, so a fallback path does not silently land in an ineligible deployment.&lt;/P&gt;
&lt;P&gt;Multi-region strategy is no longer just a disaster-recovery concern. It is also lifecycle resilience — the ability to test, stage, and absorb model changes without coupling your platform to a single region release schedule.&lt;/P&gt;
&lt;H1&gt;8. Future-Proofing Through Abstraction&lt;/H1&gt;
&lt;P&gt;Future-proofing is architectural, not procedural. The goal is to design systems that adapt to change without requiring code rewrites every time a model is promoted, deprecated, or retired.&lt;/P&gt;
&lt;H3&gt;Abstract model calls behind a service layer&lt;/H3&gt;
&lt;P&gt;Avoid calling Azure OpenAI APIs directly from the application code. Introduce an internal Model Service that owns model selection, retry and fallback, prompt-template lookup, and response validation. The application asks for an outcome ("summarize this", "classify that"); the Model Service decides which model and which prompt to use.&lt;/P&gt;
&lt;H3&gt;Externalize model names and configuration&lt;/H3&gt;
&lt;P&gt;Store model identifiers, versions, and parameters in configuration or feature flags — never as hard-coded strings. Changing models then becomes a configuration change, not a deployment.&lt;/P&gt;
&lt;H3&gt;Centralize prompt logic&lt;/H3&gt;
&lt;P&gt;Maintain prompts in a registry or template repository, not scattered across codebases. This enables centralized versioning, A/B testing without code changes, and prompt optimization that is decoupled from application releases.&lt;/P&gt;
&lt;H3&gt;Avoid scattering model identifiers across the codebase&lt;/H3&gt;
&lt;P&gt;Use constants, enums, or configuration references rather than literal model strings repeated across many files. The number of files that have to change at upgrade time is a leading indicator of how painful the upgrade will be.&lt;/P&gt;
&lt;P&gt;Benefits of abstraction:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Seamless model replacement — swap models without touching application logic.&lt;/LI&gt;
&lt;LI&gt;Multi-model strategies — the Model Router pattern becomes trivial to add.&lt;/LI&gt;
&lt;LI&gt;Provider flexibility — integrating additional or alternative providers becomes a service-layer change, not an application to rewrite.&lt;/LI&gt;
&lt;LI&gt;Faster adoption of new capabilities — reasoning controls, function calling, structured outputs land in one place.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;EM&gt;Common mistake: Prototyping with direct API calls for speed and never refactoring. The technical debt accumulates until a model upgrade requires an emergency engineering sprint.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Figure 5 — Abstraction Layer for Future-Proofing.&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H1&gt;Final Perspective&lt;/H1&gt;
&lt;P&gt;The most important shift this article asks for is a change in operational mindset:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Model upgrades are not emergencies. They are scheduled events.&lt;/LI&gt;
&lt;LI&gt;Retirement deadlines are not surprising. They are published timelines, often with months of notice.&lt;/LI&gt;
&lt;LI&gt;Architecture fails when teams treat models as static dependencies. They succeed when they treat models as evolving infrastructure.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In practice, GenAIOps means:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Automated evaluation that runs continuously&lt;/STRONG&gt;, not just during migrations.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Controlled rollouts using blue/green or canary patterns&lt;/STRONG&gt;.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Observability-driven decisions based on metrics, not intuition.&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Lifecycle-aware planning&lt;/STRONG&gt;, with retirement dates tracked alongside library and runtime upgrades.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Modular design that decouples applications&lt;/STRONG&gt; from specific model versions.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Across the three parts of this series we have covered the architectural decisions that frame an Azure OpenAI / Microsoft Foundry Models workload (Part 1), the Well-Architected Framework discipline that keeps it sustainable (Part 2), and the GenAIOps practices that let it evolve without firefighting (Part 3). The organizations that succeed long-term are the ones that plan for model evolution from day one, invest in evaluation and observability tooling, decouple application logic from model specifics, and treat prompts and configurations as versioned artifacts.&lt;/P&gt;
&lt;P&gt;Generative AI architecture is not about deploying a model endpoint. It is about building a platform that absorbs change gracefully as the AI landscape shifts. The retirement of a model should be a routine operational event, not a crisis. If your architecture makes model upgrades feel risky or expensive, refactor before the next retirement deadline forces your hand.&lt;/P&gt;
&lt;H1&gt;Lifecycle &amp;amp; GenAIOps Decision Matrix&lt;/H1&gt;
&lt;P&gt;Use this as a checklist when reviewing or signing off on the GenAIOps posture of an Azure OpenAI / Microsoft Foundry Models platform. One row per decision; one rule of thumb per row.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Area&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Decision&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Rule of thumb&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Watch out for&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;Lifecycle&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Version expiry tracking&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Treat model versions as expiring dependencies: inventory every deployed model/version, track deprecation/retirement dates, and design so swapping versions is a configuration change (details on upgrade modes in Part 2).&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Pinning versions without an owner; discovering retirement dates after an outage or emergency migration window.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Evaluation&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Promotion gates&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Pass the regression suite + meet domain-specific quality and latency thresholds before promoting any model.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Subjective "feels better" sign-off; gates that exist on paper but never block a release.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Evaluation&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Pipeline integration&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Evaluation runs in CI/CD on every candidate; the same suite watches prompt changes.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Manual evaluation runs that only happen under retirement pressure.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Observability&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Latency and error metrics&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Track p50/p95/p99 latency, 429/503/4xx rates, token trend, and model-version distribution. Alert on tail latency and sustained throttling.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Average-only dashboards; missed Service Health notifications for model retirements.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Observability&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Quality drift&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Trend per-prompt success rate, fallback rate, and user-satisfaction signals; surface drift before users complain.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Treating quality as a one-time evaluation event.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Architecture&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Model Router&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Centralize model selection, canary, and fallback (including Priority Processing on eligible deployments) behind a router service.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Application code that calls a specific model deployment by name; routing logic scattered across services.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Architecture&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Abstraction layer&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Application code asks for an outcome; the Model Service decides which model and prompt; configuration drives model selection.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Hard-coded model identifiers across many files; bypass paths that skip the service layer.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Prompts&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Prompt governance&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Prompts in Git, behind feature flags, with regression tests, prompt-level metrics, and PII redaction in logs.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Prompts copy-pasted across services; PII in logs; no rollback path for a regressed prompt.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Fine-tune&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Fine-tuned model lifecycle&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Track fine-tuned models against base-model dates; schedule retraining during the predecessor's Legacy/Deprecated window.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Treating fine-tuned models as permanent infrastructure; lost or unversioned training datasets.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Regional&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Multi-region for lifecycle resilience&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Maintain staging in early-release regions; route across regions to absorb staggered rollouts and capacity gaps.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Single-region production with no early-release staging; routing rules that ignore tier-eligibility constraints.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H1&gt;Disclaimer&lt;/H1&gt;
&lt;P&gt;&lt;EM&gt;I am a Microsoft employee. The views and opinions expressed in this article are my own and do not necessarily reflect those of Microsoft. This content is informational and educational; it is not an official Microsoft statement, recommendation, or commitment. Service tiers, model availability, lifecycle stages, deprecation timelines, regional rollouts, pricing, and SLAs evolve — always validate against the latest Microsoft Learn documentation before making architectural or migration decisions.&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;References&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/model-retirements" target="_blank"&gt;&lt;STRONG&gt;Azure OpenAI model deprecations and retirements&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/working-with-models" target="_blank"&gt;&lt;STRONG&gt;Working with Azure OpenAI models — versioning and upgrades&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/provisioned-throughput" target="_blank"&gt;&lt;STRONG&gt;Provisioned throughput for Azure OpenAI&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/foundry/openai/concepts/priority-processing" target="_blank"&gt;&lt;STRONG&gt;Enable Priority Processing for Microsoft Foundry Models&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-foundry/concepts/evaluation-approach-gen-ai" target="_blank"&gt;&lt;STRONG&gt;Azure AI Foundry — evaluation of generative AI applications&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/monitoring" target="_blank"&gt;&lt;STRONG&gt;Monitor Azure OpenAI&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/api-management/genai-gateway-capabilities" target="_blank"&gt;&lt;STRONG&gt;Azure API Management — GenAI Gateway capabilities&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/frontdoor/front-door-routing-architecture" target="_blank"&gt;&lt;STRONG&gt;Azure Front Door routing for AI back-ends&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/managed-identity" target="_blank"&gt;&lt;STRONG&gt;Use managed identities with Azure OpenAI&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/content-safety/" target="_blank"&gt;&lt;STRONG&gt;Azure AI Content Safety&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/fine-tuning" target="_blank"&gt;&lt;STRONG&gt;Fine-tune models with Azure OpenAI&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/well-architected/" target="_blank"&gt;&lt;STRONG&gt;Azure Well-Architected Framework&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Wed, 17 Jun 2026 16:39:08 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/azure-openai-architecture-the-decisions-that-actually-matter/ba-p/4528901</guid>
      <dc:creator>luciacasucci</dc:creator>
      <dc:date>2026-06-17T16:39:08Z</dc:date>
    </item>
    <item>
      <title>Power Platform tenant inventory — a community showcase of the API-first management surface</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/power-platform-tenant-inventory-a-community-showcase-of-the-api/ba-p/4519598</link>
      <description>&lt;img /&gt;
&lt;P data-line="8"&gt;Source:&amp;nbsp;&lt;A href="https://github.com/SweetsNSavories/VerseOps" data-href="https://github.com/SweetsNSavories/VerseOps" target="_blank"&gt;github.com/SweetsNSavories/VerseOps&lt;/A&gt;&amp;nbsp;· MIT.&lt;/P&gt;
&lt;P data-line="8"&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;EM&gt;Figure 1 — VerseOps loaded against a live tenant. Per-row capacity (DB / File / Log / FinOps DB / FinOps File GB) is computed from the BAP&amp;nbsp;$expand=properties.capacity&amp;nbsp;call; per-env asset counts are joined client-side from the Inventory API result set. Tenant identifiers redacted; everything else is real.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&amp;nbsp;&lt;EM&gt;Figure 2 — One environment row expanded. The row-details template fans out the inventory: Solutions / Apps / Flows / Agents (joined from the Inventory API and per-env Dataverse Web API calls), Power Pages sites (mspp_website&amp;nbsp;table on the env's Dataverse), and the env's&amp;nbsp;systemusers&amp;nbsp;(with their assigned licenses joined from Microsoft Graph). All asset counts (9 / 3 / 53 / 241) are real.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P data-line="16"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;EM&gt;Figure 3 — Total Assets drawer (click the Total Assets KPI tile). The whole panel is fed by a single tenant-wide Inventory API query; the per-type counts are computed client-side from&amp;nbsp;assetType. The "most recent" name surfaces the freshest asset of each kind so an admin can sanity-check that the tenant feed is current.&lt;/EM&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P data-line="19"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;EM&gt;Figure 4 — Licenses Consumed drawer (click the Licensed Users KPI tile). The list is the union of every assigned&amp;nbsp;servicePlan&amp;nbsp;from&amp;nbsp;/users?$select=assignedLicenses&amp;nbsp;rolled up to the SKU level using the tenant's&amp;nbsp;subscribedSkus&amp;nbsp;catalog from Microsoft Graph. SKU codes are public; the only tenant-specific data is the per-SKU seat count on the right.&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H2 data-line="24"&gt;Why this exists&lt;/H2&gt;
&lt;P data-line="26"&gt;The recurring questions at the start of every governance cycle are well known:&lt;/P&gt;
&lt;P data-line="28"&gt;&lt;EM&gt;"How many environments do we actually have? Who owns the apps in them? How much Dataverse capacity is sitting in places no one remembers creating? Which makers left the company three months ago and still own production flows?"&lt;/EM&gt;&lt;/P&gt;
&lt;P data-line="30"&gt;The official answers — Power Platform admin center (PPAC), the&amp;nbsp;&lt;STRONG&gt;Power Platform inventory&lt;/STRONG&gt;&amp;nbsp;page, and the&amp;nbsp;&lt;STRONG&gt;Usage&lt;/STRONG&gt;&amp;nbsp;page — already exist and are the right starting point for daily work; they cover the common cases comprehensively. There are still moments, however, when an administrator needs:&lt;/P&gt;
&lt;OL data-line="32"&gt;
&lt;LI data-line="32"&gt;A&amp;nbsp;&lt;STRONG&gt;single offline snapshot&lt;/STRONG&gt;&amp;nbsp;they can search, sort, filter, and ship to a stakeholder without exposing the live admin center.&lt;/LI&gt;
&lt;LI data-line="33"&gt;A&amp;nbsp;&lt;STRONG&gt;diff&lt;/STRONG&gt;&amp;nbsp;between this morning and last Friday —&amp;nbsp;&lt;EM&gt;what changed?&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="34"&gt;&lt;STRONG&gt;Joined views&lt;/STRONG&gt;&amp;nbsp;that the portal doesn't ship out of the box: per-env capacity × per-env asset count × per-env user count, all in one sortable grid.&lt;/LI&gt;
&lt;LI data-line="35"&gt;The&amp;nbsp;&lt;STRONG&gt;raw JSON&lt;/STRONG&gt;&amp;nbsp;behind every row, one click away, when something doesn't match what the portal shows.&lt;/LI&gt;
&lt;LI data-line="36"&gt;A&amp;nbsp;&lt;STRONG&gt;starting point&lt;/STRONG&gt;&amp;nbsp;— code they can fork, instrument, and turn into the governance tool they actually wanted.&lt;/LI&gt;
&lt;/OL&gt;
&lt;P data-line="38"&gt;VerseOps targets that long tail. The UI surface is roughly five files; every outbound call is enumerated in&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/docs/network-endpoints.md" data-href="../network-endpoints.md" target="_blank"&gt;docs/network-endpoints.md&lt;/A&gt;. The codebase is deliberately small, read-only by design, and positioned as a foundation that adopting teams are expected to fork, instrument, and extend.&lt;/P&gt;
&lt;H2 data-line="42"&gt;How it complements the official "Inventory" and "Usage" pages&lt;/H2&gt;
&lt;P data-line="44"&gt;Microsoft's&amp;nbsp;&lt;A href="https://learn.microsoft.com/power-platform/admin/power-platform-inventory" data-href="https://learn.microsoft.com/power-platform/admin/power-platform-inventory" target="_blank"&gt;Power Platform inventory&lt;/A&gt;&amp;nbsp;gives administrators a unified view of agents, apps, and flows tenant-wide, refreshed within ~15 minutes. The&amp;nbsp;&lt;A href="https://learn.microsoft.com/power-platform/admin/usage" data-href="https://learn.microsoft.com/power-platform/admin/usage" target="_blank"&gt;Usage page&lt;/A&gt;&amp;nbsp;tracks engagement and adoption. Both ship in the admin center today and should be every admin's first stop.&lt;/P&gt;
&lt;P data-line="46"&gt;VerseOps is positioned as a&amp;nbsp;&lt;STRONG&gt;complement, not a replacement&lt;/STRONG&gt;:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Need&lt;/th&gt;&lt;th&gt;PPAC Inventory / Usage&lt;/th&gt;&lt;th&gt;VerseOps&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Daily inventory browsing in a portal&lt;/td&gt;&lt;td&gt;✅ Recommended&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Filter / sort / search on any column&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Resource-detail drill-in (owner, env, dates)&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Export to Excel&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;td&gt;✅ (CSV / cache copy)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Capacity (DB / File / Log / FinOps GB) joined per env on the same row as asset count&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Partial&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;One-click "show me the raw Dataverse / PPAC JSON" inspector&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;❌&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Local SQLite cache for offline browsing on a plane / in an air-gapped review&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;❌&lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Diff between today's snapshot and yesterday's&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;❌&lt;/td&gt;&lt;td&gt;✅ (cache-based, on roadmap)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Source you can fork&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;n/a&lt;/td&gt;&lt;td&gt;✅ MIT, single solution&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Telemetry sent to Microsoft / vendor&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;per Microsoft's data policy&lt;/td&gt;&lt;td&gt;&lt;STRONG&gt;None — zero outbound calls beyond Microsoft's own APIs&lt;/STRONG&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="61"&gt;If you only ever need 1–4 above, stay in the admin center; it's faster and always up to date. VerseOps shows up when you need 5–11.&lt;/P&gt;
&lt;H2 data-line="65"&gt;Architecture in one diagram&lt;/H2&gt;
&lt;img /&gt;
&lt;P data-line="114"&gt;Key architectural properties:&lt;/P&gt;
&lt;UL data-line="116"&gt;
&lt;LI data-line="116"&gt;&lt;STRONG&gt;Single process, no server-side footprint.&lt;/STRONG&gt;&amp;nbsp;Every call runs in the signed-in user's security context. There is no daemon, no sync job, no message bus. The operating system schedules the network calls; the user triggers a refresh.&lt;/LI&gt;
&lt;LI data-line="117"&gt;&lt;STRONG&gt;Two distinct cloud planes.&lt;/STRONG&gt;&amp;nbsp;Management-plane calls (api.powerplatform.com,&amp;nbsp;api.bap.microsoft.com,&amp;nbsp;graph.microsoft.com) are kept separate from data-plane calls ({org}.crm.dynamics.com&amp;nbsp;per environment), with audience switching handled centrally by the auth layer.&lt;/LI&gt;
&lt;LI data-line="118"&gt;&lt;STRONG&gt;The local SQLite database is the only state.&lt;/STRONG&gt;&amp;nbsp;Removing&amp;nbsp;%LOCALAPPDATA%\VerseOps\&amp;nbsp;returns the application to a blank slate. No other persistence exists.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 data-line="122"&gt;What's actually feasible with the Power Platform API today&lt;/H2&gt;
&lt;P data-line="124"&gt;Microsoft has been very public about its&amp;nbsp;&lt;A href="https://devblogs.microsoft.com/powerplatform/power-platform-api-and-sdks-from-ux-first-to-api-first/" data-href="https://devblogs.microsoft.com/powerplatform/power-platform-api-and-sdks-from-ux-first-to-api-first/" target="_blank"&gt;shift from a UX-first to an API-first development model for Power Platform programmability&lt;/A&gt;: new capabilities ship in the API first, then propagate to SDKs, CLI, PowerShell cmdlets, and connectors. The&amp;nbsp;&lt;A href="https://learn.microsoft.com/power-platform/admin/programmability-extensibility-overview" data-href="https://learn.microsoft.com/power-platform/admin/programmability-extensibility-overview" target="_blank"&gt;Programmability and extensibility overview&lt;/A&gt;&amp;nbsp;lays out the full toolchain — REST API, .NET SDK (&lt;A href="https://www.nuget.org/packages/Microsoft.PowerPlatform.Management/" data-href="https://www.nuget.org/packages/Microsoft.PowerPlatform.Management/" target="_blank"&gt;Microsoft.PowerPlatform.Management&lt;/A&gt;), Python SDK, Power Platform CLI, PowerShell cmdlets, and the Power Platform for Admins V2 connector.&lt;/P&gt;
&lt;P data-line="126"&gt;VerseOps is a deliberately small showcase of what the&amp;nbsp;&lt;STRONG&gt;.NET SDK + Inventory API&lt;/STRONG&gt;&amp;nbsp;combination unlocks once you put a UI on it:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Capability&lt;/th&gt;&lt;th&gt;API used&lt;/th&gt;&lt;th&gt;SDK / endpoint&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;List every environment in the tenant with name / region / SKU / version / security group / default-flag&lt;/td&gt;&lt;td&gt;Power Platform API (PPAC)&lt;/td&gt;&lt;td&gt;Microsoft.PowerPlatform.Management&amp;nbsp;SDK&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Per-tenant capacity (DB / File / Log / FinOps DB / FinOps File GB)&lt;/td&gt;&lt;td&gt;Power Platform API (PPAC)&lt;/td&gt;&lt;td&gt;SDK&amp;nbsp;Licensing.Tenant.GetCurrentCapacityAllocations()&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Per-environment capacity in&amp;nbsp;&lt;STRONG&gt;one tenant-wide call&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;BAP capacity (legacy GA)&lt;/td&gt;&lt;td&gt;GET /providers/Microsoft.BusinessAppPlatform/scopes/admin/environments?api-version=2020-10-01&amp;amp;$expand=properties.capacity&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;STRONG&gt;Every&lt;/STRONG&gt;&amp;nbsp;canvas app, model-driven app, code app, cloud flow, agent flow, and Copilot Studio agent in the tenant in&amp;nbsp;&lt;STRONG&gt;one POST&lt;/STRONG&gt;&lt;/td&gt;&lt;td&gt;Inventory API (preview)&lt;/td&gt;&lt;td&gt;POST https://api.powerplatform.com/resourcequery/resources/query?api-version=2024-10-01&amp;nbsp;(KQL-style query against&amp;nbsp;PowerPlatformResources)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;DLP policies + connector classification (Business / Non-Business / Blocked)&lt;/td&gt;&lt;td&gt;BAP Governance v2&lt;/td&gt;&lt;td&gt;GET /providers/PowerPlatform.Governance/v2/policies?api-version=2018-01-01&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Per-env solutions / Power Pages sites / system users / roles / app + flow status&lt;/td&gt;&lt;td&gt;Dataverse Web API v9.2&lt;/td&gt;&lt;td&gt;GET {org}/api/data/v9.2/solutions,&amp;nbsp;appmodules,&amp;nbsp;workflows,&amp;nbsp;canvasapps,&amp;nbsp;systemusers,&amp;nbsp;mspp_websites&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;User license SKU resolution + security-group display names&lt;/td&gt;&lt;td&gt;Microsoft Graph&lt;/td&gt;&lt;td&gt;GET /v1.0/subscribedSkus,&amp;nbsp;/users,&amp;nbsp;/groups,&amp;nbsp;/directoryObjects/getByIds&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="138"&gt;The headline shape of this:&amp;nbsp;&lt;STRONG&gt;one tenant-wide POST replaces what used to be N×6 per-environment GETs.&lt;/STRONG&gt;&amp;nbsp;For a tenant with 700 environments, that's the difference between ~4,000 round-trips per refresh and ~10. The same&amp;nbsp;Microsoft.PowerPlatform.Management&amp;nbsp;SDK that powers the new admin-center surfaces is the same one your tooling uses — there's no longer a "fast official one and a slow community one".&lt;/P&gt;
&lt;H2 data-line="142"&gt;A note on the BAP API deprecation path&lt;/H2&gt;
&lt;P data-line="144"&gt;Several BAP routes the community has relied on for years are now in a clear&amp;nbsp;&lt;EM&gt;consolidation&lt;/EM&gt;&amp;nbsp;track rather than a&amp;nbsp;&lt;EM&gt;deprecation&lt;/EM&gt;&amp;nbsp;one — but the destination is the same. From the official&amp;nbsp;&lt;A href="https://learn.microsoft.com/power-platform/admin/programmability-versioning-support" data-href="https://learn.microsoft.com/power-platform/admin/programmability-versioning-support" target="_blank"&gt;Versioning and support&lt;/A&gt;&amp;nbsp;page:&lt;/P&gt;
&lt;P data-line="146"&gt;&lt;EM&gt;"The 2020-10-01 Generally available version of Power Platform API is specific to environment management and is also commonly referred to as&amp;nbsp;&lt;STRONG&gt;Business Application Platform (BAP) API&lt;/STRONG&gt;. The functionality of this set of endpoints are made available in the newer versions of Power Platform API along with many additional features after version 2022-03-01-preview."&lt;/EM&gt;&lt;/P&gt;
&lt;P data-line="148"&gt;In practice, what this means for tools like VerseOps:&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;BAP route VerseOps uses today&lt;/th&gt;&lt;th&gt;Status (May 2026)&lt;/th&gt;&lt;th&gt;Modern equivalent on&amp;nbsp;api.powerplatform.com&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;/scopes/admin/environments?$expand=properties.capacity&lt;/td&gt;&lt;td&gt;GA (api-version=2020-10-01); functionally superseded but still recommended for tenant-wide capacity&lt;/td&gt;&lt;td&gt;Will move to a Licensing namespace endpoint as parity completes; track&amp;nbsp;&lt;A href="https://learn.microsoft.com/power-platform/admin/programmability-whats-new-changed" data-href="https://learn.microsoft.com/power-platform/admin/programmability-whats-new-changed" target="_blank"&gt;Programmability what's new&lt;/A&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;PowerPlatform.Governance/v2/policies&amp;nbsp;(DLP)&lt;/td&gt;&lt;td&gt;Stable&lt;/td&gt;&lt;td&gt;Watch the new Connectivity / Governance namespace endpoints (e.g.&amp;nbsp;&lt;A href="https://learn.microsoft.com/rest/api/power-platform/connectivity/connectors/list-connectors" data-href="https://learn.microsoft.com/rest/api/power-platform/connectivity/connectors/list-connectors" target="_blank"&gt;List Connectors&lt;/A&gt;, shipped July 2025)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Microsoft.BusinessAppPlatform&amp;nbsp;provider routes&lt;/td&gt;&lt;td&gt;All being mirrored under&amp;nbsp;api.powerplatform.com&amp;nbsp;namespaces (Licensing, EnvironmentManagement, AppManagement, Authorization, Governance, Connectivity)&lt;/td&gt;&lt;td&gt;Use the SDK — Microsoft maintains the mapping for you&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;col style="width: 33.33%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P data-line="156"&gt;Microsoft's official guidance is unambiguous:&amp;nbsp;&lt;STRONG&gt;use the Power Platform API surface (api.powerplatform.com) and one of the official SDKs&lt;/STRONG&gt;&amp;nbsp;(&lt;A href="https://www.nuget.org/packages/Microsoft.PowerPlatform.Management/" data-href="https://www.nuget.org/packages/Microsoft.PowerPlatform.Management/" target="_blank"&gt;.NET&lt;/A&gt;,&amp;nbsp;&lt;A href="https://pypi.org/project/powerplatform-management/" data-href="https://pypi.org/project/powerplatform-management/" target="_blank"&gt;Python&lt;/A&gt;, CLI, PowerShell,&amp;nbsp;&lt;A href="https://learn.microsoft.com/connectors/powerplatformadminv2/" data-href="https://learn.microsoft.com/connectors/powerplatformadminv2/" target="_blank"&gt;Power Platform for Admins V2 connector&lt;/A&gt;) for any new automation. BAP routes won't disappear without a deprecation cycle, but new features ship to&amp;nbsp;api.powerplatform.com&amp;nbsp;first and may never come back to BAP.&lt;/P&gt;
&lt;P data-line="158"&gt;VerseOps reflects this exactly: every new feature added since April 2026 went to&amp;nbsp;api.powerplatform.com, the BAP capacity client is isolated to a single ~150-line file (&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/VerseOps.App/Inventory/Services/BapCapacityClient.cs" data-href="../../VerseOps.App/Inventory/Services/BapCapacityClient.cs" target="_blank"&gt;BapCapacityClient.cs&lt;/A&gt;) so it can be swapped out the moment the per-env capacity surface lands on the new API, and the token-acquisition layer (&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/VerseOps.App/Auth/AuthService.cs" data-href="../../VerseOps.App/Auth/AuthService.cs" target="_blank"&gt;AuthService.cs&lt;/A&gt;) supports both audiences side by side until that day comes.&lt;/P&gt;
&lt;H2 data-line="162"&gt;Who this helps&lt;/H2&gt;
&lt;P data-line="164"&gt;The MIT license permits unrestricted internal adaptation; adopting teams are encouraged to fork, re-brand, and re-sign the binary with their own enterprise code-signing certificate as part of internal distribution. Typical adopters include:&lt;/P&gt;
&lt;UL data-line="166"&gt;
&lt;LI data-line="166"&gt;&lt;STRONG&gt;Power Platform administrators&lt;/STRONG&gt;&amp;nbsp;running quarterly governance reviews who need a single defensible snapshot of current tenant state.&lt;/LI&gt;
&lt;LI data-line="167"&gt;&lt;STRONG&gt;Center-of-Excellence (CoE) leads&lt;/STRONG&gt;&amp;nbsp;who previously relied on the&amp;nbsp;&lt;A href="https://learn.microsoft.com/power-platform/guidance/coe/" data-href="https://learn.microsoft.com/power-platform/guidance/coe/" target="_blank"&gt;CoE Starter Kit&lt;/A&gt;&amp;nbsp;and are&amp;nbsp;&lt;A href="https://learn.microsoft.com/power-platform/admin/power-platform-inventory" data-href="https://learn.microsoft.com/power-platform/admin/power-platform-inventory" target="_blank"&gt;moving to the in-product Inventory + Usage pages&lt;/A&gt;, but still require a code-level surface to extend.&lt;/LI&gt;
&lt;LI data-line="168"&gt;&lt;STRONG&gt;FinOps and capacity owners&lt;/STRONG&gt;&amp;nbsp;identifying the ~5% of environments that consume 80% of Dataverse storage, with FinOps DB / FinOps File / Log GB visible on the same row as the environment name.&lt;/LI&gt;
&lt;LI data-line="169"&gt;&lt;STRONG&gt;Mission-critical and regulated workloads&lt;/STRONG&gt;&amp;nbsp;(financial services, healthcare, public sector) where a desktop tool that authenticates as the human administrator, emits zero telemetry, and stores all state locally is materially easier to risk-accept than a SaaS dashboard.&lt;/LI&gt;
&lt;LI data-line="170"&gt;&lt;STRONG&gt;Security and penetration-test teams&lt;/STRONG&gt;&amp;nbsp;who require a reproducible, auditable, signed Windows binary and a clear inventory of what it touches. The&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/sbom.cdx.json" data-href="../../sbom.cdx.json" target="_blank"&gt;SBOM&lt;/A&gt;,&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/SECURITY.md" data-href="../../SECURITY.md" target="_blank"&gt;SECURITY.md&lt;/A&gt;,&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/SIGNING.md" data-href="../../SIGNING.md" target="_blank"&gt;SIGNING.md&lt;/A&gt;, and&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/.github/workflows/codeql.yml" data-href="../../.github/workflows/codeql.yml" target="_blank"&gt;CodeQL workflow&lt;/A&gt;&amp;nbsp;are committed to the repository.&lt;/LI&gt;
&lt;LI data-line="171"&gt;&lt;STRONG&gt;Engineering teams learning the Power Platform API&lt;/STRONG&gt;&amp;nbsp;who want a non-trivial, well-commented .NET sample that exercises every major namespace.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 data-line="175"&gt;Where this could go next&lt;/H2&gt;
&lt;P data-line="177"&gt;The same API surface that powers VerseOps today can support a substantially richer set of experiences. Candidate directions follow; community input on prioritization is welcome via the&amp;nbsp;&lt;A href="https://github.com/SweetsNSavories/VerseOps/issues" data-href="https://github.com/SweetsNSavories/VerseOps/issues" target="_blank"&gt;issue tracker&lt;/A&gt;.&lt;/P&gt;
&lt;H3 data-line="179"&gt;1. An&amp;nbsp;&lt;EM&gt;agentic&lt;/EM&gt;&amp;nbsp;governance assistant&lt;/H3&gt;
&lt;P data-line="180"&gt;Wrap the local SQLite cache + the same auth pipeline behind a Microsoft 365 Copilot agent (or a Foundry agent), and let an admin ask things like:&lt;/P&gt;
&lt;UL data-line="182"&gt;
&lt;LI data-line="182"&gt;&lt;EM&gt;"Which environments grew the most this week and who owns the new flows?"&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="183"&gt;&lt;EM&gt;"List every canvas app with a deprecated connector that's still 'On' in a production env."&lt;/EM&gt;&lt;/LI&gt;
&lt;LI data-line="184"&gt;&lt;EM&gt;"Show me orphaned resources owned by users disabled in Entra in the last 30 days."&lt;/EM&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P data-line="186"&gt;The Power Platform API + Inventory API already returns everything you need to answer these in seconds. The agent surface is just a new face for the same data — and because the cache is local, the agent can run&amp;nbsp;&lt;STRONG&gt;without ever sending tenant data to a third party&lt;/STRONG&gt;.&lt;/P&gt;
&lt;H3 data-line="188"&gt;2. Periodic snapshots → drift report&lt;/H3&gt;
&lt;P data-line="189"&gt;A scheduled task that runs&amp;nbsp;VerseOps.App --refresh --headless&amp;nbsp;once a day, writes the SQLite snapshot to a versioned folder, and emails a delta. "Today vs yesterday: +12 canvas apps in the Default env, –3 envs decommissioned, capacity climbed 4.1 GB on org-prod-eu."&lt;/P&gt;
&lt;H3 data-line="191"&gt;3. Multi-tenant fan-out for MSPs / consultancies&lt;/H3&gt;
&lt;P data-line="192"&gt;Same EXE, multiple tenant profiles, side-by-side comparison view. The auth layer already supports&amp;nbsp;--tenant &amp;lt;guid&amp;gt;; the cache schema is per-tenant-keyed.&lt;/P&gt;
&lt;H3 data-line="194"&gt;4. Plug-ins for the Inventory API custom queries&lt;/H3&gt;
&lt;P data-line="195"&gt;The Inventory API's&amp;nbsp;POST /resourcequery/resources/query&amp;nbsp;accepts arbitrary KQL-style projections. A plug-in directory of "common admin questions as queries" (orphaned apps, oldest unused flows, premium connector usage by env) could grow organically.&lt;/P&gt;
&lt;H3 data-line="197"&gt;5. Sister tools in Python / TypeScript&lt;/H3&gt;
&lt;P data-line="198"&gt;The&amp;nbsp;&lt;A href="https://pypi.org/project/powerplatform-management/" data-href="https://pypi.org/project/powerplatform-management/" target="_blank"&gt;Python SDK&lt;/A&gt;&amp;nbsp;is GA; a Jupyter notebook that mirrors VerseOps' three core panels (env list + capacity + assets) would be ~200 lines and would land instantly with the data-science crowd.&lt;/P&gt;
&lt;P data-line="200"&gt;The repository is intended as a working base for these explorations: the foundational ~80% — authentication, caching, paging, retry, redaction, error capture, and theming — is already implemented and exercised against a live ~700-environment tenant. Proposals for any of the directions above can be filed on the&amp;nbsp;&lt;A href="https://github.com/SweetsNSavories/VerseOps/issues" data-href="https://github.com/SweetsNSavories/VerseOps/issues" target="_blank"&gt;issue tracker&lt;/A&gt;.&lt;/P&gt;
&lt;H2 data-line="204"&gt;What's in the repository&lt;/H2&gt;
&lt;P data-line="206"&gt;Everything below is on&amp;nbsp;main&amp;nbsp;at&amp;nbsp;&lt;A href="https://github.com/SweetsNSavories/VerseOps" data-href="https://github.com/SweetsNSavories/VerseOps" target="_blank"&gt;github.com/SweetsNSavories/VerseOps&lt;/A&gt;, MIT-licensed:&lt;/P&gt;
&lt;UL data-line="208"&gt;
&lt;LI data-line="208"&gt;The single WPF EXE —&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/VerseOps.App/" data-href="../../VerseOps.App/" target="_blank"&gt;VerseOps.App/&lt;/A&gt;&lt;/LI&gt;
&lt;LI data-line="209"&gt;API clients, one per Microsoft service —&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/VerseOps.App/Inventory/Services/" data-href="../../VerseOps.App/Inventory/Services/" target="_blank"&gt;VerseOps.App/Inventory/Services/&lt;/A&gt;&lt;/LI&gt;
&lt;LI data-line="210"&gt;SQLite catalog schema —&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/VerseOps.App/Inventory/Sql/schema.sql" data-href="../../VerseOps.App/Inventory/Sql/schema.sql" target="_blank"&gt;VerseOps.App/Inventory/Sql/schema.sql&lt;/A&gt;&lt;/LI&gt;
&lt;LI data-line="211"&gt;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/README.md" data-href="../../README.md" target="_blank"&gt;README.md&lt;/A&gt;&amp;nbsp;— install, run, build&lt;/LI&gt;
&lt;LI data-line="212"&gt;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/SECURITY.md" data-href="../../SECURITY.md" target="_blank"&gt;SECURITY.md&lt;/A&gt;&amp;nbsp;— disclosure policy + threat model&lt;/LI&gt;
&lt;LI data-line="213"&gt;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/SIGNING.md" data-href="../../SIGNING.md" target="_blank"&gt;SIGNING.md&lt;/A&gt;&amp;nbsp;— three publish-with-signature paths (self-signed dev, Azure Trusted Signing, OV/EV)&lt;/LI&gt;
&lt;LI data-line="214"&gt;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/docs/network-endpoints.md" data-href="../network-endpoints.md" target="_blank"&gt;docs/network-endpoints.md&lt;/A&gt;&amp;nbsp;— every outbound host + OAuth scope&lt;/LI&gt;
&lt;LI data-line="215"&gt;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/THIRD-PARTY-NOTICES.md" data-href="../../THIRD-PARTY-NOTICES.md" target="_blank"&gt;THIRD-PARTY-NOTICES.md&lt;/A&gt;&amp;nbsp;+&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/sbom.cdx.json" data-href="../../sbom.cdx.json" target="_blank"&gt;sbom.cdx.json&lt;/A&gt;&amp;nbsp;— full dependency attribution + CycloneDX SBOM&lt;/LI&gt;
&lt;LI data-line="216"&gt;CI: build, vulnerability scan, CodeQL —&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/.github/workflows/" data-href="../../.github/workflows/" target="_blank"&gt;.github/workflows/&lt;/A&gt;&lt;/LI&gt;
&lt;LI data-line="217"&gt;Branch protection ruleset (PR required, force-push blocked) —&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/.github/branch-protection.json" data-href="../../.github/branch-protection.json" target="_blank"&gt;.github/branch-protection.json&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2 data-line="221"&gt;Try it&lt;/H2&gt;
&lt;P&gt;git clone https://github.com/SweetsNSavories/VerseOps.git cd VerseOps dotnet build VerseOps.sln -c Release .\VerseOps.App\bin\Release\net10.0-windows\VerseOps.App.exe&lt;/P&gt;
&lt;P data-line="230"&gt;Sign in with a tenant admin account (Power Platform Administrator or Dynamics 365 Administrator), click&amp;nbsp;&lt;STRONG&gt;Refresh&lt;/STRONG&gt;, and the first cold pull populates the local cache. Subsequent launches are instant from the cache; click Refresh again whenever you want a fresh snapshot.&lt;/P&gt;
&lt;H2 data-line="234"&gt;Closing thought&lt;/H2&gt;
&lt;P data-line="236"&gt;The thesis behind this post is straightforward: an API-first Power Platform management surface puts a complete tenant inventory within reach in roughly 3,000 lines of C#. The official Inventory and Usage pages remain the right tool for daily-driver scenarios. The SDK and Inventory API together cover the long tail — the cases where an organization needs a specific join, requires offline operation, or needs the answer the same week.&lt;/P&gt;
&lt;P data-line="238"&gt;VerseOps is offered to the community as that starting point. Issues and pull requests are welcome on the&amp;nbsp;&lt;A href="https://github.com/SweetsNSavories/VerseOps/issues" data-href="https://github.com/SweetsNSavories/VerseOps/issues" target="_blank"&gt;public tracker&lt;/A&gt;; security disclosures should follow the process documented in&amp;nbsp;&lt;A href="https://file+.vscode-resource.vscode-cdn.net/c%3A/Users/pravth/Downloads/VerseOps/VerseOps/SECURITY.md" data-href="../../SECURITY.md" target="_blank"&gt;SECURITY.md&lt;/A&gt;.&lt;/P&gt;
&lt;P data-line="240"&gt;—&amp;nbsp;&lt;EM&gt;Praveen T · maintainer,&amp;nbsp;&lt;A href="https://github.com/SweetsNSavories/VerseOps" data-href="https://github.com/SweetsNSavories/VerseOps" target="_blank"&gt;VerseOps&lt;/A&gt;&lt;/EM&gt;&lt;/P&gt;
&lt;H3 data-line="244"&gt;References&lt;/H3&gt;
&lt;UL data-line="246"&gt;
&lt;LI data-line="246"&gt;&lt;A href="https://learn.microsoft.com/power-platform/admin/power-platform-inventory" data-href="https://learn.microsoft.com/power-platform/admin/power-platform-inventory" target="_blank"&gt;Power Platform inventory&lt;/A&gt;&amp;nbsp;— the in-product surface VerseOps complements&lt;/LI&gt;
&lt;LI data-line="247"&gt;&lt;A href="https://learn.microsoft.com/power-platform/admin/usage" data-href="https://learn.microsoft.com/power-platform/admin/usage" target="_blank"&gt;Power Platform admin center Usage page&lt;/A&gt;&lt;/LI&gt;
&lt;LI data-line="248"&gt;&lt;A href="https://learn.microsoft.com/power-platform/admin/programmability-extensibility-overview" data-href="https://learn.microsoft.com/power-platform/admin/programmability-extensibility-overview" target="_blank"&gt;Programmability and extensibility overview&lt;/A&gt;&amp;nbsp;— official tooling map&lt;/LI&gt;
&lt;LI data-line="249"&gt;&lt;A href="https://learn.microsoft.com/power-platform/admin/programmability-versioning-support" data-href="https://learn.microsoft.com/power-platform/admin/programmability-versioning-support" target="_blank"&gt;Versioning and support&lt;/A&gt;&amp;nbsp;— the BAP-vs-PPAC story&lt;/LI&gt;
&lt;LI data-line="250"&gt;&lt;A href="https://learn.microsoft.com/power-platform/admin/programmability-whats-new-changed" data-href="https://learn.microsoft.com/power-platform/admin/programmability-whats-new-changed" target="_blank"&gt;Programmability — What's new or changed&lt;/A&gt;&amp;nbsp;— monthly release log&lt;/LI&gt;
&lt;LI data-line="251"&gt;&lt;A href="https://learn.microsoft.com/rest/api/power-platform/" data-href="https://learn.microsoft.com/rest/api/power-platform/" target="_blank"&gt;Power Platform API REST reference (latest)&lt;/A&gt;&lt;/LI&gt;
&lt;LI data-line="252"&gt;&lt;A href="https://www.nuget.org/packages/Microsoft.PowerPlatform.Management/" data-href="https://www.nuget.org/packages/Microsoft.PowerPlatform.Management/" target="_blank"&gt;Microsoft.PowerPlatform.Management on NuGet&lt;/A&gt;&amp;nbsp;— the .NET SDK VerseOps consumes&lt;/LI&gt;
&lt;LI data-line="253"&gt;&lt;A href="https://learn.microsoft.com/connectors/powerplatformadminv2/" data-href="https://learn.microsoft.com/connectors/powerplatformadminv2/" target="_blank"&gt;Power Platform for Admins V2 connector&lt;/A&gt;&amp;nbsp;— the no-code path to the same API&lt;/LI&gt;
&lt;LI data-line="254"&gt;&lt;A href="https://learn.microsoft.com/power-platform/admin/programmability-tutorial-create-daily-capacity-report" data-href="https://learn.microsoft.com/power-platform/admin/programmability-tutorial-create-daily-capacity-report" target="_blank"&gt;Tutorial: Create a daily capacity report&lt;/A&gt;&amp;nbsp;— Microsoft's own end-to-end SDK example&lt;/LI&gt;
&lt;LI data-line="255"&gt;&lt;A href="https://learn.microsoft.com/power-platform/admin/online-requirements" data-href="https://learn.microsoft.com/power-platform/admin/online-requirements" target="_blank"&gt;Power Platform URLs and IP address ranges&lt;/A&gt; — for network allow-lists&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Mon, 08 Jun 2026 13:54:14 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/power-platform-tenant-inventory-a-community-showcase-of-the-api/ba-p/4519598</guid>
      <dc:creator>PravinT</dc:creator>
      <dc:date>2026-06-08T13:54:14Z</dc:date>
    </item>
    <item>
      <title>Archiving Years of Dataverse Audit History
Before You Prune It — A Pragmatic, Open
Source Pattern</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/archiving-years-of-dataverse-audit-history-before-you-prune-it-a/ba-p/4519575</link>
      <description>&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;H2&gt;&lt;SPAN class="lia-text-color-10"&gt;Why the audit table is special&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;The&amp;nbsp;&lt;STRONG&gt;audit&amp;nbsp;table&lt;/STRONG&gt;&amp;nbsp;is different from the rest of Dataverse in two ways that matter for an archive design:&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;It’s an immutable, append-only record of&amp;nbsp;&lt;EM&gt;who changed what, when, and from where&lt;/EM&gt;&amp;nbsp;— the closest thing Dataverse has to a forensic ledger.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;The valuable part of an audit row is not the row itself; it’s the diff (old value → new value, attribute mask, related-record context). The audit row stores that diff in a packed&amp;nbsp;changedata&amp;nbsp;column, and the bound&amp;nbsp;RetrieveAuditDetails&amp;nbsp;function is what decodes it into a structured&amp;nbsp;OldValue&amp;nbsp;/&amp;nbsp;NewValue&amp;nbsp;/&amp;nbsp;ChangedAttributes&amp;nbsp;shape your downstream tools can actually query. Synapse Link with the Delta Lake profile&amp;nbsp;&lt;EM&gt;will&lt;/EM&gt;&amp;nbsp;carry the&amp;nbsp;changedata&amp;nbsp;column to the lake, but you still need a parser on the other side; this pattern calls&amp;nbsp;RetrieveAuditDetails&amp;nbsp;at archive-time so what lands in the destination is already decoded and immediately queryable.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;That combination makes the audit table the single most useful Dataverse table for:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;Regulatory and compliance investigations&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;“Why did this opportunity status change in Q3 of 2022?” forensic queries (years after the fact)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;Internal analytics on user behaviour and process adoption&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;It’s also the table that grows the fastest. The Dataverse default retention is 90 days, but in practice many enterprises extend that to several years — or set it to&amp;nbsp;&lt;EM&gt;never delete&lt;/EM&gt;&amp;nbsp;— to retain evidence for compliance and forensic review. The result, often after five to seven years, is an audit table holding tens of GB to multiple TB of capacity, dominating the entitlement bill, and rarely accessed in normal operations.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;At that point the storage conversation becomes unavoidable. The realistic choices are:&lt;/SPAN&gt;&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Keep buying entitlement.&lt;/STRONG&gt;&amp;nbsp;Predictable, but unbounded.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Move the cold tail somewhere cheaper that you control, then let Dataverse’s audit-deletion job reclaim the space.&lt;/STRONG&gt;&amp;nbsp;The hot months stay in Dataverse where users expect them; the years of historical evidence live in your own storage account, queryable when you need them.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;This pattern is for option 2 — specifically, for the&amp;nbsp;&lt;EM&gt;one-time bulk export of multi-year history&lt;/EM&gt;, with the option to keep a slow trickle running afterwards if you want to top up.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;A crucial point that often gets lost: this pipeline does not need to run live. It is perfectly reasonable to be deliberately months or years behind real-time. The goal is to get a defensible copy of&amp;nbsp;&lt;EM&gt;cold&lt;/EM&gt;&amp;nbsp;data out — the rows you are about to allow Dataverse to delete — not to mirror the audit feed in real time.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN class="lia-text-color-10"&gt;What “good” looks like for an external audit copy&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;Before showing any code, here’s the rubric I held this design to. If you build your own, hold yours to the same rubric:&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;SPAN class="lia-text-color-20"&gt;Property&lt;/SPAN&gt;&lt;/th&gt;&lt;th&gt;&lt;SPAN class="lia-text-color-20"&gt;Why it matters&lt;/SPAN&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Idempotent&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;Re-running the same time window must not duplicate rows. Network blips happen.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Crash-safe (exactly-once-effective)&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;If the process dies mid-window, the next run must replay the same window cleanly. The watermark advances&amp;nbsp;&lt;EM&gt;only&lt;/EM&gt;&amp;nbsp;after the data is durable in the destination.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Bounded memory&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;A backlog of millions of audits cannot be loaded all at once.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Backpressure-aware&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;Dataverse rate-limits aggressively. Throttle responses must not drop rows.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Observable&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;Every window logs&amp;nbsp;[entity] mode=BACKLOG/LIVE, lag=Nmin, window=10min, records=N&amp;nbsp;so you can watch it work.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Sink-agnostic&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;The “where does it land” decision is config, not code. Storage choices change; the orchestrator shouldn’t.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Field-level discretion&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;Audit details can carry PII. The pattern should let admins narrow which attributes leave the platform.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H2&gt;&lt;SPAN class="lia-text-color-10"&gt;The pattern&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;The pipeline is conceptually four stages, repeated per entity, per time window:&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;Three details in this picture do most of the resiliency work. They are deceptively simple:&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN class="lia-text-color-10"&gt;Detail 1: Half-open time windows (ge&amp;nbsp;/&amp;nbsp;lt)&lt;/SPAN&gt;&lt;/H3&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;The boundary moment (09:10:00.000) belongs to window 2, not window 1. So adjacent windows never overlap and never gap, no matter how many times you replay. This is the same trick Kafka uses for offsets — it’s why you can run the loop with confidence.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN class="lia-text-color-10"&gt;Detail 2: The destination document key is the Dataverse&amp;nbsp;auditid&amp;nbsp;GUID&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;Dataverse already assigns a globally unique GUID to every audit row. That GUID becomes the document&amp;nbsp;id&amp;nbsp;in the sink. So when you upsert the same audit twice, the second write is a no-op overwrite of the first — idempotency for free, no client-side dedupe table to maintain.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN class="lia-text-color-10"&gt;Detail 3: The watermark moves&amp;nbsp;&lt;EM&gt;after&lt;/EM&gt;&amp;nbsp;the write, not with it&lt;/SPAN&gt;&lt;/H3&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;The naive version of this pipeline does:&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;The resilient version raises a typed exception when&amp;nbsp;&lt;EM&gt;any&lt;/EM&gt;&amp;nbsp;record fails, and the watermark update is conditional on a clean write:&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;This single change is the difference between “best effort” and “exactly-once-effective.” It’s also the mistake most often made when people roll their own.&lt;/SPAN&gt;&lt;/P&gt;
&lt;img /&gt;
&lt;H2&gt;&lt;SPAN class="lia-text-color-10"&gt;Choosing where it lands&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;The orchestrator is sink-agnostic — it talks to a single&amp;nbsp;AuditSink&amp;nbsp;interface (get_state,&amp;nbsp;update_state,&amp;nbsp;write_audits) and the destination is a config switch, not a code change. The reference implementation ships with four production-shaped sinks plus a no-op for testing. None of them is&amp;nbsp;&lt;EM&gt;the&lt;/EM&gt;&amp;nbsp;answer; they map to platforms enterprises already operate:&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;SPAN class="lia-text-color-20"&gt;Sink&lt;/SPAN&gt;&lt;/th&gt;&lt;th&gt;&lt;SPAN class="lia-text-color-20"&gt;When to consider it&lt;/SPAN&gt;&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Azure Cosmos DB (NoSQL API)&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;Operational lookups — “show me everything user X did to record Y in 2022” in milliseconds. Hierarchical partition keys (/entity&amp;nbsp;+&amp;nbsp;/auditYearMonth) keep partitions small as the archive grows over years. Document TTL doubles as a retention policy if you want one. Serverless mode suits a slow-trickle archive workload.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Azure Data Lake Storage Gen2 (Parquet)&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;The cheap-cold-storage option. Years of audit history land as partitioned Parquet files (entity=…/year=…/month=…/), readable from Fabric notebooks, Synapse Serverless SQL, Databricks, or any Parquet engine. Costs scale with bytes, not throughput — ideal when the archive is rarely queried but must exist.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;OneLake (Parquet)&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;Same Parquet shape as ADLS, but landed inside a&amp;nbsp;&lt;A href="https://learn.microsoft.com/fabric/onelake/onelake-overview" target="_blank"&gt;Microsoft Fabric&lt;/A&gt;&amp;nbsp;Lakehouse. Immediately queryable from a Fabric SQL endpoint, notebooks, and Power BI without further plumbing. The natural choice if your downstream BI is Fabric.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Snowflake (MERGE INTO)&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;The natural choice when Snowflake is already the analytics platform of record and adding a separate Microsoft analytics estate just for audit data isn’t on the table.&amp;nbsp;MERGE INTO ... ON audit_id&amp;nbsp;keeps the same idempotency contract as the Cosmos upsert, and the warehouse stays paused between archival batches.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;No-op (logs only)&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/td&gt;&lt;td&gt;&lt;SPAN class="lia-text-color-20"&gt;First-day connectivity testing. Confirms the Dataverse side works before you provision any storage.&lt;/SPAN&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 50.00%" /&gt;&lt;col style="width: 50.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;A reasonable default split many enterprises arrive at:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;ADLS Gen2 / OneLake&lt;/STRONG&gt;&amp;nbsp;(or&amp;nbsp;&lt;STRONG&gt;Snowflake&lt;/STRONG&gt;, if that’s your platform) holds the durable historical archive — cheap, partitioned, queryable when (rarely) needed.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Cosmos DB&lt;/STRONG&gt;&amp;nbsp;holds the most recent N months for fast operational lookup if there is a use case for it; otherwise skip it entirely.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;Adding a sink for storage you already own (e.g., BigQuery, Redshift, on-prem object storage) is roughly 100 lines of Python and one factory entry.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN class="lia-text-color-10"&gt;What real-world numbers will look like&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;The worked test run above shows what a clean sandbox run looks like. Real numbers in your tenant will vary by orders of magnitude depending on:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;How many entities have auditing enabled&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;The shape of&amp;nbsp;RetrieveAuditDetails&amp;nbsp;calls (more changed attributes per row = more bytes per call)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;Dataverse Web API rate limits applicable to your environment&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;Concurrency you allow (max_concurrent_entities&amp;nbsp;in the config)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;Sink throughput (Cosmos serverless RU autoscale, ADLS upload bandwidth, Snowflake warehouse size)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;The useful operational signal is not the absolute throughput — it’s that the throughput is&amp;nbsp;&lt;EM&gt;stable&lt;/EM&gt;&amp;nbsp;and the per-window log lines tick predictably. If they don’t, look at lag, sink errors, or 429 responses from Dataverse before scaling up concurrency.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN class="lia-text-color-10"&gt;When to reach for it (and when not to)&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Reasonable fit:&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;You have multiple years of accumulated audit history in Dataverse and need to move the cold tail off the platform before pruning to reclaim entitlement.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;You want the&amp;nbsp;&lt;EM&gt;decoded&lt;/EM&gt;&amp;nbsp;RetrieveAuditDetails&amp;nbsp;payload (old value → new value, attribute mask, related-record context) landing in the destination ready to query — rather than the packed&amp;nbsp;changedata&amp;nbsp;column Synapse Link delivers, which still needs a parser on the consumer side.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;Your analytics platform of record sits outside Azure (most commonly Snowflake) and you don’t want to add Synapse + ADLS + Spark to your stack just to land the audit table.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;Synapse Link isn’t an option in your tenant — region pairing, governance review, or the cost floor of running ADLS + a Spark pool 24/7 don’t fit your environment.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;You’re comfortable running this as a&amp;nbsp;&lt;EM&gt;batch job&lt;/EM&gt;&amp;nbsp;— once for the historical backfill, then perhaps quarterly or annually to top up — rather than as a live continuous feed. Being deliberately months or years behind real-time is fine and often desirable.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;You want field-level control over which attributes leave the platform — useful when audit details contain regulated data.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;STRONG&gt;Not a good fit:&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;You can run&amp;nbsp;&lt;A href="https://learn.microsoft.com/power-platform/admin/audit-data-azure-synapse-link" target="_blank"&gt;Azure Synapse Link with the Delta Lake profile&lt;/A&gt;&amp;nbsp;&lt;EM&gt;and&lt;/EM&gt;&amp;nbsp;you’re happy parsing the packed&amp;nbsp;changedata&amp;nbsp;column on the consumer side,&amp;nbsp;&lt;EM&gt;and&lt;/EM&gt;&amp;nbsp;your destination is ADLS / Synapse / Power BI. That’s the supported, first-class path for the audit table — use it.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;You only need&amp;nbsp;&lt;EM&gt;current state&lt;/EM&gt;&amp;nbsp;of business tables (account, contact, opportunity). Use Synapse Link / Fabric Link — they do exactly that and you don’t need this pattern.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;You need sub-second freshness in the destination. The pattern’s natural cadence is one window length (10 min in the reference config); for true real-time, use Dataverse webhooks or change-tracking APIs.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;You don’t have somewhere to operate a small Python container, function, or scheduled job — even an annual one.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;You don’t have an internal owner who can be paged when the schedule fails.&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;&lt;SPAN class="lia-text-color-10"&gt;The reference implementation&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;The code that backs this post lives at&amp;nbsp;&lt;A href="https://github.com/SweetsNSavories/DataverseAuditLogSyn" target="_blank"&gt;https://github.com/SweetsNSavories/DataverseAuditLogSyn&lt;/A&gt;&amp;nbsp;under MIT, with no warranty. The&amp;nbsp;unified-deployment&amp;nbsp;folder is the version this post describes — single Python codebase, swap sinks via&amp;nbsp;config.json, runs locally / in a container / as an Azure Function.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;If you want the implementation depth this post deliberately leaves out — exact API shapes, watermark math, partial-failure drill, sink-author checklist, hosting variants, observability hooks, and the full list of operational responsibilities a self-hosted export carries — it all lives in one place:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN class="lia-text-color-20"&gt;&lt;A href="https://github.com/SweetsNSavories/DataverseAuditLogSyn/blob/main/unified-deployment/DESIGN.md" target="_blank"&gt;&lt;STRONG&gt;unified-deployment/DESIGN.md&lt;/STRONG&gt;&lt;/A&gt;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;Issues, forks, and pull requests welcome via the repo.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN class="lia-text-color-20"&gt;Generated 2026-05-14 from&amp;nbsp;&lt;A href="https://github.com/SweetsNSavories/DataverseAuditLogSyn/blob/main/docs/blog/archiving-dataverse-audit-logs.md" target="_blank"&gt;https://github.com/SweetsNSavories/DataverseAuditLogSyn/blob/main/docs/blog/archiving-dataverse-audit-logs.md&lt;/A&gt; · MIT licensed reference implementation, no warranty.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 08 Jun 2026 13:53:50 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/archiving-years-of-dataverse-audit-history-before-you-prune-it-a/ba-p/4519575</guid>
      <dc:creator>PravinT</dc:creator>
      <dc:date>2026-06-08T13:53:50Z</dc:date>
    </item>
    <item>
      <title>Azure OpenAI Architecture: The Decisions That Actually Matter (Part 2)</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/azure-openai-architecture-the-decisions-that-actually-matter/ba-p/4525983</link>
      <description>&lt;H1&gt;Introduction&lt;/H1&gt;
&lt;P&gt;In Part 1 of this series, we walked through the architectural decisions that shape any Azure OpenAI / Microsoft Foundry Models workload: capacity model, deployment location, governance layer, grounding strategy, and quota engineering. Part 2 moves from decisions to discipline. Once you have made those choices, how do you make sure your design holds up to the Azure Well-Architected Framework (WAF)?&lt;/P&gt;
&lt;P&gt;The five WAF pillars — Cost Optimization, Security, Reliability, Performance Efficiency, and Operational Excellence — apply just as strongly to GenAI systems as they do to traditional cloud workloads. In fact, they matter more, because GenAI systems are not static: models are upgraded and deprecated, quotas shift, usage patterns grow unpredictably, and new capacity tiers (such as Priority Processing) are introduced while you are running in production.&lt;/P&gt;
&lt;P&gt;This post walks through each pillar in the context of Azure OpenAI in Microsoft Foundry, with best practices, common pitfalls, and the trade-offs Cloud Solution Architects (CSAs) tend to hit in real engagements. Where details are time-sensitive — pricing percentages, SLA windows, model retirement timelines, regional rollout delays — they are flagged with "At the time of writing". Always confirm current behavior against Microsoft Learn before committing to a design.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Who is this series for?&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Cloud and Solution Architects&lt;/LI&gt;
&lt;LI&gt;Platform and product owners&lt;/LI&gt;
&lt;LI&gt;Senior developers responsible for operating Azure OpenAI workloads in production&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;What you’ll learn in Part 2:&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;How each WAF pillar maps to concrete Azure OpenAI design choices.&lt;/LI&gt;
&lt;LI&gt;Where Priority Processing fits across cost and performance trade-offs (and what its eligibility constraints are).&lt;/LI&gt;
&lt;LI&gt;How to plan for model lifecycle events — upgrades, deprecations, retirements — without firefighting.&lt;/LI&gt;
&lt;LI&gt;Which signals to monitor day-to-day, and how to bake them into a GenAIOps loop.&lt;/LI&gt;
&lt;LI&gt;A WAF Decision Matrix at the end of the article, to use as a reusable checklist.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In Part 3, we will look at the part that makes GenAI architecture genuinely different from a traditional service: the platform itself never stops moving.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;We’ve also included a summary decision matrix at the end of this post for quick reference.&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;1. Cost Optimization: Designing for Sustainable Scale&lt;/H1&gt;
&lt;P&gt;Cost optimization in GenAI is primarily a capacity strategy problem, not just a token-pricing problem. The first question is whether to use pay-as-you-go capacity, reserved capacity, or one of the newer tiers in between.&lt;/P&gt;
&lt;H2&gt;Reserved capacity (Provisioned Throughput Units, PTUs)&lt;/H2&gt;
&lt;P&gt;If your workload is steady or growing predictably, you can significantly reduce costs by reserving capacity up front for 1 or 3 years. At the time of writing, reservations typically yield in the range of 30–50% savings compared to hourly pay-as-you-go rates — but the exact discount depends on term length, region, and the model family, so always confirm against the current Azure pricing page.&lt;/P&gt;
&lt;P&gt;Fully utilizing a reserved (provisioned) deployment turns cloud spend into a predictable infrastructure investment, much like allocating VM or database capacity. This requires a mindset shift: treat a provisioned Azure OpenAI deployment as always-on infrastructure sized for peak demand, not as on-demand burst capacity.&lt;/P&gt;
&lt;P&gt;Importantly, PTU quota is now model-agnostic within a region. You purchase generic throughput units that can be applied to any supported model in that region, so you do not risk stranded capacity when upgrading (say, from one GPT-4 family version to a newer one) or changing model versions. Your investment follows your architecture, not a specific model endpoint.&lt;/P&gt;
&lt;H2&gt;Avoid dynamic PTU "auto-scaling"&lt;/H2&gt;
&lt;P&gt;Unlike VM-based infrastructure, dynamically scaling Azure OpenAI capacity up and down to chase cost savings is not recommended. Additional capacity is not guaranteed to be instantly available when you need to scale up, especially if other tenants are consuming the region's resources. Frequent resizing can also negate the benefits of reservations and introduce performance variability. Unused PTUs are not waste — they are headroom that absorbs burst traffic. In practice, design for the peak load and optimize through reservations rather than trying to constantly dial capacity up and down.&lt;/P&gt;
&lt;H2&gt;Batch tier&lt;/H2&gt;
&lt;P&gt;Use Batch deployments for asynchronous, non-user-facing jobs (large-scale document processing, nightly data enrichment, evals, embeddings backfills). At the time of writing, Batch can reduce cost per token by up to around 50% compared to Standard pay-as-you-go calls, in exchange for a 24-hour completion window. It also takes pressure off your real-time deployments.&lt;/P&gt;
&lt;H2&gt;Priority Processing&lt;/H2&gt;
&lt;P&gt;For workloads that need prompt responses but do not yet warrant a full dedicated PTU deployment, Azure OpenAI offers Priority Processing. Functionally, it is pay-per-token like Standard, but with SLA-backed lower and more consistent latency on the shared infrastructure.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Activation&lt;/STRONG&gt;: set the service_tier attribute on the request to "priority" (other values are "default" and "auto").&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Model eligibility:&lt;/STRONG&gt; at the time of writing, requires model versions released on or after 2025-12-01.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Deployment eligibility: &lt;/STRONG&gt;only available on Global Standard or Data Zone Standard (US) deployments.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Pricing:&lt;/STRONG&gt; at the time of writing, roughly 20–40% higher per-token cost than Standard, but still meaningfully cheaper than reserving PTU for a low-volume latency-critical path.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Treat Priority Processing as the natural in-between rung: more predictable than Standard for latency-sensitive production traffic, but without the commitment and capacity-planning effort of PTU.&lt;/P&gt;
&lt;H2&gt;Putting it together&lt;/H2&gt;
&lt;P&gt;Segment your workloads by interaction pattern and performance need, then assign the most cost-efficient capacity model to each. A common anti-pattern is over-provisioning expensive real-time capacity for jobs that could run asynchronously. Evaluate whether each use case truly requires sub-second latency, or whether a longer batch window (minutes or hours) is acceptable. Use real-time capacity for customer-facing queries and time-sensitive tasks; use Batch or Priority Processing for everything else, depending on tolerance for latency.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [&lt;/EM&gt;&lt;/STRONG&gt;&lt;EM&gt;Diagram 1 — Cost Strategy Layering]&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;2. Security: Compliance, Isolation, and Data Protection&lt;/H1&gt;
&lt;P&gt;Security in Azure OpenAI begins with deciding where your inference runs and how data is handled. This is often a compliance-driven decision before it is an architectural one.&lt;/P&gt;
&lt;H2&gt;Deployment scope&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Global deployments&lt;/STRONG&gt; — Maximize model availability and capacity by allowing Azure to route inference across regions. Pro: broad elasticity and access to the latest models. Con: data is not confined to a single geography, which may violate strict data residency requirements. Global also adds slight troubleshooting complexity, since requests can be served from various regions.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Data Zone deployments&lt;/STRONG&gt; — Constrain inference to a specific zone or political boundary (for example, EU-only or US-only Data Zones). Pro: a compliance-friendly middle ground — data processing stays within a defined region set (for example, entirely within the EU to satisfy GDPR), while retaining more elasticity than a single region. Con: slightly reduced model availability and capacity headroom compared to Global.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Regional deployments&lt;/STRONG&gt; — Confine inference to one Azure region. Pro: meets the most stringent data sovereignty requirements and can minimize latency for users in that region. Con: limited to the capacity and models available in one region, with no automatic overflow if the region is saturated. New model versions may also roll out to some regions later than others — at the time of writing we have observed delays of roughly 2–6 months for certain releases in specific regions; check Microsoft Learn for the current rollout schedule.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Choosing among these is a regulatory risk-management decision, not just an infrastructure preference. Engage your compliance and data governance teams early to determine the minimum scope of data movement that satisfies requirements. Many teams initially over-constrain this choice out of caution; it is often better to start with a broader deployment (Global or multi-region Data Zone) where permissible, and tighten the scope later if needed. Conversely, if your organization mandates that all data stay in-country, you might go straight to Regional and invest in architectural mitigation for its limitations (capacity planning, multi-region backup plans).&lt;/P&gt;
&lt;H2&gt;Baseline protections + defense in depth&lt;/H2&gt;
&lt;P&gt;Regardless of deployment type, Azure OpenAI provides baseline protections: it does not use your prompts or completions to train the underlying models, and all data is encrypted in transit (TLS 1.2+) and at rest (AES-256). Defense in depth is still essential — implement compensating controls at multiple layers:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Redact sensitive data&lt;/STRONG&gt; from prompts (or prevent it from being entered) at the client or gateway layer. Use Azure API Management policies or custom middleware to strip out PII or secrets before requests reach the model.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Apply content filtering&lt;/STRONG&gt; to both prompts and responses. Use the built-in content filters and/or Azure AI Content Safety to detect and block sensitive or undesirable input and output.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Use strong authentication and role-based access control.&lt;/STRONG&gt; Front your Azure OpenAI endpoint with Microsoft Entra ID; scope tokens with least privilege (for example, the Cognitive Services OpenAI User role or managed identity access) instead of distributing master API keys. If a credential is compromised, the blast radius is limited.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;Additional best practices&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Managed Identities &lt;/STRONG&gt;— use them for any internal communication between your application and Azure OpenAI (or other Azure services like storage and databases) instead of embedding API keys. This eliminates the risk of leaking secrets and simplifies credential rotation.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Private endpoints&lt;/STRONG&gt; — enable Azure Private Link to keep traffic between your application and the Azure OpenAI service inside your virtual network and the Azure backbone, off the public internet.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Content Safety tooling&lt;/STRONG&gt; — integrate Azure AI Content Safety or custom validation functions to scan prompts and completions for policy violations or confidential data. This extra inspection layer can catch issues the base filter misses, and lets you log or modify disallowed content before it reaches the user.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In short, security for GenAI is not just about encryption or API keys — it is about reducing the blast radius of any potential breach or misuse. Confine inference to approved locations, strip sensitive data before it reaches the model, and strictly limit which identities and networks can call your endpoints.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&amp;nbsp;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [Diagram 2 — Data Boundary Visualization]&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H1&gt;3. Reliability: Designing for Change, Not Just Stability&lt;/H1&gt;
&lt;P&gt;Reliability in Azure OpenAI is as much about managing model evolution as it is about traditional uptime. Unlike static services, GenAI models are periodically updated and improved by the provider. New versions are released, older versions are deprecated and eventually retired — so a truly reliable system must plan for these changes just as carefully as it plans for hardware failures.&lt;/P&gt;
&lt;H2&gt;Model lifecycle&lt;/H2&gt;
&lt;P&gt;At the time of writing, Generally Available (GA) models are typically supported for at least 12 months after release, followed by a deprecation phase of roughly 6 months before retirement. Always confirm the current support windows on Microsoft Learn before locking in a design — these timelines have shifted in the past and may shift again as new model families ship.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;When retirement hits:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Standard deployments still pinned to a retired model (with "No Auto-Upgrade" set) stop responding to requests entirely — the API typically returns HTTP 404 (or a similar error) for that model name.&lt;/LI&gt;
&lt;LI&gt;Provisioned deployments using a retired model return HTTP 410 (Gone) errors until you manually switch them to a supported model.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In short, every model version you deploy has a built-in expiration date. Good reliability planning means never being caught unprepared by a model retirement.&lt;/P&gt;
&lt;H2&gt;Auto-upgrade modes for Standard deployments&lt;/H2&gt;
&lt;P&gt;Three modes are available:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Auto-upgrade to the latest version&lt;/STRONG&gt; — the deployment moves to the new default model version as soon as Azure makes it available. Always on a supported version, but you have no control over timing. Generally not recommended for mission-critical production workloads, since new versions can have different behavior.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Upgrade only on retirement&lt;/STRONG&gt; — the deployment stays on its current version until that version is about to be retired, then automatically switches to the latest. Recommended for most production Standard deployments: stability during the model's supported lifespan, with continuity guaranteed at retirement. You still need to test and adjust to the new version, but at least you do not face an outage if you miss the date.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;No auto-upgrade&lt;/STRONG&gt; — the deployment stays pinned to a specific version unless you change it manually. Not recommended for production: it puts the entire burden on you to track retirement timelines.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Most teams choose option 2 ("upgrade on retirement") for Standard. It allows controlled change during the model's supported period and provides a safety net at retirement. Proactively evaluate new versions for quality, performance, and cost before the forced swap, but the setting greatly reduces the risk of surprise outages.&lt;/P&gt;
&lt;H2&gt;Provisioned (PTU) migrations&lt;/H2&gt;
&lt;P&gt;Provisioned deployments do not support auto-upgrade — you must manage these migrations yourself. Azure sends retirement announcements via Azure Service Health alerts and emails, at the time of writing typically 60 days or more in advance. Have a runbook ready. Two approaches are common:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;In-place migration &lt;/STRONG&gt;— upgrade the deployment's model version through the portal or CLI. The endpoint stays the same and the model is updated behind it. Fast, no new connection string, but expect a brief disruption during the switch and rollback is not straightforward (you may need to contact support to re-enable the old version, if at all possible).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Side-by-side (blue/green) &lt;/STRONG&gt;— create a new deployment with the new model version in parallel. Gradually shift traffic (for example, 10% via APIM routing rules), monitor, and roll back instantly if needed. Maximum control and safety, at the cost of running two deployments in parallel for the migration window.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Before any model migration, verify you have sufficient PTU quota in the region for the new model. More advanced models may require more throughput units for the same workload than smaller predecessors — at the time of writing, plan for the possibility that a new generation needs roughly two times (or more) the PTUs to deliver similar throughput. Request quota increases before you hit the upgrade window, not during it.&lt;/P&gt;
&lt;H2&gt;Multi-region strategy&lt;/H2&gt;
&lt;P&gt;Consider a multi-region strategy to improve reliability during model rollouts and deprecations. New model versions do not always appear in all regions simultaneously — at the time of writing, Microsoft often launches a model in one region (frequently East US or West Europe) first.&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Maintain a secondary deployment&lt;/STRONG&gt; in a "first-wave" region to evaluate new versions early.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Use a traffic manager &lt;/STRONG&gt;(Azure Front Door, Traffic Manager) to fail over to a region where the model is still available if your primary region lags behind.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Multi-region active-active &lt;/STRONG&gt;designs also protect you against single-region outages.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In essence, reliability for GenAI means designing for change. A highly reliable platform is not one that never changes; it is one that changes gracefully. Model upgrades, deprecations, and capacity adjustments should be routine, well-rehearsed events — not fire drills. Achieving this typically requires automation for detecting and applying updates, redundant deployments or regions for flexibility, and ongoing testing of new models well before your current ones retire.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [Diagram 3 — Model Upgrade Strategy]&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;H1&gt;4. Performance Efficiency: Predictability Over Raw Speed&lt;/H1&gt;
&lt;P&gt;Performance in GenAI is multi-dimensional. It is not just about raw throughput or the fastest response on an empty system — it is about consistent, predictable latency at scale. Users care that responses are reliably snappy under load, not just fast in ideal conditions.&lt;/P&gt;
&lt;H2&gt;Performance profiles by capacity model&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Standard &lt;/STRONG&gt;(shared infrastructure) — multi-tenant, no guaranteed latency SLA. Performance fluctuates with regional demand; you may see throttling (HTTP 429) at peak. Best-effort: great for development, testing, and non-critical workloads, but not a fit for consistent low latency under spikes.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Priority Processing &lt;/STRONG&gt;— also shared infrastructure, but your requests jump the queue ahead of Standard traffic. At the time of writing, this is the only pay-per-token tier with an SLA on latency. Activated by setting the service_tier attribute to "priority" on each request (other values: "default", "auto"). Requires model versions released on or after 2025-12-01 and is only available on Global Standard or Data Zone Standard (US) deployments. Pricing premium is roughly 20–40% over Standard. The natural fit for latency-sensitive workloads at intermediate scale — better than Standard, without committing to PTU.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Provisioned Throughput &lt;/STRONG&gt;(dedicated capacity) — reserved capacity with isolation from other tenants. The most consistent performance and the strongest Azure SLA on latency (typically bounded p50 and p99 within your provisioned capacity). If your application has strict response-time requirements or user-facing SLAs and the volume justifies it, PTU is the right answer.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;A practical pattern: Standard for early-stage and non-critical scenarios; Priority Processing for latency-sensitive paths that have not yet earned a PTU reservation; PTU for steady, high-volume, latency-critical production traffic.&lt;/P&gt;
&lt;H2&gt;Model selection and configuration&lt;/H2&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Model size&lt;/STRONG&gt; — smaller models generally respond faster than larger ones. Do not automatically pick the biggest model if a smaller one meets your quality bar.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;max_tokens &lt;/STRONG&gt;— capping response length caps worst-case latency and cost. A 500-token cap finishes sooner than 2000 tokens, even when users ask open-ended questions.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Sampling parameters&lt;/STRONG&gt; — low temperature (more deterministic) and a high top_p can shave a small amount of processing overhead versus highly creative or multi-sample setups. Minor compared to model size and length, but real.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Streaming responses&lt;/STRONG&gt; — enable streaming wherever possible. The first tokens arrive immediately while the model is still generating; perceived latency drops dramatically even when total time is unchanged.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Treat performance as an explicit design goal. Choose the right capacity model for the job, tune model settings to avoid unnecessary slowdowns, and do not over-engineer with a larger model than needed. A common mistake is defaulting to the biggest model "just in case". Benchmark — a smaller model with good prompt engineering often delivers a fraction of the latency at a fraction of the cost, with negligible quality loss.&lt;/P&gt;
&lt;H1&gt;5. Operational Excellence: Running GenAI as a Living System&lt;/H1&gt;
&lt;P&gt;Operational excellence in GenAI means treating your platform as a continuously evolving product. Models change, user behavior shifts, new features ship. Success requires ongoing monitoring, maintenance, and improvement processes — often called GenAIOps (or MLOps for generative AI).&lt;/P&gt;
&lt;H2&gt;Proactive monitoring&lt;/H2&gt;
&lt;P&gt;Set up Azure Service Health alerts for your Azure OpenAI / Foundry resource to be notified about service incidents and, importantly, upcoming model deprecations or retirements. At the time of writing, Microsoft typically gives around 60 days of notice for retirement events — but it is easy to miss those notifications if no one is watching. Early awareness lets you test new models and plan migrations calmly instead of reacting at the last minute.&lt;/P&gt;
&lt;P&gt;Continuously track key metrics in Azure Monitor or Application Insights, with alerts on anomalies:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Latency percentiles &lt;/STRONG&gt;— monitor p50, p95, and p99. A trend up in tail latency is an early warning of saturation or regression.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Error rates&lt;/STRONG&gt; — watch HTTP 429 (throttling) and HTTP 503 (server) error trends. Spikes signal capacity limits or service-side issues.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Capacity utilization&lt;/STRONG&gt; — for PTU, watch utilization continuously. Sustained operation near 100% means no headroom for bursts. On Standard, watch token usage against subscription limits and quotas.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Token consumption trends&lt;/STRONG&gt; — track growth over time. Helps with cost forecasting and reveals runaway usage (unexpectedly popular features, looping clients).&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Useful alerting practices: alert on p99 latency breaching a threshold, on any sustained increase in 429s, or when PTU utilization regularly exceeds around 80%. Early warning lets you scale up, optimize, adjust prompts, or throttle specific users before user experience suffers.&lt;/P&gt;
&lt;H2&gt;Evaluation and reproducibility&lt;/H2&gt;
&lt;P&gt;Use the evaluation tooling in Azure AI Foundry to compare outputs from two models side by side on a fixed set of test prompts. Re-evaluate periodically — slowly degrading quality often goes unnoticed without a structured comparison.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Implement Infrastructure-as-Code (IaC) and GitOps practices &lt;/STRONG&gt;for your Azure OpenAI and supporting resources (APIM, storage, key vault, monitoring). Bicep, ARM, or Terraform templates checked into source control make environments reproducible across dev/test/prod, simplify recovery, and enable change tracking. If something breaks, you can roll back to a known-good configuration quickly.&lt;/P&gt;
&lt;P&gt;In summary, operational excellence for GenAI is about continuous learning and improvement. Embrace an AI DevOps culture: invest in monitoring, train your team on model changes, keep optimizing prompts and configurations, and refine processes after each lesson learned. The effort pays off by preventing fire-drills and keeping the platform robust as it evolves.&lt;/P&gt;
&lt;H1&gt;Final Perspective and Key Takeaways&lt;/H1&gt;
&lt;P&gt;Applying the Well-Architected Framework to Azure OpenAI forces a higher level of architectural rigor — exactly what GenAI projects in production need. Each pillar drives concrete decisions.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Key takeaways from Part 2:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Cost Optimization&lt;/STRONG&gt; — align capacity to workload patterns. Reserve for steady, predictable load; use Batch for offline jobs; use Priority Processing for latency-sensitive paths that do not yet justify PTU; do not pay for ultra-low latency you do not need.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Security&lt;/STRONG&gt; — match deployment scope (Global, Data Zone, Regional) to compliance requirements, then layer controls (network isolation, identity and access, data sanitization, content filtering) to minimize blast radius.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Reliability&lt;/STRONG&gt; — anticipate continuous model evolution. Use upgrade-on-retirement for Standard, run parallel deployments for PTU migrations, and design for multi-region failover where it matters. Reliability is about avoiding surprises, not just outages.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Performance Efficiency&lt;/STRONG&gt; — choose the right capacity model, right-size models and responses, and use streaming. A smaller model with good prompt engineering often beats a bigger one on user experience.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Operational Excellence &lt;/STRONG&gt;— treat the platform as a living product. Monitor, alert, automate, evaluate, and version everything as code. The discipline keeps the platform improving instead of decaying.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;The organizations that succeed with Azure OpenAI / Microsoft Foundry Models are those that treat capacity planning, security and compliance, model lifecycle management, and governance as first-class design concerns — not afterthoughts. Generative AI architecture is not about deploying a model and walking away; it is about building a resilient, adaptable platform that gracefully evolves as models change and usage grows.&lt;/P&gt;
&lt;P&gt;In Part 3, we bring everything together into a comprehensive reference architecture for an enterprise-grade Azure OpenAI platform — combining scalable capacity strategies, layered security and governance, proactive lifecycle (GenAIOps) practices, and multi-region resiliency into a cohesive blueprint ready for production.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [Diagram 4 — WAF pillars summary]&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;WAF Decision Matrix : Quick Reference&lt;/H1&gt;
&lt;P&gt;Use this as a checklist when reviewing or sign-off-ing an Azure OpenAI / Microsoft Foundry Models design. One row per decision; one rule of thumb per row.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Pillar&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Decision&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Rule of thumb&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Watch out for&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;nbsp;&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Capacity tier mix&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Variable load → Standard. Latency-critical → Priority Processing. Offline bulk → Batch. Steady high-volume → PTU.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Single-tier platforms over-pay for elasticity or under-deliver on latency.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Cost&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Reservation term (PTU)&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;1- or 3-year terms for predictable workloads; size for peak, not for average.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Dynamic resizing of PTU to chase savings; capacity not guaranteed at scale-up time.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Cost&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Priority Processing eligibility&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Requires service_tier="priority", model 2025-12-01+, Global Standard or Data Zone Standard (US).&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Assuming it works on every region/model — confirm eligibility before committing the design.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Security&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Deployment scope&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;No residency rule → Global. Multi-region zone OK → Data Zone. Strict residency → Regional.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Over-constraining out of caution; or under-constraining and missing a compliance requirement.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Security&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Identity and access&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Microsoft Entra ID + Managed Identity + scoped roles. No master keys in apps.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Long-lived API keys distributed across teams.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Security&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Network and data&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Private Link for in-network traffic; PII redaction at the gateway; content filtering on prompts and responses.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Public endpoints, raw PII in prompts, only relying on the built-in filter.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Reliability&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Auto-upgrade strategy&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Standard → "upgrade on retirement". PTU → planned blue/green migration with sufficient quota in advance.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Pinning Standard with no auto-upgrade and forgetting; in-place PTU migration with no rollback path.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Reliability&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Multi-region&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Active-active (or first-wave secondary) for critical paths; traffic manager for failover.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Single-region production with no plan for capacity or model-rollout lag.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Performance&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Capacity match&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Match capacity tier to latency target: Standard for non-critical; Priority for latency-sensitive; PTU for SLA-bound.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Expecting Standard to deliver consistent low latency under spike load.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Performance&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Model and response sizing&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Pick the smallest model that meets quality. Cap max_tokens. Stream responses.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Defaulting to the largest model "just in case"; long uncapped responses; no streaming.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Operations&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Monitoring and alerting&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Track p50/p95/p99, 429/503 rates, PTU utilization, and token trends. Alert on tail latency and sustained throttling.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Average-only dashboards; missed Service Health notifications for model retirements.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Operations&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;IaC and GitOps&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Bicep/ARM/Terraform under source control; reproducible dev/test/prod; pipeline-driven changes.&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Click-ops in the portal; environment drift between dev and prod.&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H1&gt;Disclaimer&lt;/H1&gt;
&lt;P&gt;&lt;EM&gt;I am a Microsoft employee. The views and opinions expressed in this article are my own and do not necessarily reflect those of Microsoft. This content is informational and educational; it is not an official Microsoft statement, recommendation, or commitment. Service tiers, model availability, pricing, SLAs, and feature eligibility evolve — always validate against the latest Microsoft Learn documentation before making architectural decisions.&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;References&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/well-architected/" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Azure Well-Architected Framework&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/overview" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Azure OpenAI in Microsoft Foundry — overview&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/provisioned-throughput" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Provisioned throughput for Azure OpenAI&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/foundry/openai/concepts/priority-processing" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Enable Priority Processing for Microsoft Foundry Models&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/batch" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Batch deployments for Azure OpenAI&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/concepts/model-retirements" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Model deprecations and retirements&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/legal/cognitive-services/openai/data-privacy" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Data, privacy, and security for Azure OpenAI&lt;/STRONG&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/managed-identity" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Use managed identities with Azure OpenAI&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/cognitive-services-virtual-networks" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Azure Private Link for Azure AI services&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/content-safety/" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Azure AI Content Safety&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/api-management/genai-gateway-capabilities" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Azure API Management — GenAI Gateway patterns&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/monitoring" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Monitor Azure OpenAI&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-foundry/concepts/evaluation-approach-gen-ai" target="_blank" rel="noopener"&gt;&lt;STRONG&gt;Azure AI Foundry evaluation tools&lt;/STRONG&gt;&lt;/A&gt;&lt;STRONG&gt; &lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
      <pubDate>Mon, 08 Jun 2026 13:53:24 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/azure-openai-architecture-the-decisions-that-actually-matter/ba-p/4525983</guid>
      <dc:creator>luciacasucci</dc:creator>
      <dc:date>2026-06-08T13:53:24Z</dc:date>
    </item>
    <item>
      <title>Azure OpenAI Architecture: The Decisions That Actually Matter (Part 1)</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/azure-openai-architecture-the-decisions-that-actually-matter/ba-p/4525976</link>
      <description>&lt;P&gt;Generative AI demos often succeed because they hide the hard parts of architecture. They usually run under ideal conditions: low, steady traffic, no sudden bursts, no competing teams, and minimal regulatory scrutiny. In production, however, Azure OpenAI systems face a very different reality – variable loads, service quotas, compliance constraints, evolving model versions, and the need for cost visibility.&lt;/P&gt;
&lt;P&gt;The difference between a great demo and a resilient production platform isn’t the model itself – it’s the early architectural decisions. The choices you make from day one determine whether your generative AI solution can handle real-world demand or buckle under pressure.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Who is this series for?&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Cloud and Solution Architects&lt;/LI&gt;
&lt;LI&gt;Platform and product owners&lt;/LI&gt;
&lt;LI&gt;Senior developers responsible for operating Azure OpenAI workloads in production&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;What you’ll learn in Part 1: &lt;/STRONG&gt;We’ll walk through five foundational design decisions for Azure OpenAI, explain why they matter, and highlight key trade-offs and pitfalls we’ve seen in real-world deployments:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Capacity Model&lt;/STRONG&gt; – Choosing between Standard (PAYGO), Priority Processing, Batch, or Provisioned Throughput (PTU)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Deployment Location&lt;/STRONG&gt; – Global vs. Data Zone vs. Regional hosting&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Governance Layer&lt;/STRONG&gt; – When and why to introduce a GenAI gateway&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Grounding Strategy&lt;/STRONG&gt; – When to use Retrieval-Augmented Generation (RAG)&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Quota Engineering&lt;/STRONG&gt; – How to plan for service limits and avoid throttling&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In Part 2, we’ll translate these principles into concrete implementations: multi-region topologies, cost allocation strategies, observability and monitoring patterns, and other best practices for reliability, security, and DevOps in Azure OpenAI. Part 3 will connect these decisions to GenAIOps best practices to help ensure your solution is future-proof.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;We’ve also included a summary decision matrix at the end of this post for quick reference.&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;1. Capacity Model: PAYGO, Priority, Batch, or Dedicated Throughput?&lt;/H1&gt;
&lt;P&gt;At the time of writing, Azure OpenAI (now part of Microsoft Foundry Models) offers four capacity models for hosting models, each with distinct cost, latency, and operational characteristics. Most production solutions combine two or more of these tiers:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Standard (pay-as-you-go, shared): &lt;/STRONG&gt;Multi-tenant, elastic capacity. You pay per token, with no upfront commitment and no cost when idle.&lt;/LI&gt;
&lt;LI&gt;Pros: Simple and flexible; ideal for dev/test and for moderate or unpredictable traffic patterns.&lt;/LI&gt;
&lt;LI&gt;Cons: No guaranteed throughput or low-latency SLA – performance may vary with regional load. Under heavy usage, you may see high latency or HTTP 429 “Too Many Requests” errors due to shared capacity limits.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Priority Processing (pay-per-token, SLA-backed low latency): &lt;/STRONG&gt;A pay-as-you-go service tier that routes traffic through reserved compute, giving consistent low latency for business-critical, user-facing workloads without buying PTUs. At the time of writing, it is available on Global Standard and Data Zone Standard (US) deployments and requires recent model versions (2025-12-01 or later). It can be enabled per deployment in Microsoft Foundry, or set on individual API calls via the optional service_tier attribute (auto / default / priority) on the chat completions and responses APIs. Always confirm current model and region eligibility in the Microsoft Learn article “Enable priority processing for Microsoft Foundry Models.”&lt;/LI&gt;
&lt;LI&gt;Pros: Predictable, low-latency responses with the simplicity of pay-per-token billing – a strong fit for bursty, business-hour, or latency-sensitive traffic where PTU commitment isn’t justified. Uses the same Standard quota pool, and can be layered on top of PTU for steady-state capacity plus an elastic priority lane for spikes.&lt;/LI&gt;
&lt;LI&gt;Cons: Per-token pricing is higher than Standard PAYGO. Requires eligible deployment types and current model versions, so it is not a drop-in for legacy deployments. Like all PAYGO modes, it is still subject to TPM/RPM limits and the same throttling behaviour if quota is exhausted.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Batch (asynchronous): &lt;/STRONG&gt;Offline job processing. You submit requests in bulk (e.g., via a file) and receive results after up to 24 hours.&lt;/LI&gt;
&lt;LI&gt;Pros: Optimized for high throughput at a much lower cost (roughly 50% less per token than real-time requests at the time of writing). Batch jobs use separate “enqueued tokens” quotas, so they won’t interfere with interactive traffic.&lt;/LI&gt;
&lt;LI&gt;Cons: Not suitable for real-time use – no immediate responses or latency guarantees. Requires extra orchestration (staging requests, handling outputs). At the time of writing, Batch does not support embedding models, so vector indexing jobs must use Standard mode – always check the Azure OpenAI documentation for the latest supported model list.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Provisioned Throughput (dedicated PTUs): &lt;/STRONG&gt;Reserved, dedicated capacity. You purchase a fixed amount of capacity (Provisioned Throughput Units) and pay for it hourly, whether used or not.&lt;/LI&gt;
&lt;LI&gt;Pros: Guaranteed throughput and consistent low latency, since you’re isolated from other tenants; suitable for high-volume services with strict SLAs.&lt;/LI&gt;
&lt;LI&gt;Cons: Requires careful sizing of PTUs to match your peak demand – under-provision and you’ll still get 429s (now self-inflicted), over-provision and you pay for unused capacity. In addition, output tokens count more heavily against PTU usage (e.g., generative tokens from GPT-4 consume multiple capacity units each), so planning must account for both prompt and completion length.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;To right-size your PTU, you’ll need an estimate of the following metrics:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Requests per minute&lt;/LI&gt;
&lt;LI&gt;Average tokens per request&lt;/LI&gt;
&lt;LI&gt;Peak concurrency&lt;/LI&gt;
&lt;LI&gt;Prompt + completion token size&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;By plugging these into the Azure OpenAI PTU Calculator (linked in the References section), you can get a first estimate of the size of purchase you need to make based on your consumption.&lt;/P&gt;
&lt;P&gt;Most production solutions use a hybrid approach: for example, Provisioned capacity for steady, critical real-time traffic, Priority Processing for latency-sensitive bursts that exceed PTU headroom, Standard for overflow or early-stage apps, and Batch for large-scale offline processing. As a rule of thumb: if a user is waiting for a response, use a real-time endpoint (Standard, Priority, or PTU). Use PTU when you need strict latency consistency at high, predictable volume; use Priority Processing when you need SLA-backed low latency without committing to PTUs; use Standard for everything else interactive. If a task can be handled asynchronously, offload it to Batch to reduce cost and keep interactive systems responsive.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Pitfall – Sizing for average load instead of peak burst. &lt;/STRONG&gt;One company provisioned capacity only for typical throughput and was overwhelmed when traffic spiked ~3× beyond normal. They maxed out their PTU allocation, triggering a flood of 429 errors. Lesson: model your peak tokens-per-minute (TPM) and requests-per-minute (RPM), not just the average, and add a safety margin to avoid unexpected throttling.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Insight – Separate real-time and background workloads. &lt;/STRONG&gt;An initial version of a news analytics bot processed all articles on demand, leading to slow, costly responses. The team later moved heavy processing to Batch jobs (pre-computing article embeddings and summaries), cutting end-user latency by 80% and halving costs.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [Diagram 1 – Capacity Model and Deployment]&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;2. Deployment Location: Where Does Inference Run?&lt;/H1&gt;
&lt;P&gt;After choosing the capacity model, decide where your Azure OpenAI instance is hosted. This affects latency, scalability, compliance, and model availability. Azure provides three options:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Global – &lt;/STRONG&gt;Your endpoint isn’t tied to a specific region.&lt;/LI&gt;
&lt;LI&gt;Pros: Maximum elasticity and often the best performance stability, since Azure can route traffic to any available regional capacity. You also usually get access to new model releases first on global endpoints.&lt;/LI&gt;
&lt;LI&gt;Cons: Data is processed across multiple regions (may violate strict data residency needs). Troubleshooting can be more complex when calls are served from various locations.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Data Zone – &lt;/STRONG&gt;Inference is restricted to a defined geography (e.g., all Azure EU regions).&lt;/LI&gt;
&lt;LI&gt;Pros: Ensures data stays within a specific political boundary for compliance (e.g., GDPR) while retaining some elasticity across multiple regional datacenters in that zone.&lt;/LI&gt;
&lt;LI&gt;Cons: Smaller capacity pool than Global, and possibly a slight delay in getting certain new model versions compared to global rollout. A good balance if you require geographic control without completely sacrificing scalability.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Regional – &lt;/STRONG&gt;Inference runs in a single Azure region that you choose.&lt;/LI&gt;
&lt;LI&gt;Pros: Strict data residency and potentially minimal latency if your users are near that region.&lt;/LI&gt;
&lt;LI&gt;Cons: No ability to burst to other regions – you are limited to one datacenter’s capacity. If that region faces high load or an outage, your service is impacted. Some model versions or features may also take longer to become available in a given region than on Global. For current model and region availability, refer to the Azure AI Foundry – Model Deployment Types documentation in the References section.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Pitfall – Over-constraining location without need. &lt;/STRONG&gt;Some teams unnecessarily default to a narrow deployment. For instance, a company chose a local Regional deployment out of habit, then discovered the Azure OpenAI model they needed wasn’t available in that region for several months, forcing a last-minute migration to a broader Data Zone. Lesson: unless you have a clear compliance or latency requirement, start with a less restrictive option (Global or multi-region Data Zone) to avoid capacity or availability issues.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Example: &lt;/STRONG&gt;One enterprise began with a Global deployment for performance and simplicity, but later had to move to an EU Data Zone to meet GDPR rules, trading some elasticity for compliance. Conversely, a team that started with a single-region setup ran into scaling limits and delayed feature rollouts; they eventually reconfigured to a Data Zone to tap into a larger resource pool.&lt;/P&gt;
&lt;H1&gt;3. Governance Layer: When a GenAI Gateway Is Needed&lt;/H1&gt;
&lt;P&gt;As Azure OpenAI usage scales to multiple applications or teams, direct API calls from each app become hard to manage. A central API gateway (such as an Azure API Management instance in front of the OpenAI endpoints) is recommended to enforce enterprise policies and provide a single point of oversight. A gateway enables:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Central Authentication &amp;amp; RBAC: &lt;/STRONG&gt;Use Microsoft Entra ID for authentication instead of distributing API keys, and enforce role-based access so each app or team only accesses allowed resources.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Usage Quotas &amp;amp; Throttling: &lt;/STRONG&gt;Allocate token or request quotas per application or client. This prevents one service from monopolizing the OpenAI service and can smooth out bursts by applying backpressure (e.g., returning 429s or queueing requests) before Azure OpenAI’s own limits are exceeded.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Intelligent Routing: &lt;/STRONG&gt;Direct traffic flexibly – route most requests to a primary model deployment, send a fraction to a new model version (canary), or fail over to a secondary region or the Standard tier if the primary is constrained.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Unified Monitoring &amp;amp; Cost Management: &lt;/STRONG&gt;Log all requests in one place. This gives you a clear view of consumption by team or feature, helps with debugging, and supports internal charge-back or cost governance.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;A gateway doesn’t make the model faster or more scalable by itself – it’s about control, security, and manageability, not raw performance. That said, for any multi-team or multi-application scenario, a gateway quickly becomes essential to avoid “shadow AI” deployments and chaotic usage patterns.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;When to add: &lt;/STRONG&gt;Introduce a GenAI gateway once more than one application or team is using the service, or whenever you need to enforce cross-cutting policies. Implementing it early can save a lot of headaches compared to retrofitting it later.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Example: &lt;/STRONG&gt;An e-commerce company initially allowed several departments to call the Azure OpenAI API directly. Soon, they had no clear visibility into who was using how many tokens, and costs spiked unexpectedly. They deployed an APIM gateway to require proper authentication, impose per-app quotas, and log usage metrics. The result was rapid identification of the top token-consuming app (preventing it from starving others) and much better cost control.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;[Diagram 2 – GenAI Gateway Functionalities and deployment Location sprectrum]&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;4. Grounding Strategy: When to Use RAG (Retrieval-Augmented Generation)&lt;/H1&gt;
&lt;P&gt;Many enterprise use cases demand that the model’s answers include specific internal knowledge or citations. Retrieval-Augmented Generation (RAG) is the solution when your AI needs to ground its responses in external data. RAG works by retrieving relevant content from your own data sources and providing it to the model in the prompt:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Document Indexing: &lt;/STRONG&gt;First, collect your reference documents (files, knowledge bases, etc.) and break them into chunks, optionally adding metadata (titles, tags). Store these in a vector index or search database after transforming each chunk into an embedding vector.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Relevant Retrieval: &lt;/STRONG&gt;For each user query, create an embedding of the question and retrieve the top-matching document chunks from the index via similarity search.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Augmented Prompt: &lt;/STRONG&gt;Prepend or append the retrieved text snippets to the model’s prompt (often along with instructions to use them for reference).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;LLM Response: &lt;/STRONG&gt;The model (e.g., GPT-4) processes the augmented prompt and generates an answer that incorporates the provided reference information (often with source citations if required).&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;By injecting enterprise data at prompt time, RAG can significantly reduce hallucinations and increase the factual accuracy of outputs. Users get answers that reflect real data you’ve provided, rather than just the model’s training data.&lt;/P&gt;
&lt;P&gt;However, RAG adds complexity, latency, and cost. You must maintain additional infrastructure (embedding computation and a vector store or search index). Each query now has extra steps, typically adding 200–500 ms to response time. The vector database and compute for embeddings also incur costs – industry estimates often put a full RAG pipeline at 3–5× the cost of using the base model alone, especially at scale. You’ll need a strategy for keeping your index updated as source data changes, and robust handling for cases where no relevant data is found.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;When to use RAG: &lt;/STRONG&gt;Use RAG if your model must reliably incorporate proprietary, dynamic, or highly specific information that isn’t part of its training data, or when you need to provide source references for answers. If your scenario is more open-ended or doesn’t require up-to-date factual grounding, you can often skip RAG to keep the system simpler and faster.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Pitfall: &lt;/STRONG&gt;Some teams adopt RAG by default, which can slow development and complicate the system unnecessarily. It’s often better to start with a simpler approach and add RAG later if you find the model’s answers need external support.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Examples: &lt;/STRONG&gt;One consulting firm added RAG to their internal Q&amp;amp;A bot to leverage proprietary research. Answers became more accurate, but query latency jumped to ~5 seconds due to the retrieval overhead, forcing them to optimize their embeddings pipeline and caching. Conversely, a health company launched a chatbot without RAG and discovered it gave incorrect medical answers because it couldn’t reference the latest policy documents – a failure that a RAG approach could have mitigated.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; [Diagram 3 – RAG High Level Flow and Anatomy]&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;5. Quota Engineering: Avoiding Bottlenecks and Throttling&lt;/H1&gt;
&lt;P&gt;The Azure OpenAI Service imposes quota limits to protect the system. If you don’t plan for these, they can become points of failure in production. Key limits include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Tokens per Minute (TPM): &lt;/STRONG&gt;Maximum tokens (input + output) your deployment can process per minute (your primary throughput cap).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Requests per Minute (RPM): &lt;/STRONG&gt;Maximum number of API calls per minute.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Concurrent Requests: &lt;/STRONG&gt;Maximum number of requests processed simultaneously.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Model-specific limits: &lt;/STRONG&gt;Certain model types have their own constraints (e.g., the maximum request rate for GPT-4 may be lower than for GPT-3.5 due to higher computational load).&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;If you exceed these limits, Azure OpenAI will return errors – usually HTTP 429 (Too Many Requests) for quota exhaustion or 503 (Service Unavailable) if the service is stressed. In other words, hitting a quota isn’t a theoretical worry; it will result in rejected requests once you cross the threshold.&lt;/P&gt;
&lt;H2&gt;Quota Tiers and Deployment Types&lt;/H2&gt;
&lt;P&gt;Azure OpenAI uses a tiered quota system where limits depend on your subscription’s access level. Specific numeric quotas change frequently, so always verify against the Azure OpenAI Quota Guide (linked in the References section).&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Tier 1 (Default): &lt;/STRONG&gt;Standard quota allocations suitable for development and moderate production workloads. At the time of writing, GPT-4 deployments in Tier 1 commonly start at quotas in the low tens of thousands of TPM and around a thousand RPM, but exact values vary by region and model – always check the current Azure OpenAI Quota Guide for live numbers.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Tier 2 and Above: &lt;/STRONG&gt;Higher quotas available through approval processes, typically for enterprise customers with demonstrated high-volume needs. These tiers can provide significantly more capacity than Tier 1; consult the Quota Guide for current multipliers and approval paths.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;Standard (pay-as-you-go) deployments share regional quota pools and are subject to TPM/RPM limits that can vary by region and model. Provisioned Throughput (PTU) deployments operate differently – you purchase dedicated capacity measured in PTUs, and your throughput is determined by your PTU allocation rather than by TPM/RPM limits. PTUs still have implicit rate limits based on the processing capacity of your purchased units.&lt;/P&gt;
&lt;P&gt;The Batch API uses a separate quota system with “enqueued tokens” limits, allowing much higher total throughput (often millions of tokens per day) but without real-time guarantees.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Best practices to manage quotas:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Capacity planning: &lt;/STRONG&gt;Calculate your peak usage requirements (e.g., max prompt+completion tokens per request × peak requests per minute). Ensure your chosen plan or quota can handle this, or request an increase in advance.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Design for bursts: &lt;/STRONG&gt;Traffic often comes in waves. Aim to operate well below your limits so you can absorb sudden surges. As a guideline, keep usage under ~70% of your TPM/RPM limits during normal operation, leaving headroom for peaks. If your usage is spiking above 85% regularly at the 95th percentile, it’s time to scale up capacity or optimize usage.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Graceful degradation: &lt;/STRONG&gt;Implement exponential backoff (with jitter) on the client side when retries are necessary. This prevents a stampede of retries (a “retry storm”) that would otherwise compound the load problem. At the platform level, use queues or token-bucket rate limiters (possibly in your APIM gateway) to smooth bursts.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Circuit breakers: &lt;/STRONG&gt;Have fallback plans for extreme scenarios. Temporarily disable non-critical features or queue requests when approaching critical limits to prevent a total outage.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Example: &lt;/STRONG&gt;A fintech company’s trading chatbot ran fine in testing, but during a market surge their question volume tripled. This breached their tokens-per-minute quota and led to a flood of 429 errors. Worse, their code immediately retried each failed request without delay, intensifying the load and effectively causing a self-inflicted denial-of-service outage. They resolved it by using exponential backoff and partitioning users across multiple deployments.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;img /&gt;
&lt;P&gt;&lt;EM&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;[Diagram 4 – Quota Engineering]&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;H1&gt;Final Perspective and Key Takeaways&lt;/H1&gt;
&lt;P&gt;Ultimately, building a production-grade Azure OpenAI solution is much more about well-structured cloud architecture than about the model itself. An advanced model can underperform in a fragile setup, while even a basic model can excel in a solid architecture.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Key takeaways from Part 1:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;STRONG&gt;Plan for peak loads. &lt;/STRONG&gt;Design for the worst-case traffic (and add buffer), not the average. If you need strict performance guarantees, invest in dedicated capacity early.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Avoid unnecessary constraints. &lt;/STRONG&gt;Don’t lock into a restricted deployment unless required by compliance or latency – new models and extra capacity reach global deployments first.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Use real-time vs. batch wisely. &lt;/STRONG&gt;Real-time endpoints (Standard, Priority, or PTU) should be reserved for interactive, user-facing tasks; move large or non-urgent jobs to Batch for roughly half the cost per token (at the time of writing).&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Pick the right real-time tier. &lt;/STRONG&gt;Use Priority Processing when you need SLA-backed low latency without committing to PTUs, PTU for high, predictable volumes, and Standard for everything else interactive.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Implement a gateway for scale. &lt;/STRONG&gt;If you have multiple applications or teams, use an API Management gateway for authentication, rate limiting, logging, and multi-region routing.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Adopt RAG only if needed. &lt;/STRONG&gt;Don’t introduce a retrieval-augmented generation layer unless your application truly demands external data or source citations.&lt;/LI&gt;
&lt;LI&gt;&lt;STRONG&gt;Engineer for limits and failure. &lt;/STRONG&gt;Treat rate limits and error handling as fundamental design criteria. Build in monitoring, backoff, and fallback mechanisms so the system degrades gracefully.&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;In short, succeeding with Azure OpenAI in production means treating it as a full-stack architecture challenge rather than just an API integration. By proactively addressing scalability, deployment, governance, data grounding, and quotas, you can turn a promising demo into a stable, cost-efficient, and compliant AI platform.&lt;/P&gt;
&lt;P&gt;In the next part, we’ll explore how to put these principles into practice – including multi-region architectures, cost-sharing strategies for teams, advanced monitoring/logging setups, and other patterns for making Azure OpenAI a robust enterprise service.&lt;/P&gt;
&lt;H1&gt;Decision Matrix: Quick Reference&lt;/H1&gt;
&lt;P&gt;Use this matrix as a fast first cut on the five Part 1 decisions. It is not a substitute for a full design review, but it captures the trade-offs most teams need to evaluate up front.&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table border="1" style="border-width: 1px;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Decision&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Choose this when…&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Avoid when…&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Primary risk&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Capacity – Standard (PAYGO)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Dev/test, unpredictable or bursty traffic, MVPs, overflow&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;You need guaranteed latency or strict SLAs&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;429 throttling under shared load&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Capacity – Priority Processing&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Latency-sensitive, business-critical real-time traffic where you don’t want PTU commitment; burst lane on top of PTU&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Deployment type / model version isn’t eligible; cost-sensitive, low-priority workloads&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Higher per-token cost than Standard; still PAYGO quota-bound&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Capacity – Batch&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Async jobs, embeddings refresh, large offline summarization&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;User is waiting; or model is unsupported (e.g., embeddings, at the time of writing)&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Up to 24h turnaround; orchestration overhead&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Capacity – Provisioned (PTU)&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;High-volume real-time workloads with strict SLAs and predictable load&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Demand is low or highly variable&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Over-/under-provisioning costs&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Deployment – Global&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;You want widest model availability and best elasticity&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Strict data residency or regulatory constraints&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Less control over where data is processed&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Deployment – Data Zone&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Geographic compliance (e.g., EU/US) with some elasticity&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Single-region residency is mandated&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Some lag on newest model versions&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Deployment – Regional&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Strict data residency or co-located low-latency users&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;You need to scale beyond one region’s capacity&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Capacity ceilings and slower model rollout&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Governance – GenAI Gateway&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Multiple apps/teams, need RBAC, quotas, routing, central logging&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Single small app where overhead exceeds benefit&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Adds latency and another component to operate&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Grounding – RAG&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Need proprietary, dynamic, or cited answers&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Open-ended creative tasks where freshness isn’t required&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Latency, cost, and index freshness drift&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;STRONG&gt;Quota – Plan &amp;amp; Tier Up Early&lt;/STRONG&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;You’re close to TPM/RPM ceilings or expecting growth&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Your peak forecast is well below current quota&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;Last-minute throttling and outages&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;colgroup&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;col style="width: 25.00%" /&gt;&lt;/colgroup&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;P&gt;&lt;EM&gt;Tip: If you can only optimize for one decision in Part 1, start with capacity model and quota engineering – they are the two most common sources of production incidents we see in real deployments. Pairing PTUs (or Priority Processing) for steady, latency-sensitive traffic with Standard PAYGO for overflow is a pattern that consistently delivers both reliability and cost control.&lt;/EM&gt;&lt;/P&gt;
&lt;H1&gt;Disclaimer&lt;/H1&gt;
&lt;P&gt;The views expressed in this article are those of the author and do not necessarily reflect the official policy or position of Microsoft. The author is a Microsoft employee.&lt;/P&gt;
&lt;H1&gt;References&lt;/H1&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="https://techcommunity.microsoft.com/blog/azure-ai-foundry-blog/best-practice-guidance-for-ptu/4152133" target="_blank" rel="noopener"&gt;PTU Best Practice Guidance&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://techcommunity.microsoft.com/blog/startupsatmicrosoftblog/azure-openai-best-practices-a-quick-reference-guide-to-optimize-your-deployments/4403546" target="_blank" rel="noopener"&gt;Azure OpenAI Best Practices – Quick Reference&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/quota" target="_blank" rel="noopener"&gt;Azure OpenAI Quota Guide&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-foundry/openai/how-to/latency" target="_blank" rel="noopener"&gt;Azure OpenAI Latency Optimization Guide&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/azure/ai-foundry/foundry-models/concepts/deployment-types" target="_blank" rel="noopener"&gt;Azure AI Foundry – Model Deployment Types&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://learn.microsoft.com/en-us/ai/playbook/solutions/generative-ai/genai-gateway/" target="_blank" rel="noopener"&gt;GenAI Gateway / APIM&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="https://www.ptucalc.com/" target="_blank" rel="noopener"&gt;Azure OpenAI PTU Calculator&lt;/A&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;A href="#community--1-_References" target="_blank" rel="noopener"&gt;Enable priority processing for Microsoft Foundry Models – Microsoft Learn&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Mon, 08 Jun 2026 13:53:07 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/azure-openai-architecture-the-decisions-that-actually-matter/ba-p/4525976</guid>
      <dc:creator>luciacasucci</dc:creator>
      <dc:date>2026-06-08T13:53:07Z</dc:date>
    </item>
    <item>
      <title>Enabling AI-Driven SAP Development with GitHub Copilot: Plans and Usage-Based Billing Transformation</title>
      <link>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/enabling-ai-driven-sap-development-with-github-copilot-plans-and/ba-p/4526021</link>
      <description>&lt;H5&gt;&lt;STRONG&gt;Introduction:&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Empower SAP customers with a strategic understanding of GitHub Copilot offerings, including plan options, value realization, account models, and key considerations for enterprise adoption. Through a guided, step-by-step setup in Visual Studio Code, SAP developers will gain hands-on experience with GitHub Copilot and Copilot Chat in real-world development scenarios. In addition, a practical exercise demonstrates how to configure and optimize Copilot within Visual Studio Code enabling SAP teams to effectively adopt AI-assisted development and accelerate application delivery.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Imagine you are an SAP developer working within a fast-paced enterprise environment, tasked with delivering a new feature or extension for a business-critical application, such as SAP S/4HANA or SAP BTP. With limited familiarity with the existing codebase and tight delivery timelines, ensuring quality, performance, and reliability is essential. GitHub Copilot provides a powerful AI-assisted development experience that can help SAP developers accelerate delivery while maintaining high standards. It can interpret complex code, generate documentation, and assist in writing efficient, error-free code enabling teams to meet deadlines and deliver high-quality solutions with confidence.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot plans for SAP Customers:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Starting June 1, 2026&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;, &lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;GitHub is transitioning GitHub Copilot from a request-based billing model to a usage-based billing model.&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt; For SAP customers, this shift enables more granular cost alignment with actual AI usage across development teams, supporting improved transparency and budget control within SAP programs.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Organizations and enterprises can leverage this model to better manage consumption across SAP development scenarios such as S/4HANA extensions, BTP applications, and integrations while optimizing costs based on real usage patterns. Individual SAP developers will also benefit from flexible billing aligned to their actual Copilot usage.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot Capabilities for SAP Development:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot offers a range of capabilities designed to support SAP developers across the entire development lifecycle from coding and testing to collaboration and deployment.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot in the CLI&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;: SAP developers can use a chat-like interface directly in the terminal to interact with command-line tools. Copilot provides command suggestions and explanations, helping streamline development workflows for SAP integrations, deployments, and automation tasks.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;AI-Generated Pull Request Summaries&lt;/SPAN&gt;&lt;SPAN data-contrast="auto"&gt;: Copilot generates intelligent summaries of pull requests, highlighting key changes, impacted files, and areas requiring attention. This enables SAP teams to accelerate code reviews and improve collaboration especially in complex enterprise environments. (Not available in the Free plan.)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot Extensions&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Copilot Extensions allow SAP customers to integrate external tools and systems such as SAP BTP services or other enterprise platforms into the development workflow. These extensions can be customized and shared to support organization-specific SAP scenarios.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Custom Instructions&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;SAP teams can tailor Copilot responses by providing context about development standards, tools and project requirements ensuring outputs align with SAP best practices and enterprise guidelines.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot Memory (Public Preview)&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Copilot can learn from and retain context about a repository, improving the relevance and quality of suggestions. This is particularly valuable for SAP projects with complex codebases and domain-specific logic.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot Spaces&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Organize SAP project assets such as code, documentation, and specifications into contextual “Spaces.” This ensures Copilot delivers responses grounded in the appropriate SAP business and technical context.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="5" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="7" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot in GitHub Desktop&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Automatically generate commit messages and descriptions based on SAP code changes, improving consistency, traceability, and developer efficiency.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot Agents for SAP Development:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot Chat in Visual Studio Code provides specialized agents designed to support different stages of the SAP development lifecycle ranging from planning to implementation and knowledge exploration.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Agent (Execution Agent)&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Use the Agent when you need to implement a specific SAP development task, such as building extensions, integrations, or enhancements for SAP S/4HANA or SAP BTP.&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;The Agent can autonomously identify relevant files, propose code changes, execute supporting commands, and iteratively refine outputs to complete the task efficiently.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Plan (Planning Agent)&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Use the Plan agent when you want to define a structured, step-by-step approach before implementation. This is particularly useful for SAP scenarios requiring careful design such as complex integrations or multi-system workflows. The Plan agent breaks down requirements into clear steps that can be executed by the Agent.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="4" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Ask (Knowledge Agent)&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Use the Ask agent to explore SAP-related code, development patterns, or general technical concepts without making changes. This is ideal for understanding unfamiliar codebases, learning new SAP development paradigms, or clarifying architecture and best practices.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Implementing GitHub Copilot in SAP Environments:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;SAP organizations can follow a structured approach to successfully set up and scale GitHub Copilot across development teams:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;335559685&amp;quot;:360}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Subscribe and Select the Right Plan&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Begin by subscribing to GitHub Copilot and selecting the appropriate plan (Business or Enterprise) based on your SAP landscape, governance needs, and scale of adoption.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Establish Governance and Policies&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Define organizational policies to control how GitHub Copilot is used across SAP development scenarios. This includes enabling or restricting specific features to align with compliance, security, and SAP development standards.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Configure Secure Networking&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Ensure secure connectivity by configuring proxy servers or firewalls to allow required Copilot endpoints. SAP customers may also need to manage SSL certificates to align with enterprise security requirements.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Provision Access to Development Teams&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Enable GitHub Copilot for selected SAP developers or teams such as those working on SAP BTP extensions, integrations, or modernization initiatives. A phased rollout can help identify challenges and demonstrate early value before scaling organization wide.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Drive Adoption Across SAP Teams&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Establish a structured enablement strategy including training, best practices, and internal champions to promote effective usage of Copilot within SAP development workflows. A self-service licensing model can further accelerate adoption.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="6" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Support Developer Authentication&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;In enterprise environments, ensure SAP developers complete the required authentication steps to access Copilot from their development tools, such as Visual Studio Code.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="7" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Enhance the Copilot Experience&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;SAP organizations can further optimize value by:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Integrating knowledge bases to provide SAP-specific context (Enterprise plan)&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Customizing Copilot through tailored AI models aligned to SAP development needs&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="o" data-font="Courier New" data-listid="6" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:1440,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Courier New&amp;quot;,&amp;quot;469769242&amp;quot;:[9675],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;o&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="2"&gt;&lt;SPAN data-contrast="auto"&gt;Leveraging Copilot Extensions to integrate SAP tools and other enterprise systems into the development workflow&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Set Up GitHub Copilot in Visual Studio Code:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;For SAP developers, setting up GitHub Copilot is a simple process:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Ensure you are using the latest version of Visual Studio Code to support modern SAP development workflows (e.g., SAP BTP and full-stack development).&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;In the Status Bar, select the GitHub Copilot icon and choose Use AI Features to begin setup.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Sign in with your GitHub account and follow the authentication prompts to enable access.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;If your account is already authenticated, select Set up Copilot to complete activation.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="7" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="5" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Follow the guided steps to authorize Copilot within your development environment.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;If no subscription is assigned, SAP developers will be onboarded to the GitHub Copilot Free plan for initial evaluation.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Once setup is complete, GitHub Copilot is ready to assist with SAP development tasks such as code generation, documentation, and optimization.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Customize GitHub Copilot Settings for SAP Development:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;SAP developers can tailor GitHub Copilot behavior to align with enterprise development standards and project requirements:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Access Settings by selecting the gear icon in the lower-left corner of Visual Studio Code.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Navigate to GitHub Copilot configurations, organized into key areas:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Code Editing Settings&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Configure inline code suggestions, next-edit predictions, and language-specific behaviors to support SAP development languages and frameworks.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Chat Settings&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Customize how Copilot Chat behaves, including terminal integration helpful for managing SAP build, deployment, and integration tasks.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="9" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;hybridMultilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Agent Settings&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Control advanced capabilities such as agent mode, request limits, and tool approvals to align with SAP governance, security, and compliance requirements.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;134233117&amp;quot;:true,&amp;quot;134233118&amp;quot;:true,&amp;quot;201341983&amp;quot;:2,&amp;quot;335559740&amp;quot;:300}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Selecting Where GitHub Copilot Agents Run in SAP Development:&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;In addition to selecting the appropriate Copilot agent for a specific task, SAP developers can control where the agent executes using the Agent Target option in the Chat view. This capability determines how the agent interacts with SAP development environments and when results are delivered.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="1" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Local Execution&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Runs directly within the developer’s environment with full access to the workspace, tools, and codebase. Ideal for SAP developers working on real-time coding tasks, exploring complex SAP codebases, or making controlled updates where step-by-step review is required.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="2" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot CLI (Local Background Execution)&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Executes tasks in the background on the developer’s machine. Suitable for SAP scenarios where predefined tasks such as script generation, automation, or batch updates can run while developers continue working on other SAP components.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="3" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Cloud Execution&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Runs remotely in GitHub and integrates with workflows such as issues and pull requests. This option is well-suited for SAP teams collaborating on large-scale projects, enabling developers to delegate tasks, generate pull requests, and streamline code reviews across distributed teams.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;UL&gt;
&lt;LI aria-setsize="-1" data-leveltext="" data-font="Symbol" data-listid="10" data-list-defn-props="{&amp;quot;335552541&amp;quot;:1,&amp;quot;335559685&amp;quot;:720,&amp;quot;335559991&amp;quot;:360,&amp;quot;469769226&amp;quot;:&amp;quot;Symbol&amp;quot;,&amp;quot;469769242&amp;quot;:[8226],&amp;quot;469777803&amp;quot;:&amp;quot;left&amp;quot;,&amp;quot;469777804&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;469777815&amp;quot;:&amp;quot;multilevel&amp;quot;}" data-aria-posinset="4" data-aria-level="1"&gt;&lt;SPAN data-contrast="auto"&gt;Third-Party Execution&lt;/SPAN&gt;&amp;nbsp;&lt;BR /&gt;&lt;SPAN data-contrast="auto"&gt;Uses external AI platforms (such as Anthropic or OpenAI) to run agents either locally or in the cloud. This provides flexibility for SAP customers to integrate advanced AI capabilities into their development workflows, depending on enterprise architecture and governance requirements.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H5&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Controlling Agent Permissions (for SAP Customers):&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;You can define how much autonomy your digital agents have by using the Permissions settings within the Chat experience. Adjusting these levels allows you to balance operational efficiency with governance and oversight an important consideration in SAP-driven business processes.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;DIV class="styles_lia-table-wrapper__h6Xo9 styles_table-responsive__MW0lN"&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Permission Level&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:2,&amp;quot;335551620&amp;quot;:2,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Description&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:2,&amp;quot;335551620&amp;quot;:2,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Default Approval&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:2,&amp;quot;335551620&amp;quot;:2,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Only low-risk, read-only actions are executed automatically. Most agent-initiated actions require user confirmation, ensuring control over business-critical operations and data changes.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Bypass Approvals&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:2,&amp;quot;335551620&amp;quot;:2,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;All agent actions are automatically approved without user prompts. This setting streamlines workflows but should be used with appropriate governance controls, especially in sensitive SAP environments.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Autopilot&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335551550&amp;quot;:2,&amp;quot;335551620&amp;quot;:2,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;td&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;Enables fully autonomous execution. The agent handles actions end-to-end, including responding to clarification requests, without user intervention. Ideal for well-defined scenarios, but requires strong trust, monitoring, and compliance alignment.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{&amp;quot;201341983&amp;quot;:0,&amp;quot;335559739&amp;quot;:0,&amp;quot;335559740&amp;quot;:240}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/DIV&gt;
&lt;H5&gt;&lt;STRONG&gt;&lt;SPAN data-contrast="auto"&gt;Conclusion: &lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/STRONG&gt;&lt;/H5&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;GitHub Copilot offers SAP organizations a powerful way to modernize development through AI-assisted engineering. It combines intelligent code generation, contextual insights, and advanced features like agents, CLI integration, and memory to accelerate delivery while maintaining enterprise-grade quality and compliance.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN data-contrast="auto"&gt;It’s usage-based billing model further enhances value by aligning costs with actual adoption, providing transparency, scalability, and control across scenarios such as S/4HANA extensions, SAP BTP applications, and integrations. With a structured approach, covering plan selection, governance, secure configuration, and phased rollout, organizations can integrate Copilot effectively while meeting SAP-specific standards. Ultimately, Copilot enables SAP teams to boost productivity, enhance collaboration, and drive innovation at scale, delivering faster time to market and sustained business value.&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H5&gt;&lt;SPAN data-contrast="auto"&gt;Reference links:&lt;/SPAN&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/H5&gt;
&lt;P&gt;&lt;A href="https://docs.github.com/en/copilot/get-started/plans" target="_blank"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Plans for GitHub Copilot - GitHub Docs&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://docs.github.com/en/copilot/concepts/billing/usage-based-billing-for-individuals" target="_blank"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Usage-based billing for individuals - GitHub Docs&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN data-ccp-props="{}"&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="https://docs.github.com/en/copilot/concepts/billing/usage-based-billing-for-organizations-and-enterprises" target="_blank"&gt;&lt;SPAN data-contrast="none"&gt;&lt;SPAN data-ccp-charstyle="Hyperlink"&gt;Usage-based billing for organizations and enterprises - GitHub Docs&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/A&gt;&lt;/P&gt;</description>
      <pubDate>Mon, 08 Jun 2026 13:52:48 GMT</pubDate>
      <guid>https://techcommunity.microsoft.com/t5/microsoft-mission-critical-blog/enabling-ai-driven-sap-development-with-github-copilot-plans-and/ba-p/4526021</guid>
      <dc:creator>AnuradhaKarnam</dc:creator>
      <dc:date>2026-06-08T13:52:48Z</dc:date>
    </item>
  </channel>
</rss>

