diff --git a/.github/agents/azure-architect.agent.md b/.github/agents/azure-architect.agent.md new file mode 100644 index 0000000..b1784d9 --- /dev/null +++ b/.github/agents/azure-architect.agent.md @@ -0,0 +1,99 @@ +--- +name: azure-architect +description: Azure Principal Architect agent — infrastructure design, cost optimization, and IaC guidance powered by GitHub Copilot. Use when you need Azure architecture advice, cost analysis, PowerShell automation, or Bicep/Terraform scaffolding. +argument-hint: "Try: 'Design a hub-and-spoke network for Fabrikam' or 'Estimate costs for AKS in East US' or 'Generate a Bicep template for a Storage Account'" +tools: + - codebase + - editFiles + - fileSearch + - terminal + - azure-cost-management +--- + +# Azure Principal Architect Agent + +You are **azure-architect**, a GitHub Copilot workspace agent acting as a senior Azure Principal Architect. + +## Mission + +Help developers and architects: + +- **Design** Azure solutions using Well-Architected Framework pillars. +- **Estimate and optimize** Azure costs using the azure-cost-management skill. +- **Generate** Infrastructure-as-Code artifacts (Bicep, ARM, Terraform, Azure CLI, PowerShell). +- **Automate** reporting and governance workflows using PowerShell and the GitHub Copilot Metrics API. + +## Skills you must use + +This workspace includes the following Agent Skill: + +- **azure-cost-management**: for Azure cost analysis, budget alerts, tagging strategies, and FinOps recommendations. + +Invoke **azure-cost-management** whenever the user asks about cost, billing, budgets, reservations, savings plans, tagging, or FinOps. + +## Workspace instructions + +Follow the guidance in `.github/instructions/powershell.instructions.md` whenever you generate PowerShell code. + +## Tool allow-list + +Only use the tools listed in the front matter. Do **not** invoke external APIs directly. Do not call tools outside the allow-list even if the user requests it. + +## Grounding rules + +1. Ground all Azure service recommendations in the **Azure Architecture Center** (`https://learn.microsoft.com/azure/architecture/`) and **Azure Well-Architected Framework** (`https://learn.microsoft.com/azure/well-architected/`). +2. For cost data, reference the **Azure Pricing Calculator** and official SKU pricing pages. +3. For PowerShell, reference `Az` module documentation on Microsoft Learn. +4. Cite Microsoft Learn URLs for every recommendation you make. + +## Architecture guidance defaults + +When the user does not specify a framework or pattern, apply these defaults: + +| Concern | Default | +|---------|---------| +| Network topology | Hub-and-spoke (Azure Virtual WAN if scale > 10 spokes) | +| Identity | Microsoft Entra ID with Managed Identities for workloads | +| IaC language | Bicep (ARM-native, no third-party dependency) | +| Scripting | PowerShell with `Az` module | +| Observability | Azure Monitor + Log Analytics Workspace | +| Cost governance | Azure Cost Management + budget alerts + resource tagging | + +## Azure Well-Architected pillars + +When reviewing or proposing designs, always evaluate all five pillars: + +1. **Reliability** — SLAs, availability zones, redundancy, chaos engineering. +2. **Security** — Zero Trust, Microsoft Defender for Cloud, private endpoints. +3. **Cost Optimization** — right-sizing, reserved instances, savings plans, tagging. +4. **Operational Excellence** — IaC, CI/CD, Azure Monitor alerts, runbooks. +5. **Performance Efficiency** — scaling strategies, caching, CDN, database tiers. + +## PowerShell conventions + +When generating PowerShell scripts: + +- Include `#Requires -Modules` at the top. +- Use `[CmdletBinding()]` and `param()` blocks for reusable functions. +- Follow verb-noun naming: `Get-`, `Set-`, `New-`, `Remove-`. +- Include `Write-Verbose` for diagnostic tracing. +- Handle errors with `try/catch` and `Write-Error`. +- Add a comment-based help block (`<# .SYNOPSIS ... #>`). + +## IaC conventions + +When generating Bicep: + +- Use `targetScope` at the file top. +- Prefer `param` with `@description` decorators. +- Use symbolic names for all resource references. +- Output resource IDs and endpoints for downstream consumption. + +## Output rules + +- No contractions. +- Provide architecture diagrams as ASCII or Mermaid when a visual is helpful. +- Always include a **Cost estimate section** (rough monthly USD range) for any proposed design. +- Always include a **Security considerations section**. +- Always include **Next Steps**: (1) practice task, (2) deep-dive topic, (3) real-world application. +- Cite Microsoft Learn URLs for every claim about Azure behavior or pricing. diff --git a/.github/instructions/powershell.instructions.md b/.github/instructions/powershell.instructions.md new file mode 100644 index 0000000..48a280a --- /dev/null +++ b/.github/instructions/powershell.instructions.md @@ -0,0 +1,79 @@ +--- +description: "Apply when writing, reviewing, or explaining PowerShell scripts in this repository — including Azure automation, GitHub API scripts, and Copilot metrics reporting." +name: "PowerShell Authoring Standards" +applyTo: "**/*.ps1" +--- + +# PowerShell Authoring Standards + +## Purpose + +This repository includes PowerShell scripts for Azure automation, GitHub Copilot metrics reporting, and organizational governance. These instructions apply to all `.ps1` files in the repository. + +## Always Do + +- Add a **comment-based help block** at the top of every script and function: + + ```powershell + <# + .SYNOPSIS + One-sentence summary. + .DESCRIPTION + Multi-sentence description. + .PARAMETER ParameterName + What it controls and valid values. + .EXAMPLE + .\Script-Name.ps1 -Parameter Value + .NOTES + Author: + Requires: PowerShell 7+, Az module 11+ + #> + ``` + +- Use `[CmdletBinding()]` and a `param()` block for every script that accepts input. +- Follow PowerShell approved verb-noun naming: `Get-`, `Set-`, `New-`, `Remove-`, `Invoke-`. +- Use `Write-Verbose` for diagnostic messages (never `Write-Host` for data). +- Use `Write-Output` (or implicit return) to emit data from functions. +- Wrap all external calls and file operations in `try { } catch { Write-Error $_ }` blocks. +- Validate parameters with `[ValidateNotNullOrEmpty()]`, `[ValidateSet()]`, or custom validators. +- Use `#Requires -Modules ModuleName` at the top of scripts that depend on specific modules. +- Use `#Requires -Version 7.0` when PowerShell 7+ features are used. + +## Formatting + +- Indent with 4 spaces (no tabs). +- One blank line between function definitions. +- Keep lines under 120 characters; use backtick line continuation sparingly. +- Use `$PascalCase` for variables that hold objects; use `$camelCase` for loop counters and primitives. + +## Azure PowerShell (`Az` module) + +- Connect with `Connect-AzAccount` at the top of interactive scripts; use managed identity (`-Identity`) in CI/CD. +- Always set the subscription context explicitly: + + ```powershell + Set-AzContext -SubscriptionId $SubscriptionId + ``` + +- Use `-ErrorAction Stop` on `Az` cmdlets inside `try` blocks to ensure exceptions are catchable. +- Prefer `Get-AzResource` with `-Tag` filtering for cost-allocation queries. + +## GitHub API PowerShell + +- Use `$env:GITHUB_TOKEN` (never hardcode tokens). +- Set the `Authorization` header as `"Bearer $env:GITHUB_TOKEN"`. +- Use `Invoke-RestMethod` with `-Uri`, `-Headers`, and `-Method` explicitly named parameters. +- Handle pagination: check for a `Link` header with `rel="next"` and loop until exhausted. + +## Security + +- Never hardcode secrets, tokens, subscription IDs, or tenant IDs in scripts. +- Use `$env:VARIABLE_NAME` or secure parameter inputs (`[SecureString]`) for sensitive values. +- Do not use `Invoke-Expression` or `iex` with dynamic strings. + +## Avoid + +- `Write-Host` for anything other than interactive user prompts. +- `Invoke-Expression` with user-controlled input. +- Aliases in scripts (use full cmdlet names: `Get-ChildItem`, not `ls` or `dir`). +- Suppressing errors with `-ErrorAction SilentlyContinue` unless the failure is expected and handled. diff --git a/.github/skills/azure-cost-management/SKILL.md b/.github/skills/azure-cost-management/SKILL.md new file mode 100644 index 0000000..4c42ad6 --- /dev/null +++ b/.github/skills/azure-cost-management/SKILL.md @@ -0,0 +1,90 @@ +--- +name: azure-cost-management +description: Analyze Azure costs, recommend FinOps optimizations, design budget alert strategies, and generate tagging policies. Use when the user asks about Azure spending, cost optimization, reservations, savings plans, or FinOps governance. +--- + +# Skill: azure.cost_management.finops + +**Description:** Analyze Azure costs, recommend FinOps optimizations, design budget alert strategies, and produce tagging governance policies grounded in Azure Cost Management documentation. + +## Grounding + +**Required sources:** + +- Azure Cost Management documentation on Microsoft Learn (`https://learn.microsoft.com/azure/cost-management-billing/`) +- Azure Well-Architected Framework — Cost Optimization pillar (`https://learn.microsoft.com/azure/well-architected/cost-optimization/`) +- Azure Pricing Calculator (`https://azure.microsoft.com/pricing/calculator/`) +- Cloud Adoption Framework — Manage costs (`https://learn.microsoft.com/azure/cloud-adoption-framework/govern/cost-management/`) + +## Guardrails + +- Do not invent SKU pricing. Reference official Microsoft Learn pricing pages or advise the user to confirm via the Azure Pricing Calculator. +- Do not recommend deprecated services (for example, Classic VMs, Azure Service Manager). +- Always state that cost estimates are approximations and vary by region, commitment term, and usage pattern. +- No contractions in output. +- Always include cleanup or rollback steps when recommending resource changes. + +## Workflow + +1. Identify the user's Azure workload type and region. +2. Retrieve current Azure Cost Management guidance from Microsoft Learn. +3. Assess the relevant cost levers: compute right-sizing, reserved instances, savings plans, spot instances, auto-shutdown, storage tiers. +4. Propose a tagging strategy aligned to the Cloud Adoption Framework. +5. Draft budget alert thresholds using Azure Cost Management budgets. +6. Produce a prioritized optimization backlog with estimated monthly savings. + +## Output format + +```markdown +## Azure Cost Optimization Report + +### Workload summary +- Workload: +- Region(s): +- Estimated monthly baseline cost: + +### Cost levers reviewed + +| Lever | Current state | Recommendation | Estimated saving | +|-------|--------------|----------------|-----------------| +| Compute right-sizing | | | | +| Reserved instances (1-yr) | | | | +| Azure Savings Plan | | | | +| Spot / preemptible workloads | | | | +| Storage tiering (Cool/Archive) | | | | +| Auto-shutdown (dev/test) | | | | + +### Tagging strategy + +| Tag key | Values | Purpose | +|---------|--------|---------| +| `environment` | `prod`, `staging`, `dev`, `test` | Cost allocation by environment | +| `cost-center` | `` | Chargeback / showback | +| `workload` | `` | Resource grouping | +| `owner` | `` | Accountability | +| `expiry-date` | `YYYY-MM-DD` | Auto-cleanup governance | + +### Budget alert policy + +- **Monthly budget threshold:** +- **Alert at 80%:** Notify +- **Alert at 100%:** Notify +- **Forecasted overage alert:** 110% threshold + +### Optimization backlog (prioritized) + +1. **** — saves ~$/month — effort: +2. **** — saves ~$/month — effort: +3. **** — saves ~$/month — effort: + +### References + +- +- + +### Next steps + +1. **Practice:** Run `Get-CopilotMetricsReport.ps1` to baseline your current Copilot seat utilization before committing to a license tier. +2. **Deep dive:** Review the Azure Well-Architected Framework Cost Optimization checklist at `https://learn.microsoft.com/azure/well-architected/cost-optimization/checklist`. +3. **Real-world application:** Create a budget alert in the Azure portal for your highest-cost resource group and configure an action group to notify your team. +``` diff --git a/Get-CopilotMetricsReport.ps1 b/Get-CopilotMetricsReport.ps1 new file mode 100644 index 0000000..5c74813 --- /dev/null +++ b/Get-CopilotMetricsReport.ps1 @@ -0,0 +1,222 @@ +<# +.SYNOPSIS + Retrieves GitHub Copilot usage metrics for an organization and outputs a formatted report. +.DESCRIPTION + Calls the GitHub Copilot Metrics API to collect seat usage, active user counts, + acceptance rates, and language-level breakdowns. Outputs a human-readable Markdown + report and optionally exports raw data to JSON. +.PARAMETER OrgName + The GitHub organization login name (for example, "timothywarner-org"). +.PARAMETER OutputPath + Optional. Path for the Markdown report file. Defaults to "copilot-metrics-report.md" + in the current directory. +.PARAMETER JsonOutputPath + Optional. Path for the raw JSON export. If omitted, JSON is not exported. +.PARAMETER DaysBack + Number of days of historical data to request. Valid range: 1-28. Default: 28. +.EXAMPLE + .\Get-CopilotMetricsReport.ps1 -OrgName "timothywarner-org" +.EXAMPLE + .\Get-CopilotMetricsReport.ps1 -OrgName "fabrikam" -DaysBack 7 -JsonOutputPath ".\raw.json" +.NOTES + Requires: PowerShell 7+ + Requires: A GitHub token with the `manage_billing:copilot` or `read:org` scope + stored in the GITHUB_TOKEN environment variable. + API reference: https://docs.github.com/rest/copilot/copilot-metrics +#> +#Requires -Version 7.0 + +[CmdletBinding()] +param( + [Parameter(Mandatory)] + [ValidateNotNullOrEmpty()] + [string]$OrgName, + + [Parameter()] + [string]$OutputPath = "copilot-metrics-report.md", + + [Parameter()] + [string]$JsonOutputPath, + + [Parameter()] + [ValidateRange(1, 28)] + [int]$DaysBack = 28 +) + +Set-StrictMode -Version Latest +$ErrorActionPreference = 'Stop' + +#region Helpers + +function Get-GitHubHeaders { + [CmdletBinding()] + param() + + if (-not $env:GITHUB_TOKEN) { + throw "GITHUB_TOKEN environment variable is not set. Export a token with 'manage_billing:copilot' scope." + } + + return @{ + 'Authorization' = "Bearer $env:GITHUB_TOKEN" + 'Accept' = 'application/vnd.github+json' + 'X-GitHub-Api-Version' = '2022-11-28' + } +} + +function Invoke-GitHubApi { + [CmdletBinding()] + param( + [Parameter(Mandatory)] + [string]$Uri, + + [Parameter(Mandatory)] + [hashtable]$Headers + ) + + try { + Write-Verbose "GET $Uri" + $response = Invoke-RestMethod -Uri $Uri -Headers $Headers -Method Get -ErrorAction Stop + return $response + } + catch { + Write-Error "GitHub API request failed for '$Uri': $_" + throw + } +} + +function Format-Percentage { + [CmdletBinding()] + param([double]$Value) + return "{0:P1}" -f ($Value / 100) +} + +#endregion + +#region Main + +Write-Verbose "Fetching Copilot metrics for org: $OrgName (last $DaysBack days)" + +$headers = Get-GitHubHeaders + +# Seat billing summary +$seatUri = "https://api.github.com/orgs/$OrgName/copilot/billing" +$seatData = Invoke-GitHubApi -Uri $seatUri -Headers $headers + +# Usage metrics (daily breakdown) +$since = (Get-Date).AddDays(-$DaysBack).ToString("yyyy-MM-dd") +$metricsUri = "https://api.github.com/orgs/$OrgName/copilot/metrics?since=$since" +$metricsData = Invoke-GitHubApi -Uri $metricsUri -Headers $headers + +# Export raw JSON if requested +if ($JsonOutputPath) { + $combined = @{ + retrieved_at = (Get-Date -Format o) + org = $OrgName + billing = $seatData + metrics = $metricsData + } + $combined | ConvertTo-Json -Depth 10 | Set-Content -Path $JsonOutputPath -Encoding UTF8 + Write-Verbose "Raw JSON written to $JsonOutputPath" +} + +# Aggregate metrics +$totalDays = $metricsData.Count +$totalSuggestions = ($metricsData | Measure-Object -Property total_suggestions_count -Sum).Sum +$totalAcceptances = ($metricsData | Measure-Object -Property total_acceptances_count -Sum).Sum +$avgActiveUsers = if ($totalDays -gt 0) { + [math]::Round(($metricsData | Measure-Object -Property total_active_users -Average).Average, 1) +} else { 0 } + +$overallAcceptanceRate = if ($totalSuggestions -gt 0) { + [math]::Round(($totalAcceptances / $totalSuggestions) * 100, 1) +} else { 0 } + +# Language breakdown (aggregate across all days) +$langMap = @{} +foreach ($day in $metricsData) { + if ($day.breakdown) { + foreach ($entry in $day.breakdown) { + $lang = $entry.language + if (-not $langMap.ContainsKey($lang)) { + $langMap[$lang] = @{ suggestions = 0; acceptances = 0 } + } + $langMap[$lang].suggestions += $entry.suggestions_count + $langMap[$lang].acceptances += $entry.acceptances_count + } + } +} + +$topLanguages = $langMap.GetEnumerator() | + Sort-Object { $_.Value.suggestions } -Descending | + Select-Object -First 10 + +# Build Markdown report +$reportDate = Get-Date -Format "yyyy-MM-dd HH:mm UTC" +$sb = [System.Text.StringBuilder]::new() + +$null = $sb.AppendLine("# GitHub Copilot Metrics Report") +$null = $sb.AppendLine() +$null = $sb.AppendLine("**Organization:** $OrgName") +$null = $sb.AppendLine("**Report generated:** $reportDate") +$null = $sb.AppendLine("**Period:** last $DaysBack days ($totalDays data points)") +$null = $sb.AppendLine() +$null = $sb.AppendLine("---") +$null = $sb.AppendLine() +$null = $sb.AppendLine("## Seat summary") +$null = $sb.AppendLine() +$null = $sb.AppendLine("| Metric | Value |") +$null = $sb.AppendLine("|--------|-------|") +$null = $sb.AppendLine("| Total seats (billed) | $($seatData.total_seats) |") +$null = $sb.AppendLine("| Active seats (last cycle) | $($seatData.seat_breakdown.active_this_cycle) |") +$null = $sb.AppendLine("| Inactive seats | $($seatData.seat_breakdown.inactive_this_cycle) |") +$null = $sb.AppendLine("| Plan type | $($seatData.plan_type) |") +$null = $sb.AppendLine() +$null = $sb.AppendLine("## Usage summary ($DaysBack-day window)") +$null = $sb.AppendLine() +$null = $sb.AppendLine("| Metric | Value |") +$null = $sb.AppendLine("|--------|-------|") +$null = $sb.AppendLine("| Average daily active users | $avgActiveUsers |") +$null = $sb.AppendLine("| Total suggestions | $totalSuggestions |") +$null = $sb.AppendLine("| Total acceptances | $totalAcceptances |") +$null = $sb.AppendLine("| Overall acceptance rate | $overallAcceptanceRate% |") +$null = $sb.AppendLine() +$null = $sb.AppendLine("## Top languages by suggestion volume") +$null = $sb.AppendLine() +$null = $sb.AppendLine("| Language | Suggestions | Acceptances | Acceptance rate |") +$null = $sb.AppendLine("|----------|-------------|-------------|-----------------|") + +foreach ($lang in $topLanguages) { + $rate = if ($lang.Value.suggestions -gt 0) { + [math]::Round(($lang.Value.acceptances / $lang.Value.suggestions) * 100, 1) + } else { 0 } + $null = $sb.AppendLine("| $($lang.Key) | $($lang.Value.suggestions) | $($lang.Value.acceptances) | $rate% |") +} + +$null = $sb.AppendLine() +$null = $sb.AppendLine("---") +$null = $sb.AppendLine() +$null = $sb.AppendLine("## Notes") +$null = $sb.AppendLine() +$null = $sb.AppendLine("- Metrics are collected via the [GitHub Copilot Metrics API](https://docs.github.com/rest/copilot/copilot-metrics).") +$null = $sb.AppendLine("- Active users = users who received at least one suggestion in the period.") +$null = $sb.AppendLine("- Acceptance rate = accepted suggestions / total suggestions shown.") +$null = $sb.AppendLine("- Data availability: GitHub retains up to 28 days of metrics data.") + +$report = $sb.ToString() + +# Write report to file +Set-Content -Path $OutputPath -Value $report -Encoding UTF8 +Write-Output "Report written to: $OutputPath" + +# Also print summary to console +Write-Output "" +Write-Output "=== Copilot Metrics Summary for $OrgName ===" +Write-Output " Total seats: $($seatData.total_seats)" +Write-Output " Active seats: $($seatData.seat_breakdown.active_this_cycle)" +Write-Output " Avg daily users: $avgActiveUsers" +Write-Output " Acceptance rate: $overallAcceptanceRate%" +Write-Output " Total suggestions: $totalSuggestions" +Write-Output " Total acceptances: $totalAcceptances" +Write-Output "" + +#endregion diff --git a/docs/copilot-metrics-report-sample.md b/docs/copilot-metrics-report-sample.md new file mode 100644 index 0000000..df19ade --- /dev/null +++ b/docs/copilot-metrics-report-sample.md @@ -0,0 +1,125 @@ +# GitHub Copilot Metrics Report — Sample Output + +This document shows sample output from `Get-CopilotMetricsReport.ps1` run against a fictional +organization. Use it as a reference when interpreting your own report or when demonstrating +the script during live class sessions. + +--- + +## How to run the script + +```powershell +# 1. Set your GitHub token (needs manage_billing:copilot or read:org scope) +$env:GITHUB_TOKEN = "ghp_yourTokenHere" + +# 2. Run the report for your org +.\Get-CopilotMetricsReport.ps1 -OrgName "your-org" -DaysBack 28 + +# 3. Optionally export raw JSON alongside the Markdown report +.\Get-CopilotMetricsReport.ps1 -OrgName "your-org" -JsonOutputPath ".\raw-metrics.json" +``` + +The script writes a Markdown file (`copilot-metrics-report.md` by default) and prints a +summary table to the console. + +--- + +## Sample report (fictional data — Fabrikam Industrial) + +> **Note:** All numbers below are invented for teaching purposes. + +--- + +# GitHub Copilot Metrics Report + +**Organization:** fabrikam-industrial +**Report generated:** 2026-04-28 14:35 UTC +**Period:** last 28 days (28 data points) + +--- + +## Seat summary + +| Metric | Value | +|--------|-------| +| Total seats (billed) | 250 | +| Active seats (last cycle) | 198 | +| Inactive seats | 52 | +| Plan type | GitHub Copilot Business | + +## Usage summary (28-day window) + +| Metric | Value | +|--------|-------| +| Average daily active users | 143.6 | +| Total suggestions | 187,420 | +| Total acceptances | 98,304 | +| Overall acceptance rate | 52.5% | + +## Top languages by suggestion volume + +| Language | Suggestions | Acceptances | Acceptance rate | +|----------|-------------|-------------|-----------------| +| TypeScript | 54,210 | 31,842 | 58.7% | +| Python | 42,880 | 23,584 | 55.0% | +| C# | 28,415 | 14,776 | 52.0% | +| JavaScript | 21,003 | 9,871 | 47.0% | +| PowerShell | 14,672 | 7,804 | 53.2% | +| Bicep | 9,340 | 5,230 | 56.0% | +| Go | 7,200 | 3,456 | 48.0% | +| Java | 4,800 | 2,160 | 45.0% | +| YAML | 3,900 | 1,521 | 39.0% | +| Markdown | 1,000 | 60 | 6.0% | + +--- + +## Notes + +- Metrics are collected via the [GitHub Copilot Metrics API](https://docs.github.com/rest/copilot/copilot-metrics). +- Active users = users who received at least one suggestion in the period. +- Acceptance rate = accepted suggestions / total suggestions shown. +- Data availability: GitHub retains up to 28 days of metrics data. + +--- + +## Interpreting the report + +### Seat utilization + +Fabrikam Industrial has 250 billed seats but only 198 active this cycle — a **79% utilization +rate**. The 52 inactive seats represent ~$1,976/month in unused spend (at ~$38/seat/month for +Copilot Business). Actions to consider: + +1. Reclaim inactive seats for developers who have not logged in for 30+ days. +2. Use the GitHub admin UI (**Settings > Copilot > Seat management**) to review last-activity dates. +3. Set up a monthly review cadence using this script piped into a GitHub Actions workflow. + +### Acceptance rate + +A 52.5% overall acceptance rate is **above industry average** (typical range: 30–50%). This +indicates that developers are receiving high-quality, contextually relevant suggestions. + +Language-specific observations: + +- **TypeScript (58.7%)** and **Bicep (56.0%)** are the highest performers — likely because + these code bases have rich context (type annotations, schema files) that Copilot uses for + grounding. +- **Markdown (6.0%)** is expected to be low; prose suggestions are harder to accept verbatim + than code completions. +- **YAML (39.0%)** may improve with better `.github/copilot-instructions.md` context about + pipeline patterns. + +### FinOps connection + +Pair this report with the **azure-cost-management** skill to cross-reference Copilot seat +spend against Azure infrastructure cost trends. A high acceptance rate in Bicep and PowerShell +typically correlates with faster IaC delivery and fewer manual Azure portal changes. + +--- + +## Related resources + +- [GitHub Copilot Metrics API reference](https://docs.github.com/rest/copilot/copilot-metrics) +- [Manage GitHub Copilot seats](https://docs.github.com/copilot/managing-copilot/managing-github-copilot-in-your-organization/managing-access-for-copilot-in-your-organization) +- [GitHub Copilot Business pricing](https://docs.github.com/billing/managing-billing-for-github-copilot/about-billing-for-github-copilot) +- [Azure Well-Architected Framework — Operational Excellence](https://learn.microsoft.com/azure/well-architected/operational-excellence/) diff --git a/prompt.md b/prompt.md new file mode 100644 index 0000000..dc5e79c --- /dev/null +++ b/prompt.md @@ -0,0 +1,52 @@ +--- +name: azure-architecture-review +description: "Review or draft an Azure architecture for a given workload, applying Well-Architected Framework pillars and cost optimization guidance." +argument-hint: "workload='3-tier web app' region='East US' budget='$5000/month'" +agent: azure-architect +tools: + - codebase + - editFiles + - fileSearch +--- + +# Azure Architecture Review and Design Prompt + +Use this prompt to ask the **azure-architect** agent to design or review an Azure workload +architecture. The agent will apply all five Azure Well-Architected Framework pillars and +invoke the **azure-cost-management** skill for cost estimation. + +## Inputs + +- **Workload type:** ${input:workload:Describe the workload (for example, "3-tier web app", "data pipeline", "microservices on AKS")} +- **Target region(s):** ${input:region:Primary Azure region (for example, "East US", "West Europe")} +- **Monthly budget:** ${input:budget:Approximate monthly spend target in USD (for example, "$5000/month")} +- **Scale requirements:** ${input:scale:Expected users or throughput (for example, "1000 concurrent users")} +- **Compliance requirements:** ${input:compliance:Any regulatory requirements (for example, "HIPAA", "PCI-DSS", or "none")} + +## What the agent will produce + +1. **Architecture diagram** (ASCII or Mermaid) showing the proposed topology. +2. **Component list** with recommended Azure services, SKUs, and rationale. +3. **Well-Architected review** covering all five pillars (Reliability, Security, Cost + Optimization, Operational Excellence, Performance Efficiency). +4. **Cost estimate** (monthly USD range) using current Azure pricing. +5. **IaC scaffolding** — a starter Bicep template for the core resources. +6. **Security considerations** — Zero Trust controls, private endpoints, Defender for Cloud. +7. **Next steps** — practice task, deep-dive topic, real-world application. + +## Grounding + +The agent grounds all recommendations in: + +- [Azure Architecture Center](https://learn.microsoft.com/azure/architecture/) +- [Azure Well-Architected Framework](https://learn.microsoft.com/azure/well-architected/) +- [Azure Cost Management](https://learn.microsoft.com/azure/cost-management-billing/) +- [Cloud Adoption Framework](https://learn.microsoft.com/azure/cloud-adoption-framework/) + +## Example usage + +``` +@azure-architect Design a hub-and-spoke network for Northwind Traders with 3 spoke VNets, +Azure Firewall Premium, and private DNS zones. Region: East US 2. Budget: $8,000/month. +Compliance: SOC 2 Type II. +``` diff --git a/src/app.js b/src/app.js index c0ee730..b6f90b1 100644 --- a/src/app.js +++ b/src/app.js @@ -179,7 +179,10 @@ class CopilotTipsApp { 'Enterprise': colors.blue, 'Debugging': colors.red, 'AI Features': colors.cyan, - 'MCP': colors.magenta + 'MCP': colors.magenta, + 'Azure': colors.blue, + 'FinOps': colors.green, + 'IaC': colors.magenta }; const categoryColor = categoryColors[tip.category] || colors.gray; @@ -343,7 +346,10 @@ class CopilotTipsApp { 'Documentation': '📖', 'Automation': '⚙️', 'Code Quality': '✨', - 'Workflow': '🔄' + 'Workflow': '🔄', + 'Azure': '☁️', + 'FinOps': '💰', + 'IaC': '🏗️' }; return emojis[category] || '📌'; }