<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Azure with AJ</title>
    <description>A blog by an Azure, DevOps and AI enthusiast, sharing valuable insights and expertise.</description>
    <link>https://azurewithaj.com/</link>
    <atom:link href="https://azurewithaj.com/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Fri, 06 Mar 2026 20:13:42 +0000</pubDate>
    <lastBuildDate>Fri, 06 Mar 2026 20:13:42 +0000</lastBuildDate>
    <generator>Jekyll v4.4.1</generator>
    
      <item>
        <title>MCP Apps: Interactive Dashboards Inside Your AI Conversations</title>
        <description>&lt;p&gt;If you’ve been working with AI agents lately, you’ve probably hit a limitation: the agent can describe what it found, but it can’t show you anything interactive. Your agent finishes scanning a dataset and presents a table in text format. You need to explore further, so you ask it to reorganise the results. Another round trip. Another text response.&lt;/p&gt;

&lt;p&gt;MCP Apps change that equation entirely. They let your MCP servers return interactive HTML interfaces such as dashboards, forms, visualisations and configuration panels that render directly inside your AI conversation. No tab switching. No context loss. Just rich, interactive interfaces right where you’re having the conversation.&lt;/p&gt;

&lt;p&gt;In this post, I’ll explain what MCP Apps are, how they work, why they matter, and how you can leverage them in real scenarios like browsing Azure resources with an interactive dashboard.&lt;/p&gt;

&lt;h2 id=&quot;what-are-mcp-apps&quot;&gt;What Are MCP Apps?&lt;/h2&gt;

&lt;p&gt;MCP Apps are an extension to the Model Context Protocol that lets MCP tools declare and serve interactive user interfaces. Rather than returning only text, images, or structured data, a tool can now say “render this HTML interface alongside your response.”&lt;/p&gt;

&lt;p&gt;The key insight is simple: sometimes showing is better than telling. An agent can describe “your database has performance bottlenecks in query processing,” but an interactive graph lets you drill into the call stacks, hover for timing details, and validate the analysis yourself.&lt;/p&gt;

&lt;p&gt;MCP Apps bridge the gap between pure text-based AI interactions and rich desktop applications. They give agents a visual voice.&lt;/p&gt;

&lt;h2 id=&quot;the-problem-mcp-apps-solve&quot;&gt;The Problem MCP Apps Solve&lt;/h2&gt;

&lt;p&gt;Traditional agent workflows suffer from a classic problem: agents work in text space, but developers think in visual and interactive space. When an agent presents findings, you often want to explore further, but the agent can only respond with more text.&lt;/p&gt;

&lt;p&gt;MCP Apps flip this around. Agents can now display:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Interactive dashboards&lt;/strong&gt;: Visualise metrics, logs, or resource states&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Forms with validation&lt;/strong&gt;: Configure systems with confidence&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Data tables with sorting and filtering&lt;/strong&gt;: Explore large datasets without truncation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Visualisations&lt;/strong&gt;: Flame graphs, heatmaps, network diagrams, 3D models&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Terminal-like interfaces&lt;/strong&gt;: Real-time monitoring and status updates&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;File pickers and selectors&lt;/strong&gt;: Choose resources from rich interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent doesn’t lose context, and it works alongside the interactive UI. When you interact with the app, it can call MCP tools to fetch fresh data, validate your choices, or execute actions.&lt;/p&gt;

&lt;h2 id=&quot;how-mcp-apps-work&quot;&gt;How MCP Apps Work&lt;/h2&gt;

&lt;p&gt;Understanding the architecture helps explain why MCP Apps are secure and efficient.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph LR
    A[&quot;MCP Server&amp;lt;br/&amp;gt;Registers Tool&quot;] --&amp;gt; B[&quot;Tool Description&amp;lt;br/&amp;gt;Includes UI Resource URI&quot;]
    B --&amp;gt; C[&quot;Host/Agent&amp;lt;br/&amp;gt;LLM Decides to Call Tool&quot;]
    C --&amp;gt; D[&quot;Host Fetches&amp;lt;br/&amp;gt;UI Resource&amp;lt;br/&amp;gt;from Server&quot;]
    D --&amp;gt; E[&quot;Sandboxed iframe&amp;lt;br/&amp;gt;Renders HTML/JS&quot;]
    E --&amp;gt; F[&quot;Bidirectional&amp;lt;br/&amp;gt;Communication&amp;lt;br/&amp;gt;via postMessage&quot;]
    F --&amp;gt; G[&quot;App Calls Tools&amp;lt;br/&amp;gt;Host Updates Display&quot;]
    
    style A fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style B fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style C fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style D fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style E fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style F fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style G fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The flow works in four key steps:&lt;/p&gt;

&lt;h3 id=&quot;1-tool-registration-with-ui-metadata&quot;&gt;1. Tool Registration with UI Metadata&lt;/h3&gt;

&lt;p&gt;An MCP server registers a tool with a special &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_meta.ui.resourceUri&lt;/code&gt; field that points to an HTML interface:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nf&quot;&gt;registerAppTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;list-azure-storage&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;List Azure Storage Accounts&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Browse storage accounts with filtering and drill-down&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;inputSchema&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;_meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
      &lt;span class=&quot;na&quot;&gt;ui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
        &lt;span class=&quot;na&quot;&gt;resourceUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ui://storage-dashboard/mcp-app.html&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; 
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;async &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Fetch storage account data&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;listStorageAccounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;2-ui-preloading-and-resource-fetching&quot;&gt;2. UI Preloading and Resource Fetching&lt;/h3&gt;

&lt;p&gt;When an agent calls the tool, the host can preload the UI resource before the tool even executes. The host fetches the bundled HTML from the server, which is typically a single file containing HTML, CSS, and JavaScript bundled together.&lt;/p&gt;

&lt;h3 id=&quot;3-sandboxed-rendering&quot;&gt;3. Sandboxed Rendering&lt;/h3&gt;

&lt;p&gt;The host renders the HTML in a sandboxed iframe. This is crucial for security, as the app can’t access the parent window’s DOM, steal cookies, or execute scripts in the parent context. All communication happens through the postMessage API, which is controlled by the host.&lt;/p&gt;

&lt;h3 id=&quot;4-bidirectional-communication&quot;&gt;4. Bidirectional Communication&lt;/h3&gt;

&lt;p&gt;The app and host communicate via JSON-RPC over postMessage. The app can:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Receive the initial tool result when rendered&lt;/li&gt;
  &lt;li&gt;Call tools on the server (e.g., “fetch more data with these filters”)&lt;/li&gt;
  &lt;li&gt;Send log messages back to the host&lt;/li&gt;
  &lt;li&gt;Update the model’s context with structured data&lt;/li&gt;
  &lt;li&gt;Request actions like opening URLs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This bidirectional flow means your UI stays dynamic without page reloads.&lt;/p&gt;

&lt;h2 id=&quot;practical-uses-building-an-azure-storage-dashboard&quot;&gt;Practical Uses: Building an Azure Storage Dashboard&lt;/h2&gt;

&lt;p&gt;Let me walk through a concrete example: building an interactive dashboard to browse Azure storage accounts.&lt;/p&gt;

&lt;p&gt;Instead of asking your agent “list all storage accounts and filter by location,” you could have an interactive dashboard where you:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;See all storage accounts in a table&lt;/li&gt;
  &lt;li&gt;Filter by resource group, region, or storage type&lt;/li&gt;
  &lt;li&gt;Click to view details (access keys, endpoints, configuration)&lt;/li&gt;
  &lt;li&gt;Perform actions (create a new account, update settings, delete a container)&lt;/li&gt;
  &lt;li&gt;Copy information without manual re-typing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s an example of how the server implements this:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;// Server side: register the tool with UI metadata&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;registerAppTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;storage-dashboard&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Azure Storage Dashboard&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Interactive dashboard for browsing and managing storage accounts&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;inputSchema&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;subscriptionId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;resourceGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;_meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
      &lt;span class=&quot;na&quot;&gt;ui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
        &lt;span class=&quot;na&quot;&gt;resourceUri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ui://storage-dashboard/app.html&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; 
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;async &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Fetch storage accounts from Azure&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getStorageAccounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;subscriptionId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;resourceGroup&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt; 
        &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
        &lt;span class=&quot;na&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Register the UI resource&lt;/span&gt;
&lt;span class=&quot;nf&quot;&gt;registerAppResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ui://storage-dashboard/app.html&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;mimeType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;RESOURCE_MIME_TYPE&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;async &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;html&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;fs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;readFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;dist/app.html&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;utf-8&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
          &lt;span class=&quot;na&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ui://storage-dashboard/app.html&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;mimeType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;RESOURCE_MIME_TYPE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;html&lt;/span&gt; 
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;On the UI side, the dashboard receives the storage account data and renders it interactively:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;// Client side: UI implementation&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;@modelcontextprotocol/ext-apps&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; 
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Storage Dashboard&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
  &lt;span class=&quot;na&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;1.0.0&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; 
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Receive initial data from the tool&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ontoolresult&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)?.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;renderStorageTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// When user filters, call a tool to fetch filtered data&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;async&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;applyFilters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;callServerTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;storage-dashboard&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
      &lt;span class=&quot;na&quot;&gt;subscriptionId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;subscription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;resourceGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;filters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;group&lt;/span&gt; 
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]?.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;nf&quot;&gt;renderStorageTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;renderStorageTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Render interactive table with filtering, sorting, drill-down&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// Users can see all accounts at once, explore details,&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// and perform actions without leaving the UI&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This approach gives you:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Instant visual feedback&lt;/strong&gt;: Tables, icons, colours communicate status at a glance&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Exploration without friction&lt;/strong&gt;: Filter, sort, drill down without conversation turns&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Context preservation&lt;/strong&gt;: Everything stays in one place—the agent’s workspace&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Reduced latency&lt;/strong&gt;: UI interactions feel responsive&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than asking your agent “show me storage accounts in the Australia regions” five times with slightly different filters, you see all options at once and click to explore.&lt;/p&gt;

&lt;h2 id=&quot;security-considerations-for-mcp-apps&quot;&gt;Security Considerations for MCP Apps&lt;/h2&gt;

&lt;p&gt;MCP Apps run in a sandboxed iframe, which provides strong security isolation, but “sandboxed” does not mean “bulletproof.” Here are security practices you should follow:&lt;/p&gt;

&lt;h3 id=&quot;sandboxing-fundamentals&quot;&gt;Sandboxing Fundamentals&lt;/h3&gt;

&lt;p&gt;MCP Apps run inside a sandboxed iframe with these restrictions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;No DOM access&lt;/strong&gt;: The app can’t access the parent window’s document or modify the main page&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No cookie theft&lt;/strong&gt;: localStorage and sessionStorage are isolated&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No page navigation&lt;/strong&gt;: The app can’t redirect the parent window&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Restricted script execution&lt;/strong&gt;: Scripts in the app run only within the sandbox&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All communication between the app and host happens through postMessage, which is an explicit, controlled channel.&lt;/p&gt;

&lt;h3 id=&quot;content-security-policy-csp&quot;&gt;Content Security Policy (CSP)&lt;/h3&gt;

&lt;p&gt;When serving your UI, specify which external origins can load resources. This prevents your app from accidentally (or maliciously) loading scripts from untrusted domains:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nf&quot;&gt;registerAppResource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ui://storage-dashboard/app.html&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;na&quot;&gt;mimeType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;RESOURCE_MIME_TYPE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;_meta&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;ui&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;csp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;https://cdn.jsdelivr.net&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;https://cdn.example.com&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;async &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Serve HTML&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;permission-requests&quot;&gt;Permission Requests&lt;/h3&gt;

&lt;p&gt;Your app can request permissions (microphone, camera, geolocation), but these go through the host. The user is always in control of what the app can access. If your app doesn’t need a permission, don’t request it.&lt;/p&gt;

&lt;h3 id=&quot;input-validation-and-sanitisation&quot;&gt;Input Validation and Sanitisation&lt;/h3&gt;

&lt;p&gt;Since your app receives data from the server and may send data back to the server, validate everything:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;// On the client: validate server responses&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ontoolresult&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]?.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Validate the data structure&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;isArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Expected array of accounts&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Sanitise rendered content if it comes from user input&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;account&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;sanitiseHTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;account&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
    
    &lt;span class=&quot;nf&quot;&gt;renderStorageTable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Invalid tool result:&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;tool-call-authorisation&quot;&gt;Tool Call Authorisation&lt;/h3&gt;

&lt;p&gt;The host controls which tools your app can call. When you call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app.callServerTool()&lt;/code&gt;, the host validates that:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The tool exists on the server&lt;/li&gt;
  &lt;li&gt;The host has access to that tool&lt;/li&gt;
  &lt;li&gt;The user has authorised the interaction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You don’t need to implement authorisation on the client, as the host enforces it.&lt;/p&gt;

&lt;h3 id=&quot;secure-default-data-handling&quot;&gt;Secure Default Data Handling&lt;/h3&gt;

&lt;p&gt;MCP Apps can request “rich context” updates to the model. Be careful what data you send:&lt;/p&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;// Good: send only necessary data&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;updateContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;azure://storage/account/myaccount&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;myaccount&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;mimeType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;application/json&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// Bad: don&apos;t send secrets or sensitive tokens&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;app&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;updateContext&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;resource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;accessKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;very-secret-key&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Never do this&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;server-side-security&quot;&gt;Server-Side Security&lt;/h3&gt;

&lt;p&gt;Your MCP server also has security responsibilities:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Validate inputs&lt;/strong&gt;: Check tool arguments before executing&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Authenticate requests&lt;/strong&gt;: Ensure the user has Azure/cloud access&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Limit data exposure&lt;/strong&gt;: Don’t return secrets, access keys, or connection strings to the UI&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Rate limiting&lt;/strong&gt;: Protect against abuse&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Audit logging&lt;/strong&gt;: Track who accessed what dashboards and resources&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-typescript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nf&quot;&gt;registerAppTool&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;storage-dashboard&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;cm&quot;&gt;/* ... */&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;async &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Validate inputs&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;subscriptionId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;?.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/^&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;a-f0-9-&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;]{36}&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Invalid subscription ID format&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Check authentication&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getCurrentUser&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Authentication required&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Verify user has access to this subscription&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;hasAccess&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;verifySubscriptionAccess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
      &lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;subscriptionId&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hasAccess&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Access denied&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Fetch data and return (without secrets)&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;await&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getStorageAccounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;subscriptionId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;c1&quot;&gt;// Remove sensitive data before returning&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;safeAccounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;accounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;acc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;acc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;kind&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// Never include:&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;// primaryEndpoints, accessKey, connectionString, etc.&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}));&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;safeAccounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;getting-started-with-mcp-apps&quot;&gt;Getting Started with MCP Apps&lt;/h2&gt;

&lt;p&gt;Building an MCP App is straightforward. The MCP team provides several ways to get started:&lt;/p&gt;

&lt;h3 id=&quot;using-an-ai-coding-agent-fastest&quot;&gt;Using an AI Coding Agent (Fastest)&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; At the time of writing, MCP Apps are only supported in VS Code Insiders, so you will need the Insiders build to render apps inside the editor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you have access to Claude Code, VS Code with GitHub Copilot, or another agent that supports skills, you can leverage the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;create-mcp-app&lt;/code&gt; skill:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# Install the skill (Claude Code example)&lt;/span&gt;
/plugin marketplace add modelcontextprotocol/ext-apps
/plugin &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;mcp-apps@modelcontextprotocol-ext-apps
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then ask your agent: “Create an MCP App that displays a live Azure storage account dashboard.”&lt;/p&gt;

&lt;p&gt;The agent will scaffold a complete project with server, UI, and configuration files ready to run.&lt;/p&gt;

&lt;h3 id=&quot;manual-setup&quot;&gt;Manual Setup&lt;/h3&gt;

&lt;p&gt;If you prefer hands-on control, clone the examples repository and modify a starter template:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;git clone https://github.com/modelcontextprotocol/ext-apps.git
&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;ext-apps/examples/basic-server-react
npm &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run build &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run serve
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;a href=&quot;https://github.com/modelcontextprotocol/ext-apps&quot;&gt;ext-apps repository&lt;/a&gt; includes starter templates for React, Vue, Svelte, Preact, Solid, and vanilla JavaScript. Choose the framework that matches your preferences.&lt;/p&gt;

&lt;h3 id=&quot;testing-your-app&quot;&gt;Testing Your App&lt;/h3&gt;

&lt;p&gt;For development, use the basic-host test interface to debug your app locally:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;ext-apps/examples/basic-host
&lt;span class=&quot;nv&quot;&gt;SERVERS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;[&quot;http://localhost:3001/mcp&quot;]&apos;&lt;/span&gt; npm start
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Navigate to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://localhost:8080&lt;/code&gt; to see your app render in an MCP-compatible host.&lt;/p&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s Next?&lt;/h2&gt;

&lt;p&gt;MCP Apps are still early, but adoption is growing rapidly. VS Code, Claude Desktop, Postman, and other AI environments already support them. As more tools and agents integrate MCP, you’ll see dashboards and interactive workflows become standard.&lt;/p&gt;

&lt;p&gt;The implications for DevOps and cloud engineering are particularly interesting. Instead of describing infrastructure or asking an agent to list resources in text, you could have interactive dashboards for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Resource discovery and filtering&lt;/strong&gt;: Browse Azure resources visually&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Configuration wizards&lt;/strong&gt;: Step through deployment decisions with validation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Monitoring and alerting&lt;/strong&gt;: Real-time dashboards alongside AI analysis&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Approval workflows&lt;/strong&gt;: Review changes and approve with confidence&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cost analysis&lt;/strong&gt;: Interactive charts and drill-down into spending patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The combination of AI agents and interactive dashboards creates a powerful new class of tools.&lt;/p&gt;

&lt;h2 id=&quot;demo-mcp-storage-account-app&quot;&gt;Demo: MCP Storage Account App&lt;/h2&gt;

&lt;p&gt;I built a small demo MCP App that surfaces Azure storage accounts in a simple dashboard so you can explore the list, inspect details, and validate the flow end to end. If you want a practical reference implementation, you can find it here:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tw3lveparsecs/mcp-apps-demo&quot;&gt;https://github.com/tw3lveparsecs/mcp-apps-demo&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;key-takeaways&quot;&gt;Key Takeaways&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;MCP Apps solve a real problem&lt;/strong&gt;: Text-based agent responses don’t scale for exploration, configuration, or monitoring&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Security is built-in&lt;/strong&gt;: Sandboxed iframes isolate apps from the host, but you still need to validate inputs and protect secrets&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The architecture is elegant&lt;/strong&gt;: Simple tool registration with UI metadata, bidirectional postMessage communication, and no reinventing the wheel for authentication&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Azure integration is practical&lt;/strong&gt;: You can build dashboards that replace manual CLI queries and portal browsing&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The ecosystem is growing&lt;/strong&gt;: With VS Code support and multiple framework options, building MCP Apps is accessible to most developers&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Have you started building MCP Apps? What problems are you trying to solve with interactive dashboards? Share your experiences in the comments. I’d love to hear how the community is pushing this technology forward.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://modelcontextprotocol.io/docs/extensions/apps&quot;&gt;Model Context Protocol: MCP Apps Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.visualstudio.com/blogs/2026/01/26/mcp-apps-support&quot;&gt;VS Code MCP Apps Support: Official Announcement&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/modelcontextprotocol/ext-apps&quot;&gt;MCP Apps SDK and Examples: GitHub&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://modelcontextprotocol.io/specification&quot;&gt;MCP Specification&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 14 Feb 2026 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/mcp-apps/</link>
        <guid isPermaLink="true">https://azurewithaj.com/mcp-apps/</guid>
        
        <category>mcp</category>
        
        <category>ai</category>
        
        <category>agents</category>
        
        <category>vscode</category>
        
        <category>github</category>
        
        <category>copilot</category>
        
        
        <category>AI</category>
        
        <category>DevOps</category>
        
      </item>
    
      <item>
        <title>GitHub Copilot&apos;s Agentic Memory: Teaching AI to Remember and Learn Your Codebase</title>
        <description>&lt;p&gt;One of the biggest challenges with AI coding assistants has been their stateless nature with every interaction starting from scratch, requiring developers to repeatedly explain coding conventions, architectural patterns, and repository-specific knowledge. GitHub has just changed the game with the public preview of &lt;strong&gt;agentic memory&lt;/strong&gt; for GitHub Copilot, a revolutionary capability that allows AI agents to remember and learn from your codebase over time.&lt;/p&gt;

&lt;p&gt;This isn’t just another incremental improvement, it’s a fundamental shift toward truly intelligent AI assistants that grow smarter with every interaction. Let’s dive into how this groundbreaking feature works and why it’s set to transform how we collaborate with AI in our development workflows.&lt;/p&gt;

&lt;h2 id=&quot;the-problem-context-lost-in-translation&quot;&gt;The Problem: Context Lost in Translation&lt;/h2&gt;

&lt;p&gt;Picture this scenario: You’re working on a complex enterprise application with specific coding conventions, database connection patterns, and synchronised configuration files. Every time you interact with GitHub Copilot, you find yourself explaining the same architectural decisions and coding standards. The AI produces decent code, but it lacks the deep understanding of your repository’s unique patterns and requirements.&lt;/p&gt;

&lt;p&gt;Traditional AI assistants suffer from “contextual amnesia” - they can’t retain knowledge between sessions. This means:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Repetitive explanations&lt;/strong&gt;: Constantly re-explaining coding conventions and patterns&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Inconsistent suggestions&lt;/strong&gt;: AI recommendations that don’t align with established codebase patterns&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Missed relationships&lt;/strong&gt;: Failing to understand dependencies between files that must stay synchronised&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Generic responses&lt;/strong&gt;: One-size-fits-all solutions that don’t respect repository-specific best practices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While we can leverage GitHub Copilot’s instructions to provide context, this approach is limited. Instructions can become lengthy, hard to maintain, and still don’t solve the problem of retaining knowledge across sessions.&lt;/p&gt;

&lt;h2 id=&quot;introducing-agentic-memory-ai-that-learns-and-remembers&quot;&gt;Introducing Agentic Memory: AI That Learns and Remembers&lt;/h2&gt;

&lt;p&gt;Agentic memory represents a paradigm shift in how AI assistants work with code. Instead of starting fresh with each interaction, Copilot now builds and maintains a persistent understanding of your repository through “memories”. Tightly scoped pieces of knowledge that it discovers and validates over time.&lt;/p&gt;

&lt;h3 id=&quot;how-memories-are-created&quot;&gt;How Memories Are Created&lt;/h3&gt;

&lt;p&gt;The memory system works through what GitHub calls “just-in-time verification”. Here’s the elegant process:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Copilot Agent Working] --&amp;gt; B{Discovers Actionable Pattern}
    B --&amp;gt;|Yes| C[Create Memory with Citations]
    B --&amp;gt;|No| D[Continue Work]
    C --&amp;gt; E[Store Memory in Repository]
    E --&amp;gt; F[Available for Future Sessions]

    style A fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style C fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style E fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style F fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When Copilot discovers something worth remembering, it creates a structured memory entry:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;subject&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;API version synchronisation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;fact&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;API version must match between client SDK, server routes, and documentation.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;citations&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;src/client/sdk/constants.ts:12&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;server/routes/api.go:8&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;docs/api-reference.md:37&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;reason&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;If the API version is not kept properly synchronised, the integration can fail or exhibit subtle bugs. Remembering these locations will help ensure they are kept synchronised in future updates.&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;memory-validation-and-self-healing&quot;&gt;Memory Validation and Self-Healing&lt;/h3&gt;

&lt;p&gt;The brilliant aspect of this system is its self-healing nature. Before applying any stored memory, Copilot validates it against the current codebase:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Agent Starts New Session] --&amp;gt; B[Retrieve Repository Memories]
    B --&amp;gt; C[Check Citations Against Current Code]
    C --&amp;gt; D{Citations Valid?}
    D --&amp;gt;|Yes| E[Apply Memory Knowledge]
    D --&amp;gt;|No| F[Store Corrected Memory or Discard]
    E --&amp;gt; G[Continue with Enhanced Context]
    F --&amp;gt; G

    style A fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style C fill:#f59e0b,stroke:#d97706,stroke-width:3px,color:#fff
    style E fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style F fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style G fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This real-time verification ensures that memories remain accurate even as code evolves, branches change, and files are refactored.&lt;/p&gt;

&lt;h2 id=&quot;privacy-and-security-is-it-safe-to-use&quot;&gt;Privacy and Security: Is it safe to use?&lt;/h2&gt;

&lt;p&gt;One of the first questions that comes to mind with any AI memory system is privacy and security. Is it safe to let an AI remember details about my codebase?&lt;/p&gt;

&lt;p&gt;What I had to understand is that Copilot Memory stores repository-scoped memories &lt;strong&gt;only&lt;/strong&gt;. This means memories are tied to a specific repository and can only be used by Copilot operations on that same repository.&lt;/p&gt;

&lt;p&gt;Key points:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Repository Isolation&lt;/strong&gt;: Memories are strictly scoped to individual repositories (not shared across repositories or orgs)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Permission-Based Creation&lt;/strong&gt;: Only contributors with write permissions can create memories&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Access Control&lt;/strong&gt;: Memories can be used by other users with appropriate repository access, but not outside that repository&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Management Tools&lt;/strong&gt;: Repository owners can view and delete stored memories via repository settings&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Automatic Expiry&lt;/strong&gt;: Memories automatically delete after 28 days unless refreshed through validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This ensures that sensitive repository knowledge stays within the appropriate boundaries while enabling powerful AI assistance.&lt;/p&gt;

&lt;h2 id=&quot;current-availability-and-getting-started&quot;&gt;Current Availability and Getting Started&lt;/h2&gt;

&lt;p&gt;Agentic memory is currently available in public preview for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Copilot Coding Agent&lt;/strong&gt;: Enhanced task completion with repository-specific knowledge&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Copilot Code Review&lt;/strong&gt;: Smarter pull request reviews based on learned patterns&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Copilot CLI&lt;/strong&gt;: Context-aware command-line assistance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;enabling-memory-for-your-team&quot;&gt;Enabling Memory for Your Team&lt;/h3&gt;

&lt;p&gt;The feature is opt-in and available for all paid Copilot plans:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For Individual Users (Copilot Pro/Pro+):&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Navigate to &lt;a href=&quot;https://github.com/settings/copilot&quot;&gt;Personal Copilot Settings&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Under “Features”, find “Copilot Memory”&lt;/li&gt;
  &lt;li&gt;Select “Enabled” from the dropdown&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;For Organisations and Enterprises:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Go to Organisation/Enterprise Settings&lt;/li&gt;
  &lt;li&gt;Navigate to Copilot policies&lt;/li&gt;
  &lt;li&gt;Enable Copilot Memory for your team&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Repository Management:&lt;/strong&gt;
Repository owners can review and manage stored memories via:
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Repository Settings &amp;gt; Copilot &amp;gt; Memory&lt;/code&gt;&lt;/p&gt;

&lt;h2 id=&quot;implementation-best-practices&quot;&gt;Implementation Best Practices&lt;/h2&gt;

&lt;p&gt;To maximise the value of agentic memory in your development workflows:&lt;/p&gt;

&lt;h3 id=&quot;1-start-with-high-impact-repositories&quot;&gt;1. Start with High-Impact Repositories&lt;/h3&gt;

&lt;p&gt;Enable memory on repositories with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Complex coding conventions&lt;/li&gt;
  &lt;li&gt;Synchronised configuration files&lt;/li&gt;
  &lt;li&gt;Specific architectural patterns&lt;/li&gt;
  &lt;li&gt;Multiple team contributors&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-monitor-memory-quality&quot;&gt;2. Monitor Memory Quality&lt;/h3&gt;

&lt;p&gt;Regularly review stored memories to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Remove outdated or incorrect memories&lt;/li&gt;
  &lt;li&gt;Validate that learned patterns align with current practices&lt;/li&gt;
  &lt;li&gt;Ensure memories reflect your team’s coding standards&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-leverage-cross-agent-benefits&quot;&gt;3. Leverage Cross-Agent Benefits&lt;/h3&gt;

&lt;p&gt;Use multiple Copilot features together:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Let Code Review agents learn from expert developer patterns&lt;/li&gt;
  &lt;li&gt;Allow Coding Agent to benefit from review insights&lt;/li&gt;
  &lt;li&gt;Use CLI with enhanced repository context&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;4-educate-your-team&quot;&gt;4. Educate Your Team&lt;/h3&gt;

&lt;p&gt;Ensure team members understand:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;How memories are created and validated&lt;/li&gt;
  &lt;li&gt;The privacy and security model&lt;/li&gt;
  &lt;li&gt;How to review and manage repository memories&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion-a-new-era-of-intelligent-development&quot;&gt;Conclusion: A New Era of Intelligent Development&lt;/h2&gt;

&lt;p&gt;GitHub Copilot’s agentic memory represents a fundamental evolution in AI-assisted development. By solving the “contextual amnesia” problem, it enables AI agents to become true collaboration partners that grow more valuable over time.&lt;/p&gt;

&lt;p&gt;The beauty lies not just in the technical implementation, but in how it transforms the developer experience. No more explaining the same patterns repeatedly. No more generic suggestions that miss repository-specific context. Instead, you get AI assistance that truly understands your codebase and respects your team’s established practices.&lt;/p&gt;

&lt;p&gt;As we embrace this new era of agentic AI, the question isn’t whether to adopt these capabilities, but how quickly we can integrate them into our development workflows to unlock their full potential.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have you enabled agentic memory in your repositories yet? What patterns do you hope Copilot will learn from your codebase? Share your experiences and thoughts in the comments below.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.blog/ai-and-ml/github-copilot/building-an-agentic-memory-system-for-github-copilot/&quot;&gt;Building an Agentic Memory System for GitHub Copilot&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.blog/changelog/2026-01-15-agentic-memory-for-github-copilot-is-in-public-preview/&quot;&gt;Agentic Memory Public Preview Announcement&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.github.com/en/copilot/concepts/agents/copilot-memory&quot;&gt;About Agentic Memory for GitHub Copilot&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.github.com/en/copilot/how-tos/use-copilot-agents/copilot-memory&quot;&gt;Enabling and Curating Copilot Memory&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 21 Jan 2026 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/github-copilot-agentic-memory/</link>
        <guid isPermaLink="true">https://azurewithaj.com/github-copilot-agentic-memory/</guid>
        
        <category>github</category>
        
        <category>copilot</category>
        
        <category>ai</category>
        
        <category>agentic</category>
        
        <category>memory</category>
        
        
        <category>AI</category>
        
      </item>
    
      <item>
        <title>Beyond Planning: How GitHub Spec Kit Transforms Ideas into Implementation</title>
        <description>&lt;p&gt;In my journey exploring agentic DevOps tools, I’ve previously written about &lt;a href=&quot;https://azurewithaj.com/posts/agentic-devops-delivered-major-enhancement/&quot;&gt;delivering major enhancements using Awesome Copilot&lt;/a&gt; and &lt;a href=&quot;https://azurewithaj.com/posts/github-plan-agent/&quot;&gt;GitHub’s built-in Plan Agent&lt;/a&gt;. Each tool has pushed the boundaries of what’s possible when AI assists with development workflows. Today, I’m diving into my experience with &lt;strong&gt;GitHub Spec Kit&lt;/strong&gt;, a developer-centric toolkit that takes planning and implementation to an entirely new level of detail and sophistication.&lt;/p&gt;

&lt;p&gt;This post explores how Spec Kit compares to the other tools I’ve evaluated, the unique advantages it brings to the developer experience, and why it might be the most comprehensive approach to AI-assisted development I’ve encountered yet.&lt;/p&gt;

&lt;h2 id=&quot;what-is-github-spec-kit&quot;&gt;What is GitHub Spec Kit?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/github/spec-kit&quot;&gt;GitHub Spec Kit&lt;/a&gt; is an open-source toolkit designed to help developers create detailed specifications and implementation plans directly within their development environment. Unlike the more accessible Plan Agent or the prompt-based Awesome Copilot approach, Spec Kit is purpose-built for developers who want to stay in their IDE while creating incredibly detailed project specifications.&lt;/p&gt;

&lt;p&gt;The toolkit provides structured templates, workflows, and methodologies for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Requirements gathering&lt;/strong&gt;: Systematic approach to capturing functional and non-functional requirements&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Technical specification&lt;/strong&gt;: Detailed architecture and implementation planning&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Task breakdown&lt;/strong&gt;: Granular work item creation with dependencies and acceptance criteria&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Implementation tracking&lt;/strong&gt;: Progress monitoring and milestone management&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;my-demo-project-visualising-spec-kit-in-action&quot;&gt;My Demo Project: Visualising Spec Kit in Action&lt;/h2&gt;

&lt;p&gt;To truly understand how Spec Kit works, I’ve been building a demo web application that demonstrates the toolkit’s capabilities and workflow using GitHub Spec Kit. The project showcases how Spec Kit transforms high-level ideas into detailed, implementable specifications.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;a href=&quot;https://github.com/tw3lveparsecs/github-spec-kit-demo-app&quot;&gt;Demo repository available here&lt;/a&gt; &lt;em&gt;(Note: This project is still in active development as I continue exploring Spec Kit’s capabilities)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The demo includes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Interactive visualisation of the Spec Kit workflow&lt;/li&gt;
  &lt;li&gt;Sample scenarios showcasing various inputs and their resulting outputs&lt;/li&gt;
  &lt;li&gt;Custom scenario builder using your own specifications&lt;/li&gt;
  &lt;li&gt;Exploration of tokens and constitution principles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;../assets/images/posts/2025-12-16-github-spec-kit/demo_app_overview.png&quot; alt=&quot;Spec Kit demo application overview&quot; /&gt;
&lt;em&gt;My demo application showcasing GitHub Spec Kit’s workflow and capabilities&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;the-evolution-from-simple-planning-to-comprehensive-specification&quot;&gt;The Evolution: From Simple Planning to Comprehensive Specification&lt;/h2&gt;

&lt;p&gt;Let me position Spec Kit within my broader experience with agentic development tools:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Awesome Copilot] --&amp;gt; B[Proven Prompts&amp;lt;br/&amp;gt;&amp;amp; Agents]
    B --&amp;gt; C[Manual Integration&amp;lt;br/&amp;gt;Required]

    D[Plan Agent] --&amp;gt; E[Built-in VS Code&amp;lt;br/&amp;gt;Integration]
    E --&amp;gt; F[Zero Configuration&amp;lt;br/&amp;gt;Planning]

    G[GitHub Spec Kit] --&amp;gt; H[Developer-Centric&amp;lt;br/&amp;gt;Toolkit]
    H --&amp;gt; I[Comprehensive&amp;lt;br/&amp;gt;Specification Framework]

    C --&amp;gt; J[Good for: Accessing&amp;lt;br/&amp;gt;Library of Customisations]
    F --&amp;gt; K[Good for: Natural&amp;lt;br/&amp;gt;Language Planning]
    I --&amp;gt; L[Good for: Staying&amp;lt;br/&amp;gt;in the IDE]

    style A fill:#6366f1,stroke:#4f46e5,stroke-width:2px,color:#fff
    style B fill:#818cf8,stroke:#6366f1,stroke-width:2px,color:#fff
    style C fill:#a5b4fc,stroke:#818cf8,stroke-width:2px,color:#1e1b4b
    style D fill:#f97316,stroke:#ea580c,stroke-width:2px,color:#fff
    style E fill:#fb923c,stroke:#f97316,stroke-width:2px,color:#fff
    style F fill:#fdba74,stroke:#fb923c,stroke-width:2px,color:#431407
    style G fill:#10b981,stroke:#059669,stroke-width:2px,color:#fff
    style H fill:#34d399,stroke:#10b981,stroke-width:2px,color:#fff
    style I fill:#6ee7b7,stroke:#34d399,stroke-width:2px,color:#022c22
    style J fill:#a5b4fc,stroke:#818cf8,stroke-width:2px,color:#1e1b4b
    style K fill:#fdba74,stroke:#fb923c,stroke-width:2px,color:#431407
    style L fill:#6ee7b7,stroke:#34d399,stroke-width:2px,color:#022c22
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each tool serves different needs:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Awesome Copilot&lt;/strong&gt;: Flexible, customisable, requires configuration knowledge&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Plan Agent&lt;/strong&gt;: Accessible, integrated, easy to get started&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Spec Kit&lt;/strong&gt;: Requires setup knowledge, developer-focused, keeps you in the IDE&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;my-experience-four-key-observations&quot;&gt;My Experience: Four Key Observations&lt;/h2&gt;

&lt;h3 id=&quot;1-developer-centric-and-ide-native&quot;&gt;1. Developer-Centric and IDE-Native&lt;/h3&gt;

&lt;p&gt;One of Spec Kit’s greatest strengths is how it keeps you firmly planted in your development environment. Unlike web-based planning tools or even the Chat view in VS Code, Spec Kit integrates directly into your project structure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I observed:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Specifications become part of your repository, versioned alongside your code&lt;/li&gt;
  &lt;li&gt;Templates and workflows integrate with your existing development tools&lt;/li&gt;
  &lt;li&gt;No context switching between planning and implementation environments&lt;/li&gt;
  &lt;li&gt;Natural integration with Git workflows for specification evolution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach feels natural for developers who prefer staying in their IDE rather than switching to separate planning tools.&lt;/p&gt;

&lt;h3 id=&quot;2-barrier-to-entry-vs-accessibility&quot;&gt;2. Barrier to Entry vs Accessibility&lt;/h3&gt;

&lt;p&gt;While Spec Kit’s developer-centric approach is a strength, it also creates a higher barrier to entry compared to something like Plan Agent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plan Agent advantages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Works immediately in VS Code with zero setup&lt;/li&gt;
  &lt;li&gt;Natural language interface - just describe what you want&lt;/li&gt;
  &lt;li&gt;No need to understand templates or workflow structures&lt;/li&gt;
  &lt;li&gt;Easy to get started&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Spec Kit considerations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Requires understanding of the toolkit’s structure and methodology&lt;/li&gt;
  &lt;li&gt;Initial setup and configuration needed&lt;/li&gt;
  &lt;li&gt;Need familiarity with templates and specification formats&lt;/li&gt;
  &lt;li&gt;Best suited for developers comfortable with structured approaches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For teams new to AI-assisted development, Plan Agent provides a gentler introduction. Spec Kit is better suited for teams ready to invest in a more comprehensive planning methodology.&lt;/p&gt;

&lt;h3 id=&quot;3-incredibly-detailed-planning-and-implementation&quot;&gt;3. Incredibly Detailed Planning and Implementation&lt;/h3&gt;

&lt;p&gt;Where Spec Kit truly shines is in the depth and detail of the plans it helps you create.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Level of detail I experienced:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Requirements&lt;/strong&gt;: Not just functional requirements, but detailed acceptance criteria, edge cases, and non-functional requirements&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Implementation phases&lt;/strong&gt;: Granular task breakdown with dependencies, and success criteria&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Test plans&lt;/strong&gt;: Detailed test plans specific to each user story&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: Built-in templates for technical documentation, API specs, and user guides&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;4-understanding-each-phase-and-input-requirements&quot;&gt;4. Understanding Each Phase and Input Requirements&lt;/h3&gt;

&lt;p&gt;To get the most out of Spec Kit, I found you need to understand its methodology and provide specific inputs at each phase. This isn’t necessarily a limitation, but it does require investment in learning the system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key phases I learned:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Discovery Phase&lt;/strong&gt;: Gathering requirements, stakeholder input, and constraints&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Specification Phase&lt;/strong&gt;: Creating detailed technical and functional specifications&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Planning Phase&lt;/strong&gt;: Breaking down work into implementable tasks&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Implementation Phase&lt;/strong&gt;: Executing against the detailed specifications&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Validation Phase&lt;/strong&gt;: Testing and verification against original requirements&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Critical inputs for success:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Context&lt;/strong&gt;: Detailed background about the system, users, and constraints&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Requirements&lt;/strong&gt;: Clear functional and non-functional requirements&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Constraints&lt;/strong&gt;: Technical, business, and resource limitations&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;: External systems, APIs, and integration requirements&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Success criteria&lt;/strong&gt;: Measurable outcomes and acceptance criteria&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;when-to-use-each-tool-my-current-thinking&quot;&gt;When to Use Each Tool: My Current Thinking&lt;/h2&gt;

&lt;p&gt;Based on my experience across all three tools, here’s my current framework for tool selection:&lt;/p&gt;

&lt;h3 id=&quot;use-plan-agent-when&quot;&gt;Use Plan Agent When:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Natural language&lt;/strong&gt;: Prefer a natural language centric approach&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Proof of concepts&lt;/strong&gt;: Exploring feasibility of ideas&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Team onboarding&lt;/strong&gt;: Introducing AI-assisted planning&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Accessibility priority&lt;/strong&gt;: Need zero-configuration solutions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;use-awesome-copilot-when&quot;&gt;Use Awesome Copilot When:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Custom workflows&lt;/strong&gt;: Need specific prompt structures or agents&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Team standards&lt;/strong&gt;: Require consistent planning templates&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Iterative refinement&lt;/strong&gt;: Building on proven prompt libraries&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Flexibility priority&lt;/strong&gt;: Need to customise approaches&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;use-spec-kit-when&quot;&gt;Use Spec Kit When:&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Developer centric&lt;/strong&gt; Prefer a developer centric approach&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Developer teams&lt;/strong&gt;: Working with teams comfortable with structured approaches&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Investment in planning&lt;/strong&gt;: Invested in gathering and providing inputs for each phase of the workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-future-of-specification-driven-development&quot;&gt;The Future of Specification-Driven Development&lt;/h2&gt;

&lt;p&gt;Spec Kit represents a fascinating evolution in how we think about AI-assisted development. Rather than replacing human planning, it provides structure and methodology to make our planning more comprehensive and actionable.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The investment in learning Spec Kit’s methodology pays dividends in the quality and detail of the resulting specifications. For development teams ready to embrace structured, specification-driven development, Spec Kit provides a powerful framework for transforming ideas into thoroughly planned implementations.&lt;/p&gt;

&lt;p&gt;The key insight from my experience across all three tools is that different projects require different levels of planning sophistication. Having access to this spectrum of tools, from the quick accessibility of Plan Agent to the developer centric approach of Spec Kit. It enables us to match our planning approach to our project needs.&lt;/p&gt;

&lt;p&gt;Have you experimented with GitHub Spec Kit or similar specification frameworks? I’d love to hear about your experiences and how you’re integrating structured planning into your development workflows.&lt;/p&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/github/spec-kit&quot;&gt;GitHub Spec Kit Repository&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/tw3lveparsecs/github-spec-kit-demo-app&quot;&gt;My Demo Application&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://azurewithaj.com/posts/github-plan-agent/&quot;&gt;My Previous Post: From Awesome Copilot to Plan Agent&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://azurewithaj.com/posts/agentic-devops-delivered-major-enhancement/&quot;&gt;My Previous Post: Delivering Major Enhancements Without Writing Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 15 Dec 2025 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/github-spec-kit/</link>
        <guid isPermaLink="true">https://azurewithaj.com/github-spec-kit/</guid>
        
        <category>github</category>
        
        <category>copilot</category>
        
        <category>agent</category>
        
        <category>devops</category>
        
        <category>agentic</category>
        
        <category>ai</category>
        
        <category>spec-kit</category>
        
        <category>planning</category>
        
        
        <category>DevOps</category>
        
        <category>AI</category>
        
      </item>
    
      <item>
        <title>From Awesome Copilot to Plan Agent: GitHub&apos;s Built-in Planning Revolution</title>
        <description>&lt;p&gt;In my &lt;a href=&quot;https://azurewithaj.com/posts/agentic-devops-delivered-major-enhancement&quot;&gt;previous post about delivering major enhancements using agentic DevOps&lt;/a&gt;, I shared how I leveraged &lt;a href=&quot;https://github.com/github/awesome-copilot&quot;&gt;GitHub’s Awesome Copilot repository&lt;/a&gt; to access proven prompts and agents for creating implementation plans. That approach served me well, but GitHub has now introduced something that changes the game entirely: the built-in &lt;strong&gt;Plan agent&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This post explores how the new Plan agent compares to my previous Awesome Copilot workflow, what’s changed in my approach, and whether this native integration delivers on its promise of streamlining complex coding tasks.&lt;/p&gt;

&lt;h2 id=&quot;the-evolution-from-external-resources-to-native-integration&quot;&gt;The Evolution: From External Resources to Native Integration&lt;/h2&gt;

&lt;h3 id=&quot;my-previous-approach-with-awesome-copilot&quot;&gt;My Previous Approach with Awesome Copilot&lt;/h3&gt;

&lt;p&gt;When I wrote about my agentic DevOps journey, my planning workflow relied on external resources:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Accessing the Awesome Copilot repository&lt;/strong&gt; for proven prompts and methodologies&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Using the Create Implementation Plan prompt&lt;/strong&gt; to generate comprehensive technical plans&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Applying the Implementation Plan agent (formerly chat mode)&lt;/strong&gt; to iteratively refine and expand the plan&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Optionally using the MCP server&lt;/strong&gt; to integrate these resources into my workflow&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach worked exceptionally well, but it required:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Knowledge of where to find these resources&lt;/li&gt;
  &lt;li&gt;Manual integration of prompts and agents&lt;/li&gt;
  &lt;li&gt;Context switching between resources and VS Code&lt;/li&gt;
  &lt;li&gt;Configuration of MCP servers for seamless integration&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;the-new-built-in-plan-agent&quot;&gt;The New Built-in Plan Agent&lt;/h3&gt;

&lt;p&gt;With VS Code 1.105, GitHub introduced the Plan agent as a native feature. Instead of hunting for external prompts or configuring MCP servers, you can now access planning capabilities directly from the Chat view.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph LR
    subgraph Previous[&quot;Previous Approach&quot;]
        A[Awesome Copilot Repo] --&amp;gt; B[Find Prompts]
        B --&amp;gt; C[Configure Agents]
        C --&amp;gt; D[Create Plan]
    end

    subgraph Current[&quot;Current Approach&quot;]
        E[Open Chat View] --&amp;gt; F[Select Plan Agent]
        F --&amp;gt; G[Describe Task]
        G --&amp;gt; H[Receive Plan]
    end

    style A fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style B fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style C fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style D fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style E fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style F fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style G fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style H fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;how-the-plan-agent-works&quot;&gt;How the Plan Agent Works&lt;/h2&gt;

&lt;p&gt;The Plan agent is designed to help you analyse tasks, break them down into steps, and generate implementation plans before you start development. This approach helps avoid missing important requirements, something I emphasised heavily in my previous workflow.&lt;/p&gt;

&lt;h3 id=&quot;getting-started-with-plan-agent&quot;&gt;Getting Started with Plan Agent&lt;/h3&gt;

&lt;p&gt;To use the Plan agent:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Open the Chat view (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+Alt+I&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Select &lt;strong&gt;Plan&lt;/strong&gt; from the agents dropdown&lt;/li&gt;
  &lt;li&gt;Describe your task in detail&lt;/li&gt;
  &lt;li&gt;Review and refine the generated plan&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;the-handoff-feature&quot;&gt;The Handoff Feature&lt;/h3&gt;

&lt;p&gt;One of the most powerful features of the Plan agent is the &lt;strong&gt;handoff&lt;/strong&gt; capability. After finalising your plan, you can:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Start implementation immediately&lt;/strong&gt;: Transition directly to coding with context preserved&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Save the plan for later&lt;/strong&gt;: Store the plan for future reference or team collaboration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This handoff feature uses VS Code’s new custom chat modes system, creating guided workflows that transition between planning and implementation phases with suggested next steps.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;../assets/images/posts/2025-12-10-github-plan-agent/plan_agent_handoff.png&quot; alt=&quot;Plan agent handoff options&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;comparing-the-two-approaches&quot;&gt;Comparing the Two Approaches&lt;/h2&gt;

&lt;h3 id=&quot;what-awesome-copilot-offered&quot;&gt;What Awesome Copilot Offered&lt;/h3&gt;

&lt;p&gt;The Awesome Copilot resources provided:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Curated prompts&lt;/strong&gt;: Community-tested and refined over time&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Structured templates&lt;/strong&gt;: Consistent format for implementation plans&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Agents&lt;/strong&gt;: Persona-driven interactions for specific tasks&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;: Ability to customise and extend prompts&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MCP integration&lt;/strong&gt;: Programmatic access to resources&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;what-plan-agent-brings&quot;&gt;What Plan Agent Brings&lt;/h3&gt;

&lt;p&gt;The built-in Plan agent offers:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Zero configuration&lt;/strong&gt;: Works out of the box in VS Code&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Native integration&lt;/strong&gt;: Seamless experience within the editor&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Handoff workflow&lt;/strong&gt;: Direct transition from planning to implementation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Context preservation&lt;/strong&gt;: Plan context carries through to development&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Subagent support&lt;/strong&gt;: Works alongside VS Code’s new isolated subagents feature&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;my-experience-plan-agent-vs-awesome-copilot&quot;&gt;My Experience: Plan Agent vs Awesome Copilot&lt;/h2&gt;

&lt;h3 id=&quot;the-good-accessibility-and-workflow&quot;&gt;The Good: Accessibility and Workflow&lt;/h3&gt;

&lt;p&gt;The Plan agent’s greatest strength is its &lt;strong&gt;accessibility&lt;/strong&gt;. It’s incredibly intuitive and requires virtually no learning curve. Within minutes of opening the Chat view, I was generating comprehensive plans without needing to reference external documentation or configure anything.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;iterative refinement process&lt;/strong&gt; feels natural. Unlike my previous workflow where I’d copy prompts from Awesome Copilot and paste them into chat, the Plan agent maintains conversation context seamlessly. I can ask for more detail on specific steps, request alternative approaches, or drill down into technical considerations without losing the thread of the discussion.&lt;/p&gt;

&lt;p&gt;Perhaps most impressive is the &lt;strong&gt;handoff mechanism&lt;/strong&gt;. The ability to transition directly from planning to implementation or save the plan to a file while preserving all context eliminates friction.&lt;/p&gt;

&lt;h3 id=&quot;the-trade-offs-structure-and-depth&quot;&gt;The Trade-offs: Structure and Depth&lt;/h3&gt;

&lt;p&gt;The Plan agent’s output differs from what I was accustomed to with Awesome Copilot’s structured templates:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plan Structure&lt;/strong&gt;: The Awesome Copilot “Create Implementation Plan” prompt produced well-structured output with clearly articulated goals and tasks broken down hierarchically, making it suitable for backlog items, stakeholder communication, or sprint ceremonies. In contrast, the Plan agent breaks plans down into detailed bulleted steps focused on technical implementation. While this works well for development, it’s less structured for project management purposes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Risk and Dependency Analysis&lt;/strong&gt;: I’ve noticed that &lt;strong&gt;dependencies and risks aren’t explicitly called out&lt;/strong&gt; in the plans. The Awesome Copilot templates had dedicated sections for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Technical dependencies and integration points&lt;/li&gt;
  &lt;li&gt;Potential risks and mitigation strategies&lt;/li&gt;
  &lt;li&gt;Security and compliance considerations&lt;/li&gt;
  &lt;li&gt;Performance implications&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;integration-with-the-broader-agentic-workflow&quot;&gt;Integration with the Broader Agentic Workflow&lt;/h2&gt;

&lt;p&gt;The Plan agent doesn’t exist in isolation. It’s part of a broader ecosystem that GitHub introduced at Universe 2025:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Plan Agent] --&amp;gt; B[Create Implementation Plan]
    B --&amp;gt; C{Handoff Decision}
    C --&amp;gt;|Immediate| D[Start Implementation]
    C --&amp;gt;|Delegate| E[Coding Agent]
    C --&amp;gt;|Save| F[Plan for Later]

    D --&amp;gt; G[Local Development]
    E --&amp;gt; H[Autonomous Development]
    F --&amp;gt; I[Team Collaboration]

    G --&amp;gt; J[Pull Request]
    H --&amp;gt; J
    I --&amp;gt; K[Future Session]

    style A fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style B fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style C fill:#f59e0b,stroke:#d97706,stroke-width:3px,color:#fff
    style D fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style E fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style F fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style G fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style H fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style I fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style J fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style K fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;subagents-for-research&quot;&gt;Subagents for Research&lt;/h3&gt;

&lt;p&gt;The new isolated subagents feature complements the Plan agent perfectly. You can use subagents for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Context gathering&lt;/strong&gt;: Research authentication mechanisms, API patterns, or existing implementations&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Analysis&lt;/strong&gt;: Investigate codebase structure or dependency relationships&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Parallel research&lt;/strong&gt;: Delegate research tasks while you focus on planning&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;delegation-to-coding-agent&quot;&gt;Delegation to Coding Agent&lt;/h3&gt;

&lt;p&gt;If your repository has the &lt;a href=&quot;https://aka.ms/coding-agent-docs&quot;&gt;Copilot coding agent enabled&lt;/a&gt;, you can delegate directly from your planning session. This mirrors my previous workflow but with better context preservation:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Plan with the Plan agent&lt;/li&gt;
  &lt;li&gt;Refine and finalise the plan&lt;/li&gt;
  &lt;li&gt;Delegate to the coding agent&lt;/li&gt;
  &lt;li&gt;Review and merge the PR&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;The introduction of the Plan agent signals GitHub’s commitment to making agentic workflows more accessible. Rather than requiring developers to discover and configure external resources, core capabilities are being baked into the tools we use daily. The journey from Awesome Copilot prompts to the built-in Plan agent represents a significant step forward in making agentic DevOps accessible to all developers. While Awesome Copilot remains a valuable resource for customised workflows and team-specific templates, the Plan agent provides an excellent starting point that requires zero configuration.&lt;/p&gt;

&lt;p&gt;For my workflow, the Plan agent has become my default starting point for new features and enhancements. The seamless integration, handoff capabilities, and context preservation make it a natural fit for the agentic DevOps approach I outlined in my previous post.&lt;/p&gt;

&lt;p&gt;Have you tried the Plan agent in VS Code? I’d love to hear how it compares to your existing planning workflows. Share your experiences in the comments below.&lt;/p&gt;

&lt;h2 id=&quot;further-reading&quot;&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.visualstudio.com/updates/v1_105#_plan-agent&quot;&gt;VS Code 1.105 Release Notes - Plan Agent&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.visualstudio.com/docs/copilot/chat/chat-planning&quot;&gt;Using the Built-in Plan Agent in VS Code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/github/awesome-copilot&quot;&gt;GitHub’s Awesome Copilot Repository&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://code.visualstudio.com/docs/copilot/customization/custom-chat-modes#_handoffs&quot;&gt;Custom Chat Modes and Handoffs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://azurewithaj.com/posts/agentic-devops-delivered-major-enhancement/&quot;&gt;My Previous Post: Delivering Major Enhancements Without Writing Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 09 Dec 2025 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/github-plan-agent/</link>
        <guid isPermaLink="true">https://azurewithaj.com/github-plan-agent/</guid>
        
        <category>github</category>
        
        <category>copilot</category>
        
        <category>agent</category>
        
        <category>devops</category>
        
        <category>agentic</category>
        
        <category>ai</category>
        
        <category>plan</category>
        
        
        <category>DevOps</category>
        
        <category>AI</category>
        
      </item>
    
      <item>
        <title>Azure Copilot Agents: Transforming Cloud Operations</title>
        <description>&lt;p&gt;Microsoft Ignite 2025 has delivered what might be the most transformative announcement for cloud operations teams: &lt;strong&gt;Azure Copilot Agents&lt;/strong&gt;. This isn’t just another AI assistant, it’s a fundamental reimagining of how we deploy, monitor, optimise, and troubleshoot cloud infrastructure.&lt;/p&gt;

&lt;p&gt;The announcement centres around five specialised agents that work together as an orchestrated team, each bringing deep expertise in their domain while maintaining the context and governance that enterprise cloud operations demand. This is the natural evolution of what we’ve been building toward in the DevOps space: AI that doesn’t just complete our commands, but actively participates in the operational lifecycle.&lt;/p&gt;

&lt;h2 id=&quot;the-problem-cloud-operations-complexity-at-scale&quot;&gt;The Problem: Cloud Operations Complexity at Scale&lt;/h2&gt;

&lt;p&gt;Before we dive into the solution, let’s acknowledge the reality of modern cloud operations. Today’s cloud teams are drowning in complexity:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Deployment sprawl&lt;/strong&gt;: Managing infrastructure across multiple regions, subscriptions, and resource types&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Reactive troubleshooting&lt;/strong&gt;: Constant fire-fighting instead of proactive optimisation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Knowledge silos&lt;/strong&gt;: Deep expertise trapped in individual team members&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Context switching&lt;/strong&gt;: Bouncing between Azure Portal, CLI tools, monitoring dashboards, and documentation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compliance burden&lt;/strong&gt;: Ensuring security and governance across growing environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The traditional approach requires teams to master dozens of services, maintain mental models of complex interdependencies, and execute repetitive operational tasks that could be automated if only we had the orchestration capabilities to make it happen safely and reliably.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Cloud Operations Team] --&amp;gt; B[Azure Portal]
    A --&amp;gt; C[Azure CLI]
    A --&amp;gt; D[PowerShell Scripts]
    A --&amp;gt; E[Monitoring Dashboards]
    A --&amp;gt; F[Documentation Sites]

    B -.-&amp;gt;|No shared context| C
    C -.-&amp;gt;|Manual coordination| D
    D -.-&amp;gt;|Reactive responses| E
    E -.-&amp;gt;|Knowledge gaps| F
    F -.-&amp;gt;|Context switching| B

    G[Complex Cloud Environment] --&amp;gt; H[Deployment Issues]
    G --&amp;gt; I[Performance Problems]
    G --&amp;gt; J[Security Concerns]
    G --&amp;gt; K[Cost Overruns]

    style A fill:#f59e0b,stroke:#d97706,stroke-width:3px,color:#fff
    style B fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style C fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style D fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style E fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style F fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style G fill:#dc2626,stroke:#991b1b,stroke-width:3px,color:#fff
    style H fill:#ef4444,stroke:#dc2626,stroke-width:2px,color:#fff
    style I fill:#ef4444,stroke:#dc2626,stroke-width:2px,color:#fff
    style J fill:#ef4444,stroke:#dc2626,stroke-width:2px,color:#fff
    style K fill:#ef4444,stroke:#dc2626,stroke-width:2px,color:#fff
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;the-transformation-azure-copilot-as-your-cloud-operations-command-centre&quot;&gt;The Transformation: Azure Copilot as Your Cloud Operations Command Centre&lt;/h2&gt;

&lt;p&gt;Azure Copilot Agents transforms this fragmented experience into a unified, intelligent operations platform. Instead of managing tools, you’re orchestrating specialised agents that bring deep expertise to every aspect of cloud operations.&lt;/p&gt;

&lt;p&gt;The core insight is elegant: &lt;strong&gt;Azure Copilot becomes your cloud operations command centre&lt;/strong&gt;, intelligently surfacing the right agent at the right time based on your needs. Whether you’re deploying new infrastructure, investigating performance issues, or optimising costs, the appropriate specialist agent appears with full context and actionable recommendations.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Azure Copilot Command Centre] --&amp;gt; B[Deployment Agent]
    A --&amp;gt; C[Observability Agent]
    A --&amp;gt; D[Optimisation Agent]
    A --&amp;gt; E[Resiliency Agent]
    A --&amp;gt; F[Troubleshooting Agent]

    B &amp;lt;--&amp;gt; C
    C &amp;lt;--&amp;gt; D
    D &amp;lt;--&amp;gt; E
    E &amp;lt;--&amp;gt; F
    F &amp;lt;--&amp;gt; B

    G[Cloud Operations Team] --&amp;gt; A

    H[Unified Context &amp;amp; Governance] --&amp;gt; A
    I[Azure Well-Architected Framework] --&amp;gt; A
    J[Enterprise Controls] --&amp;gt; A

    style A fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style B fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#fff
    style C fill:#8b5cf6,stroke:#7c3aed,stroke-width:2px,color:#fff
    style D fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#fff
    style E fill:#10b981,stroke:#059669,stroke-width:2px,color:#fff
    style F fill:#06b6d4,stroke:#0891b2,stroke-width:2px,color:#fff
    style G fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style H fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style I fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style J fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;the-five-specialised-agents-your-cloud-operations-dream-team&quot;&gt;The Five Specialised Agents: Your Cloud Operations Dream Team&lt;/h2&gt;

&lt;p&gt;Let’s explore each agent and understand how they transform specific operational workflows.&lt;/p&gt;

&lt;h3 id=&quot;1-deployment-agent-your-virtual-cloud-architect&quot;&gt;1. Deployment Agent: Your Virtual Cloud Architect&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Deployment Agent&lt;/strong&gt; serves as a virtual cloud solution architect, guiding you through infrastructure planning and deployment with precision and best practices built-in.&lt;/p&gt;

&lt;h4 id=&quot;what-makes-it-game-changing&quot;&gt;What Makes It Game-Changing&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Intelligent planning&lt;/strong&gt;: Translates high-level goals into detailed infrastructure blueprints&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Azure Well-Architected compliance&lt;/strong&gt;: All recommendations follow Microsoft’s framework&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Multi-turn conversations&lt;/strong&gt;: Clarifies requirements through iterative discussion&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Complete automation&lt;/strong&gt;: Generates ready-to-deploy code configurations&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Integrated workflows&lt;/strong&gt;: Direct integration with GitHub and VS Code for the Web&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;example-workflow&quot;&gt;Example Workflow&lt;/h4&gt;

&lt;p&gt;Here’s how the Deployment Agent transforms a typical infrastructure request:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;sequenceDiagram
    participant O as Operations Team
    participant AC as Azure Copilot
    participant DA as Deployment Agent
    participant GH as GitHub
    participant VS as VS Code Web

    O-&amp;gt;&amp;gt;AC: &quot;I need a scalable web app with SQL database&quot;
    AC-&amp;gt;&amp;gt;DA: Routes to Deployment Agent
    DA-&amp;gt;&amp;gt;DA: Analyzes requirements
    DA-&amp;gt;&amp;gt;AC: Asks clarifying questions about scale, regions, security
    O-&amp;gt;&amp;gt;AC: Provides additional context
    DA-&amp;gt;&amp;gt;DA: Generates comprehensive plan
    DA-&amp;gt;&amp;gt;AC: Returns detailed infrastructure blueprint
    O-&amp;gt;&amp;gt;AC: Approves plan
    DA-&amp;gt;&amp;gt;DA: Generates code configurations
    DA-&amp;gt;&amp;gt;AC: Presents configurations in artifact pane
    O-&amp;gt;&amp;gt;VS: Opens in VS Code for the Web
    O-&amp;gt;&amp;gt;GH: Creates pull request
    GH-&amp;gt;&amp;gt;GH: CI/CD pipeline deploys infrastructure

    Note over O: Primary User
    Note over AC: Central Orchestrator
    Note over DA: Specialist Agent
    Note over GH: Version Control
    Note over VS: Development Environment
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;2-observability-agent-your-investigation-specialist&quot;&gt;2. Observability Agent: Your Investigation Specialist&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Observability Agent&lt;/strong&gt; transforms how you handle Azure Monitor alerts and incident investigation by providing deep, automated analysis and clear remediation paths.&lt;/p&gt;

&lt;h4 id=&quot;key-capabilities&quot;&gt;Key Capabilities&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Automated investigations&lt;/strong&gt;: Creates Azure Monitor issues and runs root cause analysis&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Contextual insights&lt;/strong&gt;: Leverages your specific environment data&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Multi-alert correlation&lt;/strong&gt;: Identifies patterns across related alerts&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Actionable remediation&lt;/strong&gt;: Provides specific steps to resolve issues&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Support escalation&lt;/strong&gt;: Automatically creates support requests when needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;practical-usage-patterns&quot;&gt;Practical Usage Patterns&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Direct Alert Investigation:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# When viewing an alert in Azure Portal&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Can you help investigate this alert?&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# For specific alerts&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Start an investigation for my alert: /subscriptions/[...]/alerts/ALERT_ID&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Proactive Monitoring:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;s2&quot;&gt;&quot;What are the key alerts raised in the last 24 hours?&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Show me any patterns in Application Insights failures&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-optimisation-agent-your-cost-and-performance-expert&quot;&gt;3. Optimisation Agent: Your Cost and Performance Expert&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Optimisation Agent&lt;/strong&gt; focuses on reducing costs and carbon emissions while maintaining performance, a critical capability for sustainable cloud operations.&lt;/p&gt;

&lt;h4 id=&quot;current-focus-areas&quot;&gt;Current Focus Areas&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Resource Types:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Virtual Machines (VMs)&lt;/li&gt;
  &lt;li&gt;Virtual Machine Scale Sets (VMSS)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Optimisation Capabilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Detailed recommendations&lt;/strong&gt;: Specific actions with cost impact analysis&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Alternative options&lt;/strong&gt;: Multiple approaches for comparison&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Script generation&lt;/strong&gt;: Ready-to-execute PowerShell and Azure CLI commands&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Visual insights&lt;/strong&gt;: Charts showing expected results&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Carbon footprint&lt;/strong&gt;: Environmental impact analysis&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;example-optimisation-workflow&quot;&gt;Example Optimisation Workflow&lt;/h4&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Request Optimisation] --&amp;gt; B[Agent Analyses Usage Patterns]
    B --&amp;gt; C[Identifies Opportunities]
    C --&amp;gt; D[Calculates Impact]
    D --&amp;gt; E[Generates Recommendations]
    E --&amp;gt; F[Creates Visual Charts]
    F --&amp;gt; G[Provides Scripts]
    G --&amp;gt; H{Approve Changes?}
    H --&amp;gt;|Yes| I[Execute Optimisations]
    H --&amp;gt;|No| J[Explore Alternatives]
    J --&amp;gt; E
    I --&amp;gt; K[Monitor Results]

    style A fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style B fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style C fill:#8b5cf6,stroke:#7c3aed,stroke-width:2px,color:#fff
    style D fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style E fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#fff
    style F fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style G fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style H fill:#f59e0b,stroke:#d97706,stroke-width:3px,color:#fff
    style I fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style J fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style K fill:#10b981,stroke:#059669,stroke-width:2px,color:#fff
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&quot;sample-optimisation-requests&quot;&gt;Sample Optimisation Requests&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Subscription-wide Analysis:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Show me the top five cost-saving opportunities for subscription [GUID]&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Summarise total potential cost and carbon reduction from all active recommendations&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Resource-specific Optimisation:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Show me cost saving recommendations for [Resource URI]&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Is there an alternate recommendation for ContosoVM1?&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Generate a PowerShell script to apply the recommended optimisations&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;4-resiliency-agent-your-business-continuity-guardian&quot;&gt;4. Resiliency Agent: Your Business Continuity Guardian&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Resiliency Agent&lt;/strong&gt; helps ensure your Azure resources can recover from failures, cyber attacks, data corruption, and datacentre outages.&lt;/p&gt;

&lt;h4 id=&quot;core-responsibilities&quot;&gt;Core Responsibilities&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Zonal resiliency configuration&lt;/strong&gt;: Multi-zone deployment strategies&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Backup management&lt;/strong&gt;: Azure Backup policy implementation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Disaster recovery&lt;/strong&gt;: Azure Site Recovery setup and management&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Security posture&lt;/strong&gt;: Recovery services security improvements&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compliance monitoring&lt;/strong&gt;: Backup and recovery compliance checking&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;zonal-resiliency-automation&quot;&gt;Zonal Resiliency Automation&lt;/h4&gt;

&lt;p&gt;The agent provides ready-to-deploy scripts for configuring zonal resiliency across supported services:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Supported Services:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Virtual Machines&lt;/li&gt;
  &lt;li&gt;App Services&lt;/li&gt;
  &lt;li&gt;Azure Database for PostgreSQL&lt;/li&gt;
  &lt;li&gt;Azure Database for MySQL&lt;/li&gt;
  &lt;li&gt;SQL Managed Instance&lt;/li&gt;
  &lt;li&gt;Azure Cache for Redis&lt;/li&gt;
  &lt;li&gt;Azure Firewall&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;sample-resiliency-tasks&quot;&gt;Sample Resiliency Tasks&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure Hardening:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Configure zonal resiliency for this resource&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Which service groups are currently not zonally resilient?&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Increase the security level of this vault&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Backup and Recovery:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;s2&quot;&gt;&quot;How many backup jobs failed in the last 24 hours?&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Which data sources don&apos;t have a recovery point within the last 7 days?&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Help me create vault ABC&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;5-troubleshooting-agent-your-technical-support-specialist&quot;&gt;5. Troubleshooting Agent: Your Technical Support Specialist&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Troubleshooting Agent&lt;/strong&gt; accelerates issue resolution by running diagnostics, providing solutions, and creating support requests when needed.&lt;/p&gt;

&lt;h4 id=&quot;advanced-capabilities&quot;&gt;Advanced Capabilities&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Root cause analysis&lt;/strong&gt;: Deep diagnostic investigation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;One-click fixes&lt;/strong&gt;: Automated resolution for common issues&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Support request generation&lt;/strong&gt;: Automated ticket creation with full context&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Resource-specific expertise&lt;/strong&gt;: Specialised knowledge for different Azure services&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;specialised-service-support&quot;&gt;Specialised Service Support&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Azure Cosmos DB:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Help me troubleshoot why my Cosmos DB Cassandra API is failing&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;I&apos;m trying to connect to Azure Cosmos DB from my local machine, but I keep getting a timeout&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Virtual Machines:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Help me investigate why my VM is unhealthy&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;I can&apos;t connect to my VM, can you help me troubleshoot?&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Azure Kubernetes Service:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Investigate the health of my pods&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Identify reasons for high CPU or memory usage in my AKS cluster&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;agent-orchestration-the-magic-of-intelligent-routing&quot;&gt;Agent Orchestration: The Magic of Intelligent Routing&lt;/h2&gt;

&lt;p&gt;What makes Azure Copilot Agents truly powerful is the intelligent orchestration. You don’t need to manually select which agent to use, the system automatically surfaces the right agent based on your request.&lt;/p&gt;

&lt;h3 id=&quot;how-orchestration-works&quot;&gt;How Orchestration Works&lt;/h3&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[User Request] --&amp;gt; B[Azure Copilot Orchestration]
    B --&amp;gt; C{Request Analysis}

    C --&amp;gt;|&quot;Deploy infrastructure&quot;| D[Deployment Agent]
    C --&amp;gt;|&quot;Investigate alert&quot;| E[Observability Agent]
    C --&amp;gt;|&quot;Reduce costs&quot;| F[Optimisation Agent]
    C --&amp;gt;|&quot;Configure backups&quot;| G[Resiliency Agent]
    C --&amp;gt;|&quot;Fix connection issue&quot;| H[Troubleshooting Agent]

    D --&amp;gt; I[Specialised Response]
    E --&amp;gt; I
    F --&amp;gt; I
    G --&amp;gt; I
    H --&amp;gt; I

    I --&amp;gt; J[Cross-Agent Collaboration]
    J --&amp;gt; K[Unified Result]

    style A fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style B fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style C fill:#f59e0b,stroke:#d97706,stroke-width:3px,color:#fff
    style D fill:#3b82f6,stroke:#2563eb,stroke-width:2px,color:#fff
    style E fill:#8b5cf6,stroke:#7c3aed,stroke-width:2px,color:#fff
    style F fill:#f59e0b,stroke:#d97706,stroke-width:2px,color:#fff
    style G fill:#10b981,stroke:#059669,stroke-width:2px,color:#fff
    style H fill:#06b6d4,stroke:#0891b2,stroke-width:2px,color:#fff
    style I fill:#64748b,stroke:#475569,stroke-width:2px,color:#fff
    style J fill:#8b5cf6,stroke:#7c3aed,stroke-width:2px,color:#fff
    style K fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;cross-agent-collaboration&quot;&gt;Cross-Agent Collaboration&lt;/h3&gt;

&lt;p&gt;The real magic happens when agents work together. For example:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Troubleshooting Agent&lt;/strong&gt; identifies a performance issue&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Optimisation Agent&lt;/strong&gt; provides cost-effective solutions&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Deployment Agent&lt;/strong&gt; generates infrastructure changes&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Resiliency Agent&lt;/strong&gt; ensures the solution includes backup strategies&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Observability Agent&lt;/strong&gt; sets up monitoring for the new configuration&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;getting-started-enabling-agent-mode&quot;&gt;Getting Started: Enabling Agent Mode&lt;/h2&gt;

&lt;p&gt;Using Azure Copilot Agents is straightforward once your tenant has access:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Azure Copilot Agents is currently in preview and access will be rolled out gradually over time.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;step-1-enable-agent-mode&quot;&gt;Step 1: Enable Agent Mode&lt;/h3&gt;

&lt;p&gt;In Azure Copilot, start a conversation as you normally would, then select the agent mode icon.&lt;/p&gt;

&lt;h3 id=&quot;step-2-natural-language-requests&quot;&gt;Step 2: Natural Language Requests&lt;/h3&gt;

&lt;p&gt;Simply describe what you need in natural language:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;s2&quot;&gt;&quot;I need to set up a resilient web application with global load balancing&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;Why is my Application Insights showing high response times?&quot;&lt;/span&gt;
&lt;span class=&quot;s2&quot;&gt;&quot;What are the biggest cost optimisation opportunities in my environment?&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;step-3-review-and-approve&quot;&gt;Step 3: Review and Approve&lt;/h3&gt;

&lt;p&gt;Agents provide detailed plans and recommendations before taking any action. You maintain full control over what gets implemented.&lt;/p&gt;

&lt;h3 id=&quot;step-4-monitor-and-iterate&quot;&gt;Step 4: Monitor and Iterate&lt;/h3&gt;

&lt;p&gt;Use the unified interface to track agent progress, review results, and provide feedback for continuous improvement.&lt;/p&gt;

&lt;h2 id=&quot;enterprise-considerations-security-and-governance&quot;&gt;Enterprise Considerations: Security and Governance&lt;/h2&gt;

&lt;p&gt;Microsoft has built enterprise-grade controls into the agent experience, addressing critical concerns for production use.&lt;/p&gt;

&lt;h3 id=&quot;tenant-level-access-control&quot;&gt;Tenant-Level Access Control&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Gradual rollout&lt;/strong&gt;: Access is managed at the tenant level with gradual expansion&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Administrator control&lt;/strong&gt;: IT admins can enable/disable access and manage user groups&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Audit trail&lt;/strong&gt;: Complete logging of all agent activities&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compliance integration&lt;/strong&gt;: Works within existing Azure governance frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;security-best-practices&quot;&gt;Security Best Practices&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Built-in Protections:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Integration with Azure RBAC&lt;/li&gt;
  &lt;li&gt;Compliance with organisational policies&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;privacy-and-data-handling&quot;&gt;Privacy and Data Handling&lt;/h3&gt;

&lt;p&gt;Microsoft has implemented strict data handling practices:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Conversations are encrypted and secured&lt;/li&gt;
  &lt;li&gt;No training data extraction from your environment&lt;/li&gt;
  &lt;li&gt;Compliance with enterprise privacy requirements&lt;/li&gt;
  &lt;li&gt;Integration with existing Azure security controls&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;current-limitations-and-future-roadmap&quot;&gt;Current Limitations and Future Roadmap&lt;/h2&gt;

&lt;h3 id=&quot;current-preview-limitations&quot;&gt;Current Preview Limitations&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Deployment Agent:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Terraform configurations only (ARM and Bicep coming)&lt;/li&gt;
  &lt;li&gt;Greenfield deployments only (existing infrastructure import coming)&lt;/li&gt;
  &lt;li&gt;Manual CI/CD integration (automated pipelines coming)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Optimisation Agent:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;VMs and VMSS only (more resource types coming)&lt;/li&gt;
  &lt;li&gt;No automatic execution (approval workflows coming)&lt;/li&gt;
  &lt;li&gt;Limited budget integration (full cost management coming)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Observability Agent:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Application Insights alerts only (broader alert types coming)&lt;/li&gt;
  &lt;li&gt;Investigation only (automatic remediation coming)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Language Support:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Full support in English only&lt;/li&gt;
  &lt;li&gt;Limited support for other languages&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;expected-enhancements&quot;&gt;Expected Enhancements&lt;/h3&gt;

&lt;p&gt;Microsoft has outlined several areas of active development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Expanded Resource Support:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;More resource types for optimisation&lt;/li&gt;
  &lt;li&gt;Broader troubleshooting capabilities&lt;/li&gt;
  &lt;li&gt;Enhanced resiliency configurations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Deeper Integration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Native CI/CD pipeline creation&lt;/li&gt;
  &lt;li&gt;Advanced governance controls&lt;/li&gt;
  &lt;li&gt;Multi-cloud scenarios&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Advanced Capabilities:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Predictive optimisation recommendations&lt;/li&gt;
  &lt;li&gt;Automated remediation with approval workflows&lt;/li&gt;
  &lt;li&gt;Cross-tenant collaboration for managed service providers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;strategic-implications-the-future-of-cloud-operations&quot;&gt;Strategic Implications: The Future of Cloud Operations&lt;/h2&gt;

&lt;p&gt;Azure Copilot Agents represents more than just new tooling, it’s a fundamental shift toward &lt;strong&gt;agentic cloud operations&lt;/strong&gt;. This transformation has several strategic implications:&lt;/p&gt;

&lt;h3 id=&quot;1-role-evolution&quot;&gt;1. Role Evolution&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cloud Architects&lt;/strong&gt; become orchestrators, focusing on:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Strategic planning and governance&lt;/li&gt;
  &lt;li&gt;Agent delegation and oversight&lt;/li&gt;
  &lt;li&gt;Cross-platform integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Operations Engineers&lt;/strong&gt; shift from reactive to proactive:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Defining automation policies&lt;/li&gt;
  &lt;li&gt;Monitoring agent effectiveness&lt;/li&gt;
  &lt;li&gt;Continuous improvement processes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-skill-development&quot;&gt;2. Skill Development&lt;/h3&gt;

&lt;p&gt;New competencies become critical:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Agent prompt engineering&lt;/strong&gt;: Crafting effective requests&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Agentic workflow design&lt;/strong&gt;: Orchestrating multi-agent processes&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;AI-human collaboration&lt;/strong&gt;: Working effectively with AI partners&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-organisational-changes&quot;&gt;3. Organisational Changes&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Faster Innovation Cycles:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Rapid infrastructure experimentation&lt;/li&gt;
  &lt;li&gt;Automated compliance and security&lt;/li&gt;
  &lt;li&gt;Continuous optimisation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Improved Reliability:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Proactive issue detection&lt;/li&gt;
  &lt;li&gt;Consistent best practices application&lt;/li&gt;
  &lt;li&gt;Reduced human error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cost Efficiency:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Automated optimisation recommendations&lt;/li&gt;
  &lt;li&gt;Resource right-sizing&lt;/li&gt;
  &lt;li&gt;Predictive capacity planning&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion-embracing-the-agentic-future&quot;&gt;Conclusion: Embracing the Agentic Future&lt;/h2&gt;

&lt;p&gt;Microsoft Ignite 2025’s Azure Copilot Agents announcement signals the beginning of truly agentic cloud operations. This isn’t just an incremental improvement, it’s a fundamental reimagining of how we interact with cloud infrastructure.&lt;/p&gt;

&lt;p&gt;The five specialised agents (Deployment, Observability, Optimisation, Resiliency, and Troubleshooting) work together as an expert team that never sleeps, never forgets best practices, and continuously learns from your environment. The intelligent orchestration means you focus on strategic decisions while agents handle operational execution.&lt;/p&gt;

&lt;h3 id=&quot;key-takeaways&quot;&gt;Key Takeaways&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Start experimenting now&lt;/strong&gt;: Request preview access and begin familiarising your team&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Plan for workflow changes&lt;/strong&gt;: Consider how agentic operations will transform your processes&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Invest in agent skills&lt;/strong&gt;: Begin developing prompt engineering and AI collaboration competencies&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Prepare governance frameworks&lt;/strong&gt;: Establish controls and approval processes for agent activities&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Measure and iterate&lt;/strong&gt;: Track efficiency gains and optimise agent utilisation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The transformation is already underway. Organisations that embrace agentic cloud operations now will have a significant advantage in speed, reliability, and cost efficiency. The question isn’t whether this future will arrive, it’s whether you’ll be ready to lead in it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ready to start your agentic cloud operations journey?&lt;/strong&gt; Begin by exploring the &lt;a href=&quot;https://learn.microsoft.com/en-us/azure/copilot/agents-preview&quot;&gt;Azure Copilot Agents documentation&lt;/a&gt; and requesting access for your organisation.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Have you started experimenting with Azure Copilot Agents? I’d love to hear about your experiences and what use cases you’re exploring. Share your thoughts and questions in the comments below.&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 23 Nov 2025 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/azure-copilot-agents/</link>
        <guid isPermaLink="true">https://azurewithaj.com/azure-copilot-agents/</guid>
        
        <category>azure</category>
        
        <category>copilot</category>
        
        <category>agent</category>
        
        <category>ai</category>
        
        <category>agentic</category>
        
        <category>devops</category>
        
        <category>ignite</category>
        
        <category>operations</category>
        
        
        <category>DevOps</category>
        
        <category>AI</category>
        
      </item>
    
      <item>
        <title>Welcome Home, Agents: How GitHub Copilot Agent HQ is Transforming Development Workflows</title>
        <description>&lt;p&gt;The development landscape has fundamentally shifted. We’re no longer working with simple AI assistants that complete our code,we’re orchestrating fleets of specialised agents that can take on entire features, collaborate across tools, and work asynchronously while we sleep. GitHub’s announcement of &lt;strong&gt;Agent HQ&lt;/strong&gt; at Universe 2025 marks a pivotal moment in how we think about development workflows, and the accompanying VS Code updates make this vision tangible today.&lt;/p&gt;

&lt;p&gt;After spending the last few months working deeply with GitHub Copilot’s coding agent and now experimenting with the latest VS Code agent integrations, I’ve witnessed firsthand how this transformation changes everything from how we plan work to how we manage our development sessions. This isn’t hype,it’s a fundamental shift in how development teams operate.&lt;/p&gt;

&lt;h2 id=&quot;the-problem-fragmented-agent-experiences&quot;&gt;The Problem: Fragmented Agent Experiences&lt;/h2&gt;

&lt;p&gt;Before Agent HQ, working with AI agents felt like managing multiple contractors who all used different communication channels, had no visibility into each other’s work, and required constant context switching. You might have:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;GitHub Copilot coding agent&lt;/strong&gt; running on GitHub.com&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;VS Code local chat sessions&lt;/strong&gt; for immediate help&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;GitHub Copilot CLI&lt;/strong&gt; for terminal commands&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Third-party agents&lt;/strong&gt; like OpenAI Codex or Anthropic Claude in their native interfaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each operated in its own silo. You’d assign work to a coding agent on GitHub, switch to VS Code to write some code with chat assistance, jump to the terminal for CLI help, and then try to mentally piece together what was happening across all these sessions. The cognitive overhead was immense, and the lack of unified visibility meant agents couldn’t benefit from each other’s context.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Developer] --&amp;gt; B[GitHub Copilot on GitHub.com]
    A --&amp;gt; C[VS Code Chat Sessions]
    A --&amp;gt; D[GitHub Copilot CLI]
    A --&amp;gt; E[Third-Party Agents]

    B -.-&amp;gt;|No visibility| C
    C -.-&amp;gt;|No visibility| D
    D -.-&amp;gt;|No visibility| E
    E -.-&amp;gt;|No visibility| B

    style A fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style B fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style C fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style D fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style E fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;the-vision-agent-hq-as-your-development-command-centre&quot;&gt;The Vision: Agent HQ as Your Development Command Centre&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.blog/news-insights/company-news/welcome-home-agents/&quot;&gt;GitHub’s Agent HQ&lt;/a&gt; fundamentally reimagines this experience. Instead of disconnected tools, you get &lt;strong&gt;mission control&lt;/strong&gt;,a unified command centre that follows you wherever you work. Whether you’re in VS Code, on GitHub.com, using the CLI, or even on mobile, you have consistent visibility and control over all your agents.&lt;/p&gt;

&lt;p&gt;The core principle is elegant: &lt;strong&gt;GitHub is your Agent HQ&lt;/strong&gt;. It’s where agents live, work, and collaborate, just like human developers do through pull requests and issues.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Agent HQ: Mission Control] --&amp;gt; B[VS Code Sessions]
    A --&amp;gt; C[GitHub Copilot Coding Agent]
    A --&amp;gt; D[GitHub Copilot CLI]
    A --&amp;gt; E[Third-Party Agents]
    A --&amp;gt; F[Mobile/Web Access]

    B &amp;lt;--&amp;gt; C
    C &amp;lt;--&amp;gt; D
    D &amp;lt;--&amp;gt; E
    E &amp;lt;--&amp;gt; B

    G[Developer] --&amp;gt; A

    style A fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style G fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style B fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style C fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style D fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style E fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style F fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;the-game-changer-agent-sessions-view-in-vs-code&quot;&gt;The Game Changer: Agent Sessions View in VS Code&lt;/h2&gt;

&lt;p&gt;The October 2025 VS Code release (v1.106) brings Agent HQ directly into your editor with the &lt;strong&gt;Agent Sessions view&lt;/strong&gt;. This is now enabled by default and provides centralised management of all your active agent sessions, both local and remote.&lt;/p&gt;

&lt;h3 id=&quot;what-the-agent-sessions-view-gives-you&quot;&gt;What the Agent Sessions View Gives You&lt;/h3&gt;

&lt;p&gt;The Agent Sessions view is organised by source, making it easy to see exactly what’s happening across your development environment:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Local Chat Sessions&lt;/strong&gt;: Your VS Code chat conversations&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Copilot Coding Agent&lt;/strong&gt;: Background agent sessions running on GitHub&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;GitHub Copilot CLI&lt;/strong&gt;: Terminal-based agent sessions&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Third-Party Agents&lt;/strong&gt;: Sessions from OpenAI Codex, Anthropic Claude, and others&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph LR
    A[Agent Sessions View] --&amp;gt; B[Local Sessions]
    A --&amp;gt; C[Coding Agents]
    A --&amp;gt; D[CLI Sessions]
    A --&amp;gt; E[Third-Party Agents]

    B --&amp;gt; B1[Chat Session 1]
    B --&amp;gt; B2[Chat Session 2]

    C --&amp;gt; C1[Issue #123: Add DNS Fallback]
    C --&amp;gt; C2[Issue #456: Fix Bug]

    D --&amp;gt; D1[Terminal Session 1]

    E --&amp;gt; E1[OpenAI Codex Session]
    E --&amp;gt; E2[Anthropic Claude Session]

    style A fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style B fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style C fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style D fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
    style E fill:#94a3b8,stroke:#64748b,stroke-width:2px,color:#0f172a
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;practical-workflow-with-agent-sessions&quot;&gt;Practical Workflow with Agent Sessions&lt;/h3&gt;

&lt;p&gt;Here’s how this changes your daily workflow:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Morning Stand-up Scenario:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;1.&lt;/span&gt; Open VS Code
&lt;span class=&quot;p&quot;&gt;2.&lt;/span&gt; Check Agent Sessions view
&lt;span class=&quot;p&quot;&gt;3.&lt;/span&gt; See that the coding agent completed 3 PRs overnight
&lt;span class=&quot;p&quot;&gt;4.&lt;/span&gt; Review the CLI agent&apos;s deployment preparation
&lt;span class=&quot;p&quot;&gt;5.&lt;/span&gt; Resume your local chat session from yesterday
&lt;span class=&quot;p&quot;&gt;6.&lt;/span&gt; All without leaving your editor
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can search sessions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ctrl+Alt+F&lt;/code&gt;), quickly jump between them, and see the status of background work at a glance. The view also supports a consolidated single-view mode if you prefer everything in one place.&lt;/p&gt;

&lt;h2 id=&quot;plan-agent-the-strategic-thinking-partner&quot;&gt;Plan Agent: The Strategic Thinking Partner&lt;/h2&gt;

&lt;p&gt;One of the most impactful additions is the &lt;strong&gt;Plan Agent&lt;/strong&gt;, available via the agents dropdown in the Chat view. This fundamentally changes how I approach complex features.&lt;/p&gt;

&lt;h3 id=&quot;why-planning-matters-more-than-ever&quot;&gt;Why Planning Matters More Than Ever&lt;/h3&gt;

&lt;p&gt;I’ve learned from my agentic DevOps journey that the quality of AI output directly correlates with the quality of planning input. The Plan Agent addresses this by helping you:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Break down complex tasks&lt;/strong&gt; into step-by-step implementation plans&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Ask clarifying questions&lt;/strong&gt; to ensure all requirements are captured&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Identify dependencies&lt;/strong&gt; and potential issues before code is written&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Create a detailed blueprint&lt;/strong&gt; that you approve before implementation begins&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;how-we-can-use-the-plan-agent&quot;&gt;How We Can Use the Plan Agent&lt;/h3&gt;

&lt;p&gt;Here’s an example workflow:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Start with Feature Idea] --&amp;gt; B[Select Plan Agent]
    B --&amp;gt; C[Describe Feature Requirements]
    C --&amp;gt; D[Agent Asks Clarifying Questions]
    D --&amp;gt; E[Iterate on Requirements]
    E --&amp;gt; F[Review Generated Plan]
    F --&amp;gt; G{Plan Acceptable?}
    G --&amp;gt;|No| E
    G --&amp;gt;|Yes| H[Approve Plan]
    H --&amp;gt; I[Choose Implementation Method]
    I --&amp;gt; J[Local Implementation in VS Code]
    I --&amp;gt; K[Cloud Agent Implementation]

    style A fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style H fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
    style G fill:#f59e0b,stroke:#d97706,stroke-width:3px,color:#fff
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The beauty is that you invest time upfront in the plan, catching gaps and missing decisions early, before any code is written. This dramatically reduces rework and improves the final implementation quality.&lt;/p&gt;

&lt;h3 id=&quot;custom-plan-agents-for-your-team&quot;&gt;Custom Plan Agents for Your Team&lt;/h3&gt;

&lt;p&gt;VS Code also lets you create custom plan agents tailored to your organization’s workflows. Using the “Configure Custom Agent” menu, you can:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Copy the built-in plan agent as a starting point&lt;/li&gt;
  &lt;li&gt;Customise planning style to match your methodology (Agile, Waterfall, etc.)&lt;/li&gt;
  &lt;li&gt;Define specific tools and prompts for your domain&lt;/li&gt;
  &lt;li&gt;Set organization-specific guidelines and constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means your team can have consistent planning approaches while maintaining flexibility for different project types.&lt;/p&gt;

&lt;h2 id=&quot;cloud-agents-seamless-background-execution&quot;&gt;Cloud Agents: Seamless Background Execution&lt;/h2&gt;

&lt;p&gt;The October VS Code release migrated the Copilot coding agent integration from the GitHub Pull Request extension directly into the Copilot Chat extension. This might seem like a small technical change, but it’s actually huge for the user experience.&lt;/p&gt;

&lt;h3 id=&quot;what-changed-and-why-it-matters&quot;&gt;What Changed and Why It Matters&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Coding agent functionality felt bolted on, living in a separate extension with different behaviours and limited integration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now:&lt;/strong&gt; Cloud agents are first-class citizens in VS Code, providing:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Native experience&lt;/strong&gt;: Same interface patterns as local chat&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Bidirectional transitions&lt;/strong&gt;: Smoothly move between VS Code and GitHub Mission Control&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Unified context&lt;/strong&gt;: Cloud agents benefit from your local workspace context&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Consistent delegation&lt;/strong&gt;: Delegate work to cloud agents using familiar patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;example-cloud-agent-workflow&quot;&gt;Example Cloud Agent Workflow&lt;/h3&gt;

&lt;p&gt;Here’s how cloud agents fit into a typical development day:&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;gs&quot;&gt;**Morning:**&lt;/span&gt; Assign 3 issues to Copilot coding agent on GitHub.com

&lt;span class=&quot;gs&quot;&gt;**During the Day:**&lt;/span&gt; Work on other tasks, occasionally checking Agent Sessions view

&lt;span class=&quot;gs&quot;&gt;**Afternoon:**&lt;/span&gt; Coding agent creates PRs for 2 completed issues

&lt;span class=&quot;gs&quot;&gt;**Evening:**&lt;/span&gt; Review PRs in VS Code, provide feedback as PR comments

&lt;span class=&quot;gs&quot;&gt;**Overnight:**&lt;/span&gt; Coding agent iterates on feedback

&lt;span class=&quot;gs&quot;&gt;**Next Morning:**&lt;/span&gt; PRs ready to merge
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The key insight: &lt;strong&gt;You’re not blocked waiting for implementations&lt;/strong&gt;. You maintain momentum on strategic work while agents handle the execution heavy lifting.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;sequenceDiagram
    participant D as Developer
    participant GH as GitHub.com
    participant CA as Coding Agent
    participant VS as VS Code

    D-&amp;gt;&amp;gt;GH: Assign issues to @copilot
    activate CA
    CA-&amp;gt;&amp;gt;CA: Analyses requirements
    CA-&amp;gt;&amp;gt;CA: Implements features
    CA-&amp;gt;&amp;gt;GH: Creates PRs
    deactivate CA

    D-&amp;gt;&amp;gt;VS: Opens Agent Sessions view
    VS-&amp;gt;&amp;gt;GH: Fetches agent status
    GH-&amp;gt;&amp;gt;VS: Shows completed PRs

    D-&amp;gt;&amp;gt;VS: Reviews PR in editor
    D-&amp;gt;&amp;gt;GH: Adds review comments

    activate CA
    CA-&amp;gt;&amp;gt;GH: Reads feedback
    CA-&amp;gt;&amp;gt;CA: Implements changes
    CA-&amp;gt;&amp;gt;GH: Updates PR
    deactivate CA

    D-&amp;gt;&amp;gt;VS: Final review &amp;amp; merge
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;cli-agents-terminal-intelligence&quot;&gt;CLI Agents: Terminal Intelligence&lt;/h2&gt;

&lt;p&gt;The GitHub Copilot CLI integration brings agents directly into your terminal workflow. This is particularly powerful for complex command sequences and system administration tasks.&lt;/p&gt;

&lt;h3 id=&quot;how-cli-agents-work-in-vs-code&quot;&gt;How CLI Agents Work in VS Code&lt;/h3&gt;

&lt;p&gt;VS Code now provides two ways to work with CLI agents:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Chat Editor Mode&lt;/strong&gt;: Create CLI agent sessions in a dedicated editor&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Integrated Terminal Mode&lt;/strong&gt;: Run CLI agents directly in your terminal&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Chat Editor Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Full chat interface with message history&lt;/li&gt;
  &lt;li&gt;Model switching capabilities&lt;/li&gt;
  &lt;li&gt;Context attachment from workspace files&lt;/li&gt;
  &lt;li&gt;Persistent sessions across VS Code restarts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Terminal Mode Benefits:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Natural command-line feel&lt;/li&gt;
  &lt;li&gt;Immediate execution in your shell environment&lt;/li&gt;
  &lt;li&gt;Integration with existing shell history&lt;/li&gt;
  &lt;li&gt;Quick access via terminal dropdown&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;practical-cli-agent-use-cases&quot;&gt;Practical CLI Agent Use Cases&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure Deployment:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# In CLI agent terminal&lt;/span&gt;
@copilot How &lt;span class=&quot;k&quot;&gt;do &lt;/span&gt;I deploy this Bicep template to multiple regions with different parameters?

&lt;span class=&quot;c&quot;&gt;# Agent provides step-by-step commands&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# You can execute them directly or ask for clarifications&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Troubleshooting:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# Attach error logs&lt;/span&gt;
@copilot /attach error.log
@copilot Why is this Azure Function failing to start?

&lt;span class=&quot;c&quot;&gt;# Agent analyses logs and suggests fixes&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;cli-edit-tracking&quot;&gt;CLI Edit Tracking&lt;/h3&gt;

&lt;p&gt;A particularly useful feature: chat edit sessions now track edits made by CLI agents. When you create sessions from the Agent Sessions view, you can see edits through:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Inline edit pills&lt;/strong&gt;: Visual indicators in your code&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Working set view&lt;/strong&gt;: Comprehensive list of all changed files&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means you maintain full visibility into what CLI agents modify, just like you would with local chat sessions or coding agents.&lt;/p&gt;

&lt;h2 id=&quot;agent-delegation-orchestrating-specialised-work&quot;&gt;Agent Delegation: Orchestrating Specialised Work&lt;/h2&gt;

&lt;p&gt;The delegation model is where Agent HQ truly shines. Instead of doing everything yourself, you can delegate specific tasks to the most appropriate agent for the job.&lt;/p&gt;

&lt;h3 id=&quot;how-delegation-works&quot;&gt;How Delegation Works&lt;/h3&gt;

&lt;p&gt;From any chat session, you can:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Identify specialised work&lt;/strong&gt;: “This needs deployment expertise”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Use the cloud button&lt;/strong&gt;: Delegates to available agents&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Choose the agent&lt;/strong&gt;: Select from Copilot coding agent or third-party agents&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Monitor progress&lt;/strong&gt;: Track in Agent Sessions view&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;From CLI to Coding Agent:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/delegate&lt;/code&gt; command in CLI editors or terminal instances allows you to hand off work directly to the Copilot coding agent. This is incredibly useful when you realise a terminal task requires broader codebase changes.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;# In CLI agent session&lt;/span&gt;
@copilot Create a deployment script &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;multi-region failover

&lt;span class=&quot;c&quot;&gt;# Agent realises this needs code changes&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# You delegate to coding agent&lt;/span&gt;
/delegate Create the deployment script and integrate with CI/CD pipeline

&lt;span class=&quot;c&quot;&gt;# Coding agent picks up work, creates branch, implements changes&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;delegation-strategy&quot;&gt;Delegation Strategy&lt;/h3&gt;

&lt;p&gt;A strategic mental model for choosing the right agent for each task:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Local Chat (VS Code)&lt;/strong&gt;: Quick questions, code explanations, immediate assistance&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Plan Agent&lt;/strong&gt;: Strategic planning, requirement refinement, architectural decisions&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Coding Agent&lt;/strong&gt;: Feature implementation, bug fixes, pattern replication&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;CLI Agent&lt;/strong&gt;: Deployment commands, system configuration, troubleshooting&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Third-Party Agents&lt;/strong&gt;: Specialised tasks (e.g., OpenAI Codex for Python, Claude for documentation)&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Development Task] --&amp;gt; B{Task Type?}

    B --&amp;gt;|Quick Question| C[Local VS Code Chat]
    B --&amp;gt;|Complex Feature| D[Plan Agent]
    B --&amp;gt;|Implementation| E[Coding Agent]
    B --&amp;gt;|Terminal/Deploy| F[CLI Agent]
    B --&amp;gt;|Specialised| G[Third-Party Agent]

    D --&amp;gt; H[Create Plan]
    H --&amp;gt; E

    C --&amp;gt; I{Needs More?}
    I --&amp;gt;|Yes| E
    I --&amp;gt;|No| J[Done]

    E --&amp;gt; K[Creates PR]
    K --&amp;gt; L[Review in VS Code]

    F --&amp;gt; M{Complex Changes?}
    M --&amp;gt;|Yes| E
    M --&amp;gt;|No| N[Execute Commands]

    style A fill:#2563eb,stroke:#1e40af,stroke-width:3px,color:#fff
    style B fill:#f59e0b,stroke:#d97706,stroke-width:3px,color:#fff
    style I fill:#f59e0b,stroke:#d97706,stroke-width:3px,color:#fff
    style M fill:#f59e0b,stroke:#d97706,stroke-width:3px,color:#fff
    style J fill:#059669,stroke:#047857,stroke-width:3px,color:#fff
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;custom-agents-tailoring-ai-to-your-workflow&quot;&gt;Custom Agents: Tailoring AI to Your Workflow&lt;/h2&gt;

&lt;p&gt;One of the most powerful features is the ability to create custom agents with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.agent.md&lt;/code&gt; files. These replace the previous “chat modes” and are now compatible across VS Code, GitHub Copilot Cloud Agents, and GitHub CLI.&lt;/p&gt;

&lt;h3 id=&quot;why-custom-agents-matter&quot;&gt;Why Custom Agents Matter&lt;/h3&gt;

&lt;p&gt;Custom agents let you:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Encode team knowledge&lt;/strong&gt;: Specific patterns, conventions, and best practices&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Create specialists&lt;/strong&gt;: Security-focused agents, testing agents, documentation agents&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Define workflows&lt;/strong&gt;: Multi-step processes unique to your organization&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Control behaviours&lt;/strong&gt;: Precise guardrails and guidelines for AI behaviour&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;creating-a-custom-agent&quot;&gt;Creating a Custom Agent&lt;/h3&gt;

&lt;p&gt;Custom agent files live in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.github/agents/&lt;/code&gt; and use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.agent.md&lt;/code&gt; suffix:&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Generate an implementation plan for new features or refactoring existing code.&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Planner&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;vscode&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;tools&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;fetch&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;githubRepo&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;search&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;usages&quot;&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Claude Sonnet &lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;handoffs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;label&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Implement Plan&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;agent&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;agent&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;prompt&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Implement the plan outlined above.&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;

&lt;span class=&quot;gh&quot;&gt;# Planning instructions&lt;/span&gt;

You are in planning mode. Your task is to generate an implementation plan for a new feature or for refactoring existing code.
Don&apos;t make any code edits, just generate a plan.

The plan consists of a Markdown document that describes the implementation plan, including the following sections:
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; Overview: A brief description of the feature or refactoring task.
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Requirements: A list of requirements for the feature or refactoring task.
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Implementation Steps: A detailed list of steps to implement the feature or refactoring task.
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Testing: A list of tests that need to be implemented to verify the feature or refactoring task.
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;custom-agent-metadata&quot;&gt;Custom Agent Metadata&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target&lt;/code&gt; property is particularly important as it determines how the agent runs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target: vscode&lt;/code&gt;&lt;/strong&gt;: Optimised for local VS Code chat with access to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;: Custom display name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;description&lt;/code&gt;: Agent purpose&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;argument-hint&lt;/code&gt;: Guidance on prompting&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;model&lt;/code&gt;: Preferred AI model&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tools&lt;/code&gt;: Available VS Code tools&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handoffs&lt;/code&gt;: Links to other agents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target: github-copilot&lt;/code&gt;&lt;/strong&gt;: Prepared for cloud agents and CLI with:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;: Display name&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;description&lt;/code&gt;: Purpose&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tools&lt;/code&gt;: Limited to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;edit&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;search&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shell&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;custom-agent&lt;/code&gt;, and MCP tools&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mcp-servers&lt;/code&gt;: Model Context Protocol server access&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target&lt;/code&gt;: Deployment environment&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;agent-handoffs-workflow-orchestration&quot;&gt;Agent Handoffs: Workflow Orchestration&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handoffs&lt;/code&gt; property enables guided transitions between agents, letting you chain multi-step workflows:&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Feature Development Agent&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;handoffs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;plan-agent&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;testing-agent&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;security-agent&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;documentation-agent&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;

&lt;span class=&quot;gu&quot;&gt;## Workflow&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
1.&lt;/span&gt; Start with plan-agent for requirements
&lt;span class=&quot;p&quot;&gt;2.&lt;/span&gt; Implement features
&lt;span class=&quot;p&quot;&gt;3.&lt;/span&gt; Hand off to testing-agent for test coverage
&lt;span class=&quot;p&quot;&gt;4.&lt;/span&gt; Hand off to security-agent for security review
&lt;span class=&quot;p&quot;&gt;5.&lt;/span&gt; Hand off to documentation-agent for docs
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This creates a pipeline where each agent specialises in its domain, but they work together seamlessly.&lt;/p&gt;

&lt;h3 id=&quot;vs-code-agent-file-editing&quot;&gt;VS Code Agent File Editing&lt;/h3&gt;

&lt;p&gt;The VS Code editor now provides rich support for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.agent.md&lt;/code&gt; files:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Validation&lt;/strong&gt;: Real-time errors for invalid configurations&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Code completions&lt;/strong&gt;: IntelliSense for properties and values&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Hovers&lt;/strong&gt;: Documentation for each property&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Code actions&lt;/strong&gt;: Quick fixes and migrations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There’s even an auto-migration feature for older &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.chatmode.md&lt;/code&gt; files with a quick fix to convert them to the new format.&lt;/p&gt;

&lt;h2 id=&quot;enterprise-considerations-control-and-governance&quot;&gt;Enterprise Considerations: Control and Governance&lt;/h2&gt;

&lt;p&gt;With great power comes great responsibility. Agent HQ includes enterprise-grade controls that I consider essential for production use.&lt;/p&gt;

&lt;h3 id=&quot;the-agent-control-plane&quot;&gt;The Agent Control Plane&lt;/h3&gt;

&lt;p&gt;GitHub’s control plane provides centralised governance for AI agents across your organization:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Agent Access Control&lt;/strong&gt;: Define which agents are allowed in your org&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Model Access Management&lt;/strong&gt;: Control access to specific AI models&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Security Policies&lt;/strong&gt;: Set organization-wide security rules&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Audit Logging&lt;/strong&gt;: Complete audit trails of agent activities&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Usage Metrics&lt;/strong&gt;: Understand Copilot usage across teams&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;branch-controls-for-agent-created-code&quot;&gt;Branch Controls for Agent-Created Code&lt;/h3&gt;

&lt;p&gt;Utilise branch controls provide granular oversight:&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;gu&quot;&gt;## Branch Protection for Agent PRs&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; CI required before allowing any modifications to agent PRs
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Status checks must pass before human review
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Draft PRs block GitHub Actions workflows by default
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Require approval from someone other than the task requester
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This ensures agent-created code goes through the same rigour as human-written code.&lt;/p&gt;

&lt;h3 id=&quot;identity-and-attribution&quot;&gt;Identity and Attribution&lt;/h3&gt;

&lt;p&gt;All agent work is properly attributed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Co-authored commits&lt;/strong&gt;: Shows both agent and human collaborator&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Session logs&lt;/strong&gt;: Complete transparency into agent decision-making&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Review requirements&lt;/strong&gt;: Enforces separation of duties&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Audit trails&lt;/strong&gt;: Full compliance documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;security-best-practices-with-agent-hq&quot;&gt;Security Best Practices with Agent HQ&lt;/h2&gt;

&lt;p&gt;Working with AI agents introduces new security considerations. Here’s how to maintain security hygiene while leveraging Agent HQ’s capabilities:&lt;/p&gt;

&lt;h3 id=&quot;1-start-with-recommended-defaults&quot;&gt;1. Start with Recommended Defaults&lt;/h3&gt;

&lt;p&gt;The built-in security protections are solid:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Sandboxed execution environments&lt;/li&gt;
  &lt;li&gt;Read-only repository access&lt;/li&gt;
  &lt;li&gt;Branch naming restrictions (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copilot/*&lt;/code&gt; only)&lt;/li&gt;
  &lt;li&gt;Branch protection compliance&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-add-custom-instructions-for-security&quot;&gt;2. Add Custom Instructions for Security&lt;/h3&gt;

&lt;p&gt;In your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.github/copilot-instructions.md&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;gu&quot;&gt;## Security Requirements&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; Never commit secrets, API keys, or passwords
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Use Azure Key Vault references for sensitive data
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; Implement least privilege access patterns
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; All security-sensitive changes require security-agent review
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;3-configure-firewall-settings&quot;&gt;3. Configure Firewall Settings&lt;/h3&gt;

&lt;p&gt;For enterprise environments, customise agent internet access:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# Recommended: Allow specific internal resources&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;firewall&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;enabled&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;recommended_allowlist&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;custom_allowlist&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;domains&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;artifacts.company.internal&quot;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;packages.company.internal&quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;4-review-session-logs&quot;&gt;4. Review Session Logs&lt;/h3&gt;

&lt;p&gt;Make it a practice to review agent session logs at &lt;a href=&quot;https://github.com/copilot/agents&quot;&gt;github.com/copilot/agents&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Internal reasoning&lt;/strong&gt;: Understand the agent’s decision-making&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Tool usage&lt;/strong&gt;: What commands were executed&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Code changes&lt;/strong&gt;: Complete diffs&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Test results&lt;/strong&gt;: Validation outputs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-github-mcp-registry-extending-agent-capabilities&quot;&gt;The GitHub MCP Registry: Extending Agent Capabilities&lt;/h2&gt;

&lt;p&gt;VS Code is the only editor that supports the full Model Context Protocol (MCP) specification, and the October release makes it even better with the GitHub MCP Registry integration.&lt;/p&gt;

&lt;h3 id=&quot;what-is-mcp&quot;&gt;What is MCP?&lt;/h3&gt;

&lt;p&gt;Model Context Protocol allows agents to interact with external services and data sources. Think of it as APIs for AI agents.&lt;/p&gt;

&lt;h3 id=&quot;one-click-mcp-server-installation&quot;&gt;One-Click MCP Server Installation&lt;/h3&gt;

&lt;p&gt;The GitHub MCP Registry in VS Code lets you:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Discover&lt;/strong&gt;: Browse available MCP servers (Stripe, Figma, Sentry, etc.)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Install&lt;/strong&gt;: One-click installation directly from VS Code&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Enable&lt;/strong&gt;: Instant availability for all agents&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Configure&lt;/strong&gt;: Workspace or user-level installation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This means your agents can interact with your tools and services without custom integration work.&lt;/p&gt;

&lt;h3 id=&quot;creating-custom-agents-with-mcp-tools&quot;&gt;Creating Custom Agents with MCP Tools&lt;/h3&gt;

&lt;p&gt;Combine custom agents with MCP servers for powerful workflows:&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Deployment Agent&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;target&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;github-copilot&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;tools&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;shell&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;custom-agent&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;mcp-servers&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;azure-mcp&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;datadog-mcp&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;---&lt;/span&gt;

&lt;span class=&quot;gh&quot;&gt;# Deployment Specialist&lt;/span&gt;

You handle Azure deployments and monitoring.

When deploying:
&lt;span class=&quot;p&quot;&gt;
1.&lt;/span&gt; Use azure-mcp to validate resource configurations
&lt;span class=&quot;p&quot;&gt;2.&lt;/span&gt; Execute deployments via shell tool
&lt;span class=&quot;p&quot;&gt;3.&lt;/span&gt; Use datadog-mcp to set up monitoring
&lt;span class=&quot;p&quot;&gt;4.&lt;/span&gt; Create deployment documentation
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;example-workflow-putting-it-all-together&quot;&gt;Example Workflow: Putting It All Together&lt;/h2&gt;

&lt;p&gt;Let us walk through how we can use all these features together in a typical development scenario.&lt;/p&gt;

&lt;h3 id=&quot;scenario-adding-a-complex-feature-to-an-infrastructure-project&quot;&gt;Scenario: Adding a Complex Feature to an Infrastructure Project&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Planning with Plan Agent (10 minutes)&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;Me: I need to add geo-redundant disaster recovery to our Azure landing zone pattern

Plan Agent: [Asks clarifying questions about RPO/RTO requirements, budget constraints, region preferences]

[After discussion...]

Plan Agent: Here&apos;s your comprehensive plan with 4 phases, 15 tasks, dependencies mapped...
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create Backlog Items&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using the awesome-copilot prompts (via MCP server):&lt;/p&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;@copilot Use the create-github-issues-from-plan prompt to generate issues from this plan

[Generates 15 detailed GitHub issues with descriptions, acceptance criteria, dependencies]
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Delegate to Coding Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Assign issues to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;@copilot&lt;/code&gt; on GitHub.com. Monitor progress via Agent Sessions view in VS Code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Parallel Development&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While coding agent works on infrastructure, we use:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Local Chat&lt;/strong&gt;: Quick questions about Azure services&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;CLI Agent&lt;/strong&gt;: Test deployment commands&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Custom Security Agent&lt;/strong&gt;: Review security implications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 5: PR Reviews&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As PRs arrive:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Review in VS Code&lt;/li&gt;
  &lt;li&gt;Use custom testing agent to validate&lt;/li&gt;
  &lt;li&gt;Provide feedback as PR comments&lt;/li&gt;
  &lt;li&gt;Coding agent iterates automatically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Integration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use CLI agent to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Deploy to test environment&lt;/li&gt;
  &lt;li&gt;Run integration tests&lt;/li&gt;
  &lt;li&gt;Monitor with MCP-connected tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Result:&lt;/strong&gt; Feature delivered in days instead of weeks, with consistent quality and complete documentation.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;gantt
    title Agent HQ Workflow Timeline
    dateFormat YYYY-MM-DD

    section Planning
    Plan Agent Discussion       :2025-11-20, 1d

    section Backlog
    Generate Issues             :2025-11-20, 1d

    section Development
    Coding Agent Work           :2025-11-21, 3d
    Parallel Local Development  :2025-11-21, 3d
    CLI Testing                 :2025-11-22, 2d

    section Review
    PR Reviews                  :2025-11-24, 2d
    Agent Iterations            :2025-11-24, 2d

    section Integration
    Deployment &amp;amp; Testing        :2025-11-26, 1d
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;whats-next-the-future-of-agent-hq&quot;&gt;What’s Next: The Future of Agent HQ&lt;/h2&gt;

&lt;p&gt;GitHub’s roadmap for Agent HQ is ambitious and exciting:&lt;/p&gt;

&lt;h3 id=&quot;upcoming-third-party-agents&quot;&gt;Upcoming Third-Party Agents&lt;/h3&gt;

&lt;p&gt;Over the coming months, agents from these providers will be available:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Anthropic Claude&lt;/strong&gt;: Deep reasoning and code analysis&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;OpenAI Codex&lt;/strong&gt;: Advanced code generation (already available in Insiders)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Google Jules&lt;/strong&gt;: Google’s coding agent capabilities&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cognition&lt;/strong&gt;: Specialised development workflows&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;xAI&lt;/strong&gt;: Elon Musk’s AI coding assistant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All accessible through your existing GitHub Copilot subscription, no additional accounts needed.&lt;/p&gt;

&lt;h3 id=&quot;enhanced-mission-control&quot;&gt;Enhanced Mission Control&lt;/h3&gt;

&lt;p&gt;Upcoming improvements to mission control:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Mobile app access&lt;/strong&gt;: Monitor agents from anywhere&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Slack/Linear/Teams integrations&lt;/strong&gt;: Agent notifications in your workflow tools&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Advanced delegation&lt;/strong&gt;: More sophisticated task routing&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Multi-agent collaboration&lt;/strong&gt;: Agents working together on complex tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;code-quality-integration&quot;&gt;Code Quality Integration&lt;/h3&gt;

&lt;p&gt;GitHub Code Quality (in public preview) will integrate with Agent HQ to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Pre-review agent code&lt;/strong&gt;: Automated quality checks before human review&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Maintainability scoring&lt;/strong&gt;: Org-wide code health visibility&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Automatic remediation&lt;/strong&gt;: Agents fix quality issues proactively&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion-a-new-era-of-development&quot;&gt;Conclusion: A New Era of Development&lt;/h2&gt;

&lt;p&gt;Agent HQ represents a fundamental shift in how we think about development teams. We’re moving from a world where developers write all code to one where developers orchestrate specialised agents that handle implementation while humans focus on strategy, architecture, and quality.&lt;/p&gt;

&lt;p&gt;The VS Code October 2025 release makes this vision tangible. With the Agent Sessions view, Plan Agent, cloud agents, CLI integration, custom agents, and MCP support, we now have a cohesive environment for agentic development.&lt;/p&gt;

&lt;p&gt;What strikes me most is how natural it feels. Yes, there’s a learning curve and some rough edges to smooth out, but the core experience of working with agents through Agent HQ feels intuitive. It’s not bolted-on AI,it’s AI integrated into the development workflow we already know.&lt;/p&gt;

&lt;p&gt;The key insight: &lt;strong&gt;This isn’t about AI replacing developers. It’s about transforming development from a primarily solitary activity to an orchestrated collaboration between humans and specialised agents.&lt;/strong&gt; The developer’s role evolves from writing every line of code to designing systems, defining requirements, reviewing implementations, and making strategic decisions.&lt;/p&gt;

&lt;p&gt;For those of us who have spent years in DevOps, this is the natural evolution we’ve been working toward: automation that doesn’t just handle repetitive tasks but actively participates in the creative process of building software.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ready to embrace Agent HQ?&lt;/strong&gt; Start small:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Enable the Agent Sessions view in VS Code&lt;/li&gt;
  &lt;li&gt;Try the Plan Agent for your next feature&lt;/li&gt;
  &lt;li&gt;Create one custom agent for your team’s domain&lt;/li&gt;
  &lt;li&gt;Delegate a well-defined task to the coding agent&lt;/li&gt;
  &lt;li&gt;Reflect on what worked and iterate&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The future of development is here. Welcome home, agents.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Have you started working with Agent HQ and the new VS Code agent features? I’d love to hear about your experiences and what patterns you’ve discovered. Share your thoughts in the comments below.&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 16 Nov 2025 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/welcome-home-agents/</link>
        <guid isPermaLink="true">https://azurewithaj.com/welcome-home-agents/</guid>
        
        <category>github</category>
        
        <category>copilot</category>
        
        <category>agent</category>
        
        <category>devops</category>
        
        <category>agentic</category>
        
        <category>ai</category>
        
        <category>vscode</category>
        
        <category>hq</category>
        
        
        <category>DevOps</category>
        
        <category>AI</category>
        
      </item>
    
      <item>
        <title>DevOps: Enhanced Release Automation with GitHub&apos;s AI-Powered Release Notes</title>
        <description>&lt;p&gt;In my previous article, “&lt;a href=&quot;https://azurewithaj.com/posts/devops-release-tags/&quot;&gt;DevOps: Automating Release Tags&lt;/a&gt;”, I shared how we automated version tagging and release creation using GitHub Actions. While that solution worked well, the release notes generation was basic, essentially just copying the PR title and description. Today, I’ll show you how we evolved this approach by leveraging GitHub’s powerful automatic release notes generation API.&lt;/p&gt;

&lt;h2 id=&quot;the-evolution-from-basic-to-intelligent-release-notes&quot;&gt;The Evolution: From Basic to Intelligent Release Notes&lt;/h2&gt;

&lt;p&gt;Our original workflow created releases with simple summaries, but we wanted something more comprehensive and professional. We envisioned release notes that would include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Comprehensive Release Overview&lt;/strong&gt;: A clear summary of what’s included in the release&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Merged Pull Requests&lt;/strong&gt;: A complete list of all PRs that contributed to the release&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Contributor Recognition&lt;/strong&gt;: Acknowledgement of all team members who contributed to this release&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Complete Changelog&lt;/strong&gt;: A full, detailed changelog showing every change with proper attribution and links&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;GitHub provides a powerful API that generates release notes automatically based on pull requests, labels, and commit history. This seemed like the perfect solution, but how do we integrate it effectively into our existing automation workflow?&lt;/p&gt;

&lt;h2 id=&quot;leveraging-the-github-api-for-release-notes-generation&quot;&gt;Leveraging the GitHub API for Release Notes Generation&lt;/h2&gt;

&lt;h3 id=&quot;understanding-the-github-release-notes-api&quot;&gt;Understanding the GitHub Release Notes API&lt;/h3&gt;

&lt;p&gt;The GitHub API provides a dedicated endpoint for generating release notes: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/repos/{owner}/{repo}/releases/generate-notes&lt;/code&gt;. This endpoint is intelligent. It analyses all changes between two tags, extracts contributors, and formats everything into a polished markdown changelog.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key API Parameters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tag_name&lt;/code&gt;: The tag for which you’re generating release notes (required)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;previous_tag_name&lt;/code&gt;: The tag to compare against (optional, but essential for meaningful changelogs)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;target_commitish&lt;/code&gt;: The target branch or commit (defaults to the repository’s default branch)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;integration-strategy&quot;&gt;Integration Strategy&lt;/h3&gt;

&lt;p&gt;Rather than making shell calls with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;curl&lt;/code&gt;, I discovered that using GitHub’s JavaScript API client within &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;actions/github-script@v7&lt;/code&gt; provided a cleaner, more reliable approach. This eliminated the need for complex JSON manipulation with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;jq&lt;/code&gt; and provided better error handling.&lt;/p&gt;

&lt;p&gt;Here’s how the integration works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Fetch Latest Tag&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, we need to identify the latest tag to compare against our new tagged release:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Get latest tag&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;get_tag&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;git fetch --tags&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;latest_tag=$(git tag --sort=-v:refname | head -n 1)&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;echo &quot;latest_tag=$latest_tag&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;

&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This step is crucial, it gives the API the context it needs to generate a meaningful changelog comparing the latest tagged version with our new tagged release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Tag our New Release&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Bump version and create tag&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bump_tag&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;latest_tag=${{ steps.get_tag.outputs.latest_tag }}&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;is_major=${{ steps.major_trigger.outputs.major }}&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;if [[ -z &quot;$latest_tag&quot; ]]; then&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;new_tag=&quot;v1.0.0&quot;&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;else&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;IFS=&apos;.&apos; read -r major minor patch &amp;lt;&amp;lt;&amp;lt; &quot;${latest_tag#v}&quot;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;if [[ &quot;$is_major&quot; == &quot;true&quot; ]]; then&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;new_tag=&quot;v$((major+1)).0.0&quot;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;else&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;new_tag=&quot;v$major.$minor.$((patch+1))&quot;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;fi&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;fi&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;git config user.name &quot;github-actions&quot;&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;git config user.email &quot;github-actions@github.com&quot;&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;git tag &quot;$new_tag&quot;&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;git push origin &quot;$new_tag&quot;&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;echo &quot;new_tag=$new_tag&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;

&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This step creates the new tag for our release based on whether it’s a major or minor release.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Call the GitHub API with JavaScript&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;
&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Generate release notes&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;release_notes&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/github-script@v7&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;const tag = &apos;${{ steps.bump_tag.outputs.new_tag }}&apos;;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;const latestTag = &apos;${{ steps.get_tag.outputs.latest_tag }}&apos;;&lt;/span&gt;

      &lt;span class=&quot;s&quot;&gt;// Use GitHub&apos;s automatic release notes generation API&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;const response = await github.rest.repos.generateReleaseNotes({&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;owner: context.repo.owner,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;repo: context.repo.repo,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;tag_name: tag,&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;previous_tag_name: latestTag || undefined, // Use previous tag if available&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;target_commitish: &apos;main&apos;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;});&lt;/span&gt;

      &lt;span class=&quot;s&quot;&gt;// Determine release type based on version number analysis&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;const major = tag.split(&apos;.&apos;)[0].replace(&apos;v&apos;, &apos;&apos;);&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;const minor = tag.split(&apos;.&apos;)[1];&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;const patch = tag.split(&apos;.&apos;)[2];&lt;/span&gt;

      &lt;span class=&quot;s&quot;&gt;let releaseType;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;if (minor === &apos;0&apos; &amp;amp;&amp;amp; patch === &apos;0&apos;) {&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;releaseType = &quot;🚀 Major Release&quot;;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;} else if (patch === &apos;0&apos;) {&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;releaseType = &quot;✨ Minor Release&quot;;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;} else {&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;releaseType = &quot;🐛 Patch Release&quot;;&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;}&lt;/span&gt;

      &lt;span class=&quot;s&quot;&gt;// Combine release type with auto-generated notes&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;const releaseNotes = `${releaseType} ${tag}\n\n${response.data.body}`;&lt;/span&gt;

      &lt;span class=&quot;s&quot;&gt;// Write to file for use in release creation&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;const fs = require(&apos;fs&apos;);&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;fs.writeFileSync(&apos;release-notes.txt&apos;, releaseNotes);&lt;/span&gt;

      &lt;span class=&quot;s&quot;&gt;// Also output for debugging&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;core.setOutput(&apos;release_notes&apos;, releaseNotes);&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;core.setOutput(&apos;release_name&apos;, response.data.name);&lt;/span&gt;

&lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Create GitHub Release&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;steps.is_major.outputs.major == &apos;true&apos;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;gh release create &quot;${{ steps.bump_tag.outputs.new_tag }}&quot; \&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;--title &quot;Release ${{ steps.bump_tag.outputs.new_tag }}&quot; \&lt;/span&gt;
      &lt;span class=&quot;s&quot;&gt;--notes-file release-notes.txt&lt;/span&gt;

&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This step uses the GitHub API to generate the release notes and writes the final notes to a file for the release creation step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Benefits of This Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Automatic Context Awareness&lt;/strong&gt;: GitHub’s API analyses commit history, PR titles, and labels to categorise changes intelligently&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Built-in Contributor Detection&lt;/strong&gt;: The API automatically identifies and credits all contributors&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;No Manual Parsing&lt;/strong&gt;: Unlike shell-based approaches, we don’t need complex regex or JSON parsing&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;handling-edge-cases&quot;&gt;Handling Edge Cases&lt;/h3&gt;

&lt;p&gt;The implementation accounts for several edge cases:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. First Release (No Previous Tag)&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;nx&quot;&gt;previous_tag_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;latestTag&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;latestTag&lt;/code&gt; is undefined (first release), the API generates notes for all commits in the repository, which is appropriate for initial releases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. No Changes Between Tags&lt;/strong&gt;
The API gracefully handles scenarios where tags are identical or when no PRs exist between versions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Missing PR Metadata&lt;/strong&gt;
If PRs lack proper labels or descriptions, the API uses commit messages and titles as fallbacks.&lt;/p&gt;

&lt;h2 id=&quot;the-complete-enhanced-workflow&quot;&gt;The Complete Enhanced Workflow&lt;/h2&gt;

&lt;p&gt;Here’s the complete GitHub Actions workflow that combines automated tagging with intelligent release notes:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;
&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Enhanced Tag and Release with AI-Powered Notes&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;branches&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;main&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;tag-and-release&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;permissions&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;write&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;pull-requests&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;read&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Checkout code&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Get latest PR merged&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;pr&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/github-script@v7&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const prs = await github.rest.pulls.list({&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;owner: context.repo.owner,&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;repo: context.repo.repo,&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;state: &apos;closed&apos;,&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;sort: &apos;updated&apos;,&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;direction: &apos;desc&apos;,&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;per_page: 1&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;});&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const pr = prs.data.find(pr =&amp;gt; pr.merged_at &amp;amp;&amp;amp; pr.merge_commit_sha === context.sha);&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;if (!pr) throw new Error(&apos;No merged PR found for this commit.&apos;);&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;core.setOutput(&apos;pr_number&apos;, pr.number);&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;core.setOutput(&apos;pr_title&apos;, pr.title);&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;core.setOutput(&apos;pr_body&apos;, pr.body);&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Check for major release trigger&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;major_trigger&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/github-script@v7&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const prNumber = Number(process.env.PR_NUMBER || &apos;${{ steps.pr.outputs.pr_number }}&apos;);&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;let isMajor = false;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;if (prNumber) {&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;const pr = await github.rest.pulls.get({&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;owner: context.repo.owner,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;repo: context.repo.repo,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;pull_number: prNumber&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;});&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;const labels = pr.data.labels.map(l =&amp;gt; l.name.toLowerCase());&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;if (labels.includes(&apos;major-release&apos;)) isMajor = true;&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;if (pr.data.title.includes(&apos;[major]&apos;) || (pr.data.body &amp;amp;&amp;amp; pr.data.body.includes(&apos;[major]&apos;))) isMajor = true;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;} else {&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;// Fallback: check commit message&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;const commit = await github.rest.repos.getCommit({&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;owner: context.repo.owner,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;repo: context.repo.repo,&lt;/span&gt;
                &lt;span class=&quot;s&quot;&gt;ref: context.sha&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;});&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;if (commit.data.commit.message.includes(&apos;[major]&apos;)) isMajor = true;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;core.setOutput(&apos;major&apos;, isMajor ? &apos;true&apos; : &apos;false&apos;);&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Get latest tag&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;get_tag&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;git fetch --tags&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;latest_tag=$(git tag --sort=-v:refname | head -n 1)&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;echo &quot;latest_tag=$latest_tag&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Bump version and create tag&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;bump_tag&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;latest_tag=${{ steps.get_tag.outputs.latest_tag }}&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;is_major=${{ steps.major_trigger.outputs.major }}&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;if [[ -z &quot;$latest_tag&quot; ]]; then&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;new_tag=&quot;v1.0.0&quot;&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;IFS=&apos;.&apos; read -r major minor patch &amp;lt;&amp;lt;&amp;lt; &quot;${latest_tag#v}&quot;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;if [[ &quot;$is_major&quot; == &quot;true&quot; ]]; then&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;new_tag=&quot;v$((major+1)).0.0&quot;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;else&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;new_tag=&quot;v$major.$minor.$((patch+1))&quot;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;fi&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;fi&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;git config user.name &quot;github-actions&quot;&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;git config user.email &quot;github-actions@github.com&quot;&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;git tag &quot;$new_tag&quot;&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;git push origin &quot;$new_tag&quot;&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;echo &quot;new_tag=$new_tag&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Check if major version&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;is_major&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;tag=${{ steps.bump_tag.outputs.new_tag }}&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;major=$(echo $tag | cut -d&apos;.&apos; -f1 | tr -d &apos;v&apos;)&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;minor=$(echo $tag | cut -d&apos;.&apos; -f2)&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;patch=$(echo $tag | cut -d&apos;.&apos; -f3)&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;if [[ &quot;$minor&quot; == &quot;0&quot; &amp;amp;&amp;amp; &quot;$patch&quot; == &quot;0&quot; ]]; then&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;echo &quot;major=true&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;else&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;echo &quot;major=false&quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;fi&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Generate release notes&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;release_notes&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/github-script@v7&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;script&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const tag = &apos;${{ steps.bump_tag.outputs.new_tag }}&apos;;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const latestTag = &apos;${{ steps.get_tag.outputs.latest_tag }}&apos;;&lt;/span&gt;

            &lt;span class=&quot;s&quot;&gt;// Use GitHub&apos;s automatic release notes generation API&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const response = await github.rest.repos.generateReleaseNotes({&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;owner: context.repo.owner,&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;repo: context.repo.repo,&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;tag_name: tag,&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;previous_tag_name: latestTag || undefined, // Use previous tag if available&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;target_commitish: &apos;main&apos;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;});&lt;/span&gt;

            &lt;span class=&quot;s&quot;&gt;// Determine release type based on version number analysis&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const major = tag.split(&apos;.&apos;)[0].replace(&apos;v&apos;, &apos;&apos;);&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const minor = tag.split(&apos;.&apos;)[1];&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const patch = tag.split(&apos;.&apos;)[2];&lt;/span&gt;

            &lt;span class=&quot;s&quot;&gt;let releaseType;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;if (minor === &apos;0&apos; &amp;amp;&amp;amp; patch === &apos;0&apos;) {&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;releaseType = &quot;🚀 Major Release&quot;;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;} else if (patch === &apos;0&apos;) {&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;releaseType = &quot;✨ Minor Release&quot;;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;} else {&lt;/span&gt;
              &lt;span class=&quot;s&quot;&gt;releaseType = &quot;🐛 Patch Release&quot;;&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;s&quot;&gt;// Combine release type with auto-generated notes&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const releaseNotes = `${releaseType} ${tag}\n\n${response.data.body}`;&lt;/span&gt;

            &lt;span class=&quot;s&quot;&gt;// Write to file for use in release creation&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;const fs = require(&apos;fs&apos;);&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;fs.writeFileSync(&apos;release-notes.txt&apos;, releaseNotes);&lt;/span&gt;

            &lt;span class=&quot;s&quot;&gt;// Also output for debugging&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;core.setOutput(&apos;release_notes&apos;, releaseNotes);&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;core.setOutput(&apos;release_name&apos;, response.data.name);&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Create GitHub Release&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;steps.is_major.outputs.major == &apos;true&apos;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;env&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;gh release create &quot;${{ steps.bump_tag.outputs.new_tag }}&quot; \&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;--title &quot;Release ${{ steps.bump_tag.outputs.new_tag }}&quot; \&lt;/span&gt;
            &lt;span class=&quot;s&quot;&gt;--notes-file release-notes.txt&lt;/span&gt;

&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;key-improvements-over-the-original-workflow&quot;&gt;Key Improvements Over the Original Workflow&lt;/h2&gt;

&lt;h3 id=&quot;1-intelligent-release-notes&quot;&gt;1. &lt;strong&gt;Intelligent Release Notes&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The GitHub API automatically:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Summarise changes since last release&lt;/li&gt;
  &lt;li&gt;Lists all contributors&lt;/li&gt;
  &lt;li&gt;Groups changes logically&lt;/li&gt;
  &lt;li&gt;Filters out noise (like dependency updates)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;2-better-historical-context&quot;&gt;2. &lt;strong&gt;Better Historical Context&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;By comparing against the previous tag, the release notes include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;All changes since the last release&lt;/li&gt;
  &lt;li&gt;Complete PR history with links&lt;/li&gt;
  &lt;li&gt;Proper attribution for each contribution&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-enhanced-major-releases&quot;&gt;3. &lt;strong&gt;Enhanced Major Releases&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;Major version releases get special treatment:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Prominent release highlights section&lt;/li&gt;
  &lt;li&gt;Assists with highlighting warnings about breaking changes&lt;/li&gt;
  &lt;li&gt;Enhanced formatting for visibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;4-robust-error-handling&quot;&gt;4. &lt;strong&gt;Robust Error Handling&lt;/strong&gt;&lt;/h3&gt;

&lt;p&gt;The workflow handles edge cases:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;First release (no previous tag)&lt;/li&gt;
  &lt;li&gt;Missing PR metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;By combining GitHub’s automatic release notes API with our existing automated tagging workflow, we’ve created a powerful, hands-off release management system.&lt;/p&gt;

&lt;p&gt;The result is a system that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Runs completely automatically&lt;/li&gt;
  &lt;li&gt;Generates comprehensive, well-formatted release notes&lt;/li&gt;
  &lt;li&gt;Recognises all contributors&lt;/li&gt;
  &lt;li&gt;Scales effortlessly as the team grows&lt;/li&gt;
  &lt;li&gt;Requires zero manual intervention&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tw3lveparsecs/azure-iac-and-devops/tree/main/.github/workflows/tags-and-release.yml&quot;&gt;Click here to view a working example of the complete workflow on GitHub.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’re still manually creating release notes, I highly recommend implementing this approach.&lt;/p&gt;

&lt;p&gt;Have you implemented automated release notes in your projects? What challenges did you face? Share your experiences in the comments below!&lt;/p&gt;
</description>
        <pubDate>Tue, 21 Oct 2025 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/devops-release-tag-generation/</link>
        <guid isPermaLink="true">https://azurewithaj.com/devops-release-tag-generation/</guid>
        
        <category>devops</category>
        
        <category>release</category>
        
        <category>tags</category>
        
        <category>automation</category>
        
        <category>api</category>
        
        
        <category>DevOps</category>
        
      </item>
    
      <item>
        <title>Building a Star Wars E-Commerce Empire with GitHub Spark: A Weekend DevOps Story</title>
        <description>&lt;p&gt;As a DevOps professional whose primary expertise lies in infrastructure, automation, and operational excellence rather than frontend development, I’ve always faced a persistent challenge: creating functional, presentable web applications for demos and presentations. This gap became particularly evident when conducting demonstrations and end-to-end workflows at community meetups and in my day-to-day job, where I needed to showcase the complete picture, not just the infrastructure layer.&lt;/p&gt;

&lt;p&gt;Enter GitHub Spark, a tool that promises to transform ideas into full-stack intelligent applications through natural language. This is the story of how I built a fully functional Star Wars-themed e-commerce platform in a single weekend, juggling personal commitments while giving it only 50% of my attention, and the valuable lessons I learned about AI-powered development along the way.&lt;/p&gt;

&lt;h2 id=&quot;the-challenge-frontend-development-for-devops-professionals&quot;&gt;The Challenge: Frontend Development for DevOps Professionals&lt;/h2&gt;

&lt;p&gt;My professional world revolves around CI/CD pipelines, infrastructure as code, container orchestration, and automated deployments. I excel at building the engines that power software delivery, but creating the user-facing interfaces that demonstrate these capabilities? That’s historically been my Achilles’ heel.&lt;/p&gt;

&lt;p&gt;This skill gap created several challenges:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Demo Limitations&lt;/strong&gt;: Showcasing infrastructure concepts without compelling frontends meant relying on PowerPoint slides and command-line demonstrations&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Presentation Impact&lt;/strong&gt;: Audience connecting more readily with visual, interactive demonstrations rather than terminal outputs&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Time Investment&lt;/strong&gt;: The learning curve for modern frontend frameworks (React, Vue, Angular) requiring significant time investment&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Rapid Prototyping&lt;/strong&gt;: Needing to quickly spin up functional demos for presentations and workshops&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I needed a solution that would allow me to create production quality frontends without becoming a full-time frontend developer. GitHub Spark seemed to offer exactly that promise.&lt;/p&gt;

&lt;h2 id=&quot;the-experiment-building-for-the-galactic-empire&quot;&gt;The Experiment: Building for the Galactic Empire&lt;/h2&gt;

&lt;h3 id=&quot;why-star-wars-e-commerce&quot;&gt;Why Star Wars E-Commerce?&lt;/h3&gt;

&lt;p&gt;I needed to build a fully functional e-commerce application for an upcoming demo. Being a lifelong Star Wars fan, there was never any question about the theme, of course it had to be Star Wars themed. Why build a generic shopping cart when you could be procuring Imperial starships for the Empire?&lt;/p&gt;

&lt;p&gt;So I set out to create a Star Wars themed e-commerce platform where I could purchase Imperial starships on behalf of the Empire. The application needed to be more than just a pretty mock up with a Star Wars skin, it required genuine functionality:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Product Catalogue&lt;/strong&gt;: Display various Imperial starships with descriptions and specifications&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Shopping Cart&lt;/strong&gt;: Add and remove items with persistent state&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Credit System&lt;/strong&gt;: Track available Imperial credits and deduct them after purchases&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Transaction Management&lt;/strong&gt;: Handle the complete purchase flow from selection to confirmation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Responsive Design&lt;/strong&gt;: Work seamlessly across different devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project would serve multiple purposes:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Test GitHub Spark’s capabilities with a real-world application&lt;/li&gt;
  &lt;li&gt;Create a reusable demo platform for presentations&lt;/li&gt;
  &lt;li&gt;Explore the boundaries of AI-powered development&lt;/li&gt;
  &lt;li&gt;Fill the gap in my skillset without weeks or months of learning&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;the-weekend-build-from-concept-to-functional-application&quot;&gt;The Weekend Build: From Concept to Functional Application&lt;/h3&gt;

&lt;p&gt;What impressed me most wasn’t just that GitHub Spark could build the application, it was the speed and quality of what it produced while I was multitasking with personal commitments throughout the weekend.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Saturday Morning: Initial Concept] --&amp;gt; B[Spark Session 1: Basic Structure]
    B --&amp;gt; C[Live Preview: Product Display]
    C --&amp;gt; D[Saturday Afternoon: Shopping Features]
    D --&amp;gt; E[Spark Session 2: Cart Functionality]
    E --&amp;gt; F[Live Preview: Working Cart]
    F --&amp;gt; G[Sunday Morning: Credit System]
    G --&amp;gt; H[Spark Session 3: Transaction Logic]
    H --&amp;gt; I[Live Preview: Complete Purchase Flow]
    I --&amp;gt; J[Sunday Afternoon: Polish &amp;amp; Testing]
    J --&amp;gt; K[Functional E-Commerce Platform]

    style A fill:#2188ff,stroke:#1b6cc7,stroke-width:3px,color:#ffffff
    style K fill:#28a745,stroke:#1e7e34,stroke-width:3px,color:#ffffff
    style C fill:#f9c513,stroke:#d4a00a,stroke-width:2px,color:#000000
    style F fill:#f9c513,stroke:#d4a00a,stroke-width:2px,color:#000000
    style I fill:#f9c513,stroke:#d4a00a,stroke-width:2px,color:#000000
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;what-github-spark-delivered&quot;&gt;What GitHub Spark Delivered&lt;/h3&gt;

&lt;p&gt;The platform Spark created included:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Core E-Commerce Functionality&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Product listing with detailed starship specifications&lt;/li&gt;
  &lt;li&gt;Functional shopping cart with add/remove capabilities&lt;/li&gt;
  &lt;li&gt;Imperial credit tracking system&lt;/li&gt;
  &lt;li&gt;Complete checkout and purchase flow&lt;/li&gt;
  &lt;li&gt;Order confirmation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Visual Design&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Star Wars themed interface with appropriate styling&lt;/li&gt;
  &lt;li&gt;Responsive layout that worked across devices&lt;/li&gt;
  &lt;li&gt;AI generated imagery fitting the Imperial aesthetic&lt;/li&gt;
  &lt;li&gt;Consistent design language throughout&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Technical Implementation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;React-based frontend with proper component structure&lt;/li&gt;
  &lt;li&gt;State management for cart and user data&lt;/li&gt;
  &lt;li&gt;Local storage persistence&lt;/li&gt;
  &lt;li&gt;Clean, maintainable code structure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most remarkable aspect? I achieved all this while simultaneously handling weekend family commitments, checking in periodically to review progress and provide the next set of instructions.&lt;/p&gt;

&lt;h2 id=&quot;the-power-of-natural-language-development&quot;&gt;The Power of Natural Language Development&lt;/h2&gt;

&lt;h3 id=&quot;how-github-spark-actually-works&quot;&gt;How GitHub Spark Actually Works&lt;/h3&gt;

&lt;p&gt;GitHub Spark operates on a fundamentally different paradigm from traditional development:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional Development&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;// You write: Component structure, state management, event handlers&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;useState&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;react&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;ShoppingCart&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setItems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([]);&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;credits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;setCredits&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

  &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addItem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nf&quot;&gt;setItems&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([...&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

  &lt;span class=&quot;c1&quot;&gt;// ... 50+ lines of implementation logic&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;GitHub Spark Development&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;You write: &quot;Add a shopping cart that tracks Imperial starships.
Users should be able to add ships, see the total cost, and have
their available credits updated after purchase.&quot;

Spark delivers: Fully functional component with all the logic implemented
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This shift from &lt;strong&gt;implementation&lt;/strong&gt; to &lt;strong&gt;specification&lt;/strong&gt; represents a fundamental change in how we approach application development.&lt;/p&gt;

&lt;h3 id=&quot;the-iteration-loop&quot;&gt;The Iteration Loop&lt;/h3&gt;

&lt;p&gt;What makes Spark particularly powerful is the rapid iteration cycle:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Describe&lt;/strong&gt;: Use natural language to explain what you want&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Preview&lt;/strong&gt;: Instantly see the live implementation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Refine&lt;/strong&gt;: Provide feedback and adjustments&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Repeat&lt;/strong&gt;: Continue until the feature matches your vision&lt;/li&gt;
&lt;/ol&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;sequenceDiagram
    participant You
    participant Spark
    participant Preview

    You-&amp;gt;&amp;gt;Spark: &quot;Add filter for starship class&quot;
    Spark-&amp;gt;&amp;gt;Preview: Generates filter component
    Preview-&amp;gt;&amp;gt;You: Live visual feedback
    You-&amp;gt;&amp;gt;Spark: &quot;Make the filters more prominent&quot;
    Spark-&amp;gt;&amp;gt;Preview: Updates styling and layout
    Preview-&amp;gt;&amp;gt;You: Refined implementation
    You-&amp;gt;&amp;gt;Spark: &quot;Perfect! Now add sorting options&quot;
    Spark-&amp;gt;&amp;gt;Preview: Adds sorting functionality
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The preview updates in real-time, allowing you to see your ideas take shape immediately. This instant feedback loop accelerates development exponentially compared to traditional code-test-debug cycles.&lt;/p&gt;

&lt;h2 id=&quot;lessons-learned-the-hard-earned-wisdom&quot;&gt;Lessons Learned: The Hard-Earned Wisdom&lt;/h2&gt;

&lt;h3 id=&quot;lesson-1-prompt-engineering-is-critical-just-like-any-ai-tool&quot;&gt;Lesson 1: Prompt Engineering is Critical (Just Like Any AI Tool)&lt;/h3&gt;

&lt;p&gt;My biggest mistake early on was using basic, vague prompts:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad Prompt&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&quot;Add credits&quot;
&quot;Make it work&quot;
&quot;Try again&quot;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These generic instructions led to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Spark making assumptions that didn’t align with my vision&lt;/li&gt;
  &lt;li&gt;Implementing features that conflicted with existing functionality&lt;/li&gt;
  &lt;li&gt;Getting stuck in loops trying to fix issues it created&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Good Prompt&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&quot;Implement an Imperial credit system with the following specifications:
- Starting balance: 10,000 credits
- Display current balance prominently in the header
- Deduct the exact cart total when purchase is confirmed
- Show transaction confirmation with remaining balance
- Persist balance in local storage
- Prevent purchases if insufficient credits&quot;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The comprehensive prompt provided:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Clear Requirements&lt;/strong&gt;: Specific functionality expected&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Implementation Details&lt;/strong&gt;: How the feature should behave&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Edge Cases&lt;/strong&gt;: What should happen when credits are insufficient&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Persistence&lt;/strong&gt;: How data should be stored&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Insight&lt;/strong&gt;: Treat GitHub Spark prompts with the same care and detail you would bring to writing technical specifications. The quality of your output directly correlates to the quality of your input.&lt;/p&gt;

&lt;h3 id=&quot;lesson-2-the-loop-trap-is-real-and-expensive&quot;&gt;Lesson 2: The Loop Trap is Real (And Expensive)&lt;/h3&gt;

&lt;p&gt;I hit my free plan limits alarmingly quickly when I got stuck in what I call the “Try Harder Loop”:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Destructive Pattern&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;Issue occurs → &quot;Try again&quot;
Still broken → &quot;Try harder&quot;
Different error → &quot;Fix this&quot;
New problem → &quot;Still have the same issue&quot;
Plan limits exhausted → Frustration
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This happened specifically with the credit system. Spark would add the total credits, but the deduction logic wouldn’t work correctly. I kept asking it to “try again” or “fix the credit deduction,” which led to:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Multiple failed attempts consuming premium requests&lt;/li&gt;
  &lt;li&gt;Spark making random changes hoping something would stick&lt;/li&gt;
  &lt;li&gt;Spark looping through the same flawed logic&lt;/li&gt;
  &lt;li&gt;The problem getting worse, not better&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;The Solution That Worked&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;I completely removed the credit system:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&quot;Remove the entire credit tracking system.&quot;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then rebuilt with a detailed specification:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&quot;Add a credit system with these exact requirements:
1. Initialise each user with Imperial credits aligned to ship costs
2. Store in React state
3. Display current balance in header component
4. On purchase confirmation:
   - Calculate total from cart items
   - Deduct total from balance and clear cart
   - If insufficient credits: show relevant error message
5. Update balance in local storage after each transaction&quot;
6. Add a reset button to restore initial credits only visible for specific users
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key Insight&lt;/strong&gt;: When stuck in a loop, reset and approach with better specifications rather than repeatedly asking the AI to “try harder.” Each iteration in a loop consumes your request quota without making meaningful progress.&lt;/p&gt;

&lt;h3 id=&quot;lesson-3-plan-limits-are-generous-but-not-infinite&quot;&gt;Lesson 3: Plan Limits are Generous But Not Infinite&lt;/h3&gt;

&lt;p&gt;GitHub Spark operates on a premium request model:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free Plan Reality&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;50 premium requests per month&lt;/li&gt;
  &lt;li&gt;Each Spark message uses 4 premium requests&lt;/li&gt;
  &lt;li&gt;Getting stuck in loops exhausts quota rapidly&lt;/li&gt;
  &lt;li&gt;No ability to purchase additional requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Copilot Pro+ Plan&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;375 Spark messages included per month (1,500 premium requests)&lt;/li&gt;
  &lt;li&gt;Option to purchase additional messages&lt;/li&gt;
  &lt;li&gt;10 active app building sessions simultaneously&lt;/li&gt;
  &lt;li&gt;Unlimited app building overall&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My recommendation? &lt;strong&gt;If you’re serious about using Spark for multiple projects or complex applications, review Copilot plans carefully from the start.&lt;/strong&gt; The free tier is excellent for experimentation and small projects, but any substantial development work will quickly hit the limits, especially while you’re learning optimal prompting techniques.&lt;/p&gt;

&lt;h3 id=&quot;lesson-4-let-spark-handle-the-visuals-if-you-want&quot;&gt;Lesson 4: Let Spark Handle the Visuals (If You Want)&lt;/h3&gt;

&lt;p&gt;I intentionally chose not to provide custom images or assets for my Star Wars theme. I wanted to test whether Spark could handle the complete visual design independently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Result&lt;/strong&gt;: Spark generated appropriate imagery, maintained consistent styling, and created a cohesive visual experience that genuinely felt like an Imperial procurement system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When This Approach Works&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Prototyping and proof-of-concept development&lt;/li&gt;
  &lt;li&gt;Internal tools and demos&lt;/li&gt;
  &lt;li&gt;Quick mock ups for stakeholder feedback&lt;/li&gt;
  &lt;li&gt;Testing functionality before investing in design assets&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to Provide Your Own Assets&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Production applications requiring brand consistency&lt;/li&gt;
  &lt;li&gt;Client work with specific design requirements&lt;/li&gt;
  &lt;li&gt;Applications where visual design is a differentiator&lt;/li&gt;
  &lt;li&gt;When you have professional assets readily available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Insight&lt;/strong&gt;: Spark’s AI generated visuals are remarkably good for functional applications and demos, but don’t expect them to replace professional design work for customer facing products.&lt;/p&gt;

&lt;h3 id=&quot;lesson-5-incremental-development-still-wins&quot;&gt;Lesson 5: Incremental Development Still Wins&lt;/h3&gt;

&lt;p&gt;Even with AI powered development, building incrementally remains the most effective approach:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My Successful Pattern&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Core Framework First&lt;/strong&gt;: Basic app structure and routing&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Single Feature&lt;/strong&gt;: Product display working perfectly&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Next Feature&lt;/strong&gt;: Shopping cart functionality&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Integration&lt;/strong&gt;: Cart and products working together&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Transaction Logic&lt;/strong&gt;: Purchase and credit system&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Polish&lt;/strong&gt;: Refinements and edge cases&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Failed Approach&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&quot;Build a complete e-commerce platform with products, cart,
checkout, user accounts, order history, and admin panel.&quot;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This “kitchen sink” approach led to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Overwhelming Spark with too many simultaneous requirements&lt;/li&gt;
  &lt;li&gt;Features implemented half-way&lt;/li&gt;
  &lt;li&gt;Conflicting functionality between different components&lt;/li&gt;
  &lt;li&gt;Difficult to identify where things went wrong&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Insight&lt;/strong&gt;: Even with AI assistance, incremental development with clear milestones produces better results than trying to build everything at once.&lt;/p&gt;

&lt;h2 id=&quot;the-practical-impact-filling-the-gap&quot;&gt;The Practical Impact: Filling the Gap&lt;/h2&gt;

&lt;p&gt;This weekend experiment with GitHub Spark fundamentally changed my approach to demos and presentations. I now have:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Reusable Demo Platform&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Functional transaction flows demonstrating end-to-end processes&lt;/li&gt;
  &lt;li&gt;Visual interface that resonates with technical and non-technical audiences&lt;/li&gt;
  &lt;li&gt;Platform I can adapt for various presentation needs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A New Development Capability&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Ability to prototype frontend ideas rapidly&lt;/li&gt;
  &lt;li&gt;Tool for creating functional mock ups without deep frontend expertise&lt;/li&gt;
  &lt;li&gt;Platform for testing UX concepts before formal development&lt;/li&gt;
  &lt;li&gt;Bridge between infrastructure expertise and user-facing applications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Confidence in AI Assisted Development&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Understanding of how to effectively collaborate with AI tools&lt;/li&gt;
  &lt;li&gt;Experience with prompt engineering for development tasks&lt;/li&gt;
  &lt;li&gt;Knowledge of when AI assistance is most valuable&lt;/li&gt;
  &lt;li&gt;Realistic expectations for AI powered development&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-bigger-picture-ai-as-a-force-multiplier&quot;&gt;The Bigger Picture: AI as a Force Multiplier&lt;/h2&gt;

&lt;p&gt;My weekend with GitHub Spark reinforced a fundamental truth about AI in development: it’s not about replacement, but amplification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What AI Didn’t Replace&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;My understanding of application architecture&lt;/li&gt;
  &lt;li&gt;My ability to break down complex requirements&lt;/li&gt;
  &lt;li&gt;My judgment about user experience and functionality&lt;/li&gt;
  &lt;li&gt;My testing and validation expertise&lt;/li&gt;
  &lt;li&gt;My domain knowledge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What AI Amplified&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;My ability to implement ideas quickly&lt;/li&gt;
  &lt;li&gt;My capacity to create functional prototypes&lt;/li&gt;
  &lt;li&gt;My power to bridge skill gaps in frontend development&lt;/li&gt;
  &lt;li&gt;My efficiency in iterating on designs&lt;/li&gt;
  &lt;li&gt;My capability to deliver professional demos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This represents a shift from &lt;strong&gt;being limited by implementation skills&lt;/strong&gt; to &lt;strong&gt;being limited only by ideas and specifications&lt;/strong&gt;. As a DevOps professional, I’m no longer constrained by my frontend expertise when I need to create compelling demonstrations.&lt;/p&gt;

&lt;h2 id=&quot;conclusion-the-future-of-specialised-development&quot;&gt;Conclusion: The Future of Specialised Development&lt;/h2&gt;

&lt;p&gt;GitHub Spark demonstrates that we’re entering an era where deep technical specialists can operate effectively across broader domains without sacrificing their core expertise. I didn’t become a frontend developer over a weekend, I became a DevOps professional who can effectively leverage AI to create functional frontends when needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Prompt Quality Matters&lt;/strong&gt;: Invest time in comprehensive, specific prompts&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Avoid the Loop Trap&lt;/strong&gt;: Reset and respecify rather than repeatedly asking AI to “try harder”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Understand Plan Limits&lt;/strong&gt;: Choose the right tier for your usage pattern&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Incremental Wins&lt;/strong&gt;: Build features progressively, validating each step&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;AI Generated Visuals&lt;/strong&gt;: Surprisingly effective for demos and prototypes&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Specialisation + AI&lt;/strong&gt;: Powerful combination that expands capabilities without diluting expertise&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For fellow DevOps professionals, infrastructure engineers, and backend specialists who need to create compelling frontends for demos, presentations, or internal tools, GitHub Spark offers a genuine solution. It won’t replace dedicated frontend developers for production applications, but it absolutely fills the gap for creating functional, presentable interfaces without months of learning modern frontend frameworks.&lt;/p&gt;

&lt;p&gt;The Empire’s procurement system is now operational, and I built it in a weekend while barely paying full attention. That’s the power of AI assisted development when approached with the right strategies and realistic expectations.&lt;/p&gt;

&lt;p&gt;Here is a few screenshots of the final application in action:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images//posts/2025-10-14-github-spark-star-wars-ecommerce/github_spark_star_wars_home_page.png&quot; alt=&quot;Home Page&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images//posts/2025-10-14-github-spark-star-wars-ecommerce/github_spark_star_wars_add_cart.png&quot; alt=&quot;Add to Cart&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/images//posts/2025-10-14-github-spark-star-wars-ecommerce/github_spark_star_wars_submission.png&quot; alt=&quot;Submission&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Have you experimented with GitHub Spark or similar AI-powered development tools? What challenges or successes have you experienced? Share your experiences in the comments below&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 13 Oct 2025 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/github-spark-star-wars-ecommerce/</link>
        <guid isPermaLink="true">https://azurewithaj.com/github-spark-star-wars-ecommerce/</guid>
        
        <category>github</category>
        
        <category>spark</category>
        
        <category>ai</category>
        
        <category>agentic</category>
        
        <category>copilot</category>
        
        <category>frontend</category>
        
        
        <category>DevOps</category>
        
        <category>AI</category>
        
      </item>
    
      <item>
        <title>DevOps and Azure Policy Series: Remediation Tasks</title>
        <description>&lt;p&gt;Welcome to the fourth instalment of our DevOps and Azure Policy series! In our &lt;a href=&quot;https://azurewithaj.com/posts/devops-azure-policy-series-exemptions/&quot;&gt;previous post&lt;/a&gt;, we explored how to manage policy exemptions using Infrastructure as Code (IaC) and CI/CD pipelines. Today, we’re diving into another critical aspect of Azure Policy governance: &lt;strong&gt;policy remediation tasks&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While exemptions help us handle exceptions to policies, remediation tasks take the opposite approach they actively fix non-compliant resources to bring them into alignment with our organisational standards. We’ll explore what remediation tasks are, when to use them, and how to implement them through automated PowerShell scripts and CI/CD pipelines.&lt;/p&gt;

&lt;h2 id=&quot;understanding-azure-policy-remediation&quot;&gt;Understanding Azure Policy Remediation&lt;/h2&gt;

&lt;p&gt;Policy remediation is the process of automatically correcting non-compliant resources to ensure they adhere to our defined policies. Think of it as the “auto-fix” capability for our governance rules. When Azure Policy identifies resources that don’t meet our standards, remediation tasks can automatically apply the necessary changes to bring them into compliance.&lt;/p&gt;

&lt;h3 id=&quot;how-policy-remediation-works&quot;&gt;How Policy Remediation Works&lt;/h3&gt;

&lt;p&gt;The remediation process follows this workflow:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Policy Evaluation&lt;/strong&gt;: Azure Policy continuously evaluates resources against assigned policies&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compliance Assessment&lt;/strong&gt;: Resources are marked as compliant or non-compliant&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Remediation Task Creation&lt;/strong&gt;: You create a remediation task for a specific policy assignment&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Resource Discovery&lt;/strong&gt;: Azure identifies all non-compliant resources within the scope&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Automatic Correction&lt;/strong&gt;: The remediation task applies the necessary changes to fix non-compliant resources&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;types-of-remediation&quot;&gt;Types of Remediation&lt;/h3&gt;

&lt;p&gt;Azure Policy supports two main types of remediation:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Remediation Type&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
      &lt;th&gt;Use Case&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Manual Remediation&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Administrators manually review and fix non-compliant resources&lt;/td&gt;
      &lt;td&gt;Complex changes requiring human judgment&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Automatic Remediation&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;Azure Policy automatically applies predefined configurations or deploy a specific resource&lt;/td&gt;
      &lt;td&gt;Standard compliance fixes that can be safely automated&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;when-to-use-remediation-tasks&quot;&gt;When to Use Remediation Tasks&lt;/h3&gt;

&lt;p&gt;Remediation tasks are particularly valuable in these scenarios:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Tag Governance&lt;/strong&gt;: Automatically applying missing mandatory tags to resources&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Security Baseline&lt;/strong&gt;: Enabling required security features like encryption or monitoring&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cost Optimisation&lt;/strong&gt;: Implementing cost-saving configurations across resources&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Compliance Enforcement&lt;/strong&gt;: Ensuring resources meet regulatory requirements&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Operational Standards&lt;/strong&gt;: Applying consistent operational configurations&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;limitations-and-considerations&quot;&gt;Limitations and Considerations&lt;/h2&gt;

&lt;p&gt;Before implementing remediation tasks, it’s important to understand their current limitations:&lt;/p&gt;

&lt;h3 id=&quot;bicep-support-limitation&quot;&gt;Bicep Support Limitation&lt;/h3&gt;

&lt;p&gt;At the time of writing, &lt;strong&gt;policy remediation tasks are not currently supported for deployment via Azure Bicep&lt;/strong&gt;. This means that while you can define and assign policies using Bicep, the remediation tasks themselves must be managed through other means such as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Azure Portal&lt;/li&gt;
  &lt;li&gt;Azure CLI&lt;/li&gt;
  &lt;li&gt;Azure PowerShell&lt;/li&gt;
  &lt;li&gt;REST API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Due to this limitation, we’ll focus on a PowerShell-based approach.&lt;/p&gt;

&lt;h3 id=&quot;remediation-scope&quot;&gt;Remediation Scope&lt;/h3&gt;

&lt;p&gt;Remediation tasks can be created at different scopes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Management Group Level&lt;/strong&gt;: Remediate across multiple subscriptions&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Subscription Level&lt;/strong&gt;: Remediate within a specific subscription&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Resource Group Level&lt;/strong&gt;: Remediate within a specific resource group&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;resource-discovery-modes&quot;&gt;Resource Discovery Modes&lt;/h3&gt;

&lt;p&gt;Azure Policy offers two resource discovery modes for remediation:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;ExistingNonCompliant&lt;/strong&gt;: Only remediate resources that are currently non-compliant&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ReEvaluateCompliance&lt;/strong&gt;: Re-evaluate all resources and remediate any that become non-compliant&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;implementing-remediation-with-powershell&quot;&gt;Implementing Remediation with PowerShell&lt;/h2&gt;

&lt;p&gt;Let’s examine a PowerShell script that automates the creation and execution of policy remediation tasks. This script provides a standardised approach to managing remediation across your Azure environment.&lt;/p&gt;

&lt;h3 id=&quot;the-core-remediation-script&quot;&gt;The Core Remediation Script&lt;/h3&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CmdletBinding&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;param&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Parameter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Mandatory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediationFile&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Import policies to remediate from JSON file&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediations&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Content&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Path&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediationFile&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConvertFrom-Json&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

&lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Policy Remediation&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;foreach&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediations&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-Host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;------------------------------------------&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Create arguments for Start-AzPolicyRemediation&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;                  &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; - &quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Get&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Date&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Format&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;yyyyMMddHHmmss&quot;&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PolicyAssignment&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;policyAssignmentId&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ResourceDiscoveryMode&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ReEvaluateCompliance&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;managementGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;managementGroup&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;managementGroup&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ResourceDiscoveryMode&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ExistingNonCompliant&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;subscriptionId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Set-AzContext&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Subscription&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;subscriptionId&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Out-Null&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;resourceGroup&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ResourceGroupName&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;resourceGroup&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;policyDefinitionReferenceId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PolicyDefinitionReferenceId&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;policyDefinitionReferenceId&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

    &lt;/span&gt;&lt;span class=&quot;c&quot;&gt;# Start remediation task&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$pa&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-AzPolicyAssignment&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Id&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;PolicyAssignment&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-ErrorAction&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Stop&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$pa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-Host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Starting remediation task for: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Start-AzPolicyRemediation&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;@&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;kr&quot;&gt;catch&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-Host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Failed to create policy remediation task &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-Error&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Write-Host&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;------------------------------------------&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;key-script-features&quot;&gt;Key Script Features&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dynamic Naming&lt;/strong&gt;: Each remediation task gets a unique name with a timestamp to avoid conflicts:&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;n&quot;&gt;Name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$remediation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; - &quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Get-Date&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-Format&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;yyyyMMddHHmmss&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Scope Flexibility&lt;/strong&gt;: The script handles different remediation scopes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Error Handling&lt;/strong&gt;: Comprehensive error handling ensures failed remediation tasks don’t break the entire process.&lt;/p&gt;

&lt;h2 id=&quot;configuration-management&quot;&gt;Configuration Management&lt;/h2&gt;

&lt;p&gt;The script uses a JSON configuration file to define which policies to remediate. This approach provides several benefits:&lt;/p&gt;

&lt;h3 id=&quot;configuration-structure&quot;&gt;Configuration Structure&lt;/h3&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Application Name Tag Remediation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;managementGroup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;production-mg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;policyAssignmentId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/providers/microsoft.management/managementgroups/production-mg/providers/microsoft.authorization/policyassignments/tag-governance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;policyDefinitionReferenceId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;require-application-name-tag&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Storage Encryption Remediation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;subscriptionId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;12345678-1234-1234-1234-123456789012&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;policyAssignmentId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/subscriptions/12345678-1234-1234-1234-123456789012/providers/microsoft.authorization/policyassignments/security-baseline&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;policyDefinitionReferenceId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;storage-encryption-required&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Resource Group Tag Remediation&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;subscriptionId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;12345678-1234-1234-1234-123456789012&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;resourceGroup&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;production-rg&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;policyAssignmentId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;/subscriptions/12345678-1234-1234-1234-123456789012/providers/microsoft.authorization/policyassignments/tag-governance&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;policyDefinitionReferenceId&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;require-environment-tag&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;configuration-parameters&quot;&gt;Configuration Parameters&lt;/h3&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Parameter&lt;/th&gt;
      &lt;th&gt;Required&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Descriptive name for the remediation task&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;managementGroup&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Optional&lt;/td&gt;
      &lt;td&gt;Management group ID (for MG-level remediation)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;subscriptionId&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Optional&lt;/td&gt;
      &lt;td&gt;Subscription ID (for subscription/RG-level remediation)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resourceGroup&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Optional&lt;/td&gt;
      &lt;td&gt;Resource group name (for RG-level remediation)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;policyAssignmentId&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Full resource ID of the policy assignment&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;policyDefinitionReferenceId&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Yes&lt;/td&gt;
      &lt;td&gt;Reference ID of the specific policy within an initiative&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;h3 id=&quot;finding-required-ids&quot;&gt;Finding Required IDs&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Policy Assignment ID&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Navigate to the Azure Portal → Policy → Assignments&lt;/li&gt;
  &lt;li&gt;Select the policy assignment&lt;/li&gt;
  &lt;li&gt;Copy the Assignment ID from the overview blade&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Policy Definition Reference ID&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Open the policy assignment in the Azure Portal&lt;/li&gt;
  &lt;li&gt;Click “View Definition”&lt;/li&gt;
  &lt;li&gt;Locate the Policy Definition Reference IDs (usually match the display names)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;devops-integration-and-best-practices&quot;&gt;DevOps Integration and Best Practices&lt;/h2&gt;

&lt;h3 id=&quot;cicd-pipeline-integration&quot;&gt;CI/CD Pipeline Integration&lt;/h3&gt;

&lt;p&gt;While we can’t use Bicep for remediation tasks, we can still integrate them into our DevOps workflows using PowerShell and CI/CD pipelines.&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c1&quot;&gt;# Example GitHub Actions workflow for policy remediation&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Policy Remediation&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;workflow_dispatch&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;inputs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;remediation_scope&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Remediation&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;(management-group,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;subscription,&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;resource-group)&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;required&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;subscription&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;choice&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;management-group&lt;/span&gt;
          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;subscription&lt;/span&gt;
          &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;resource-group&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;jobs&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;remediate_policies&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;runs-on&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;permissions&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;id-token&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;write&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;contents&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;read&lt;/span&gt;

    &lt;span class=&quot;na&quot;&gt;steps&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Checkout code&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Azure Login&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;uses&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;azure/login@v1&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;with&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;client-id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;tenant-id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;subscription-id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;$&lt;/span&gt;

      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Run Policy Remediation&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;shell&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;pwsh&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
          &lt;span class=&quot;s&quot;&gt;./policy-remediation/policy-remediations.ps1 -remediationFile ./policy-remediation/policy-remediations.json&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;best-practices-for-remediation&quot;&gt;Best Practices for Remediation&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Test Before Production&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Always test remediation tasks in non-production environments first&lt;/li&gt;
  &lt;li&gt;Use resource group level testing to validate behaviour&lt;/li&gt;
  &lt;li&gt;Monitor remediation results closely during initial deployments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Scope Appropriately&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Start with narrow scopes (resource groups) before expanding to subscriptions or management groups&lt;/li&gt;
  &lt;li&gt;Use management group level remediation only for well-tested, low-risk policies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Configuration Management&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Keep remediation configurations in source control&lt;/li&gt;
  &lt;li&gt;Use descriptive names that clearly indicate the purpose&lt;/li&gt;
  &lt;li&gt;Document the business justification for each remediation task&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Timing Considerations&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Run remediation tasks during maintenance windows when possible&lt;/li&gt;
  &lt;li&gt;Consider the impact on running workloads&lt;/li&gt;
  &lt;li&gt;Stagger large-scale remediation across multiple time periods&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;governance-workflow-for-remediation&quot;&gt;Governance Workflow for Remediation&lt;/h2&gt;

&lt;p&gt;Implementing a structured workflow ensures remediation tasks are executed safely and effectively:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Policy Non-Compliance Detected] --&amp;gt; B{Risk Assessment}
    B --&amp;gt;|Low Risk| C[Automated Remediation]
    B --&amp;gt;|Medium Risk| D[Staged Remediation]
    B --&amp;gt;|High Risk| E[Manual Review Required]

    C --&amp;gt; F[Execute Remediation Task]
    D --&amp;gt; G[Test in Non-Production]
    E --&amp;gt; H[Platform Team Review]

    G --&amp;gt; I{Test Results OK?}
    H --&amp;gt; J{Approved for Remediation?}

    I --&amp;gt;|Yes| F
    I --&amp;gt;|No| K[Investigate Issues]
    J --&amp;gt;|Yes| D
    J --&amp;gt;|No| L[Alternative Solution Required]

    F --&amp;gt; M[Monitor Results]
    M --&amp;gt; N[Document Outcomes]
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&quot;workflow-stages&quot;&gt;Workflow Stages&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Risk Assessment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Evaluate the potential impact of automated remediation&lt;/li&gt;
  &lt;li&gt;Consider the criticality of affected resources&lt;/li&gt;
  &lt;li&gt;Assess the complexity of the required changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Approval Process&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Low-risk changes: Automated approval&lt;/li&gt;
  &lt;li&gt;Medium-risk changes: Platform team review&lt;/li&gt;
  &lt;li&gt;High-risk changes: Security and business stakeholder approval&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Execution Strategy&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Phased rollout for large-scale remediation&lt;/li&gt;
  &lt;li&gt;Monitoring and rollback capabilities&lt;/li&gt;
  &lt;li&gt;Communication to affected teams&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Post-Execution Review&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Verify compliance improvement&lt;/li&gt;
  &lt;li&gt;Document any issues encountered&lt;/li&gt;
  &lt;li&gt;Update procedures based on lessons learned&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;complete-example&quot;&gt;Complete Example&lt;/h2&gt;

&lt;p&gt;The PowerShell script, JSON configuration, and CI/CD pipeline integration we’ve explored provide a comprehensive solution for automated policy remediation. To help you implement this approach in your own environment, I’ve created a complete working example:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/tw3lveparsecs/azure-policy-with-bicep/tree/main/policy-remediation&quot;&gt;Click here to view the policy remediation example&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Policy remediation tasks provide automated compliance enforcement for Azure environments, ensuring non-compliant resources are automatically corrected rather than simply identified. While Bicep support isn’t available yet, PowerShell-based remediation workflows integrated with CI/CD pipelines offer a robust governance solution.&lt;/p&gt;

&lt;p&gt;This approach offers several advantages:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Automated Compliance&lt;/strong&gt;: Non-compliant resources are fixed automatically without manual intervention&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Scalable Governance&lt;/strong&gt;: Apply consistent standards across large Azure environments through configuration-driven remediation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Risk Management&lt;/strong&gt;: Structured workflows ensure appropriate oversight while enabling automation for low-risk changes&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;DevOps Integration&lt;/strong&gt;: JSON configuration and PowerShell scripts integrate seamlessly with modern CI/CD practices&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The combination of automated remediation with policy exemptions creates a comprehensive governance framework that balances compliance requirements with operational flexibility.&lt;/p&gt;

&lt;p&gt;In our next article, we’ll continue exploring advanced Azure Policy scenarios. Stay tuned!&lt;/p&gt;
</description>
        <pubDate>Tue, 23 Sep 2025 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/devops-azure-policy-series-remediation/</link>
        <guid isPermaLink="true">https://azurewithaj.com/devops-azure-policy-series-remediation/</guid>
        
        <category>azure</category>
        
        <category>remediation</category>
        
        <category>iac</category>
        
        <category>policy</category>
        
        <category>ci/cd</category>
        
        <category>devops</category>
        
        
        <category>Azure Policy</category>
        
        <category>DevOps</category>
        
      </item>
    
      <item>
        <title>Delivering Major Enhancements Without Writing Code: My Agentic DevOps Journey</title>
        <description>&lt;p&gt;As a busy professional, I found myself in a familiar situation, needing to deliver a major enhancement to an internal solution while managing my regular day-to-day responsibilities. The challenge wasn’t a lack of capability or resources, but rather finding the sustained focus time that complex development work typically demands.&lt;/p&gt;

&lt;p&gt;This is the story of how I successfully delivered that enhancement without writing a single line of code myself, using agentic DevOps principles and GitHub Copilot’s coding agent capabilities to transform my development approach.&lt;/p&gt;

&lt;h2 id=&quot;the-challenge-maximising-development-impact-alongside-daily-operations&quot;&gt;The Challenge: Maximising Development Impact Alongside Daily Operations&lt;/h2&gt;

&lt;p&gt;The enhancement I needed to deliver was substantial, the kind that typically requires sustained focus and deep technical thinking. However, my reality involved managing a full schedule of meetings, stakeholder communications, and immediate delivery needs. My challenge wasn’t just finding time to work on the enhancement, but optimising how I could make meaningful progress within the time constraints I had.&lt;/p&gt;

&lt;p&gt;Every traditional development session resulted in:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Context rebuilding&lt;/strong&gt;: Spending significant time re-establishing where I left off&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Fragmented thinking&lt;/strong&gt;: Difficulty maintaining the full architectural vision across interrupted sessions&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Inefficient progress&lt;/strong&gt;: Short development windows that weren’t sufficient for complex problem-solving&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cognitive overhead&lt;/strong&gt;: Mental energy divided between the enhancement and immediate responsibilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I needed a development approach that could work with my schedule, not against it, one that would allow me to make consistent progress while fulfilling my daily operational responsibilities.&lt;/p&gt;

&lt;h2 id=&quot;the-solution-agentic-devops-as-a-personal-force-multiplier&quot;&gt;The Solution: Agentic DevOps as a Personal Force Multiplier&lt;/h2&gt;

&lt;p&gt;This is where I utilised agentic DevOps, a methodology where AI agents become integral partners in your development workflow. Rather than replacing my technical expertise, these agents would amplify it, handling the implementation heavy lifting while I focused on strategic decisions and quality oversight.&lt;/p&gt;

&lt;p&gt;My key realisation? Success with agentic DevOps isn’t about having AI write perfect code immediately. It’s about creating the right structures, processes, and feedback loops that enable AI agents to deliver value consistently while working around my existing responsibilities.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-mermaid&quot;&gt;graph TD
    A[Problem: Limited Development Time] --&amp;gt; B[Agentic DevOps Approach]
    B --&amp;gt; C[Strategic Planning]
    B --&amp;gt; D[Structured Backlog Creation]
    B --&amp;gt; E[AI-Powered Development]
    B --&amp;gt; F[Human-Led Validation]

    C --&amp;gt; G[GitHub Copilot Prompts &amp;amp; Chat Modes]
    D --&amp;gt; H[Automated Issue Generation]
    E --&amp;gt; I[Coding Agent Implementation]
    F --&amp;gt; J[Quality Assurance &amp;amp; Testing]

    G --&amp;gt; K[Comprehensive Implementation Plan]
    H --&amp;gt; L[Manageable Work Items]
    I --&amp;gt; M[Production-Ready Code]
    J --&amp;gt; N[Delivered Enhancement]
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;the-foundation-strategic-planning-with-ai&quot;&gt;The Foundation: Strategic Planning with AI&lt;/h2&gt;

&lt;h3 id=&quot;how-i-leveraged-githubs-awesome-copilot-resources&quot;&gt;How I Leveraged GitHub’s Awesome Copilot Resources&lt;/h3&gt;

&lt;p&gt;My first step was pretty straightforward but made all the difference: I needed a solid plan that would set up the coding agent for success. Without getting this foundation right first, even the smartest AI would have a tough time delivering the complex enhancement I was after.&lt;/p&gt;

&lt;p&gt;This is where I accessed the wealth of proven prompts and methodologies from &lt;a href=&quot;https://github.com/github/awesome-copilot&quot;&gt;GitHub’s Awesome Copilot repository&lt;/a&gt; (There is also a MCP server that can be used to interact with GitHub’s Awesome Copilot repository to integrate prompts, instructions and chat modes into your workflow). Among the many resources available, two stood out as particularly relevant to my needs.&lt;/p&gt;

&lt;p&gt;I specifically chose to use:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Create Implementation Plan prompt&lt;/strong&gt;: A well-structured prompt to generate a comprehensive technical plan for the enhancement&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Implementation Plan chat mode:&lt;/strong&gt; A persona designed to iteratively refine and expand on the initial plan, ensuring it was detailed and actionable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;how-i-created-a-meaningful-plan&quot;&gt;How I Created a Meaningful Plan&lt;/h3&gt;

&lt;p&gt;I learned that the key to success with coding agents is providing them with rich, contextual information. I used GitHub Copilot’s prompts and chat modes to develop a plan that included:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Functional Requirements&lt;/strong&gt;: Detailed feature list and user stories&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;: External services and internal components affected&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Testing &amp;amp; Validation Criteria&lt;/strong&gt;: Clear, measurable outcomes for validation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Risks &amp;amp; Assumptions&lt;/strong&gt;: Identification of potential challenges and underlying assumptions&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-markdown highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;table class=&quot;rouge-table&quot;&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td class=&quot;rouge-gutter gl&quot;&gt;&lt;pre class=&quot;lineno&quot;&gt;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&quot;rouge-code&quot;&gt;&lt;pre&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Example implementation plan (shortened for brevity) --&amp;gt;&lt;/span&gt;

&lt;span class=&quot;gh&quot;&gt;# Create Enhancement Implementation Plan&lt;/span&gt;

&lt;span class=&quot;gu&quot;&gt;## Introduction&lt;/span&gt;

This implementation plan outlines the creation of a enhancement that follows the same structure and conventions as the existing example pattern. The new pattern will provide X enhancement to the solution, while maintaining consistency with the established pattern architecture.

&lt;span class=&quot;gu&quot;&gt;## 1. Requirements &amp;amp; Constraints&lt;/span&gt;

&lt;span class=&quot;gu&quot;&gt;### Functional Requirements&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**REQ-001**&lt;/span&gt;: Create enhancement X that mirrors the structure of the existing example pattern
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**REQ-002**&lt;/span&gt;: Support the same subscription model
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**REQ-003**&lt;/span&gt;: Include all the same core components as example pattern but adapted for X enhancement architecture
  ... (Additional functional requirements as needed)

&lt;span class=&quot;gu&quot;&gt;### Security Requirements&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**SEC-001**&lt;/span&gt;: Implement secure connectivity patterns following Azure Well-Architected Framework
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**SEC-002**&lt;/span&gt;: Support for network security and traffic inspection
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**SEC-003**&lt;/span&gt;: Ensure proper network segmentation and traffic flow control
  ... (Additional security requirements as needed)

&lt;span class=&quot;gu&quot;&gt;### Technical Constraints&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**CON-001**&lt;/span&gt;: Must use the same folder structure as example pattern
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**CON-002**&lt;/span&gt;: Must integrate with existing Bicep module registry
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**CON-003**&lt;/span&gt;: Must support the same diagnostic and monitoring capabilities
  ... (Additional constraints as needed)

&lt;span class=&quot;gu&quot;&gt;### Guidelines&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**GUD-001**&lt;/span&gt;: Follow established naming conventions for resources and parameters
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**GUD-002**&lt;/span&gt;: Maintain consistency with existing pattern documentation structure
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**GUD-003**&lt;/span&gt;: Use modular approach for different components
  ... (Additional guidelines as needed)

&lt;span class=&quot;gu&quot;&gt;### Patterns to Follow&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**PAT-001**&lt;/span&gt;: Mirror the folder structure of example pattern
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**PAT-002**&lt;/span&gt;: Use the same subscription-scoped deployment approach
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**PAT-003**&lt;/span&gt;: Implement similar parameter validation and metadata
  ... (Additional patterns as needed)

&lt;span class=&quot;gu&quot;&gt;## 2. Implementation Steps&lt;/span&gt;

&lt;span class=&quot;gu&quot;&gt;### Implementation Phase 1: Core Structure Setup&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; GOAL-001: Establish the foundational structure and main pattern files

| Task     | Description                                                                          | Completed | Date |
| -------- | ------------------------------------------------------------------------------------ | --------- | ---- |
| TASK-001 | Create new folder structure at &lt;span class=&quot;sb&quot;&gt;`bicep/patterns/&amp;lt;enhancement&amp;gt;/`&lt;/span&gt;                       |           |      |
| TASK-002 | Copy and adapt the main.bicep from example pattern as the orchestrator               |           |      |
| TASK-003 | Create &lt;span class=&quot;sb&quot;&gt;`&amp;lt;enhancement&amp;gt;.bicepparam`&lt;/span&gt; template file for parameter configuration          |           |      |
| TASK-004 | Create comprehensive README.md for the pattern with architecture overview            |           |      |
| TASK-005 | Set up examples folder with three example configurations (basic, standard, advanced) |           |      |

&lt;span class=&quot;gu&quot;&gt;### Implementation Phase 2: Enhancement Component&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; GOAL-002: Implement the enhancement component identical to example pattern

| Task     | Description                                                         | Completed | Date |
| -------- | ------------------------------------------------------------------- | --------- | ---- |
| TASK-006 | Copy management module from example pattern (example/example.bicep) |           |      |
| TASK-007 | Verify module compatibility with architecture                       |           |      |
| TASK-008 | Update any specific documentation and README                        |           |      |
| TASK-009 | Test module deployment independently                                |           |      |

... (Additional phases would follow similarly)

&lt;span class=&quot;gu&quot;&gt;## 3. Alternatives&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**ALT-001**&lt;/span&gt;: Modify existing example pattern to support both topologies - Rejected due to complexity and potential breaking changes
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**ALT-002**&lt;/span&gt;: Create a unified pattern with topology selection parameter - Rejected due to maintenance complexity and different architectural requirements
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**ALT-003**&lt;/span&gt;: Use existing archived example pattern as-is - Rejected due to structural inconsistencies with current standards
  ... (Additional alternatives as needed)

&lt;span class=&quot;gu&quot;&gt;## 4. Dependencies&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**DEP-001**&lt;/span&gt;: Access to Bicep registry for network modules
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**DEP-002**&lt;/span&gt;: Existing shared-modules for common functionality
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**DEP-003**&lt;/span&gt;: Access to test Azure subscriptions for validation
  ... (Additional dependencies as needed)

&lt;span class=&quot;gu&quot;&gt;## 5. Files&lt;/span&gt;

&lt;span class=&quot;gu&quot;&gt;### New Files to Create&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**FILE-001**&lt;/span&gt;: &lt;span class=&quot;sb&quot;&gt;`bicep/patterns/enhancement/main.bicep`&lt;/span&gt; - Main orchestrator template
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**FILE-002**&lt;/span&gt;: &lt;span class=&quot;sb&quot;&gt;`bicep/patterns/enhancement/enhancement.bicepparam`&lt;/span&gt; - Parameter template
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**FILE-003**&lt;/span&gt;: &lt;span class=&quot;sb&quot;&gt;`bicep/patterns/enhancement/README.md`&lt;/span&gt; - Pattern documentation
  ... (Additional files as needed)

&lt;span class=&quot;gu&quot;&gt;### Files to Reference/Adapt&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**FILE-013**&lt;/span&gt;: Source example pattern files for structure and parameter reference
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**FILE-014**&lt;/span&gt;: Archived example pattern files for specific configuration
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**FILE-015**&lt;/span&gt;: Existing shared modules for common functionality

&lt;span class=&quot;gu&quot;&gt;## 6. Testing&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**TEST-001**&lt;/span&gt;: Bicep template compilation and linting validation
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**TEST-002**&lt;/span&gt;: Parameter validation and type checking
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**TEST-003**&lt;/span&gt;: Deployment testing in development environment with basic example
  ... (Additional tests for standard and advanced examples, component-specific tests)

&lt;span class=&quot;gu&quot;&gt;## 7. Risks &amp;amp; Assumptions&lt;/span&gt;

&lt;span class=&quot;gu&quot;&gt;### Risks&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**RISK-001**&lt;/span&gt;: pricing model may be significantly different from example solution, affecting cost comparisons
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**RISK-002**&lt;/span&gt;: Some features available in example solution may not have direct enhancement equivalents
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**RISK-003**&lt;/span&gt;: enhancement may require different configuration approaches than traditional example solution
  ... (Additional risks as needed)

&lt;span class=&quot;gu&quot;&gt;### Assumptions&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**ASSUMPTION-001**&lt;/span&gt;: The same subscription model applies to enhancement pattern
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**ASSUMPTION-002**&lt;/span&gt;: Enhancement service is available in target regions
&lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;gs&quot;&gt;**ASSUMPTION-003**&lt;/span&gt;: Current Bicep registry contains necessary modules
  ... (Additional assumptions as needed)

&lt;span class=&quot;gu&quot;&gt;## 8. Related Specifications / Further Reading&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;
-&lt;/span&gt; Links to Microsoft articles relating enhancement
&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;how-i-transformed-my-plan-into-action-creating-an-actionable-backlog&quot;&gt;How I Transformed My Plan into Action: Creating an Actionable Backlog&lt;/h2&gt;

&lt;p&gt;With my solid implementation plan in hand, I faced the next challenge of breaking it down into manageable work items that I could effectively delegate to the coding agent. Here’s where the &lt;strong&gt;create-github-issues-feature-from-implementation-plan&lt;/strong&gt; prompt became invaluable to my workflow.&lt;/p&gt;

&lt;h3 id=&quot;how-i-generated-my-automated-backlog&quot;&gt;How I Generated My Automated Backlog&lt;/h3&gt;

&lt;p&gt;This prompt transformed my comprehensive plan into exactly what I needed:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Discrete GitHub issues&lt;/strong&gt;: Each representing a focused development task that could be completed independently&lt;/p&gt;

    &lt;p&gt;Each issue included:&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Description&lt;/strong&gt;: A detailed overview of the task&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Tasks to complete&lt;/strong&gt;: Specific steps required to complete the issue&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Requirements&lt;/strong&gt;: Any specific conditions or prerequisites for the issue&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Definition of Done&lt;/strong&gt;: Clear criteria for when the issue can be considered complete&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Dependencies&lt;/strong&gt;: Any related issues or tasks that must be completed first&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Related Files&lt;/strong&gt;: Links to any relevant documentation or code&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Implementation Plan Reference&lt;/strong&gt;: Links back to the original implementation plan for context&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Next Phase&lt;/strong&gt;: Reference to the subsequent phase in the implementation plan&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result? I had a backlog of 10 well-defined issues, each scoped perfectly for completion within a focused development session, exactly what I needed for my agentic DevOps approach.&lt;/p&gt;

&lt;h2 id=&quot;the-game-changer-the-coding-agent-as-my-development-partner&quot;&gt;The Game Changer: The Coding Agent as My Development Partner&lt;/h2&gt;

&lt;p&gt;Here’s where this approach truly transformed my productivity. Instead of trying to carve out large blocks of focused development time from my busy schedule, I assigned each backlog item to GitHub Copilot’s coding agent. The agent essentially became my dedicated developer, working through issues while I continued with my regular responsibilities.&lt;/p&gt;

&lt;h3 id=&quot;how-the-coding-agent-workflow-functioned&quot;&gt;How The Coding Agent Workflow Functioned&lt;/h3&gt;

&lt;p&gt;The process became simple:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Issue Assignment&lt;/strong&gt;: I would assign a backlog item to the coding agent&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Autonomous Development&lt;/strong&gt;: The agent implemented features based on my detailed requirements while I focused on other tasks&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Pull Request Creation&lt;/strong&gt;: Completed work was submitted for my review, ready when I had time to evaluate it&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Iterative Improvement&lt;/strong&gt;: I provided feedback through the standard PR review process during natural breaks in my day&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;how-i-maintained-quality-the-human-touch-in-the-workflow&quot;&gt;How I Maintained Quality: The Human Touch in the Workflow&lt;/h2&gt;

&lt;p&gt;While the coding agent handled implementation, my role evolved to quality oversight, which I found to be more valuable and engaging than writing code myself. This shift allowed me to focus on the strategic aspects of development that truly required my expertise.&lt;/p&gt;

&lt;h3 id=&quot;the-review-process&quot;&gt;The Review Process&lt;/h3&gt;

&lt;p&gt;I treated each pull request with the same rigour I would apply to work from any team member:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Code quality assessment&lt;/strong&gt;: Evaluating architecture, readability, and maintainability&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Functional testing&lt;/strong&gt;: Verifying implementation against my acceptance criteria&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Integration validation&lt;/strong&gt;: Ensuring compatibility with our existing systems&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Security review&lt;/strong&gt;: Following our established security guidelines&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;what-i-learned-about-effective-feedback&quot;&gt;What I Learned About Effective Feedback&lt;/h3&gt;

&lt;p&gt;Through this process, I discovered that providing specific, actionable feedback yielded the best results:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;What worked for me&lt;/strong&gt;: “Resolve Bicep warning errors related to value could be null”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;What was less effective&lt;/strong&gt;: “Resolve all warning errors in Bicep file” (too vague, led to generic solutions that required iteration)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-i-learned-the-reality-of-human-ai-partnership&quot;&gt;What I Learned: The Reality of Human-AI Partnership&lt;/h2&gt;

&lt;h3 id=&quot;what-worked-exceptionally-well-for-me&quot;&gt;What Worked Exceptionally Well for Me&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A Structured Approach&lt;/strong&gt;: The combination of detailed planning and incremental delivery proved highly effective. I found the coding agent performed best when I provided clear, specific requirements upfront.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Context Preservation&lt;/strong&gt;: Unlike my previous fragmented development attempts, the agent maintained full context across all work items, ensuring consistency and coherence throughout the enhancement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quality Consistency&lt;/strong&gt;: Code quality remained high throughout my project, as each PR received focused review attention during convenient moments in my schedule.&lt;/p&gt;

&lt;h3 id=&quot;my-challenges-and-key-learnings&quot;&gt;My Challenges and Key Learnings&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Communication Precision Matters&lt;/strong&gt;: I learned that vague feedback led to suboptimal solutions that required additional iterations. Specific, actionable guidance consistently yielded better results faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tool Integration Quirks I Encountered&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;VS Code’s GitHub PR extension currently doesn’t recognise @mentions, this occasionally caused issues when trying to assign the coding agent where I had typos and caused delays&lt;/li&gt;
  &lt;li&gt;The GitHub.com interface refreshed faster than the VS Code extension, so I often switched to the web interface&lt;/li&gt;
  &lt;li&gt;I sometimes needed to force refresh to see updates in VS Code&lt;/li&gt;
  &lt;li&gt;When Copilot created pull requests it defaulted to the base branch rather than my feature branch, so I had to manually change it each time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are minor inconveniences that I expect will improve as the tools evolve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Human Oversight Remained Critical&lt;/strong&gt;: I discovered that while the coding agent is incredibly capable, it still required my guidance for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Strategic architectural decisions that impacted other systems&lt;/li&gt;
  &lt;li&gt;Complex business logic interpretation specific to our domain&lt;/li&gt;
  &lt;li&gt;Edge case handling based on operational experience&lt;/li&gt;
  &lt;li&gt;Integration complexity management with our existing infrastructure&lt;/li&gt;
  &lt;li&gt;Security considerations that required nuanced understanding&lt;/li&gt;
  &lt;li&gt;Testing and validation to ensure functionality met real-world needs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-results-successfully-delivering-the-major-enhancement&quot;&gt;The Results: Successfully Delivering the Major Enhancement&lt;/h2&gt;

&lt;p&gt;After two weeks of applying this agentic DevOps approach, I successfully delivered the complete enhancement without writing a single line of code myself. The final solution I delivered included:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Full feature implementation&lt;/strong&gt;: All planned functionality working exactly as I specified&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Comprehensive testing&lt;/strong&gt;: Both automated and manual test coverage that I validated&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Complete documentation&lt;/strong&gt;: Technical documentation and user guides ready for the team&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Production readiness&lt;/strong&gt;: Code that met all our organisational standards and passed our quality gates&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;the-future-of-development-agentic-devops-adoption&quot;&gt;The Future of Development: Agentic DevOps Adoption&lt;/h2&gt;

&lt;h3 id=&quot;immediate-benefits&quot;&gt;Immediate Benefits&lt;/h3&gt;

&lt;p&gt;This experience demonstrated several immediate advantages of agentic DevOps:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Parallel processing&lt;/strong&gt;: Development continues while handling other responsibilities&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Consistent quality&lt;/strong&gt;: Dedicated focus on each work item&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Reduced cognitive load&lt;/strong&gt;: Less context switching and mental overhead&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Scalable approach&lt;/strong&gt;: Methodology applicable to projects of various sizes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;strategic-implications&quot;&gt;Strategic Implications&lt;/h3&gt;

&lt;p&gt;For development teams and organisations, this approach suggests:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Resource multiplication&lt;/strong&gt;: Senior developers can guide multiple parallel work streams&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Knowledge transfer&lt;/strong&gt;: AI agents can implement patterns and practices consistently&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Risk reduction&lt;/strong&gt;: Incremental delivery with continuous validation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Innovation enablement&lt;/strong&gt;: More time for strategic thinking and architectural decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;getting-started-your-agentic-devops-implementation&quot;&gt;Getting Started: Your Agentic DevOps Implementation&lt;/h2&gt;

&lt;h3 id=&quot;essential-prerequisites&quot;&gt;Essential Prerequisites&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Access to GitHub Copilot&lt;/strong&gt;: Particularly the coding agent functionality&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Structured project management&lt;/strong&gt;: Clear issue tracking and PR workflows&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Quality gates&lt;/strong&gt;: Established code review and testing processes&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Planning discipline&lt;/strong&gt;: Investment in upfront requirement definition&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;recommended-first-steps&quot;&gt;Recommended First Steps&lt;/h3&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Start small&lt;/strong&gt;: Choose a well-defined enhancement or feature&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Leverage proven prompts&lt;/strong&gt;: Use resources from the Awesome Copilot repository&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Establish feedback patterns&lt;/strong&gt;: Develop clear communication styles with AI agents&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Measure and iterate&lt;/strong&gt;: Track time savings and quality metrics&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;conclusion-redefining-whats-possible-in-development&quot;&gt;Conclusion: Redefining What’s Possible in Development&lt;/h2&gt;

&lt;p&gt;This experience fundamentally changed my perspective on software development productivity. I realised that my constraint wasn’t my coding ability or technical knowledge, it was optimising how I used my available time and focus. Agentic DevOps allowed me to solve both challenges simultaneously.&lt;/p&gt;

&lt;p&gt;By shifting my role from code writer to architect and reviewer, I was able to deliver more value in less time while maintaining the high quality standards I demand. The coding agent became my ideal development partner: tireless, consistent, and focused, requiring only strategic guidance and quality oversight from me.&lt;/p&gt;

&lt;p&gt;I’ve learned that the future of software development isn’t about replacing developers with AI, it’s about augmenting our capabilities to achieve outcomes that were previously difficult given our time and context constraints. Agentic DevOps provided me with the framework for that augmentation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ready to transform your own development approach?&lt;/strong&gt; I recommend starting with your next enhancement or feature. Create a detailed plan, break it into manageable issues, and let a coding agent handle the implementation while you focus on strategy and quality. You might be surprised by what becomes possible when you shift from writing code to orchestrating development.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;em&gt;Have you experimented with agentic DevOps approaches in your own projects? I’d love to hear about your experiences and lessons learned in the comments below.&lt;/em&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 16 Sep 2025 19:00:00 +0000</pubDate>
        <link>https://azurewithaj.com/agentic-devops-delivered-major-enhancement/</link>
        <guid isPermaLink="true">https://azurewithaj.com/agentic-devops-delivered-major-enhancement/</guid>
        
        <category>github</category>
        
        <category>copilot</category>
        
        <category>agent</category>
        
        <category>devops</category>
        
        <category>agentic</category>
        
        <category>ai</category>
        
        
        <category>DevOps</category>
        
        <category>AI</category>
        
      </item>
    
  </channel>
</rss>
