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 fb40deee..64d33817 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 2fb75662..ca9230a7 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 88af53cf..c7e89326 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 99f28e4e..5fc9411d 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 543e3cc0..80e5a2c8 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 fefdf3e4..73702f00 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 a5d8c81b..979b65b9 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 f77bdb21..8d6a4b16 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 d45253b3..bfc7d6ad 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 2fbebda3..49a4ca39 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 210e397e..a003ec54 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."_