azure.yaml Generation
⛔ CRITICAL: Check for .NET Aspire projects FIRST
>
DO NOT manually create azure.yaml for .NET Aspire projects. If you detect:
- Files ending with
*.AppHost.csproj(e.g.,MyApp.AppHost.csproj)Aspire.HostingorAspire.AppHost.Sdkin.csprojfiles
>
STOP and use
azd init --from-codeinstead. See aspire.md for details.
Create azure.yaml in project root for AZD.
Structure
Basic (Bicep - default)
name: <project-name>
metadata:
template: azd-init
services:
<service-name>:
project: <path-to-source>
language: <python|js|ts|java|dotnet|go>
host: <containerapp|appservice|function|staticwebapp|aks>With Terraform Provider
name: <project-name>
metadata:
template: azd-init
# Specify Terraform as IaC provider
infra:
provider: terraform
path: ./infra
services:
<service-name>:
project: <path-to-source>
language: <python|js|ts|java|dotnet|go>
host: <containerapp|appservice|function|staticwebapp|aks>💡 Tip: Omit
infrasection to use Bicep (default). Addinfra.provider: terraformto use Terraform. See terraform.md for details.
Host Types
| Host | Azure Service | Use For |
|---|---|---|
containerapp | Container Apps | APIs, microservices, workers |
appservice | App Service | Traditional web apps |
function | Azure Functions | Serverless functions |
staticwebapp | Static Web Apps | SPAs, static sites |
aks | AKS | Kubernetes workloads |
Examples
Container App with Bicep (default)
name: myapp
services:
api:
project: ./src/api
language: python
host: containerapp
docker:
path: ./src/api/DockerfileContainer App with Terraform
name: myapp
infra:
provider: terraform
path: ./infra
services:
api:
project: ./src/api
language: python
host: containerapp
docker:
path: ./src/api/DockerfileContainer App with Custom Docker Context
When a non-Aspire project has a Dockerfile that expects files relative to a specific directory:
name: myapp
services:
ginapp:
project: .
host: containerapp
image: ginapp
docker:
path: ginapp/Dockerfile
context: ginapp💡 Tip: The
contextfield specifies the Docker build context directory. This is crucial for:
- Dockerfiles with
COPYcommands expecting files relative to a subdirectory- Multi-service repos where each service has its own context
⚠️ Aspire projects: Do NOT manually add per-service entries with
docker.contextfor AspireAddDockerfile()resources. Aspire handles container builds at runtime through the AppHost. The generatedazure.yamlshould contain only a singleappservice pointing to the AppHost. See aspire.md for details.
⚠️ Language Field: When using the
dockersection, thelanguagefield should be omitted or set to the language that azd will use for framework-specific behaviors. For containerized apps with custom Dockerfiles, the language is not used by azd since the build is handled by Docker. Only includelanguageif you need azd to perform additional framework-specific actions beyond Docker build.
Azure Functions
services:
functions:
project: ./src/functions
language: js
host: functionStatic Web App (with framework build)
For React, Vue, Angular, Next.js, etc. that require npm run build:
services:
web:
project: ./src/web # folder containing package.json
language: js # triggers: npm install && npm run build
host: staticwebapp
dist: dist # build output folder (e.g., dist, build, out)Static Web App (pure HTML/CSS - no build)
For pure HTML sites without a framework build step:
Static files in subfolder (recommended):
services:
web:
project: ./src/web # folder containing index.html
host: staticwebapp
dist: . # works when project != rootStatic files in root - requires build script:
⚠️ SWA CLI Limitation: When
project: ., you cannot usedist: .. Files must be copied to a separate output folder.
Add a minimal package.json with a build script:
{
"scripts": {
"build": "node -e \"require('fs').mkdirSync('public',{recursive:true});require('fs').readdirSync('.').filter(f=>/\\.(html|css|js|png|jpe?g|gif|svg|ico|json|xml|txt|webmanifest|map)$/i.test(f)).forEach(f=>require('fs').copyFileSync(f,'public/'+f))\""
}
}Then configure azure.yaml with language: js to trigger the build:
services:
web:
project: .
language: js # triggers npm install && npm run build
host: staticwebapp
dist: publicSWA Project Structure Detection
| Layout | Configuration |
|---|---|
| Static in root | project: ., language: js, dist: public + package.json build script |
| Framework in root | project: ., language: js, dist: <output> |
| Static in subfolder | project: ./path, dist: . |
| Framework in subfolder | project: ./path, language: js, dist: <output> |
Key rules:
distis relative toprojectpath- SWA CLI limitation: When
project: ., cannot usedist: .- must use a distinct folder- For static files in root, add
package.jsonwith build script to copy files to dist folder- Use
language: jsto trigger npm build even for pure static sites in rootlanguage: htmlandlanguage: staticare NOT valid - will fail
SWA Bicep Requirement
Bicep must include the azd-service-name tag:
resource staticWebApp 'Microsoft.Web/staticSites@2022-09-01' = {
name: name
location: location
tags: union(tags, { 'azd-service-name': 'web' })}}
### App Service
services: api: project: ./src/api language: dotnet host: appservice
## Hooks (Optional)
hooks: preprovision: shell: sh run: ./scripts/setup.sh postprovision: shell: sh run: ./scripts/seed-data.sh
## Valid Values
| Field | Options |
|-------|---------|
| `language` | python, js, ts, java, dotnet, go (omit for staticwebapp without build) |
| `host` | containerapp, appservice, function, staticwebapp, aks |
| `docker.path` | Path to Dockerfile (relative to project root) |
| `docker.context` | Docker build context directory (optional, defaults to directory containing Dockerfile) |
> 💡 **Docker Context:** When `docker.context` is omitted, azd uses the directory containing the Dockerfile as the build context. Specify `context` explicitly when the Dockerfile expects files from a different directory.
## Output
- `./azure.yaml`