Claude-skill-registry azure-deploy
Deploy Azure infrastructure, BFF API, Static Web Apps, and configure App Service settings
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/azure-deploy" ~/.claude/skills/majiayu000-claude-skill-registry-azure-deploy && rm -rf "$T"
skills/data/azure-deploy/SKILL.mdAzure Deploy
Category: Operations Last Updated: January 2026
Quick Reference
| Deployment Type | Tool | Skill/Guide |
|---|---|---|
| Azure Infrastructure | Azure CLI + Bicep | This skill |
| BFF API | Azure CLI / GitHub Actions | This skill |
| Office Add-ins / SWA | SWA CLI + PowerShell | This skill |
| Dataverse/PCF | PAC CLI | Use skill |
| Solution Import | PAC CLI | Use skill |
For Dataverse deployments (PCF, solutions, web resources): Use the
dataverse-deploy skill instead.
Prerequisites
Required Tools
# Verify installations az --version # Azure CLI 2.50+ az bicep version # Bicep CLI 0.39+ dotnet --version # .NET SDK 8.0+
Required Access
| Resource | Access Level |
|---|---|
| Azure Subscription | Contributor role |
| Azure AD | Application Administrator (for app registrations) |
Authentication
# Login to Azure az login # Set subscription az account set --subscription "Spaarke SPE Subscription 1" # Verify az account show --query "{Name:name, Id:id}" -o table
Environment Reference
Subscriptions & Resource Groups
| Environment | Subscription | Resource Group |
|---|---|---|
| Dev | Spaarke SPE Subscription 1 | |
| Prod | (TBD) | |
Azure Resource Endpoints (Dev)
| Service | Endpoint |
|---|---|
| BFF API | |
| Azure OpenAI | |
| AI Search | |
| Document Intelligence | |
| Key Vault | |
| AI Foundry Hub | |
| AI Foundry Project | |
Key Vault Secrets
| Secret Name | Purpose |
|---|---|
| Azure OpenAI API key |
| AI Search admin key |
| Document Intelligence key |
| Redis connection string |
| Application Insights key |
Full environment reference: See
docs/guides/AZURE-DEPLOYMENT-GUIDE.md → Environment Configuration
Deployment Type 1: Azure Infrastructure (Bicep)
When to Use
- Creating new Azure resources
- Deploying AI Foundry stack
- Setting up customer environments
Bicep Stack Locations
| Stack | Path | Purpose |
|---|---|---|
| AI Foundry | | AI Hub, Project, Storage, KV |
| Model 1 Shared | | Shared infrastructure |
| Model 2 Full | | Full customer deployment |
Deploy Infrastructure
# Navigate to infrastructure directory cd infrastructure/bicep # Deploy AI Foundry stack az deployment group create ` --resource-group spe-infrastructure-westus2 ` --template-file stacks/ai-foundry-stack.bicep ` --parameters customerId=spaarke environment=dev location=westus2
Verify Deployment
# List deployed resources az resource list ` --resource-group spe-infrastructure-westus2 ` --output table
Expected Resources (AI Foundry Stack)
| Resource Type | Name Pattern | Purpose |
|---|---|---|
| Storage Account | | AI Foundry storage |
| Key Vault | | Secrets |
| Log Analytics | | Monitoring |
| App Insights | | APM |
| ML Workspace (Hub) | | AI Foundry Hub |
| ML Workspace (Project) | | AI Foundry Project |
Deployment Type 2: BFF API (App Service)
When to Use
- Deploying API code changes
- Updating App Service configuration
- Publishing new API version
Build API
# Build release cd src/server/api/Sprk.Bff.Api dotnet publish -c Release -o ./publish # Or use publish profile dotnet publish -c Release /p:PublishProfile=Azure
Deploy to App Service
Option A: Deployment Script (Recommended for Dev)
Use the deployment script - handles build, package, deploy, and verification:
# Full build and deploy (~1 min) .\scripts\Deploy-BffApi.ps1 # Deploy existing build (faster, ~30 sec) .\scripts\Deploy-BffApi.ps1 -SkipBuild
What the script does:
- Builds the API in Release mode (unless
)-SkipBuild - Creates deployment zip package
- Deploys via Azure CLI
- Waits for app restart
- Verifies health check passes
Option A-alt: Manual Azure CLI
If you need to run steps manually:
# Build and package cd src/server/api/Sprk.Bff.Api dotnet publish -c Release -o ./publish Compress-Archive -Path './publish/*' -DestinationPath './publish.zip' -Force # Deploy az webapp deploy ` --resource-group spe-infrastructure-westus2 ` --name spe-api-dev-67e2xz ` --src-path ./publish.zip ` --type zip # Verify deployment took effect curl https://spe-api-dev-67e2xz.azurewebsites.net/healthz
Option B: GitHub Actions (Production Releases)
Use for production deployments - push to master triggers automated deployment:
# Merge to master triggers deploy-staging.yml git push origin master # Monitor deployment gh run list --workflow=deploy-staging.yml --limit 3 gh run watch
See
.github/workflows/deploy-staging.yml for configuration.
Option C: Kudu Zip Push Deploy (Troubleshooting Fallback)
Use when CLI deploy reports success but app still runs old code:
- Go to Azure Portal → App Services →
spe-api-dev-67e2xz - Click Advanced Tools → Go (opens Kudu)
- Click Tools → Zip Push Deploy
- Drag and drop
onto the pagepublish.zip - Verify new entry appears in Deployment Center logs
Note: This is a rare fallback. If CLI deploys consistently fail to update the app, check Deployment Center logs first.
Configure App Settings
# Set individual setting az webapp config appsettings set ` --resource-group spe-infrastructure-westus2 ` --name spe-api-dev-67e2xz ` --settings Ai__Enabled=true # Set multiple settings from file az webapp config appsettings set ` --resource-group spe-infrastructure-westus2 ` --name spe-api-dev-67e2xz ` --settings @appsettings.json
Required App Settings
| Setting | Example Value |
|---|---|
| |
| |
| |
| |
| |
| |
Full settings reference: See
docs/guides/AZURE-DEPLOYMENT-GUIDE.md → BFF API App Settings
Deployment Type 3: Office Add-ins (Static Web App)
When to Use
- Deploying Office Add-in changes (Outlook, Word)
- Updating taskpane UI or manifest
- Dev iteration on add-in features
Resource Reference
| Resource | Value |
|---|---|
| Static Web App Name | |
| Resource Group | |
| URL | |
| Source Directory | |
| Dist Directory | |
Dev Deployment (Recommended for Iteration)
Use the deployment script - handles all the complexity:
# Full build and deploy .\scripts\Deploy-OfficeAddins.ps1 # Skip build (use existing dist) .\scripts\Deploy-OfficeAddins.ps1 -SkipBuild # Deploy to preview environment .\scripts\Deploy-OfficeAddins.ps1 -Environment preview # Verbose output .\scripts\Deploy-OfficeAddins.ps1 -Verbose
What the script does:
- Builds webpack production bundle (unless
)-SkipBuild - Gets fresh deployment token from Azure
- Deploys using SWA CLI with spinner workaround
- Verifies deployment and shows manifest version
Manual Deployment (Alternative)
If you need to run steps manually:
# Navigate to office-addins directory cd src/client/office-addins # 1. Build production bundle npx webpack --mode production # 2. Get fresh deployment token (tokens can expire/rotate) $token = az staticwebapp secrets list ` --name spaarke-office-addins ` --resource-group spe-infrastructure-westus2 ` --query properties.apiKey -o tsv # 3. Deploy with output to log file (avoids spinner hanging issue) Start-Process -FilePath 'powershell.exe' ` -ArgumentList "-NoProfile","-Command","npx swa deploy ./dist --deployment-token $token --env production *> deploy.log" ` -NoNewWindow -Wait # 4. Check deployment result Get-Content deploy.log # 5. Verify deployment (use cache-busting param) curl "https://icy-desert-0bfdbb61e.6.azurestaticapps.net/outlook/manifest.xml?v=$(Get-Date -Format 'HHmmss')"
Why Direct Deploy Instead of GitHub Actions
| Aspect | Direct Deploy | GitHub Actions |
|---|---|---|
| Speed | ~30 seconds | 2-5 minutes (CI + deploy) |
| Requires PR | No | Yes (merge to master) |
| Best for | Dev iteration, debugging | Production releases |
| Token | Fresh each time | Stored in secrets |
Use Direct Deploy when:
- Testing UI changes
- Debugging add-in issues
- Rapid iteration cycles
- Any work that doesn't need PR review
Use GitHub Actions when:
- Ready for production release
- Changes have been code-reviewed
- Want deployment audit trail
Troubleshooting SWA Deployment
| Issue | Cause | Solution |
|---|---|---|
| Spinner hangs forever | SWA CLI spinner blocks output | Use with log redirect |
| Old token rejected | Tokens rotate periodically | Get fresh token via |
| Deployment succeeds but old content | CDN caching | Add to verify, wait 1-2 min |
| 404 on deployed files | Wrong dist path | Verify contains expected files |
Manifest Upload After Deploy
After deploying code changes, if manifest changed:
- Download manifest:
https://icy-desert-0bfdbb61e.6.azurestaticapps.net/outlook/manifest.xml - Upload to M365 Admin Center → Integrated Apps → Upload custom app
- Wait 5-15 minutes for propagation to Outlook clients
Note: Manifest version must be incremented (e.g., 1.0.1.0 → 1.0.2.0) for M365 to accept updates.
Deployment Type 4: Key Vault Secrets
Store Secrets
# Store OpenAI API key az keyvault secret set ` --vault-name sprkspaarkedev-aif-kv ` --name openai-api-key ` --value "YOUR-API-KEY" # Store from Azure resource (auto-retrieve) az keyvault secret set ` --vault-name sprkspaarkedev-aif-kv ` --name openai-api-key ` --value "$(az cognitiveservices account keys list --name spaarke-openai-dev --resource-group spe-infrastructure-westus2 --query key1 -o tsv)"
Retrieve Secrets
# Get secret value az keyvault secret show ` --vault-name sprkspaarkedev-aif-kv ` --name openai-api-key ` --query value -o tsv
Verification Procedures
API Health Check
# Check API is running curl https://spe-api-dev-67e2xz.azurewebsites.net/healthz # Expected: "Healthy" curl https://spe-api-dev-67e2xz.azurewebsites.net/ping # Expected: "pong"
Azure Resource Verification
# List resources in resource group az resource list --resource-group spe-infrastructure-westus2 -o table # Check specific resource az webapp show --name spe-api-dev-67e2xz --resource-group spe-infrastructure-westus2 --query state
AI Services Verification
# Check OpenAI deployments az cognitiveservices account deployment list ` --name spaarke-openai-dev ` --resource-group spe-infrastructure-westus2 ` -o table # Check AI Search index az search index list ` --service-name spaarke-search-dev ` --resource-group spe-infrastructure-westus2 ` -o table
Error Handling
| Error | Cause | Solution |
|---|---|---|
| Insufficient permissions | Verify Contributor role on subscription |
| Wrong resource group or name | Check resource names in Environment Reference |
| Bicep template error | Check for details |
| Missing Key Vault policy | Add access policy for your identity |
| API not started | Check Application Insights logs |
after deploy | DI scope mismatch or startup error | Check response body for error details |
| CLI deploy succeeds but old code runs | Deployment didn't register | Check Deployment Center logs; use Kudu as fallback |
Deployment Not Taking Effect (Rare)
Symptom:
az webapp deploy reports success, but the API still runs old code.
Diagnosis:
- Check Deployment Center → Logs in Azure Portal
- If no new entry with current timestamp, deployment didn't register
Solution (in order of preference):
- Restart the App Service - sometimes forces reload of new deployment
- Try alternative CLI command:
az webapp deployment source config-zip - Use Kudu Zip Push Deploy as manual fallback (see Option C above)
- After any method, verify with
curl https://{app}.azurewebsites.net/healthz
Root Cause: This is rare and may indicate Azure-side caching or deployment slot issues. For consistent deployments, use GitHub Actions (Option A).
Check Deployment Logs
# API logs (streaming) az webapp log tail --name spe-api-dev-67e2xz --resource-group spe-infrastructure-westus2 # Deployment logs az webapp log deployment show --name spe-api-dev-67e2xz --resource-group spe-infrastructure-westus2
Naming Conventions
| Resource Type | Pattern | Example |
|---|---|---|
| Resource Group | | |
| App Service | | |
| Key Vault | | |
| Storage Account | | |
| Azure OpenAI | | |
| AI Search | | |
Full naming conventions: See
docs/architecture/AZURE-RESOURCE-NAMING-CONVENTION.md
Related Skills
| Skill | Use For |
|---|---|
| Dataverse solutions, PCF controls, web resources |
| Ribbon customizations (uses solution export/import) |
| CI/CD pipeline status and automated deployment workflows |
CI/CD Integration
Automated Deployments via GitHub Actions
This skill documents manual Azure deployments. For automated deployments, see the GitHub Actions workflows:
| Workflow | Trigger | What It Deploys |
|---|---|---|
| Auto (after CI passes on master) | API to staging App Service |
| Manual trigger | Infrastructure (Bicep) + API to production |
When to Use Manual vs Automated
| Scenario | Use |
|---|---|
| Regular code deployments | Automated ( after merge to master) |
| Production deployment | Automated ( manual trigger) |
| Emergency hotfix | Manual deployment (this skill) |
| Infrastructure changes only | Manual deployment (this skill) |
| Debugging deployment issues | Manual deployment (this skill) |
Trigger Automated Deployment
# Trigger production deployment manually gh workflow run deploy-to-azure.yml # Monitor deployment progress gh run watch # View deployment status gh run list --workflow=deploy-to-azure.yml --limit 5
Check Deployment Status
# View recent deployments gh run list --workflow=deploy-to-azure.yml # View specific run details gh run view {run-id} # Download deployment artifacts gh run download {run-id}
Related Documentation
| Document | Purpose |
|---|---|
| Comprehensive deployment reference |
| Customer-facing setup guide |
| Naming standards |
Tips for AI
- Avoid discovery queries - Use endpoint values from Environment Reference above
- Operational commands OK - Deployments, secret management, configuration are permitted
- For Dataverse - Always use
skill instead of this onedataverse-deploy - Check health first - Before troubleshooting, verify
endpoint/healthz - Key Vault references - Use
syntax in App Settings@Microsoft.KeyVault(SecretUri=...) - Dev deploys - Use deployment scripts for quick iteration; GitHub Actions for production releases
- Verify deployments - After manual deploy, check
and Deployment Center logs/healthz - If CLI deploy fails silently - Try restart first, then Kudu as last resort
Deployment Scripts (Preferred for Dev)
| Component | Script | Usage |
|---|---|---|
| BFF API | | Full build+deploy in ~1 min |
| Office Add-ins | | Full build+deploy in ~30 sec |
Both scripts support
-SkipBuild flag to deploy existing builds faster.
- 500 errors after deploy - Check
response body for DI scope or startup errors/healthz
Office Add-ins Specific
- Use the script - Always use
for SWA deployments.\scripts\Deploy-OfficeAddins.ps1 - SWA CLI spinner issue - The script handles this; don't run
directly from bashnpx swa deploy - Fresh tokens - The script gets a fresh token each time; manual deploys should do the same
- CDN caching - After deploy, use
parameter to verify new content?v=timestamp - Manifest changes - After deploying manifest changes, remind user to upload to M365 Admin Center
- Version bumping - Manifest version must be incremented for M365 to accept updates