Claude-skill-registry azure-deploy

Deploy Azure infrastructure, BFF API, Static Web Apps, and configure App Service settings

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
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"
manifest: skills/data/azure-deploy/SKILL.md
source content

Azure Deploy

Category: Operations Last Updated: January 2026


Quick Reference

Deployment TypeToolSkill/Guide
Azure InfrastructureAzure CLI + BicepThis skill
BFF APIAzure CLI / GitHub ActionsThis skill
Office Add-ins / SWASWA CLI + PowerShellThis skill
Dataverse/PCFPAC CLIUse
dataverse-deploy
skill
Solution ImportPAC CLIUse
dataverse-deploy
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

ResourceAccess Level
Azure SubscriptionContributor role
Azure ADApplication 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

EnvironmentSubscriptionResource Group
DevSpaarke SPE Subscription 1
spe-infrastructure-westus2
Prod(TBD)
rg-spaarke-{customer}-prod

Azure Resource Endpoints (Dev)

ServiceEndpoint
BFF API
https://spe-api-dev-67e2xz.azurewebsites.net
Azure OpenAI
https://spaarke-openai-dev.openai.azure.com/
AI Search
https://spaarke-search-dev.search.windows.net/
Document Intelligence
https://westus2.api.cognitive.microsoft.com/
Key Vault
https://sprkspaarkedev-aif-kv.vault.azure.net/
AI Foundry Hub
sprkspaarkedev-aif-hub
AI Foundry Project
sprkspaarkedev-aif-proj

Key Vault Secrets

Secret NamePurpose
openai-api-key
Azure OpenAI API key
search-admin-key
AI Search admin key
docintel-api-key
Document Intelligence key
redis-connection
Redis connection string
appinsights-key
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

StackPathPurpose
AI Foundry
infrastructure/bicep/stacks/ai-foundry-stack.bicep
AI Hub, Project, Storage, KV
Model 1 Shared
infrastructure/bicep/stacks/model1-shared.bicep
Shared infrastructure
Model 2 Full
infrastructure/bicep/stacks/model2-full.bicep
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 TypeName PatternPurpose
Storage Account
sprk{customer}{env}aifsa
AI Foundry storage
Key Vault
sprk{customer}{env}-aif-kv
Secrets
Log Analytics
sprk{customer}{env}-aif-logs
Monitoring
App Insights
sprk{customer}{env}-aif-insights
APM
ML Workspace (Hub)
sprk{customer}{env}-aif-hub
AI Foundry Hub
ML Workspace (Project)
sprk{customer}{env}-aif-proj
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:

  1. Builds the API in Release mode (unless
    -SkipBuild
    )
  2. Creates deployment zip package
  3. Deploys via Azure CLI
  4. Waits for app restart
  5. 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:

  1. Go to Azure PortalApp Services
    spe-api-dev-67e2xz
  2. Click Advanced ToolsGo (opens Kudu)
  3. Click ToolsZip Push Deploy
  4. Drag and drop
    publish.zip
    onto the page
  5. 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

SettingExample Value
Ai__Enabled
true
Ai__OpenAiEndpoint
https://spaarke-openai-dev.openai.azure.com/
Ai__OpenAiKey
@Microsoft.KeyVault(...)
Ai__SummarizeModel
gpt-4o-mini
DocumentIntelligence__Enabled
true
DocumentIntelligence__AiSearchEndpoint
https://spaarke-search-dev.search.windows.net

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

ResourceValue
Static Web App Name
spaarke-office-addins
Resource Group
spe-infrastructure-westus2
URL
https://icy-desert-0bfdbb61e.6.azurestaticapps.net
Source Directory
src/client/office-addins
Dist Directory
src/client/office-addins/dist

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:

  1. Builds webpack production bundle (unless
    -SkipBuild
    )
  2. Gets fresh deployment token from Azure
  3. Deploys using SWA CLI with spinner workaround
  4. 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

AspectDirect DeployGitHub Actions
Speed~30 seconds2-5 minutes (CI + deploy)
Requires PRNoYes (merge to master)
Best forDev iteration, debuggingProduction releases
TokenFresh each timeStored 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

IssueCauseSolution
Spinner hangs foreverSWA CLI spinner blocks outputUse
Start-Process
with log redirect
Old token rejectedTokens rotate periodicallyGet fresh token via
az staticwebapp secrets list
Deployment succeeds but old contentCDN cachingAdd
?v=timestamp
to verify, wait 1-2 min
404 on deployed filesWrong dist pathVerify
./dist
contains expected files

Manifest Upload After Deploy

After deploying code changes, if manifest changed:

  1. Download manifest:
    https://icy-desert-0bfdbb61e.6.azurestaticapps.net/outlook/manifest.xml
  2. Upload to M365 Admin Center → Integrated Apps → Upload custom app
  3. 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

ErrorCauseSolution
AuthorizationFailed
Insufficient permissionsVerify Contributor role on subscription
ResourceNotFound
Wrong resource group or nameCheck resource names in Environment Reference
DeploymentFailed
Bicep template errorCheck
az deployment group show --name {deployment}
for details
KeyVault access denied
Missing Key Vault policyAdd access policy for your identity
App Service 503
API not startedCheck Application Insights logs
App Service 500
after deploy
DI scope mismatch or startup errorCheck
/healthz
response body for error details
CLI deploy succeeds but old code runsDeployment didn't registerCheck 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:

  1. Check Deployment CenterLogs in Azure Portal
  2. If no new entry with current timestamp, deployment didn't register

Solution (in order of preference):

  1. Restart the App Service - sometimes forces reload of new deployment
  2. Try alternative CLI command:
    az webapp deployment source config-zip
  3. Use Kudu Zip Push Deploy as manual fallback (see Option C above)
  4. 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 TypePatternExample
Resource Group
rg-spaarke-{customer}-{env}
rg-spaarke-contoso-prod
App Service
sprk-{app}-{env}
sprk-bff-dev
Key Vault
sprk{customer}{env}-{purpose}-kv
sprkspaarkedev-aif-kv
Storage Account
sprk{customer}{env}sa
sprkspaarkedevsa
Azure OpenAI
spaarke-openai-{env}
spaarke-openai-dev
AI Search
spaarke-search-{env}
spaarke-search-dev

Full naming conventions: See

docs/architecture/AZURE-RESOURCE-NAMING-CONVENTION.md


Related Skills

SkillUse For
dataverse-deploy
Dataverse solutions, PCF controls, web resources
ribbon-edit
Ribbon customizations (uses solution export/import)
ci-cd
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:

WorkflowTriggerWhat It Deploys
deploy-staging.yml
Auto (after CI passes on master)API to staging App Service
deploy-to-azure.yml
Manual triggerInfrastructure (Bicep) + API to production

When to Use Manual vs Automated

ScenarioUse
Regular code deploymentsAutomated (
deploy-staging.yml
after merge to master)
Production deploymentAutomated (
deploy-to-azure.yml
manual trigger)
Emergency hotfixManual deployment (this skill)
Infrastructure changes onlyManual deployment (this skill)
Debugging deployment issuesManual 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

DocumentPurpose
docs/guides/AZURE-DEPLOYMENT-GUIDE.md
Comprehensive deployment reference
docs/guides/CUSTOMER-DEPLOYMENT-GUIDE.md
Customer-facing setup guide
docs/architecture/AZURE-RESOURCE-NAMING-CONVENTION.md
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
    dataverse-deploy
    skill instead of this one
  • Check health first - Before troubleshooting, verify
    /healthz
    endpoint
  • Key Vault references - Use
    @Microsoft.KeyVault(SecretUri=...)
    syntax in App Settings
  • Dev deploys - Use deployment scripts for quick iteration; GitHub Actions for production releases
  • Verify deployments - After manual deploy, check
    /healthz
    and Deployment Center logs
  • If CLI deploy fails silently - Try restart first, then Kudu as last resort

Deployment Scripts (Preferred for Dev)

ComponentScriptUsage
BFF API
.\scripts\Deploy-BffApi.ps1
Full build+deploy in ~1 min
Office Add-ins
.\scripts\Deploy-OfficeAddins.ps1
Full build+deploy in ~30 sec

Both scripts support

-SkipBuild
flag to deploy existing builds faster.

  • 500 errors after deploy - Check
    /healthz
    response body for DI scope or startup errors

Office Add-ins Specific

  • Use the script - Always use
    .\scripts\Deploy-OfficeAddins.ps1
    for SWA deployments
  • SWA CLI spinner issue - The script handles this; don't run
    npx swa deploy
    directly from bash
  • Fresh tokens - The script gets a fresh token each time; manual deploys should do the same
  • CDN caching - After deploy, use
    ?v=timestamp
    parameter to verify new content
  • 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