| name | azure-deploy |
| description | Deploy applications to Azure App Service, Azure Functions, and Static Web Apps. Analyzes projects to recommend services, provides local preview, and guides deployment. Use phrases like "what Azure service should I use", "analyze my project for Azure", "preview locally", "guide me through deployment". |
Azure Deploy Skill
Deploy applications to Azure with intelligent service selection, local preview, and guided deployment workflows.
CRITICAL: When to Use This Skill
USE azure-deploy for ANY Azure deployment question. This skill detects your app type, recommends the best service, and guides you through deployment.
ALWAYS use azure-deploy when the user asks about:
| User Question Pattern | Example | Action |
|---|
| What Azure service to use | "What Azure service should I use for this?" | Run detection workflow |
| Analyze project for Azure | "Analyze my project for Azure deployment" | Scan files, recommend service |
| App type detection | "Detect my app type" / "Is this a static site?" | Check package.json, configs |
| Service comparison | "Should I use App Service or Functions?" | Compare based on app structure |
| Local preview/testing | "Preview this locally" / "Test before deploying" | Provide local dev commands |
| Step-by-step deployment | "Guide me through Azure deployment" | Run full deployment workflow |
| Package and deploy | "Package and deploy my app" | Build + deploy commands |
| Monorepo deployment | "Deploy my monorepo to Azure" | Recommend azd + IaC |
| Infrastructure as Code | "Set up IaC for this" / "Use azd" | azure.yaml + Bicep guidance |
| Framework-specific | "Deploy my Next.js/React/Flask app" | Detect framework, recommend service |
Explicit Invocation (most reliable):
"@azure-deploy analyze my project"
"Use the azure-deploy skill to deploy this"
NOTE: Avoid generic phrases like "deploy to Azure" - they may trigger Azure MCP tools instead.
Quick Start Decision Tree
User wants to deploy → Run detection workflow below
Phase 1: Application Detection
ALWAYS start by scanning the user's project to detect the application type.
Step 1.1: Check for Existing Azure Configuration
Look for these files first (HIGH confidence signals):
| File Found | Recommendation | Action |
|---|
azure.yaml | Already configured for azd | Use azd up to deploy |
function.json or host.json | Azure Functions project | Deploy as Functions |
staticwebapp.config.json | Static Web Apps project | Deploy as SWA |
If found, skip to the appropriate deployment section.
Step 1.2: Detect Application Framework
Scan for configuration files and dependencies:
Node.js / JavaScript / TypeScript:
package.json exists →
├── next.config.js/mjs/ts → Next.js
│ ├── Has `output: 'export'` → Static Web Apps (SSG)
│ └── Has API routes or no export config → App Service (SSR)
├── nuxt.config.ts/js → Nuxt
│ ├── Has `ssr: false` or `target: 'static'` → Static Web Apps
│ └── Otherwise → App Service (SSR)
├── angular.json → Angular → Static Web Apps
├── vite.config.* → Vite-based (React/Vue/Svelte) → Static Web Apps
├── gatsby-config.js → Gatsby → Static Web Apps
├── astro.config.mjs → Astro → Static Web Apps
├── nest-cli.json → NestJS → App Service
├── Has express/fastify/koa/hapi dependency → App Service
└── No framework, just static build → Static Web Apps
Python:
requirements.txt or pyproject.toml exists →
├── function_app.py exists → Azure Functions (v2 programming model)
├── Has flask dependency → App Service
├── Has django dependency → App Service
├── Has fastapi dependency → App Service
└── Has azure-functions dependency → Azure Functions
.NET:
*.csproj or *.sln exists →
├── <AzureFunctionsVersion> in csproj → Azure Functions
├── Blazor WebAssembly project → Static Web Apps
├── ASP.NET Core web app → App Service
└── .NET API project → App Service
Java:
pom.xml or build.gradle exists →
├── Has azure-functions-* dependency → Azure Functions
├── Has spring-boot dependency → App Service
└── Standard web app → App Service
Static Only:
index.html exists + no package.json/requirements.txt →
└── Pure static site → Static Web Apps
Step 1.3: Detect Multi-Service Architecture
Check for complexity indicators that suggest azd + IaC:
Multi-service triggers:
├── Monorepo structure (frontend/, backend/, api/, packages/, apps/)
├── docker-compose.yml with multiple services
├── Multiple package.json in different subdirectories
├── Database references in config (connection strings, .env files)
├── References to Redis, Service Bus, Event Hubs, Storage queues
├── User mentions "multiple environments", "staging", "production"
└── More than one deployable component detected
If multi-service detected → Recommend azd + Infrastructure as Code
See Multi-Service Deployment Guide
Step 1.4: Confidence Assessment
After detection, assess confidence:
| Confidence | Criteria | Action |
|---|
| HIGH | Azure config file found (azure.yaml, function.json, staticwebapp.config.json) | Proceed with detected service |
| MEDIUM | Framework detected from dependencies | Explain recommendation, ask for confirmation |
| LOW | Ambiguous or no clear signals | Ask clarifying questions |
Clarifying questions for LOW confidence:
- "What type of application is this? (static website, API, full-stack, serverless functions)"
- "Does your app need server-side rendering or is it purely client-side?"
- "Will you need a database, caching, or other Azure services?"
Phase 2: Local Preview (No Azure Auth Required)
Before deploying, help users test locally.
⛔ CRITICAL: macOS Compatibility
NEVER use detach: true on macOS - it WILL FAIL with "setsid: command not found".
| ❌ WRONG (fails on macOS) | ✅ CORRECT |
|---|
mode: "async", detach: true | Keep in same session + open browser |
Backgrounding with & alone | Start server, wait, then open URL |
nohup (session dies anyway) | All in one command chain |
The Working Pattern for Local Preview
The server dies when the session ends. The solution is to start the server and open the browser in ONE session before it can close:
cd /path/to/project && npm run dev &
sleep 2
open http://localhost:5173/
Why this works:
- Server starts in background (
&)
sleep 2 gives it time to bind to port
open launches browser immediately
- Browser connection keeps the server alive
Why previous approaches fail:
| Approach | Problem |
|---|
detach: true | setsid doesn't exist on macOS - silent failure |
& backgrounding alone | Server killed when bash session ends |
nohup | Session still terminates, server dies |
Running Dev Servers in Copilot CLI
Correct approach - all in one session:
cd /path/to/project && npm run dev & sleep 2 && open http://localhost:5173/
cd /path/to/project && npm run dev & sleep 3 && open http://localhost:3000/
cd /path/to/project && flask run & sleep 2 && open http://localhost:5000/
Server verification (if not opening browser):
curl -s -o /dev/null -w "%{http_code}" http://localhost:5173/
Local Preview Strategy
IMPORTANT: SWA CLI can have issues with session management, especially on macOS. Always have fallback options ready.
| Method | Best For | Reliability |
|---|
npm run dev | Development with HMR | ✅ Most reliable |
npm run preview | Test production build | ✅ Very reliable |
npx serve dist | Any static build | ✅ Very reliable |
swa start | SWA with API integration | ⚠️ Session issues on macOS |
Recommended: Framework Dev Server (Most Reliable)
For SPAs, use the framework's dev server:
npm run dev
npm run dev
ng serve
Production Build Preview
To test the actual build output:
npm run build
npm run preview
npm run preview -- --host
Fallback for any static site:
npx serve dist
cd dist && python3 -m http.server 8080
SWA CLI - Local Preview (ALWAYS Run Interactively)
✅ Best Practice: Always run SWA CLI interactively (async mode, not detached). This ensures routing rules from staticwebapp.config.json are applied.
npx --yes @azure/static-web-apps-cli start ./dist --port 4280
When to use SWA CLI instead of npm run dev:
- Need
staticwebapp.config.json routing rules (navigation fallback, headers)
- Testing authentication/authorization
- Testing with API integration (
--api-location)
Stopping SWA CLI:
pkill -f "swa"
If SWA CLI fails:
- Use
npm run dev for development (no routing rules)
- Use
npm run preview for production build testing
- Use
npx serve dist as universal fallback
- For full SWA features, deploy to Azure and test there
Azure Functions - Local Preview
npm install -g azure-functions-core-tools@4
func start
func start --port 7071
App Service Apps - Local Preview
Use the framework's built-in dev server:
npm run dev
npm start
flask run
uvicorn main:app --reload
dotnet run
./mvnw spring-boot:run
See Local Preview Guide for detailed setup and troubleshooting.
Phase 3: Prerequisites & Dependency Management
ALWAYS check and install missing dependencies before proceeding.
3.1 Azure Authentication (Auto-Login)
Check login status and automatically login if needed:
if ! az account show &>/dev/null; then
echo "Not logged in to Azure. Starting login..."
az login
fi
az account show --query "{name:name, id:id}" -o table
If the user has multiple subscriptions, help them select the correct one:
az account list --query "[].{Name:name, ID:id, Default:isDefault}" -o table
az account set --subscription "<name-or-id>"
3.2 Dependency Detection & Auto-Install
Run this check first and install any missing tools:
check_deps() {
local missing=()
command -v az &>/dev/null || missing+=("azure-cli")
command -v func &>/dev/null || missing+=("azure-functions-core-tools")
command -v swa &>/dev/null || missing+=("@azure/static-web-apps-cli")
command -v azd &>/dev/null || missing+=("azd")
echo "${missing[@]}"
}
3.3 Install Missing Tools
Azure CLI (required for all deployments):
brew install azure-cli
winget install Microsoft.AzureCLI
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
Azure Functions Core Tools (for Functions projects):
npm install -g azure-functions-core-tools@4
brew tap azure/functions && brew install azure-functions-core-tools@4
winget install Microsoft.AzureFunctionsCoreTools
Static Web Apps CLI (for SWA projects):
npm install -g @azure/static-web-apps-cli
Azure Developer CLI (for multi-service/IaC):
brew install azd
winget install Microsoft.Azd
curl -fsSL https://aka.ms/install-azd.sh | bash
3.4 Project Dependencies
Detect and install project-level dependencies:
[ -f "package.json" ] && [ ! -d "node_modules" ] && npm install
[ -f "requirements.txt" ] && [ ! -d ".venv" ] && python -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
[ -f "*.csproj" ] && dotnet restore
[ -f "pom.xml" ] && mvn dependency:resolve
Phase 4: Single-Service Deployment (Azure CLI)
4.1 Static Web Apps Deployment
Create resource and deploy:
az group create --name <resource-group> --location <location>
az staticwebapp create \
--name <app-name> \
--resource-group <resource-group> \
--location <location> \
--sku Free
az staticwebapp secrets list \
--name <app-name> \
--resource-group <resource-group> \
--query "properties.apiKey" -o tsv
swa deploy ./dist \
--deployment-token <token> \
--env production
Plain HTML Site (Single File or No Build Step):
For plain HTML sites without a build process, SWA CLI requires content in a dedicated folder:
mkdir -p dist && cp -r *.html *.css *.js *.png *.jpg *.svg dist/ 2>/dev/null || true
TOKEN=$(az staticwebapp secrets list \
--name <app-name> \
--resource-group <resource-group> \
--query "properties.apiKey" -o tsv)
swa deploy ./dist --deployment-token "$TOKEN" --env production
rm -rf dist
Smart defaults:
- SKU:
Free for dev/test, Standard for production
- Location: SWA has limited regions - use
centralus, eastus2, westus2, westeurope, or eastasia
See Static Web Apps Guide for detailed configuration.
4.2 Azure Functions Deployment
Create and deploy:
az group create --name <resource-group> --location <location>
az storage account create \
--name <storage-name> \
--resource-group <resource-group> \
--location <location> \
--sku Standard_LRS
az functionapp create \
--name <app-name> \
--resource-group <resource-group> \
--storage-account <storage-name> \
--consumption-plan-location <location> \
--runtime <node|python|dotnet|java> \
--runtime-version <version> \
--functions-version 4
func azure functionapp publish <app-name>
Smart defaults:
- Plan: Consumption (pay-per-execution) for most cases
- Runtime version: Latest LTS for the detected language
See Azure Functions Guide for advanced scenarios.
4.3 App Service Deployment
Create and deploy:
az group create --name <resource-group> --location <location>
az appservice plan create \
--name <plan-name> \
--resource-group <resource-group> \
--location <location> \
--sku B1 \
--is-linux
az webapp create \
--name <app-name> \
--resource-group <resource-group> \
--plan <plan-name> \
--runtime "<runtime>"
az webapp deploy \
--name <app-name> \
--resource-group <resource-group> \
--src-path <path-to-zip> \
--type zip
Runtime values by language:
- Node.js:
"NODE:18-lts", "NODE:20-lts"
- Python:
"PYTHON:3.11", "PYTHON:3.12"
- .NET:
"DOTNETCORE:8.0"
- Java:
"JAVA:17-java17"
Smart defaults:
- Plan SKU:
B1 for dev/test, P1v3 for production
- Always use Linux (
--is-linux) unless .NET Framework required
See App Service Guide for configuration options.
Phase 5: Multi-Service Deployment (azd + IaC)
When multiple services or infrastructure dependencies are detected, recommend Azure Developer CLI with Infrastructure as Code.
When to Use azd
- Multiple deployable components (frontend + API + functions)
- Needs database, cache, storage, or messaging services
- Requires consistent environments (dev, staging, production)
- Team collaboration with reproducible infrastructure
Initialize azd Project
azd init
azd init --template <template-name>
Project Structure
project/
├── azure.yaml # azd configuration
├── infra/
│ ├── main.bicep # Main infrastructure
│ ├── main.parameters.json
│ └── modules/ # Reusable modules
├── src/
│ ├── web/ # Frontend
│ └── api/ # Backend
Deploy with azd
azd up
azd provision
azd deploy
azd env new staging
azd env select staging
azd up
See Multi-Service Guide for azure.yaml configuration.
See Azure Verified Modules for Bicep module reference.
Troubleshooting Quick Reference
Common Issues
"Not logged in" errors:
az login
az account set --subscription "<name>"
"Resource group not found":
az group create --name <name> --location <location>
SWA deployment fails:
- Check build output directory is correct
- Verify deployment token is valid
- Ensure
staticwebapp.config.json is properly formatted
Functions deployment fails:
- Verify
host.json exists
- Check runtime version matches function app configuration
- Ensure storage account is accessible
App Service deployment fails:
- Verify runtime matches application
- Check startup command if using custom entry point
- Review deployment logs:
az webapp log tail --name <app> --resource-group <rg>
See Troubleshooting Guide for detailed solutions.
Reference Files
Load these guides as needed for detailed information: