Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Prepare applications for Azure deployment by generating infrastructure code, Dockerfiles, and config files.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/aspire.md
1# .NET Aspire Projects23> โ **CRITICAL - READ THIS FIRST**4>5> For .NET Aspire projects, **NEVER manually create azure.yaml or infra/ files.**6> Always use `azd init --from-code` which auto-detects the AppHost and generates everything correctly.7>8> **Failure to follow this causes:** "Could not find a part of the path 'infra\main.bicep'" error.910Guidance for preparing .NET Aspire applications for Azure deployment.1112**๐ For detailed AZD workflow:** See [recipes/azd/aspire.md](recipes/azd/aspire.md)1314## What is .NET Aspire?1516.NET Aspire is an opinionated, cloud-ready stack for building observable, production-ready distributed applications. Aspire projects use an AppHost orchestrator to define and configure the application's components, services, and dependencies.1718## Detection1920A .NET Aspire project is identified by:2122| Indicator | Description |23|-----------|-------------|24| `*.AppHost.csproj` | AppHost orchestrator project file |25| `Aspire.Hosting` package | Core Aspire hosting package reference |26| `Aspire.Hosting.AppHost` | Alternative Aspire hosting package |2728**Example project structure:**29```30orleans-voting/31โโโ OrleansVoting.sln32โโโ OrleansVoting.AppHost/33โ โโโ OrleansVoting.AppHost.csproj โ AppHost indicator34โโโ OrleansVoting.Web/35โโโ OrleansVoting.Api/36โโโ OrleansVoting.Grains/37```3839## Azure Preparation Workflow4041### Step 1: Detection4243When scanning the codebase (per [scan.md](scan.md)), detect Aspire by:4445```bash46# Check for AppHost project47find . -name "*.AppHost.csproj"4849# Or check for Aspire.Hosting package reference50grep -r "Aspire.Hosting" . --include="*.csproj"51```5253### โ Step 1a: Pre-Check for Custom/Non-Deployable Resources (MANDATORY)5455**Before running `azd init --from-code`, scan the AppHost source code to understand whether the app may contain local-only custom resources.**5657```bash58# Find the AppHost project and scan only its source directory59APPHOST_PROJECT=$(find . -name "*.AppHost.csproj" | head -1)60APPHOST_DIR=$(dirname "$APPHOST_PROJECT")61grep -r "ExcludeFromManifest" "$APPHOST_DIR" --include="*.cs" | head -2062```6364**PowerShell:**65```powershell66# Find the AppHost project and scan only its source directory67$appHostProject = Get-ChildItem -Recurse -Filter "*.AppHost.csproj" | Select-Object -First 168$appHostDir = $appHostProject.DirectoryName69Get-ChildItem -Path $appHostDir -Recurse -Filter "*.cs" | Select-String "ExcludeFromManifest" | Select-Object -First 2070```7172This scan is informational. `.ExcludeFromManifest()` can appear alongside deployable resources, so a positive match does **not** immediately block deployment. What matters is the final `azure.yaml` output after `azd init --from-code` completes:7374- If `azd init` **fails** with `unsupported resource type` โ see Step 2 error guidance below.75- If `azd init` **succeeds** but `azure.yaml` has an empty or missing `services` section โ see Step 4a below.7677> ๐ก **Why scan early:** Knowing that `.ExcludeFromManifest()` is present gives useful context when azd errors or generates an empty manifest โ it confirms the app intentionally targets local development rather than Azure deployment.7879### Step 2: Initialize with azd8081**CRITICAL: For Aspire projects, use `azd init --from-code -e <environment-name>` instead of creating azure.yaml manually.**8283**โ ๏ธ ALWAYS include the `-e <environment-name>` flag:** Without it, `azd init` will fail in non-interactive environments (agents, CI/CD) with the error: `no default response for prompt 'Enter a unique environment name:'`8485The `--from-code` flag:86- Auto-detects the AppHost orchestrator87- Reads the Aspire service definitions88- Generates appropriate `azure.yaml` and infrastructure89- Works in non-interactive/CI environments when combined with `-e` flag9091```bash92# Non-interactive initialization for Aspire projects (REQUIRED for agents)93ENV_NAME="$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | tr ' _' '-')-dev"94azd init --from-code -e "$ENV_NAME"95```9697**Why both flags are required:**98- `--from-code`: Tells azd to detect the AppHost automatically (no "How do you want to initialize?" prompt)99- `-e <name>`: Provides environment name upfront (no "Enter environment name:" prompt)100- Together, they enable fully non-interactive operation essential for automation, agents, and CI/CD pipelines101102**โ If `azd init --from-code` fails with "unsupported resource type":**103104This error means the AppHost contains custom Aspire resource types that azd cannot process for Azure deployment:1051061. โ **Do NOT attempt to fix this error by modifying source code** โ do not add `.ExcludeFromManifest()` calls or otherwise patch the AppHost1072. โ **Do NOT proceed with deployment** โ the application is designed for local development only1083. โ Record a blocker: "AppHost contains custom Aspire resource types (`unsupported resource type`) that cannot be deployed to Azure"1094. โ Inform the user: this application uses custom Aspire resource authoring patterns intended for local tooling, not cloud deployment110111> โ ๏ธ **Why modifying source code is forbidden:** Adding `.ExcludeFromManifest()` may suppress the error and allow `azd init` to succeed, but the deployment outcome will not reflect the application's actual intent. The custom resources are deliberately designed to be local-only.112113### Step 3: Configure Subscription and Location114115> **โ CRITICAL**: After `azd init --from-code` completes, you **MUST** immediately set the user-confirmed subscription and location.116>117> **DO NOT** skip this step or delay it until validation. The `azd init` command creates an environment but does NOT inherit the Azure CLI's subscription. If you skip this step, azd will use its own default subscription, which may differ from the user's confirmed choice.118119**Set the subscription and location immediately after initialization:**120121```bash122# Set the user-confirmed subscription ID123azd env set AZURE_SUBSCRIPTION_ID <subscription-id>124125# Set the location126azd env set AZURE_LOCATION <location>127```128129**Verify the configuration:**130131```bash132azd env get-values133```134135Confirm that `AZURE_SUBSCRIPTION_ID` and `AZURE_LOCATION` match the user's confirmed choices from [Azure Context](azure-context.md).136137### Step 4: What azd Generates138139`azd init --from-code` creates:140141| Artifact | Location | Description |142|----------|----------|-------------|143| `azure.yaml` | Project root | Service definitions from AppHost |144| `infra/` | Project root | Bicep templates for Azure resources |145| `.azure/` | Project root | Environment configuration |146147### โ Step 4a: Validate Generated Output148149**MANDATORY: After `azd init --from-code` completes, verify the generated `azure.yaml` contains deployable services.**150151```bash152# Check if azure.yaml has a non-empty services section153cat azure.yaml154```155156**If the `services` section is empty or missing:** The AppHost has no deployable resources. This happens when all resources use `.ExcludeFromManifest()` (e.g., custom resource demonstrations, local-only tooling). In this case:1571581. โ **Do NOT proceed with deployment** โ there is nothing to deploy1592. โ Keep the plan status in a valid state (for example, leave it as **Planning**) and record a blocker in the plan body with the reason: "Application contains only custom/demo Aspire resources with no Azure-deployable services"1603. โ Inform the user that this application is designed for local development and cannot be meaningfully deployed to Azure1614. โ Do NOT manually create Bicep, Dockerfiles, or azure.yaml to work around this โ the absence of services is the correct result162163**Example generated azure.yaml:**164```yaml165name: orleans-voting166# metadata section is auto-generated by azd init --from-code167168services:169web:170project: ./OrleansVoting.Web171language: dotnet172host: containerapp173174api:175project: ./OrleansVoting.Api176language: dotnet177host: containerapp178```179180### โ Step 4b: Fix Azure Functions Secret Storage (MANDATORY for Aspire + Functions)181182**MANDATORY: After `azd init --from-code` succeeds, check if the AppHost contains Azure Functions and fix secret storage configuration.**183184This step **MUST** run BEFORE `azd up` or `azd provision`. Skipping it causes a runtime failure: `Secret initialization from Blob storage failed`.185186**1. Detect Azure Functions in the AppHost:**187188```bash189APPHOST_DIR=$(dirname "$(find . -name '*.AppHost.csproj' | head -1)")190grep -n "AddAzureFunctionsProject" "$APPHOST_DIR"/*.cs191```192193**PowerShell:**194```powershell195$appHostDir = (Get-ChildItem -Recurse -Filter "*.AppHost.csproj" | Select-Object -First 1).DirectoryName196Get-ChildItem -Path $appHostDir -Filter "*.cs" | Select-String "AddAzureFunctionsProject"197```198199**If `AddAzureFunctionsProject` is NOT found โ skip this step.**200201**2. Check if `AzureWebJobsSecretStorageType` is already configured:**202203```bash204grep -n "AzureWebJobsSecretStorageType" "$APPHOST_DIR"/*.cs205```206207**PowerShell:**208```powershell209Get-ChildItem -Path $appHostDir -Filter "*.cs" | Select-String "AzureWebJobsSecretStorageType"210```211212**If already present โ skip this step.**213214**3. Add the environment variable to the Functions builder chain:**215216Use the `edit` tool to add `.WithEnvironment("AzureWebJobsSecretStorageType", "Files")` to the `AddAzureFunctionsProject` builder chain in the AppHost source file.217218**Before:**219```csharp220var functions = builder.AddAzureFunctionsProject<Projects.MyFunctions>("functions")221.WithHostStorage(storage)222.WithReference(queues);223```224225**After:**226```csharp227var functions = builder.AddAzureFunctionsProject<Projects.MyFunctions>("functions")228.WithHostStorage(storage)229.WithEnvironment("AzureWebJobsSecretStorageType", "Files")230.WithReference(queues);231```232233> ๐ก **Tip:** Place `.WithEnvironment(...)` immediately after `.WithHostStorage(...)` for clarity.234235> โ ๏ธ **Why this is required:** When Aspire uses `WithHostStorage(storage)`, it configures identity-based storage URIs (e.g., `AzureWebJobsStorage__blobServiceUri`). Azure Functions' secret/key manager does **not** support these identity-based URIs โ it requires either a connection string or file-based storage. Setting `AzureWebJobsSecretStorageType=Files` switches to file-system key storage, bypassing the incompatible blob dependency.236237See [aspire-functions-secrets reference](services/functions/aspire-containerapps.md) for additional details.238239## Flags Reference240241### azd init for Aspire242243| Flag | Required | Description |244|------|----------|-------------|245| `--from-code` | โ Yes | Auto-detect AppHost, no interactive prompts |246| `-e <name>` | โ Yes | Environment name (required for non-interactive) |247| `--no-prompt` | Optional | Skip additional confirmations |248249**Complete initialization sequence:**250```bash251# 1. Initialize the environment252ENV_NAME="$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | tr ' _' '-')-dev"253azd init --from-code -e "$ENV_NAME"254255# 2. IMMEDIATELY set the user-confirmed subscription256azd env set AZURE_SUBSCRIPTION_ID <subscription-id>257258# 3. Set the location259azd env set AZURE_LOCATION <location>260261# 4. Verify configuration262azd env get-values263```264265## Common Aspire Samples266267| Sample | Repository | Notes |268|--------|------------|-------|269| orleans-voting | [dotnet/aspire-samples](https://github.com/dotnet/aspire-samples/tree/main/samples/orleans-voting) | Orleans cluster with voting app |270| AspireYarp | [dotnet/aspire-samples](https://github.com/dotnet/aspire-samples/tree/main/samples/AspireYarp) | YARP reverse proxy |271| AspireWithDapr | [dotnet/aspire-samples](https://github.com/dotnet/aspire-samples/tree/main/samples/AspireWithDapr) | Dapr integration |272| eShop | [dotnet/eShop](https://github.com/dotnet/eShop) | Reference microservices app |273274## Troubleshooting275276### Error: "no default response for prompt 'Enter a unique environment name:'"277278**Cause:** Missing `-e` flag when running `azd init --from-code` in non-interactive environment279**Solution:** Always include the `-e <environment-name>` flag280281```bash282# โ Wrong - fails in non-interactive environments (agents, CI/CD)283azd init --from-code284285# โ Correct - provides environment name upfront286ENV_NAME="$(basename "$PWD" | tr '[:upper:]' '[:lower:]' | tr ' _' '-')-dev"287azd init --from-code -e "$ENV_NAME"288```289290**Important:** This error typically occurs when:291- Running in an agent or automation context292- No TTY is available for interactive prompts293- The `-e` flag was omitted294295### Error: "no default response for prompt 'How do you want to initialize your app?'"296297**Cause:** Missing `--from-code` flag298**Solution:** Add `--from-code` to the `azd init` command299300```bash301# โ Wrong - requires interactive prompt302azd init -e "my-env"303304# โ Correct - auto-detects AppHost305azd init --from-code -e "my-env"306```307308### No AppHost detected309310**Symptoms:** `azd init --from-code` doesn't find the AppHost311312**Solutions:**3131. Verify AppHost project exists: `find . -name "*.AppHost.csproj"`3142. Check project builds: `dotnet build`3153. Ensure Aspire.Hosting package is referenced in AppHost project316317### Error: "unsupported resource type" during manifest generation318319**Symptoms:** `azd init --from-code` fails with output like:320```321error: unsupported resource type: <custom-resource-type>322```323or the manifest generation step errors on child resources (e.g., ClockHand, or other custom resource types defined in the AppHost).324325**Cause:** The AppHost contains custom Aspire resource types that azd cannot convert to Azure deployable resources. These custom types are typically:326- Demonstration resources showing developers how to build Aspire extensions for local tooling327- Resources that wrap local services without Azure equivalents328- Custom child resources (e.g., subcomponents of a custom Aspire integration)329330**Resolution:**3313321. โ **Do NOT attempt to fix this error by modifying source code** โ do not add `.ExcludeFromManifest()` calls or otherwise patch the AppHost3332. โ **Do NOT proceed with deployment** โ this is a deployment blocker, not a recoverable error3343. โ Record a blocker in the deployment plan: "AppHost contains custom Aspire resource types not supported for Azure deployment (unsupported resource type)"3354. โ Inform the user that this application is designed for local development and cannot be meaningfully deployed to Azure336337> โ ๏ธ **Why this is a hard stop:** Custom resource types that produce "unsupported resource type" errors are intentionally not deployable. Adding `.ExcludeFromManifest()` to suppress the error may allow `azd init` to succeed, but the resulting deployment would not represent the application's actual functionality.338339### Azure Functions: Secret initialization from Blob storage failed340341**Symptoms:** Azure Functions app fails at startup with error:342```343System.InvalidOperationException: Secret initialization from Blob storage failed due to missing both344an Azure Storage connection string and a SAS connection uri.345```346347**Cause:** When using `AddAzureFunctionsProject` with `WithHostStorage(storage)`, Aspire configures identity-based storage access (managed identity). However, Azure Functions' internal secret management does not support identity-based URIs and requires file-based secret storage for Container Apps deployments.348349**Solution:** Add `AzureWebJobsSecretStorageType=Files` environment variable to the Functions resource in the AppHost **before running `azd up`**:350351```csharp352var functions = builder.AddAzureFunctionsProject<Projects.ImageGallery_Functions>("functions")353.WithReference(queues)354.WithReference(blobs)355.WaitFor(storage)356.WithRoleAssignments(storage, ...)357.WithHostStorage(storage)358.WithEnvironment("AzureWebJobsSecretStorageType", "Files") // Required for Container Apps359.WithUrlForEndpoint("http", u => u.DisplayText = "Functions App");360```361362> ๐ก **Why this is required:**363> - `WithHostStorage(storage)` sets identity-based URIs like `AzureWebJobsStorage__blobServiceUri`364> - This is correct and secure for runtime storage operations365> - However, Functions' secret/key management doesn't support these URIs366> - File-based secrets are mandatory for Container Apps deployments367368> โ ๏ธ **Important:** This is required when:369> - Using `AddAzureFunctionsProject` in Aspire370> - Using `WithHostStorage()` with identity-based storage371> - Deploying to Azure Container Apps (the default for Aspire Functions)372373**Generated Infrastructure Note:**374375If you need to modify the generated Container Apps infrastructure directly, ensure the Functions container app has this environment variable:376377```bicep378resource functionsContainerApp 'Microsoft.App/containerApps@2024-03-01' = {379properties: {380template: {381containers: [382{383env: [384{385name: 'AzureWebJobsSecretStorageType'386value: 'Files'387}388// ... other environment variables389]390}391]392}393}394}395```396397### Error: azd uses wrong subscription despite user confirmation398399**Symptoms:** `azd provision --preview` shows a different subscription than the one the user confirmed400401**Cause:** The `AZURE_SUBSCRIPTION_ID` was not set immediately after `azd init --from-code`. The Azure CLI and azd can have different default subscriptions.402403**Solution:** Always set the subscription immediately after initialization:404405```bash406# After azd init --from-code completes:407azd env set AZURE_SUBSCRIPTION_ID <user-confirmed-subscription-id>408azd env set AZURE_LOCATION <location>409410# Verify before proceeding:411azd env get-values412```413414**Prevention:** Follow the complete initialization sequence in the [Flags Reference](#azd-init-for-aspire) section above.415416## References417418- [.NET Aspire Documentation](https://learn.microsoft.com/en-us/dotnet/aspire/)419- [Azure Developer CLI (azd)](https://learn.microsoft.com/en-us/azure/developer/azure-developer-cli/)420- [Aspire Samples Repository](https://github.com/dotnet/aspire-samples)421- [azd + Aspire Integration](https://learn.microsoft.com/en-us/dotnet/aspire/deployment/azure/aca-deployment-azd-in-depth)422423## Next Steps424425After `azd init --from-code`:4261. Review generated `azure.yaml` and `infra/` files (if present)4272. Set AZURE_SUBSCRIPTION_ID and AZURE_LOCATION with `azd env set`4283. Customize infrastructure as needed4294. Proceed to **azure-validate** skill4305. Deploy with **azure-deploy** skill431432> โ ๏ธ **Important for Container Apps:** If using Aspire with Container Apps, azure-validate will check and help set up required environment variables after provisioning.433