azure.yaml Reference
Your complete guide to azure.yaml - the configuration file that makes local development with azd app absolutely delightful
🎯What is azure.yaml?
Think of azure.yaml as your project's control center. It serves two purposes:
This reference covers ALL properties - both for local development with azd appand Azure deployment with standard azd. It's the complete guide! 📚
⚡Quick Start Example
Here's a minimal azure.yaml to get you started:
name: my-awesome-app
services: web: language: TypeScript project: ./frontend ports: - "3000" uses: - api
api: language: Python project: ./backend ports: - "8000"That's it! With just this, azd app will auto-detect your tech stack, figure out how to run your services, and set up health checks. Magic! ✨
📑 Table of Contents
🏷️name(required)
Your application's name. This is the only required field in azure.yaml. Keep it simple, descriptive, and URL-friendly!
| Property | Type | Required | Pattern | Length |
|---|---|---|---|---|
name | string | ✅ Yes | ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$ | 2-64 chars |
Rules & Restrictions
- ✅ Lowercase letters (a-z), numbers (0-9), hyphens (-) only
- ✅ Must start and end with a letter or number
- ✅ Length: 2-64 characters
- ❌ No uppercase, spaces, special characters, or unicode
- ❌ Cannot be empty or just whitespace
name: my-awesome-app # Letters, numbers, dashes, underscores (1-64 chars)name: cool_project-2024 # ✅ Perfect!name: my project # ❌ No spacesname: "" # ❌ Can't be empty🎭services
The services section is where the real party happens! 🎉 This is where you define all the different pieces of your application - web frontends, APIs, background workers, databases, caches, you name it.
🧠Smart Auto-Detection
azd app is pretty smart! It auto-detects your language, framework, and how to run your service based on files in your project directory. You often only need to specify projectand ports!
Service Types
Services come in different flavors depending on what they do:
image is set.services: # HTTP service - serves web content web: project: ./frontend ports: ["3000"] type: http # Default when ports are defined
# TCP service - raw socket connections (databases) database: image: postgres:16 ports: ["5432"] type: tcp
# Process service - runs in background (workers, queues) worker: project: ./worker type: process # Default when no ports defined
# Container service - Docker image redis: image: redis:7 type: container # Auto-detected when 'image' is setService Modes
Modes determine how azd app manages the service lifecycle:
services: # Daemon - long-running server (default) api: project: ./api mode: daemon
# Watch - continuous file watcher (TypeScript, Sass, etc.) typescript: project: ./frontend command: tsc --watch mode: watch healthcheck: type: output pattern: "Found 0 errors"
# Build - one-time build that exits assets: project: ./frontend command: npm run build mode: build healthcheck: false
# Task - runs on-demand only migrate: project: ./db command: npm run migrate mode: taskComplete Service Configuration
Here's the full power of service configuration with all available options:
services: api: # Core properties language: TypeScript project: ./backend entrypoint: src/main.ts # Entry file command: "tsx watch src/main.ts" # Override default command type: http mode: daemon
# Network ports: - "8080:8080" # host:container - "127.0.0.1:9090:9090" # bind to specific IP - "3000" # auto-map to same port
# Environment environment: - name: NODE_ENV value: development - name: DB_PASSWORD secret: MY_DB_SECRET # Reference to secret
# Or as object (simpler for non-secret values) # environment: # NODE_ENV: development # API_KEY: "abc123"
# Dependencies uses: - postgres - redis
# Health monitoring healthcheck: type: http path: /health interval: 10s timeout: 5s retries: 3 start_period: 30sAll Service Properties
Complete reference of every property available for services:
| Property | Type | Default | Context | Description |
|---|---|---|---|---|
| Core Properties (Local Dev - azd app) | ||||
language | string | auto-detect | azd app | Programming language: js, ts, py, python, csharp, dotnet, go, java, rust, ruby, php, aspire |
project | string | - | Both | Relative path to service source directory |
entrypoint | string | auto-detect | azd app | Entry file (e.g., main.py, app.js, main.go) |
command | string | auto-detect | azd app | Override run command (e.g., "npm run dev") |
type | enum | http/process | azd app | Service type: http, tcp, process, container |
mode | enum | daemon | azd app | Run mode: daemon, watch, build, task |
image | string | - | Both | Docker image name. Mutually exclusive with project in some contexts. |
ports | array | - | azd app | Port mappings: ["3000"], ["3000:8080"], ["127.0.0.1:3000:8080"] |
environment | array/object | - | azd app | Environment variables as array of {name, value/secret} or key-value object |
uses | array | - | Both | Array of service/resource names this depends on. Auto-detected by azd app init |
docker | object | - | Both | Docker build configuration (see Docker section) |
healthcheck | object/bool | auto | azd app | Health check config or false to disable |
logs | object | - | azd app | Service-level logging configuration |
test | object | - | azd app | Service-level test configuration |
| Deployment Properties (azd) | ||||
host | enum | - | azd | Required for deployment. Azure service type: appservice, containerapp, function, springapp, staticwebapp, aks, ai.endpoint, azure.ai.agent |
resourceGroup | string | default RG | azd | Override resource group for this service |
resourceName | string | auto-discover | azd | Override Azure resource name |
apiVersion | string | latest | azd | Resource provider API version (Container Apps only) |
module | string | service name | azd | Infrastructure module path relative to infra folder |
dist | string | - | azd | Relative path to deployment artifacts |
k8s | object | - | azd | Kubernetes configuration for AKS deployments |
config | object | - | azd | Host-specific configuration (AI endpoints, agents, etc.) |
env | object | - | azd | Environment variables for deployment (key-value pairs) |
local | object | - | azd app | Local development configuration including customUrl |
azure | object | - | azd | Azure deployment configuration including customUrl and customDomain |
hooks | object | - | azd | Service-level hooks: predeploy, postdeploy, prerestore, postrestore, prebuild, postbuild, prepackage, postpackage, prepublish, postpublish |
Service URL Configuration
Configure custom URLs for accessing your services through the local and azure configuration objects. These URLs are used when the actual access point differs from the auto-discovered service URL.
| Property | Type | Context | Writable | Description & Examples |
|---|---|---|---|---|
local.url | string | Local dev | Readonly | Auto-discovered local URL (NEVER overridden). Always shows the actual localhost endpoint. Examples: http://localhost:3000, http://localhost:8080⚠️ If service has custom URL, both URLs are preserved separately |
local.customUrl | string | Local dev | Yes | Custom URL for accessing the service (used for display). The original localhost URL is preserved in local.url.Examples: https://myapi.ngrok.io, http://myapp.local:8080 |
azure.url | string | Azure | Readonly | Auto-discovered Azure URL (NEVER overridden). Always shows the actual provisioned endpoint. Examples: https://myapp.azurewebsites.net, https://myapi.azurecontainerapps.io⚠️ If service has custom domain, both URLs are preserved separately |
azure.customUrl | string | Azure | Yes | Custom URL for Azure deployment (used for display). The original Azure URL is preserved in azure.url. Typically used with CDN/Front Door.Examples: https://www.contoso.com, https://api.fabrikam.com/v1 |
azure.customDomain | string | Azure | Yes | Custom domain name for Azure deployment (domain only, no protocol). Converted to HTTPS URL for display. The original Azure URL is preserved in azure.url.Can be auto-discovered from Azure resource settings (e.g., App Service custom domain) or set locally in azure.yaml. Examples: www.contoso.com, api.fabrikam.com⚠️ Do not include http:// or https:// |
Common Use Cases
- Custom domains: Users access via
www.company.cominstead of Azure-generated URLs - Development tunnels: Expose local services via ngrok or similar tools
- Reverse proxies: Traffic flows through a gateway or load balancer
- CDN endpoints: Content delivered via Azure Front Door or Cloudflare
- API gateways: APIs accessed through Azure API Management
services: # Local development with ngrok tunnel api: project: ./backend ports: ["8080"] local: customUrl: https://myapi.ngrok.io # Local URL shown as: https://myapi.ngrok.io # Auto-discovered: http://localhost:8080
# Production with custom domain and CDN web: host: containerapp project: ./frontend azure: customUrl: https://www.mycompany.com customDomain: www.mycompany.com # Access URL: https://www.mycompany.com # Azure deployed to: https://web-abc123.azurecontainerapps.io
# API behind Azure API Management backend: host: containerapp project: ./api azure: customUrl: https://api.mycompany.com customDomain: api.mycompany.com # Access URL: https://api.mycompany.com # Azure deployed to: https://backend-xyz789.azurecontainerapps.io
# Both local tunnel and production custom domain fullstack: host: appservice project: ./app local: customUrl: https://app.ngrok.io azure: customUrl: https://app.company.com customDomain: app.company.com # Local: https://app.ngrok.io # Azure: https://app.company.com🎯How It Works: URL Property Design
The system maintains two separate readonly URL properties that preserve the original auto-discovered endpoints. Custom URLs are stored separately and used for display purposes.
local.url- Readonly, always preserves the original auto-discovered URL (e.g., http://localhost:3000)local.customUrl- Optional user-configured display URL (e.g., https://myapi.ngrok.io)- Both URLs are preserved separately - you can always see the actual localhost endpoint AND the custom access URL
azure.url- Readonly, always preserves the original Azure endpoint (e.g., https://myapp.azurecontainerapps.io)azure.customUrl- Optional user-configured display URL (e.g., https://www.contoso.com)azure.customDomain- Optional domain name that converts to HTTPS URL (e.g., www.contoso.com → https://www.contoso.com)- Original Azure URL is never overwritten - both the provisioned endpoint and custom domain are preserved
The local.url and azure.url properties are readonly and automatically set at runtime. You cannot directly set these in your azure.yaml. Instead, configurelocal.customUrl, azure.customUrl, orazure.customDomain to provide custom access URLs.
💡Example: URL Separation
services: api: project: ./backend ports: ["8080"] local: customUrl: https://api.ngrok.io azure: customDomain: api.mycompany.com
# What happens at runtime:
# Local development (azd app run):# - local.url = "http://localhost:8080" (auto-discovered, NEVER changes)# - local.customUrl = "https://api.ngrok.io" (user-configured)# - Display shows BOTH: "Access URL: https://api.ngrok.io" + "Local URL: http://localhost:8080"
# Azure deployment (azd deploy):# - azure.url = "https://api-xyz123.azurecontainerapps.io" (auto-discovered, NEVER changes)# - azure.customDomain = "api.mycompany.com" → converted to "https://api.mycompany.com"# - Display shows BOTH: "Access URL: https://api.mycompany.com" + "Azure URL: https://api-xyz123.azurecontainerapps.io"
# Key Point: Original URLs are ALWAYS preserved alongside custom URLs✨Display Behavior
- CLI (
azd app info): Shows both "Access URL" (custom) and original URL when they differ - Dashboard: Primary link uses the custom URL; hover/tooltip shows the original provisioned URL
- Service Discovery: Environment variables reference the appropriate URL based on context
- Logs: Both URLs included in startup messages for clarity and debugging
⚠️Important Notes
- These properties are informational only - they don't configure DNS, SSL certificates, or routing
- You must separately configure your infrastructure (custom domains, reverse proxies, CDN, etc.)
customUrlrequires full URL with protocol (http:// or https://)customDomainaccepts domain name only (e.g., www.example.com) - can be auto-discovered from Azure or set locally- Used primarily for documentation, UX, and helping developers know both the actual provisioned endpoint and the custom access point
Environment Variable Formats
services: api: # Array format (supports secrets) environment: - name: NODE_ENV value: development - name: DB_PASSWORD secret: DB_SECRET # Reference to secret
# Object format (simpler, no secrets) environment: NODE_ENV: development API_URL: http://localhost:8080 DEBUG: "true"❤️Health Checks
Health checks are how azd app knows when your services are actually ready to accept connections. No more "Connection refused" errors because you tried to hit your API before it finished starting up! 🎯
💡Pro Tip
Health checks are automatically configured for most services! HTTP services get HTTP health checks, containers with TCP ports get TCP checks, and process services get process checks. You only need to customize them if the defaults don't work for you.
Health Check Types
services: # HTTP health check (default for HTTP services) api: ports: ["8080"] healthcheck: type: http path: /health # Default is /health interval: 30s timeout: 10s retries: 3
# TCP health check - checks if port is listening database: image: postgres:16 ports: ["5432"] healthcheck: type: tcp interval: 10s retries: 5
# Process health check - verifies process is running worker: project: ./worker healthcheck: type: process interval: 15s
# Output health check - watches stdout for pattern typescript-watcher: project: ./frontend command: tsc --watch mode: watch healthcheck: type: output pattern: "Found 0 errors\. Watching for file changes" timeout: 60s
# Disable health check for build processes build-assets: project: ./assets command: npm run build mode: build healthcheck: false
# Docker Compose style (cross-platform compatible) postgres: image: postgres:16 healthcheck: test: "http://localhost:5432" # Preferred # Or: ["CMD", "pg_isready", "-U", "postgres"] interval: 10s timeout: 5s retries: 5 start_period: 40sHealth Check Properties
| Property | Type | Default | Description |
|---|---|---|---|
type | string | http/process | http, tcp, process, output, none |
path | string | /health | HTTP endpoint path |
pattern | string | - | Regex pattern for output checks |
interval | duration | 30s | Time between checks |
timeout | duration | 30s | Max time for check |
retries | integer | 3 | Failures before unhealthy |
start_period | duration | 0s | Grace period on startup |
disable | boolean | false | Set true to disable checks |
🐳Docker & Containers
Run Docker containers alongside your code services! Perfect for databases, caches, Azure emulators, and any other infrastructure you need during development.
services: custom-app: image: myapp:latest # Use existing image ports: ["8080"]
built-app: docker: path: ./Dockerfile # Path to Dockerfile context: . # Build context platform: linux/amd64 buildArgs: - NODE_VERSION=20 - BUILD_ENV=production registry: myregistry.azurecr.io image: myapp tag: v1.0.0 ports: ["8080"]📦 Container Service Properties
image- Docker image name (makes it a container service)ports- Port mappings in "host:container" formatenvironment- Environment variables for containervolumes- Persistent volume mountsdocker.path- Path to Dockerfile for buildingdocker.context- Build context directorydocker.platform- Target platform (linux/amd64, linux/arm64)docker.buildArgs- Build-time arguments
All Docker Build Properties
| Property | Type | Default | Description |
|---|---|---|---|
path | string | ./Dockerfile | Path to Dockerfile relative to service project |
context | string | project dir | Build context directory. Use "../" for monorepo shared dependencies. |
platform | string | host platform | Target platform: linux/amd64, linux/arm64, windows/amd64 |
registry | string | - | Override container registry (e.g., "myregistry.azurecr.io") |
image | string | service name | Image name (without registry/tag) |
tag | string | azd-{env}-{timestamp} | Image tag. Use "latest" with caution in production. |
buildArgs | array | - | Build arguments: ["NODE_ENV=production", "API_VERSION=v2"] |
target | string | - | Multi-stage build target (e.g., "production", "development") |
remoteBuild | boolean | false | Build in cloud (Azure Container Registry Tasks) for faster CI/CD |
Check out the Container Services Guide for detailed examples and pre-built container configurations!
☁️resources
Define Azure resources your application uses in production. While this mainly affects deployment, it's useful for documentation and understanding your app's cloud dependencies.
resources: # Azure Storage Account storage: type: Microsoft.Storage/storageAccounts
# Azure Key Vault keyvault: type: Microsoft.KeyVault/vaults
# SQL Server with dependency sqlserver: type: Microsoft.Sql/servers uses: - keyvault # Depends on key vault
# Existing resource (not provisioned by azd) existing-db: type: Microsoft.Sql/servers existing: trueResource Properties
type(required) - Azure resource typeuses- Other resources this depends onexisting- Set true for existing resources not provisioned by azd
All Resource Types
| Type | Azure Service | Common Uses |
|---|---|---|
azure.servicebus.namespace | Azure Service Bus | Message queues, pub/sub messaging |
azure.storage.account | Azure Storage | Blob storage, file shares, queues, tables |
azure.cosmos.account | Cosmos DB | NoSQL database, globally distributed |
azure.sql.server | Azure SQL Database | Relational database (SQL Server) |
azure.keyvault.vault | Azure Key Vault | Secrets, keys, certificates management |
azure.eventhub.namespace | Event Hubs | Big data streaming, event ingestion |
azure.redis.cache | Azure Cache for Redis | In-memory cache, session storage |
azure.search.service | Azure AI Search | Full-text search, vector search |
azure.appinsights.account | Application Insights | Monitoring, telemetry, diagnostics |
azure.ai.model | Azure AI Model | AI/ML models (OpenAI, etc.) |
azure.ai.project | Azure AI Project | AI project workspace |
azure.containerapp.environment | Container Apps Environment | Container app infrastructure |
azure.aks.cluster | Azure Kubernetes Service | Kubernetes cluster orchestration |
azure.container.registry | Azure Container Registry | Private Docker image registry |
Common Resource Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | enum | ✅ Yes | Azure resource type (see table above) |
uses | array | No | Names of resources this depends on |
existing | boolean | No | true if resource already exists (not provisioned by azd) |
props | object | No | Resource-specific properties (varies by type) |
✅reqs (Prerequisites)
Define prerequisite tools your project needs. azd app will check for these tools and their versions before running your application. No more "works on my machine" problems! 🎉
reqs: # Simple version check - name: node minVersion: "20.0.0"
# With installation URL override - name: python minVersion: "3.11" installUrl: "https://www.python.org/downloads/"
# Check if tool is running (Docker daemon) - name: docker minVersion: "20.0.0" checkRunning: true installUrl: "https://docs.docker.com/desktop/"
# Custom version check command - name: my-tool minVersion: "2.5.0" command: my-tool args: ["version"] versionPrefix: "v" # Strip 'v' prefix versionField: 1 # Which field has version installUrl: "https://example.com/install"
# Custom running check - name: kubernetes command: kubectl checkRunning: true runningCheckCommand: kubectl runningCheckArgs: ["cluster-info"] runningCheckExpected: "Kubernetes control plane" runningCheckExitCode: 0🔍 Built-in Tools
azd app has smart defaults for common tools: node, python, docker, go, java, dotnet, rust, etc. Just specify the name and minVersion!
🛠️ Custom Tools
For custom tools, specify how to check the version with command,args, and parsing options.
All Requirement Properties
| Property | Type | Required | Description |
|---|---|---|---|
name | string | ✅ Yes | Tool name (node, python, docker, go, etc.) |
minVersion | string | No | Minimum required version (semver format) |
command | string | No | Command to run for version check (defaults: node --version, python --version, etc.) |
args | array | No | Arguments for version command: ["--version"] |
versionPrefix | string | No | Prefix to strip from version string (e.g., "v" for "v1.2.3") |
versionField | string | No | Field name if version is in JSON output |
checkRunning | boolean | No | Also verify tool is running (e.g., Docker daemon) |
runningCheckCommand | string | No | Command to check if running |
runningCheckArgs | array | No | Arguments for running check command |
runningCheckExpected | string | No | Expected substring in output if running |
runningCheckExitCode | number | No | Expected exit code if running (default: 0) |
installUrl | string | No | URL shown to user for installation instructions |
Built-in Tool Names
These tools have automatic version detection and smart defaults:
nodepythondockergojavadotnetrustrubyphpazdkubectlterraform🪝hooks (Lifecycle Hooks)
Run custom scripts before or after commands. Perfect for setup tasks, notifications, or custom workflows.
hooks: # Simple pre-run hook prerun: run: npm install shell: sh
# Post-run notification postrun: run: echo "🚀 All services are running!" shell: sh continueOnError: true # Don't fail if hook fails
# Pre-stop hook (drain connections before shutdown) prestop: run: echo "Draining connections..." shell: sh continueOnError: true
# Post-stop cleanup poststop: run: ./scripts/cleanup.sh shell: bash
# Platform-specific hooks prerun: windows: run: .\scripts\setup.ps1 shell: pwsh posix: run: ./scripts/setup.sh shell: bashAvailable Hooks
prerun- Runs beforeazd app runpostrun- Runs afterazd app runprestop- Runs beforeazd app stoppoststop- Runs afterazd app stop
Hook Properties
run- Script or command to executeshell- Shell type (sh, bash, pwsh, powershell, cmd)continueOnError- Don't fail if hook failsinteractive- Bind to stdin/stdoutwindows- Windows-specific overrideposix- Linux/macOS override
All Hook Properties
| Property | Type | Default | Description |
|---|---|---|---|
run | string | - | Command or script to execute |
shell | enum | sh/pwsh | Shell type: sh, bash, pwsh, powershell, cmd |
continueOnError | boolean | false | Continue execution even if hook fails |
interactive | boolean | false | Allow user interaction (stdin/stdout) |
windows | object | - | Windows-specific hook config (same properties) |
posix | object | - | Linux/macOS-specific hook config (same properties) |
Available Hook Types
| Hook | Context | Trigger |
|---|---|---|
prerun | azd app | Before azd app run |
postrun | azd app | After azd app run |
prestop | azd app | Before azd app stop |
poststop | azd app | After azd app stop |
predeploy | azd | Before azd deploy |
postdeploy | azd | After azd deploy |
prerestore | azd | Before azd restore |
postrestore | azd | After azd restore |
prebuild | azd | Before building service |
postbuild | azd | After building service |
prepackage | azd | Before packaging service |
postpackage | azd | After packaging service |
prepublish | azd | Before publishing to registry |
postpublish | azd | After publishing to registry |
📊logs (Logging Configuration)
Control log filtering, classification, and Azure Log Analytics integration. Keep your logs clean and organized!
Basic Logging
logs: # Filter out noisy logs filters: exclude: - "npm warn" - "Debugger listening on" - "ExperimentalWarning"
# Override log levels classifications: - text: "DEPRECATED" level: warning - text: "fatal" level: error - text: "panic" level: errorAzure Log Analytics Integration
Stream logs from your deployed Azure services (Container Apps, App Service, Functions) directly into your local dashboard with Log Analytics integration. View local and cloud logs in one unified interface.
See the Azure Cloud Log Streaming reference for detailed setup, dashboard features, troubleshooting, and examples.
# Project-level: Configure polling behaviorlogs: analytics: pollingInterval: 30s # How often to refresh Azure logs (default: 30s) defaultTimespan: PT15M # Time range for queries (ISO 8601 duration, default: PT15M)
# Service-level: Specify Log Analytics tablesservices: web: host: appservice path: ./src/web logs: analytics: table: AppServiceConsoleLogs # App Service standard table
api: host: containerapp path: ./src/api logs: analytics: table: ContainerAppConsoleLogs_CL # Container Apps custom log table
functions: host: functions path: ./src/functions logs: analytics: table: FunctionAppLogs # Functions standard table
# Advanced: Custom KQL query (yaml-only, not exposed in dashboard UI) worker: host: functions path: ./src/worker logs: analytics: query: | FunctionAppLogs | where FunctionName == "ProcessQueue" | where TimeGenerated > ago(15m) | where Level == "Error" | order by TimeGenerated descLogging Features
- Filters: Suppress noisy patterns with regex (case-insensitive)
- Classifications: Override log levels based on text matches
- Azure Analytics: Stream logs from Container Apps, App Service, and Functions
- Unified Dashboard: View local and cloud logs in one interface with time range selection and service filtering
- Custom KQL Queries: Advanced users can provide custom Kusto queries via azure.yaml
All Logging Properties
| Property | Type | Context | Description |
|---|---|---|---|
| Filter Configuration | |||
filters.exclude | array | Global/Service | Array of regex patterns to suppress logs (case-insensitive) |
classifications | array | Global/Service | Override log levels based on patterns |
| Azure Log Analytics | |||
analytics.enabled | boolean | Global/Service | Enable Azure Log Analytics integration |
analytics.workspaceId | string | Global/Service | Log Analytics workspace ID |
analytics.table | string | Service | KQL table name (AppServiceConsoleLogs, ContainerAppConsoleLogs, etc.) |
analytics.query | string | Service | Custom KQL query (overrides default table query) |
analytics.pollInterval | string | Global/Service | Polling interval (e.g., "5s", "30s", "1m") |
analytics.streaming | boolean | Service | Use real-time streaming when available (Container Apps) |
Log Classification Properties
| Property | Type | Values | Description |
|---|---|---|---|
pattern | string | regex | Pattern to match in log text (case-insensitive) |
level | enum | debug, info, warn, error | Log level to apply when pattern matches |
🧪test (Testing Configuration)
Configure unit, integration, and e2e tests for your services. Run them all with azd app test!
# Global test configurationtest: parallel: true # Run service tests in parallel failFast: false # Continue even if a test fails outputDir: ./test-results outputFormat: junit # default, json, junit, github coverage: enabled: true threshold: 80 # Fail if coverage < 80% exclude: - "**/vendor/**" - "**/test/**"
services: api: test: # Unit tests unit: command: npm test path: tests/unit pattern: "*.test.ts" timeout: 5m env: NODE_ENV: test
# Integration tests integration: command: npm run test:integration path: tests/integration timeout: 10m
# End-to-end tests e2e: command: npm run test:e2e path: tests/e2e timeout: 15m
# Service-specific coverage coverage: enabled: true threshold: 85 exclude: - "**/*.test.ts" - "**/mocks/**"Testing Features
- Multi-level: Unit, integration, and e2e tests per service
- Parallel Execution: Run tests across services simultaneously
- Code Coverage: Track and enforce coverage thresholds
- Multiple Formats: Output as default, JSON, JUnit, or GitHub Actions format
- Fail Fast: Stop on first failure or continue to see all results
All Test Configuration Properties
| Property | Type | Default | Description |
|---|---|---|---|
| Global Options (test: top-level) | |||
parallel | boolean | false | Run tests across services in parallel |
failFast | boolean | false | Stop immediately on first test failure |
coverage | boolean | false | Collect code coverage for all services |
outputDir | string | .test-results | Directory for test output files |
outputFormat | enum | default | Output format: default, json, junit, github-actions |
| Service-Level Options (services.NAME.test) | |||
unit | object | - | Unit test configuration (see Test Type Properties) |
integration | object | - | Integration test configuration (see Test Type Properties) |
e2e | object | - | End-to-end test configuration (see Test Type Properties) |
Test Type Properties (unit/integration/e2e)
| Property | Type | Default | Description |
|---|---|---|---|
command | string | auto-detect | Test command to run (e.g., "npm test", "pytest") |
path | string | - | Path to test directory or file |
coverage | boolean | inherit | Override coverage collection for this test type |
coverageThreshold | number | - | Minimum coverage percentage (0-100, fails if below) |
timeout | string | 5m | Test timeout (e.g., "30s", "5m", "1h") |
env | object | - | Environment variables for tests (key-value pairs) |
Output Format Options
| Format | Use Case | Description |
|---|---|---|
default | Development | Human-readable console output with colors |
json | Automation | Machine-readable JSON for scripts and tools |
junit | CI/CD | JUnit XML for CI systems (Jenkins, Azure DevOps) |
github-actions | GitHub CI | GitHub Actions annotations and summaries |
🏗️infra (Infrastructure Configuration)
Configure how Azure infrastructure is provisioned for your application. Supports Bicep and Terraform!
infra: provider: bicep # or 'terraform' path: ./infra # Default: infra module: main # Default: main
# Terraform exampleinfra: provider: terraform path: ./infrastructure module: mainInfrastructure Properties
provider- bicep or terraform (default: bicep)path- Relative path to infrastructure templates (default: infra)module- Default provisioning module name (default: main)
🔄pipeline (CI/CD Configuration)
Configure continuous integration pipeline settings for GitHub Actions or Azure DevOps.
pipeline: provider: github # or 'azdo' for Azure DevOps
# Variables from azd environment to pass to pipeline variables: - AZURE_ENV_NAME - AZURE_LOCATION
# Secrets from azd environment to pass to pipeline secrets: - AZURE_SUBSCRIPTION_ID - DATABASE_PASSWORDPipeline Properties
provider- github or azdo (default: github)variables- Environment variables to set as pipeline variablessecrets- Environment variables to set as pipeline secrets
🚀Deployment & Cloud Properties
Resource Group
Override the default resource group name used for infrastructure provisioning:
resourceGroup: my-custom-rg-name # Supports environment variable substitutionRequired Versions
Specify version constraints for azd CLI and extensions:
requiredVersions: azd: ">= 0.6.0-beta.3" extensions: azure-app: ">=1.0.0" my-extension: "~2.0.0" # Supports semver constraintsInfrastructure Configuration (infra)
Define infrastructure provider and location:
infra: provider: bicep # or terraform path: infra # Path to infrastructure code (default: infra) module: main # Main module name (bicep) or path (terraform)| Property | Type | Default | Description |
|---|---|---|---|
provider | enum | bicep | Infrastructure as code provider: bicep, terraform |
path | string | infra | Relative path to infrastructure code directory |
module | string | main | Main module name (Bicep) or relative path (Terraform) |
Pipeline Configuration (pipeline)
Configure CI/CD pipeline settings:
pipeline: provider: github # or azdo (Azure DevOps) variables: NODE_ENV: production secrets: - API_KEY - DATABASE_URL| Property | Type | Description |
|---|---|---|
provider | enum | CI/CD provider: github, azdo (Azure DevOps) |
variables | object | Key-value pairs for pipeline variables |
secrets | array | Names of secrets to configure in pipeline |
State Management (state)
Configure remote state storage for infrastructure state (Terraform, etc.):
state: remote: backend: AzureBlobStorage config: accountName: mystorageaccount containerName: tfstate # Optional, defaults to project name endpoint: blob.core.windows.net # Optional| Property | Type | Description |
|---|---|---|
remote.backend | enum | Remote state backend: AzureBlobStorage |
remote.config.accountName | string | Azure Storage account name |
remote.config.containerName | string | Blob container for state (default: project name) |
remote.config.endpoint | string | Storage endpoint (default: blob.core.windows.net) |
Platform Configuration (platform)
Integration with Azure Dev Center for enterprise scenarios:
platform: type: devcenter config: name: my-dev-center project: my-dev-center-project catalog: my-catalog environmentDefinition: my-env-def environmentType: dev| Property | Type | Description |
|---|---|---|
type | enum | Platform type: devcenter |
config.name | string | Azure Dev Center name |
config.project | string | Dev Center project name |
config.catalog | string | Catalog name for environment definitions |
config.environmentDefinition | string | Environment definition name |
config.environmentType | string | Environment type (dev, test, prod) |
Workflows (workflows)
Customize azd command workflows (e.g., change the order of provision, package, deploy):
workflows: up: steps: - azd: package --all - azd: provision - azd: deploy --all
# Or as array shorthand:# workflows:# up:# - azd: package --all# - azd: provision# - azd: deploy --all| Property | Type | Description |
|---|---|---|
{workflow-name} | object/array | Workflow steps for custom command (up, provision, deploy, etc.) |
steps | array | Array of workflow steps (object format) |
steps[].azd | string | azd command to run (e.g., "provision", "deploy --all") |
Available Workflow Commands
Commands that can be customized with workflows:
upprovisiondeploydownpackagerestoreCloud Configuration (cloud)
Deploy to sovereign clouds (Azure Government, Azure China, etc.):
cloud: name: AzureUSGovernment # AzureCloud (default), AzureChinaCloud, AzureUSGovernment| Property | Type | Values | Description |
|---|---|---|---|
name | enum | AzureCloud, AzureChinaCloud, AzureUSGovernment | Azure cloud environment (default: AzureCloud) |
Service Deployment Properties
Additional service properties for Azure deployment:
services: api: host: containerapp # Required: appservice, containerapp, function, springapp, staticwebapp, aks, ai.endpoint project: ./api
# Deployment configuration resourceGroup: custom-rg # Override default resource group resourceName: my-api-instance # Override resource name discovery module: api-module # Infrastructure module for this service dist: ./dist # Path to deployment artifacts
# API version for deployment apiVersion: "2023-05-01" # Container App API version
# AKS-specific configuration k8s: deploymentPath: manifests # Path to k8s manifests namespace: production # K8s namespace deployment: name: api-deployment service: name: api-service ingress: name: api-ingress relativePath: /api
# Service hooks (in addition to global hooks) hooks: predeploy: run: npm run build shell: sh postdeploy: run: echo "Deployed successfully!" shell: sh prerestore: run: npm install postrestore: run: echo "Restored dependencies" prebuild: run: npm run lint postbuild: run: echo "Build complete" prepackage: run: npm run test postpackage: run: echo "Package ready"Service Host Types
appservice- Azure App Service (requires project + runtime)containerapp- Azure Container Apps (requires image OR project)function- Azure Functions (requires project)springapp- Azure Spring Apps (requires project)staticwebapp- Azure Static Web Apps (requires project)aks- Azure Kubernetes Service (requires project + k8s config)ai.endpoint- Azure AI Studio endpoints (requires project + config)azure.ai.agent- Azure AI Agents (requires project)
Kubernetes (k8s) Configuration
For AKS deployments, configure Kubernetes manifest paths and resource names:
| Property | Type | Description |
|---|---|---|
deploymentPath | string | Path to Kubernetes manifest files (relative to service project) |
namespace | string | Kubernetes namespace for deployment (default: default) |
deployment.name | string | Deployment resource name |
service.name | string | Service resource name |
ingress.name | string | Ingress resource name |
ingress.relativePath | string | URL path for this service (e.g., /api, /admin) |
Resource Types
Azure resource types with special configuration options:
resources: # Storage Account storage: type: storage containers: # Optional: containers to create - uploads - backups
# Cosmos DB cosmosdb: type: db.cosmos containers: - name: users partitionKeys: ["/id"] - name: orders partitionKeys: ["/customerId", "/region"]
# Event Hubs eventhubs: type: messaging.eventhubs hubs: # Hubs to create - telemetry - logs
# Service Bus servicebus: type: messaging.servicebus queues: - orders - notifications topics: - events
# App Service host resource webapp: type: host.appservice port: 80 runtime: stack: node version: "20-lts" startupCommand: "npm start" env: - name: NODE_ENV value: production
# Container App host resource api-host: type: host.containerapp port: 8080 env: - name: LOG_LEVEL value: info - name: DB_PASSWORD secret: DB_PASSWORD_SECRET
# AI/ML Resources openai: type: ai.openai.model model: name: gpt-4 version: "0613"
ai-project: type: ai.project models: - name: gpt-4o version: "2024-05-13" format: OpenAI sku: name: GlobalStandard usageName: OpenAI.GlobalStandard.gpt-4o capacity: 10
search: type: ai.search
# Database resources postgres: type: db.postgres
mysql: type: db.mysql
redis: type: db.redis
mongodb: type: db.mongo
# Key Vault vault: type: keyvault🎪The Grand Finale: Complete Example
Feast your eyes on this masterpiece! A real-world azure.yamlwith all the bells and whistles. This is what peak performance looks like! 🏆
name: epic-fullstack-app
# 🎯 Global test configurationtest: parallel: true coverage: enabled: true threshold: 80
# 📋 Prerequisitesreqs: - name: node minVersion: "20.0.0" - name: docker checkRunning: true - name: python minVersion: "3.11"
# 🪝 Lifecycle hookshooks: prerun: run: echo "🚀 Starting up..." shell: sh postrun: run: echo "✨ Ready to code!" shell: sh prestop: run: echo "⏹️ Shutting down..." shell: sh continueOnError: true poststop: run: echo "🧹 Cleanup complete!" shell: sh
# 📊 Global logginglogs: filters: exclude: - "npm warn" - "Debugger listening" classifications: - text: "error" level: error - text: "warning" level: warning analytics: pollingInterval: "10s" defaultTimespan: "30m"
# 🎭 Servicesservices: # Next.js frontend web: language: TypeScript project: ./frontend ports: ["3000"] environment: - name: NEXT_PUBLIC_API_URL value: http://localhost:8000 - name: NEXT_PUBLIC_ANALYTICS_ID secret: ANALYTICS_SECRET uses: - api healthcheck: path: /api/health interval: 10s test: unit: command: npm test coverage: threshold: 85
# FastAPI backend api: language: Python project: ./backend entrypoint: main.py ports: ["8000"] environment: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/app REDIS_URL: redis://localhost:6379 uses: - postgres - redis healthcheck: path: /health interval: 15s timeout: 5s retries: 3 start_period: 30s logs: analytics: tables: - ContainerAppConsoleLogs_CL test: unit: command: pytest tests/ path: tests integration: command: pytest tests/integration/
# Background worker worker: language: Python project: ./worker type: process environment: QUEUE_URL: redis://localhost:6379 uses: - redis healthcheck: type: process interval: 30s
# TypeScript build watcher build-types: project: ./shared command: tsc --watch --preserveWatchOutput mode: watch healthcheck: type: output pattern: "Found 0 errors" timeout: 60s
# PostgreSQL database postgres: image: postgres:16 ports: ["5432"] environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: app healthcheck: type: tcp interval: 10s retries: 5
# Redis cache redis: image: redis:7-alpine ports: ["6379"] healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s
# Azurite for Azure Storage emulation azurite: image: mcr.microsoft.com/azure-storage/azurite ports: - "10000:10000" # Blob - "10001:10001" # Queue - "10002:10002" # Table
# ☁️ Azure Resourcesresources: storage: type: Microsoft.Storage/storageAccounts keyvault: type: Microsoft.KeyVault/vaults appinsights: type: Microsoft.Insights/components🎉What's Happening Here?
- 🎯 Next.js frontend with environment variables and tests
- 🐍 FastAPI backend with health checks and Log Analytics
- ⚙️ Python background worker for queue processing
- 👀 TypeScript compiler in watch mode with output monitoring
- 🐘 PostgreSQL database container with health checks
- ⚡ Redis cache for sessions and caching
- ☁️ Azurite for Azure Storage emulation
- ✅ Prerequisites checking for Node, Docker, and Python
- 🪝 Lifecycle hooks for setup and notifications
- 📊 Global logging with filters and Azure Analytics
- 🧪 Comprehensive testing with coverage tracking
⚡Quick Reference
Cheat sheet for the impatient (we don't judge!):
# Property Quick Reference
## Root Properties (All)### Required- name - Application name (required)
### Development (azd app)- services - Service definitions- reqs - Prerequisites- hooks - Lifecycle hooks (prerun, postrun, prestop, poststop)- logs - Logging configuration- test - Testing configuration
### Deployment (azd)- resources - Azure resources- infra - Infrastructure config (Bicep/Terraform)- pipeline - CI/CD configuration- resourceGroup - Override resource group- requiredVersions - Version constraints- state - Remote state management- platform - Dev Center integration- workflows - Custom command workflows- cloud - Sovereign cloud selection- metadata - Custom metadata
## Service Properties### Core (azd app)- language - Programming language- project - Project directory- entrypoint - Entry file- command - Run command override- type - http|tcp|process|container- mode - daemon|watch|build|task
### Network & Containers- ports - Port mappings- image - Docker image- docker - Build configuration- environment - Env variables
### Dependencies & Health- uses - Service/resource dependencies- healthcheck - Health monitoring
### Configuration (azd app)- logs - Service logging config- test - Service test config
### Deployment (azd)- host - Azure service type (required for deployment)- resourceGroup - Service resource group- resourceName - Override resource name- apiVersion - API version- module - Infrastructure module- dist - Deployment artifacts path- k8s - Kubernetes configuration- config - Host-specific config- hooks - Service lifecycle hooks
## Resource Properties- type - Resource type (required)- uses - Dependencies- existing - Is existing resource- [type-specific] - Container arrays, SKU config, etc.💎Pro Tips & Tricks
🎯 Let Auto-Detection Do Its Thing
Start minimal! azd app will figure out your language, framework, and run commands. Add overrides only when needed.
🔗 Use Dependencies Wisely
The uses property ensures services start in the right order. Your API won't start until the database is healthy!
🏥 Health Checks Are Your Friend
Proper health checks prevent race conditions. For watch mode services, use output patterns instead of HTTP checks!
📊 Filter Those Logs
Nobody needs to see "npm warn deprecated" 500 times. Use log filters to keep your output clean and focused!
🐳 Containers for Infrastructure
Run databases, caches, and Azure emulators as containers. No need to install PostgreSQL on every dev machine!
🧪 Test Early, Test Often
Configure tests in azure.yaml so everyone runs them the same way. Enforce coverage thresholds to maintain quality!
🏷️metadata (Custom Metadata)
Store custom metadata about your application. Commonly used to track template information.
metadata: template: todo-nodejs-mongo@0.0.1-beta author: Azure Samples description: Full-stack application with Node.js and MongoDB customField: any-value-you-wantThe metadata section accepts any custom properties you want to store (additionalProperties: true). Most commonly used to track which template a project was created from.
Metadata Properties
| Property | Type | Description |
|---|---|---|
template | string | Template identifier (common convention: name@version) |
author | string | Template or project author |
description | string | Template or project description |
{custom} | any | Any custom fields (no restrictions) |
🔍Schema Validation & IntelliSense
Get autocomplete and validation in VS Code by adding this to the top of your azure.yaml:
Schema v1.1 (Local Development + Deployment)
Use v1.1 if you're using azd app for local development. This is a superset that includes all v1.0 properties plus local development features:
# yaml-language-server: $schema=https://raw.githubusercontent.com/jongio/azd-app/main/schemas/v1.1/azure.yaml.json
name: my-appservices: api: project: ./api ports: ["8080"] # v1.1 feature healthcheck: # v1.1 feature path: /healthSchema v1.0 (Deployment Only)
Use v1.0 if you're only using standard azd for Azure deployment without local development features:
# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json
name: my-appservices: api: host: containerapp # v1.0 deployment project: ./api💡Which Schema Should I Use?
- v1.1 - If you use
azd app runfor local development - v1.0 - If you only use
azd up/deployfor Azure deployment - v1.1 is backward compatible - All v1.0 files work with v1.1 schema
🔗 Related Documentation
Ready to Build Something Amazing? 🚀
Now that you're an azure.yaml expert, go forth and orchestrate some awesome local development environments!
Get Started Now →