How I Used GitHub Copilot CLI to Build an Azure Governance Web App: From Zero to Maturity Score in One Weekend
If you told me a year ago that I’d build a fully functioning Azure cost management and governance web application in a single weekend, without leaving my terminal I’d have laughed. But that’s exactly what happened when I sat down with GitHub Copilot CLI and a clear goal: build a web app that gives me a single-pane-of-glass view into Azure Budgets, Cost Management, Tagging, Policies, Advisor Recommendations, Orphaned Resources, Security, Service Retirements, Logging Costs, Right Sizing, and a Maturity Score Report.
Here’s how it went, what I learned, and why I believe Copilot CLI is a game-changer for anyone building cloud tooling.
What Is GitHub Copilot CLI?
For those who haven’t tried it yet, GitHub Copilot CLI is the new agentic coding assistant that lives entirely in your terminal. It replaced the older gh copilot extension (deprecated October 2025) and brings the full power of the Copilot coding agent to your command line. You install it, authenticate with your GitHub account, type copilot, and start building.
What makes it different from other AI coding tools? A few things stood out to me during this project. It defaults to Claude Sonnet 4.5 but lets you swap models mid-session with the /model command. It supports Plan Mode (Shift+Tab), which lets you collaborate on an implementation plan before any code gets written. It has deep GitHub integration issues, PRs, repos all accessible through natural language. And critically for this project, it supports MCP (Model Context Protocol) servers, which meant I could extend it with the Azure MCP Server and have Copilot understand my Azure environment natively.
The Problem: Azure Governance Is Scattered
Anyone managing Azure subscriptions at scale knows the pain. Budgets live in Cost Management. Tagging compliance is a separate report. Advisor recommendations are in their own blade. Orphaned resources require custom queries. Security findings are in Defender for Cloud. Service retirement notices come via email. And tying all of this together into a “how mature is our Azure governance?” score? That’s a spreadsheet exercise most teams dread.
I wanted a single web application that pulls all of this together and gives me an actionable maturity score.
Setting Up Copilot CLI for the Project
Getting started was straightforward. I installed Copilot CLI via winget, authenticated, and navigated to my empty project directory.
terminal
winget install GitHub.Copilot
The first thing Copilot asked was whether I trusted the files in this directory. Since it was empty, I selected “Yes, and remember this folder for future sessions.” From there, I was in an interactive session.
Connecting the Azure MCP Server
This was the key enabler for the entire project. The Azure MCP Server gives Copilot the ability to interact with Azure services, Azure Resource Graph, and perform tasks on your behalf. I configured the Azure MCP Server following Microsoft’s documentation and the azd coding-agent config flow. Once connected, Copilot could query my Azure subscriptions, understand my resource landscape, and generate code that used the correct Azure SDK patterns for my environment.
Using Plan Mode
Before writing a single line of code, I switched to Plan Mode with Shift+Tab and described what I wanted:
“I want to build a web application using React for the frontend and Node.js for the backend that connects to Azure and provides dashboards for: Budget tracking and alerts, Cost analysis and trends, Tag compliance auditing, Azure Policy compliance, Advisor recommendations, Orphaned resource detection, Security posture from Defender, Service retirement tracking, Log Analytics cost monitoring, Right-sizing recommendations, and an overall Maturity Score. Use the Azure SDK for JavaScript and Azure Resource Graph queries where appropriate.”
Copilot asked clarifying questions: Did I want multi-subscription support? (Yes.) Should the maturity score be configurable with weighted categories? (Yes.) Did I want role-based access? (Not yet, keep it simple.) After a few rounds, it produced a structured implementation plan that I reviewed and approved.
Building the App: Module by Module
- Azure Budgets
I prompted Copilot to scaffold the budget tracking module first. It generated API routes that use the @azure/arm-consumption SDK to pull budget data, current spend versus budget thresholds, and forecast projections. The frontend component rendered a clean dashboard with progress bars showing spend-to-budget ratios and colour-coded alerts for budgets approaching their thresholds.
What impressed me was how Copilot handled the Azure authentication flow. It set up DefaultAzureCredential from @azure/identity and structured the code so the same credential chain worked locally (via Azure CLI auth) and in production (via managed identity).
- Cost Management
For cost analysis, Copilot generated Azure Resource Graph queries to pull cost data by resource group, service, and tag. It created time-series charts showing daily and monthly cost trends, and added a comparison view that overlays the current month against the previous month. I steered it to include anomaly highlighting any day where spend exceeded the 30-day rolling average by more than 20% gets flagged.
- Tagging Compliance
This module was where Copilot’s plan mode really shone. I described our tagging policy (required tags: Environment, CostCenter, Owner, Project) and Copilot generated Azure Resource Graph queries that audit every resource across subscriptions, calculate compliance percentages, and produce drill-down views by resource group and resource type. It even generated a remediation helper that outputs Azure CLI commands to apply missing tags.
- Azure Policy Compliance
Copilot scaffolded an integration with the @azure/arm-policy SDK that pulls policy assignment compliance states. The dashboard shows compliant versus non-compliant resource counts per policy initiative, with the ability to drill into specific non-compliant resources. It used the policy compliance API correctly on the first pass, which saved me significant time versus reading the SDK documentation myself.
- Advisor Recommendations
The Advisor module pulls recommendations across all five categories (Cost, Security, Reliability, Operational Excellence, Performance) using the @azure/arm-advisor SDK. Copilot organized these into a prioritized list with estimated savings for cost recommendations and severity ratings for the rest. It also generated a “quick wins” view that filters for high-impact, low-effort recommendations.
- Orphaned Resources
This was one of the trickiest modules. Orphaned resources unattached disks, unused public IPs, empty network security groups, NICs not attached to VMs don’t have a single API. Copilot generated a suite of Azure Resource Graph queries to detect each type, estimated the monthly cost of each orphaned resource, and created a cleanup view with one-click remediation scripts (outputting the az commands, not executing them directly for safety).
- Security Posture
For security, Copilot integrated with the Microsoft Defender for Cloud APIs to pull the Secure Score, security recommendations, and alerts. The dashboard shows the overall secure score as a gauge, breaks down recommendations by severity, and highlights resources with active security alerts. It used the @azure/arm-security SDK and handled the different API versions gracefully.
- Service Retirements
Service retirements were interesting because there isn’t a single clean API for them. Copilot generated code that pulls service health advisories from the Azure Service Health API and filters for retirement-type events. It then cross-references your deployed resources against the affected services to produce a personalized retirement risk report showing which of your resources are impacted by upcoming retirements.
- Logging Costs
Log Analytics can become a significant cost driver if not managed carefully. Copilot built a module that queries the Log Analytics workspace usage API, breaks down ingestion by data type (table), shows daily ingestion trends, and flags tables with unusually high or growing ingestion rates. It also added a “noisy tables” detector that identifies tables contributing disproportionately to costs.
- Right-Sizing
Right-sizing recommendations came from two sources: Azure Advisor (which Copilot already integrated) and custom analysis using Azure Monitor metrics. Copilot generated code that pulls CPU and memory utilization metrics for VMs over the past 30 days, identifies consistently underutilized resources (average utilization below 20%), and recommends appropriate SKU downgrades with estimated savings.
- The Maturity Score
This was the capstone. I described the maturity scoring model I wanted: each of the ten areas above gets a score from 0 to 100 based on configurable thresholds, each area has a configurable weight, and the overall maturity score is a weighted average.
Copilot generated the scoring engine with sensible defaults: Budget coverage over 80% of subscriptions scores high. Tag compliance above 90% scores high. Less than 5% non-compliant policy resources scores high. And so on for each category. The frontend renders a radar chart showing scores across all dimensions, plus an overall maturity grade (A through F) with specific recommendations for improving each area.

Features That Made the Difference
MCP Server Integration
The Azure MCP Server was transformative. Instead of me describing Azure APIs in my prompts, Copilot could query my actual Azure environment and generate code tailored to my subscription structure, resource types, and existing configurations. This dramatically reduced the back-and-forth that would have been required otherwise.
Plan Mode
Building a ten-module application in a single weekend would have been chaotic without Plan Mode. Being able to describe the full scope, get a structured plan, and then execute module by module kept the project organized. I used /clear between major modules to reset context and keep responses sharp a tip from the official best practices documentation.
Model Switching
For the straightforward CRUD operations and API integrations, I stuck with Claude Sonnet 4.5 (the default). For the more complex maturity scoring logic and the multi-subscription aggregation patterns, I switched to Opus 4.5 with /model. The ability to choose the right model for the complexity of the task was genuinely useful.
Autopilot Mode
For the repetitive scaffolding tasks setting up API routes, creating React components for each dashboard module I used Autopilot mode (Shift+Tab to cycle to it), which lets the agent keep working until a task is complete. This meant I could describe what I wanted and let Copilot build out entire feature modules while I reviewed the output.
Custom Instructions
I created a .github/copilot-instructions.md file in my repo with project conventions: use TypeScript everywhere, follow a specific project structure, always use DefaultAzureCredential, use Recharts for data visualization, and follow our Azure Resource Graph query patterns. Copilot respected these throughout the entire build, which meant consistent code across all modules.
Lessons Learned
Start with Plan Mode for complex projects. The temptation is to just start prompting, but for anything with more than a couple of modules, the plan-first approach saves enormous time.
Use /clear between unrelated tasks. Context pollution is real. When I moved from the Security module to the Logging module, clearing the context gave me noticeably better results.
The Azure MCP Server is essential for Azure projects. Without it, you’re manually describing your Azure environment in every prompt. With it, Copilot understands your subscriptions, resource groups, and deployed services.
Review everything. Copilot generated excellent Azure Resource Graph queries, but I caught a few edge cases like queries that didn’t handle the pagination token for large result sets. The human review step is non-negotiable.
Iterate with specificity. When Copilot’s first pass wasn’t quite right, specific feedback worked much better than vague feedback. “The cost trend chart should use a stacked area chart instead of a line chart, grouped by service category” worked much better than “make the chart better.”
The Result

In one weekend, I had a working web application with eleven interconnected modules, a configurable maturity scoring engine, multi-subscription support, and dashboards that would have taken weeks to build manually. The codebase was consistent, well-structured, and followed the conventions I specified.
Is it production-ready? Yes, it has validation, authentication and proper error handling. It’s exactly what I needed, built in a fraction of the time.
GitHub Copilot CLI didn’t just help me write code faster. It helped me think through the architecture, plan the implementation, and execute systematically. For anyone building Azure tooling, governance dashboards, or FinOps solutions, I can’t recommend it enough.
Resources
GitHub Copilot CLI: github.com/features/copilot/cli
Copilot CLI Repository: github.com/github/copilot-cli
Azure MCP Server: learn.microsoft.com
Copilot CLI Best Practices: docs.github.com
Awesome Copilot (Custom Agents & Skills): github.com/github/awesome-copilot


















