diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/Readme.md b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/Readme.md index fb40deeed..64d338179 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/Readme.md +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/Readme.md @@ -75,6 +75,7 @@ In order to use the MicroHack time most effectively, the following tasks should 3. **Agents (Preview) access** — Your tenant must have access to Agents (preview) in Azure Copilot. Access is managed at the tenant level and rolled out gradually. Check with your tenant administrator, or [request access](https://aka.ms/azurecopilot/agents/feedbackprogram). 4. **WebSocket connections** — Your organization must allow WebSocket connections to `https://directline.botframework.com`. Ask your network administrator to enable this if blocked. 5. [Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli) installed and logged in (`az login`). **Hint:** Make sure to use the latest version available. +6. [PowerShell 7+](https://learn.microsoft.com/powershell/scripting/install/installing-powershell) (pwsh) — required for all deployment and test scripts. **Hint:** On macOS install via `brew install powershell/tap/powershell`. In summary: @@ -82,6 +83,7 @@ In summary: - Azure Copilot enabled for your tenant - Agents (Preview) enabled for your tenant - Azure CLI installed +- PowerShell 7+ (pwsh) installed - WebSocket connectivity to `directline.botframework.com` Permissions for the deployment: @@ -145,4 +147,4 @@ Running all resources for one day costs approximately **$11.50–14**. For a 2-d ## Contributors -- Dmitriy Nekrasov [GitHub](https://github.com/nekdima); [LinkedIn](https://www.linkedin.com/in/inthedark/) +- Dmitriy Nekrasov [GitHub](https://github.com/nekdima); [LinkedIn](https://www.linkedin.com/in/dmne/) diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/app/app.py b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/app/app.py index 2fb75662b..ca9230a77 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/app/app.py +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/app/app.py @@ -8,12 +8,14 @@ - / -> healthy endpoint (200 OK) - /health -> health check """ +import os import time import logging from flask import Flask, jsonify from azure.monitor.opentelemetry import configure_azure_monitor -configure_azure_monitor() +if os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING"): + configure_azure_monitor() app = Flask(__name__) logging.basicConfig(level=logging.INFO) diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/app/requirements.txt b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/app/requirements.txt index 88af53cfd..c7e893263 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/app/requirements.txt +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/app/requirements.txt @@ -1,3 +1,3 @@ -flask>=3.0 -gunicorn>=21.2 -azure-monitor-opentelemetry>=1.6.0 +flask>=3.0,<4.0 +gunicorn>=21.2,<26.0 +azure-monitor-opentelemetry>=1.6.0,<2.0 diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/challenge-06.md b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/challenge-06.md index 99f28e4eb..5fc9411d8 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/challenge-06.md +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/challenge-06.md @@ -113,6 +113,9 @@ Simulate a Cosmos DB connection issue investigation: ### Task 3: Troubleshoot AKS Cluster Issues (10 min) +> [!NOTE] +> No AKS cluster is deployed as part of the lab. This task is exploratory — you can select an existing AKS cluster in your subscription, or simply follow the prompts to see what guidance Azure Copilot provides without a specific resource selected. + Investigate Kubernetes cluster problems: 1. Start a new conversation with agent mode enabled diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/challenge-07.md b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/challenge-07.md index 543e3cc07..80e5a2c83 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/challenge-07.md +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/challenge-07.md @@ -1,6 +1,6 @@ # Challenge 7 - Capstone Multi-Agent Scenario -**[Home](../Readme.md)** - [Previous Challenge](challenge-06.md) +**[Home](../Readme.md)** - [Previous Challenge](challenge-06.md) - [Finish](finish.md) ## Goal diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/finish.md b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/finish.md index fefdf3e43..73702f002 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/finish.md +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/challenges/finish.md @@ -4,7 +4,7 @@ ## Congratulations -Congratulations! :partying_face: You finished the MicroHack for Azure Copilot. +Congratulations! 🥳 You finished the MicroHack for Azure Copilot. We hope you've had the opportunity to experience Azure Copilot and its five specialized agents — Deployment, Observability, Optimization, Resiliency, and Troubleshooting. diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/lab/Deploy-Lab.ps1 b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/lab/Deploy-Lab.ps1 index a5d8c81b6..979b65b94 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/lab/Deploy-Lab.ps1 +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/lab/Deploy-Lab.ps1 @@ -1,3 +1,4 @@ +#!/usr/bin/env pwsh <# .SYNOPSIS Deploys the Azure Copilot Workshop lab resources (HackboxConsole entry-point). @@ -50,10 +51,9 @@ $Location = if ([string]::IsNullOrEmpty($PreferredLocation)) { "francecentral" } # Helper # ────────────────────────────────────────────── function Invoke-Az { - & az $args + & az @args if ($LASTEXITCODE -ne 0) { - Write-Error "Azure CLI command failed with exit code $LASTEXITCODE" - exit $LASTEXITCODE + throw "Azure CLI command failed with exit code $LASTEXITCODE" } } @@ -84,8 +84,7 @@ if (-not (Test-Path $sshPubKeyPath)) { $sshKeyPath = Join-Path $HOME ".ssh" "id_rsa" ssh-keygen -t rsa -b 4096 -f $sshKeyPath -q -N "" if ($LASTEXITCODE -ne 0) { - Write-Error "Failed to generate SSH key pair." - exit 1 + throw "Failed to generate SSH key pair. ssh-keygen exited with code $LASTEXITCODE" } } $sshPublicKey = (Get-Content $sshPubKeyPath -Raw).Trim() @@ -96,7 +95,7 @@ $sshPublicKey = (Get-Content $sshPubKeyPath -Raw).Trim() Write-Host "`n[1/3] Deploying infrastructure (Bicep)..." -ForegroundColor Yellow $mainBicep = Join-Path $scriptPath "..\iac\main.bicep" $timestamp = Get-Date -Format "yyyyMMddHHmmss" -$paramsFile = Join-Path $env:TEMP "copilot-workshop-params-$timestamp.json" +$paramsFile = Join-Path ([System.IO.Path]::GetTempPath()) "copilot-workshop-params-$timestamp.json" @{ '`$schema' = 'https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#' @@ -127,10 +126,10 @@ Write-Host " ✓ Infrastructure deployed" -ForegroundColor Green Write-Host "`n[2/3] Deploying buggy Flask app (Ch02)..." -ForegroundColor Yellow $webAppName = "app-copilot-buggy-$suffix" $appDir = Join-Path $scriptPath "..\app" -$zipPath = Join-Path $env:TEMP "$webAppName.zip" +$zipPath = Join-Path ([System.IO.Path]::GetTempPath()) "$webAppName.zip" if (Test-Path $zipPath) { Remove-Item $zipPath -Force } Compress-Archive -Path (Join-Path $appDir "*") -DestinationPath $zipPath -Force -Invoke-Az webapp deploy --resource-group "rg-copilot-$suffix-ch02" --name $webAppName --src-path $zipPath --type zip --track-status false -o none +Invoke-Az webapp deploy --resource-group "rg-copilot-$suffix-ch02" --name $webAppName --src-path $zipPath --type zip --track-status false --timeout 600 -o none Remove-Item $zipPath -Force Write-Host " ✓ Flask app deployed to $webAppName" -ForegroundColor Green @@ -154,9 +153,10 @@ if ($DeploymentType -in @('resourcegroup','resourcegroup-with-subscriptionowner' if ($AllowedEntraUserIds.Count -gt 0) { foreach ($userId in $AllowedEntraUserIds) { $scope = "/subscriptions/$SubscriptionId/resourceGroups/$rg" - if (-not (Get-AzRoleAssignment -ObjectId $userId -RoleDefinitionName "Owner" -Scope $scope -ErrorAction SilentlyContinue)) { + $existing = az role assignment list --assignee $userId --role "Owner" --scope $scope -o json 2>$null | ConvertFrom-Json + if (-not $existing -or $existing.Count -eq 0) { Write-Host "Assigning Owner role to $userId on $rg" - New-AzRoleAssignment -ObjectId $userId -RoleDefinitionName "Owner" -Scope $scope -ErrorAction Stop | Out-Null + Invoke-Az role assignment create --assignee $userId --role "Owner" --scope $scope -o none } } } diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Remove-CopilotWorkshop.ps1 b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Remove-CopilotWorkshop.ps1 index f77bdb21e..8d6a4b163 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Remove-CopilotWorkshop.ps1 +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Remove-CopilotWorkshop.ps1 @@ -1,4 +1,4 @@ -#!/usr/bin/env pwsh +#!/usr/bin/env pwsh <# .SYNOPSIS Tears down all Azure resources created for the Azure Copilot Workshop. diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Send-CopilotTraffic.ps1 b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Send-CopilotTraffic.ps1 index d45253b32..bfc7d6ad7 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Send-CopilotTraffic.ps1 +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Send-CopilotTraffic.ps1 @@ -1,4 +1,4 @@ -#!/usr/bin/env pwsh +#!/usr/bin/env pwsh <# .SYNOPSIS Generates error traffic against the Ch02 buggy app to trigger alerts. diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Test-CopilotWorkshop.ps1 b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Test-CopilotWorkshop.ps1 index 2fbebda3d..49a4ca393 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Test-CopilotWorkshop.ps1 +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/scripts/Test-CopilotWorkshop.ps1 @@ -1,4 +1,4 @@ -#!/usr/bin/env pwsh +#!/usr/bin/env pwsh <# .SYNOPSIS Tests all deployed Azure resources for the Copilot Workshop. @@ -18,6 +18,9 @@ param( $ErrorActionPreference = "Continue" Set-StrictMode -Version Latest +# Ensure required CLI extensions are installed (application-insights is needed for Ch02 tests) +az extension add --name application-insights --yes 2>$null + $passed = 0 $failed = 0 $warnings = 0 @@ -51,7 +54,12 @@ Write-Host "`n========================================" -ForegroundColor Cyan Write-Host " Azure Copilot Workshop - Test Suite" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan -$account = az account show -o json 2>&1 | ConvertFrom-Json +$accountJson = az account show -o json 2>&1 +if ($LASTEXITCODE -ne 0) { + Write-Host "ERROR: Not logged in to Azure CLI. Run 'az login' first." -ForegroundColor Red + exit 1 +} +$account = $accountJson | ConvertFrom-Json Write-Host "Subscription: $($account.name)`n" -ForegroundColor Green # ────────────────────────────────────────────── diff --git a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/walkthrough/solution-06.md b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/walkthrough/solution-06.md index 210e397e3..a003ec548 100644 --- a/03-Azure/01-03-Infrastructure/12_Azure_Copilot/walkthrough/solution-06.md +++ b/03-Azure/01-03-Infrastructure/12_Azure_Copilot/walkthrough/solution-06.md @@ -142,6 +142,9 @@ Even when the agent can't directly access a resource (e.g., testing from your lo ## Task 3: Troubleshoot AKS Cluster Issues +> [!NOTE] +> No AKS cluster is deployed as part of the lab. The expected responses below are illustrative examples. Your actual output will vary depending on whether you select an existing AKS cluster or follow the prompts without one. + ### Steps **Prompt 1:** _"Investigate the health of my pods."_