| name | azd-app-onboard |
| description | Onboard any application to use 'azd app' for local multi-service development.
Guides through project detection, azure.yaml generation, environment setup,
health checks, hooks, Docker services, and MCP configuration.
USE FOR: onboard to azd app, setup azd app, configure azure.yaml, get started
with azd app, add azd app to my project, initialize azd app, new azd app project,
migrate to azd app, convert project to azd app.
DO NOT USE FOR: running services (use azd-app skill), Azure deployments (use azd deploy),
infrastructure provisioning (use azd provision).
|
Onboarding to azd app
This skill helps you onboard an existing or new application to use azd app for
local multi-service development orchestration. It covers the full onboarding journey
from project detection through verified running services.
When to Use
- Setting up
azd app in an existing project for the first time
- Creating a new
azure.yaml from scratch based on detected project structure
- Enriching an existing
azure.yaml with azd app extensions (ports, commands, health checks)
- Configuring multi-service monorepos
- Setting up environment variables, Key Vault references, Docker services, hooks, or MCP
Onboarding Workflow
Follow these steps in order. Each step builds on the previous one.
Step 1: Detect Project Structure
Run azd app init --dry-run to discover what azd app detects:
azd app init --dry-run
This scans the project directory for:
- Languages and frameworks (Node.js, Python, .NET, Java, Go, Rust, PHP)
- Package managers (npm, yarn, pnpm, pip, dotnet, maven, gradle, cargo, composer)
- Service boundaries (separate directories with their own entry points)
- Existing configuration (package.json, requirements.txt, go.mod, etc.)
- Docker files (Dockerfile, docker-compose.yml)
Step 2: Generate azure.yaml
If no azure.yaml exists:
azd app init
If azure.yaml already exists but needs azd app enrichment:
azd app init
To overwrite existing services section:
azd app init --force
Step 3: Configure Services
The generated azure.yaml should have a services section. Each service needs:
name: my-project
services:
api:
project: ./api
language: python
host: appservice
command: uvicorn main:app --reload --port {port}
ports:
- "8080"
healthcheck:
type: http
path: /health
web:
project: ./web
language: js
host: appservice
command: npm run dev -- --port {port}
ports:
- "3000"
healthcheck:
type: http
path: /
Key fields to configure per service:
| Field | Required | Description |
|---|
project | Yes | Relative path to service directory |
language | Yes | Language identifier (js, ts, python, csharp, java, go, rust, php, docker) |
command | Recommended | Custom run command (auto-detected if omitted) |
ports | Recommended | List of port strings (e.g., - "8080" or - "8080:8080") |
healthcheck.type | Recommended | Health check type: http, tcp, process, or none |
healthcheck.path | For HTTP | Health endpoint path (used with type: http) |
host | Optional | Azure host target (appservice, containerapp, function) |
Step 4: Environment Variables
Configure environment variables in azure.yaml using three formats:
services:
api:
environment:
NODE_ENV: "development"
LOG_LEVEL: "debug"
DATABASE_URL: ${POSTGRES_CONNECTION_STRING}
API_KEY: keyvault://my-vault/api-key
DB_PASSWORD: keyvault://my-vault/db-password
For shared environment variables, use an env file:
azd app run --env-file .env.development
Step 5: Docker Services
For services running in Docker containers, use host: containerapp with an image: field:
services:
redis:
host: containerapp
image: redis:7-alpine
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
postgres:
host: containerapp
image: postgres:16-alpine
ports:
- "5432:5432"
environment:
POSTGRES_DB: myapp
POSTGRES_USER: dev
POSTGRES_PASSWORD: devpassword
healthcheck:
test: ["CMD-SHELL", "pg_isready -U dev"]
interval: 10s
timeout: 5s
retries: 3
Use azd app add for well-known container services:
azd app add redis
azd app add postgres
Step 6: Lifecycle Hooks
Configure hooks for custom lifecycle behavior:
hooks:
prerun:
shell: bash
run: |
echo "Running database migrations..."
cd api && python -m alembic upgrade head
postrun:
shell: bash
run: |
echo "All services running!"
echo "API: http://localhost:8080"
echo "Web: http://localhost:3000"
prestop:
shell: bash
run: echo "Draining connections..."
poststop:
shell: bash
run: echo "Cleanup complete"
Step 7: Health Checks
Configure health endpoints for service monitoring:
services:
api:
healthcheck:
type: http
path: /health
For Docker-style health checks (container services):
services:
redis:
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
Verify health checks work:
azd app health --all --verbose
For continuous monitoring:
azd app health --stream --interval 10s
Step 8: MCP Server Setup
Enable AI assistant integration via Model Context Protocol:
azd app mcp serve
To configure your IDE (VS Code) to use the MCP server, add to .vscode/mcp.json:
{
"servers": {
"azd-app": {
"command": "azd",
"args": ["app", "mcp", "serve"]
}
}
}
This exposes tools for AI assistants to:
- List and manage services
- View logs and errors
- Install dependencies
- Check requirements
- Manage environment variables
Step 9: Verify Onboarding
Run the full verification sequence:
azd app reqs
azd app deps
azd app run --dry-run
azd app run
azd app health --all
Multi-Service Monorepo Setup
For monorepos with multiple independently-deployable services:
name: my-monorepo
services:
auth-service:
project: ./services/auth
language: ts
command: npm run dev -- --port {port}
ports:
- "4001"
healthcheck:
type: http
path: /health
api-gateway:
project: ./services/gateway
language: ts
command: npm run dev -- --port {port}
ports:
- "4000"
healthcheck:
type: http
path: /health
worker:
project: ./services/worker
language: python
command: python -m celery worker
healthcheck:
type: process
frontend:
project: ./apps/web
language: ts
command: npm run dev -- --port {port}
ports:
- "3000"
healthcheck:
type: http
path: /
Run individual services:
azd app run --service api-gateway
azd app run --service frontend
Common Issues & Solutions
| Issue | Solution |
|---|
| Port conflict | Use {port} placeholder in command — azd app manages ports automatically |
| Service not detected | Ensure service has a recognizable entry point (package.json, main.py, go.mod, etc.) |
| Health check failing | Verify the endpoint returns HTTP 200 and the path matches healthcheck.path |
| Docker service won't start | Check docker is running with azd app reqs |
| Env var not resolving | Ensure the referenced variable is set in your shell or .env file |
| Key Vault access denied | Verify az login and that your identity has Key Vault access |
Complete azure.yaml Reference
name: my-project
hooks:
prerun:
shell: bash
run: echo "starting..."
postrun:
shell: bash
run: echo "ready!"
prestop:
shell: bash
run: echo "stopping..."
poststop:
shell: bash
run: echo "stopped"
services:
service-name:
project: ./path/to/service
language: js|ts|python|csharp|java|go|rust|php
host: appservice|containerapp|function
command: "custom run command"
ports:
- "8080"
- "8080:8080"
healthcheck:
type: http|tcp|process|none
path: /health
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 10s
timeout: 5s
retries: 3
environment:
KEY: "value"
KEY: ${OTHER_VAR}
KEY: keyvault://vault/secret
container-name:
host: containerapp
image: redis:7-alpine
ports:
- "6379:6379"
environment:
KEY: value
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3