# 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.Hosting` or `Aspire.AppHost.Sdk` in `.csproj` files > > **STOP and use `azd init --from-code` instead.** See [aspire.md](aspire.md) for details. Create `azure.yaml` in project root for AZD. ## Structure ### Basic (Bicep - default) ```yaml name: metadata: template: azd-init services: : project: language: host: ``` ### With Terraform Provider ```yaml name: metadata: template: azd-init # Specify Terraform as IaC provider infra: provider: terraform path: ./infra services: : project: language: host: ``` > 💡 **Tip:** Omit `infra` section to use Bicep (default). Add `infra.provider: terraform` to use Terraform. See [terraform.md](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) ```yaml name: myapp services: api: project: ./src/api language: python host: containerapp docker: path: ./src/api/Dockerfile ``` ### Container App with Terraform ```yaml name: myapp infra: provider: terraform path: ./infra services: api: project: ./src/api language: python host: containerapp docker: path: ./src/api/Dockerfile ``` ### Container App with Custom Docker Context When a **non-Aspire** project has a Dockerfile that expects files relative to a specific directory: ```yaml name: myapp services: ginapp: project: . host: containerapp image: ginapp docker: path: ginapp/Dockerfile context: ginapp ``` > 💡 **Tip:** The `context` field specifies the Docker build context directory. This is crucial for: > - Dockerfiles with `COPY` commands 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.context` for Aspire `AddDockerfile()` resources. Aspire handles container builds at runtime through the AppHost. The generated `azure.yaml` should contain only a single `app` service pointing to the AppHost. See [aspire.md](aspire.md) for details. > ⚠️ **Language Field:** When using the `docker` section, the `language` field 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 include `language` if you need azd to perform additional framework-specific actions beyond Docker build. ### Azure Functions ```yaml services: functions: project: ./src/functions language: js host: function ``` ### Static Web App (with framework build) For React, Vue, Angular, Next.js, etc. that require `npm run build`: ```yaml 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):** ```yaml services: web: project: ./src/web # folder containing index.html host: staticwebapp dist: . # works when project != root ``` **Static files in root - requires build script:** > ⚠️ **SWA CLI Limitation:** When `project: .`, you cannot use `dist: .`. Files must be copied to a separate output folder. Add a minimal `package.json` with a build script: ```json { "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: ```yaml services: web: project: . language: js # triggers npm install && npm run build host: staticwebapp dist: public ``` ### SWA Project Structure Detection | Layout | Configuration | |--------|---------------| | Static in root | `project: .`, `language: js`, `dist: public` + package.json build script | | Framework in root | `project: .`, `language: js`, `dist: ` | | Static in subfolder | `project: ./path`, `dist: .` | | Framework in subfolder | `project: ./path`, `language: js`, `dist: ` | > **Key rules:** > - `dist` is **relative to `project`** path > - **SWA CLI limitation**: When `project: .`, cannot use `dist: .` - must use a distinct folder > - For static files in root, add `package.json` with build script to copy files to dist folder > - Use `language: js` to trigger npm build even for pure static sites in root > - `language: html` and `language: static` are **NOT valid** - will fail ### SWA Bicep Requirement Bicep must include the `azd-service-name` tag: ```bicep resource staticWebApp 'Microsoft.Web/staticSites@2022-09-01' = { name: name location: location tags: union(tags, { 'azd-service-name': 'web' })} ``` } ``` ### App Service ```yaml services: api: project: ./src/api language: dotnet host: appservice ``` ## Hooks (Optional) ```yaml 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`