diff --git a/.openpublishing.redirection.json b/.openpublishing.redirection.json
index 37d832ab98..afc112be61 100644
--- a/.openpublishing.redirection.json
+++ b/.openpublishing.redirection.json
@@ -1051,6 +1051,58 @@
{
"source_path_from_root": "/docs/reference/aspire-faq.yml",
"redirect_url": "https://discord.com/invite/h87kDAHQgJ"
+ },
+ {
+ "source_path_from_root": "/docs/architecture/overview.md",
+ "redirect_url": "https://aspire.dev/architecture/overview/"
+ },
+ {
+ "source_path_from_root": "/docs/fundamentals/telemetry.md",
+ "redirect_url": "https://aspire.dev/fundamentals/telemetry/"
+ },
+ {
+ "source_path_from_root": "/docs/get-started/migrate-from-docker-compose.md",
+ "redirect_url": "https://aspire.dev/app-host/migrate-from-docker-compose/"
+ },
+ {
+ "source_path_from_root": "/docs/get-started/docker-compose-to-apphost-reference.md",
+ "redirect_url": "https://aspire.dev/app-host/docker-compose-to-apphost-reference/"
+ },
+ {
+ "source_path_from_root": "/docs/whats-new/dotnet-aspire-9.md",
+ "redirect_url": "https://aspire.dev/whats-new/aspire-13/"
+ },
+ {
+ "source_path_from_root": "/docs/whats-new/dotnet-aspire-9.1.md",
+ "redirect_url": "https://aspire.dev/whats-new/aspire-13-1/"
+ },
+ {
+ "source_path_from_root": "/docs/whats-new/dotnet-aspire-9.2.md",
+ "redirect_url": "https://aspire.dev/whats-new/aspire-13-1/"
+ },
+ {
+ "source_path_from_root": "/docs/whats-new/dotnet-aspire-9.3.md",
+ "redirect_url": "https://aspire.dev/whats-new/aspire-13-1/"
+ },
+ {
+ "source_path_from_root": "/docs/whats-new/dotnet-aspire-9.4.md",
+ "redirect_url": "https://aspire.dev/whats-new/aspire-13-1/"
+ },
+ {
+ "source_path_from_root": "/docs/whats-new/dotnet-aspire-9.5.md",
+ "redirect_url": "https://aspire.dev/whats-new/aspire-13-1/"
+ },
+ {
+ "source_path_from_root": "/docs/whats-new/dotnet-docs-aspire-mod0.md",
+ "redirect_url": "https://aspire.dev/whats-new/aspire-13-1/"
+ },
+ {
+ "source_path_from_root": "/docs/whats-new/dotnet-docs-aspire-mod1.md",
+ "redirect_url": "https://aspire.dev/whats-new/aspire-13-1/"
+ },
+ {
+ "source_path_from_root": "/docs/whats-new/dotnet-docs-aspire-mod2.md",
+ "redirect_url": "https://aspire.dev/whats-new/aspire-13-1/"
}
]
}
diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md
deleted file mode 100644
index ce07ed0d17..0000000000
--- a/docs/architecture/overview.md
+++ /dev/null
@@ -1,195 +0,0 @@
----
-title: Aspire architecture overview
-description: Learn about the overall architecture of Aspire, including its integrations, orchestration, and networking capabilities.
-ms.date: 07/11/2025
----
-
-# Aspire architecture overview
-
-Aspire brings together a powerful suite of tools and libraries, designed to deliver a seamless and intuitive experience for developers. Its modular and extensible architecture empowers you to define your application model with precision, orchestrating intricate systems composed of services, containers, and executables. Whether your components span different programming languages, platforms, stacks, or operating systems, Aspire ensures they work harmoniously, simplifying the complexity of modern cloud-native app development.
-
-## App model architecture
-
-Resources are the building blocks of your app model. They're used to represent abstract concepts like services, containers, executables, and external integrations. Specific resources enable developers to define dependencies on concrete implementations of these concepts. For example, a `Redis` resource can be used to represent a Redis cache, while a `Postgres` resource can represent a PostgreSQL database.
-
-While the app model is often synonymous with a collection of resources, it's also a high level representation of your entire application topology. This is important, as it's architected for lowering. In this way, Aspire can be thought of as a compiler for application topology.
-
-### Lowering the model
-
-In a traditional compiler, the process of "lowering" involves translating a high-level programming language into progressively simpler representations:
-
-- **Intermediate Representation (IR):** The first step abstracts away language-specific features, creating a platform-neutral representation.
-- **Machine Code:** The IR is then transformed into machine-specific instructions tailored to a specific CPU architecture.
-
-Similarly, Aspire applies this concept to applications, treating the app model as the high-level language:
-
-- **Intermediate constructs:** The app model is first lowered into intermediate constructs, such as cloud development kit (CDK)-style object graphs. These constructs might be platform-agnostic or partially tailored to specific targets.
-- **Target runtime representation:** Finally, a publisher generates the deployment-ready artifacts—YAML, HCL, JSON, or other formats—required by the target platform.
-
-This layered approach unlocks several key benefits:
-
-- **Validation and enrichment:** Models can be validated and enriched during the transformation process, ensuring correctness and completeness.
-- **Multi-target support:** Aspire supports multiple deployment targets, enabling flexibility across diverse environments.
-- **Customizable workflow:** Developers can hook into each phase of the process to customize behavior, tailoring the output to specific needs.
-- **Clean and portable models:** The high-level app model remains expressive, portable, and free from platform-specific concerns.
-
-Most importantly, the translation process itself is highly extensible. You can define custom transformations, enrichments, and output formats, allowing Aspire to seamlessly adapt to your unique infrastructure and deployment requirements. This extensibility ensures that Aspire remains a powerful and versatile tool, capable of evolving alongside your application's needs.
-
-### Modality and extensibility
-
-Aspire operates in two primary modes, each tailored to streamline your specific needs—detailed in the following section. Both modes use a robust set of familiar APIs and a rich ecosystem of [integrations](https://aspire.dev/integrations/overview/). Each integration simplifies working with a common service, framework, or platform, such as Redis, PostgreSQL, Azure services, or Orleans, for example. These integrations work together like puzzle pieces, enabling you to define resources, express dependencies, and configure behavior effortlessly—whether you're running locally or deploying to production.
-
-Why is modality important when it comes to the AppHost's execution context? This is because it allows you to define your app model once and with the appropriate APIs, specify how resources operate in each mode. Consider the following collection of resources:
-
-- Database: PostgreSQL
-- Cache: Redis
-- AI service: Ollama or OpenAI
-- Backend: ASP.NET Core minimal API
-- Frontend: React app
-
-Depending on the mode, the AppHost might treat these resources differently. For example, in run mode, the AppHost might use a local PostgreSQL database and Redis cache—using containers, while in publish mode, it might generate deployment artifacts for Azure PostgreSQL and Redis Cache.
-
-#### Run mode
-
-The default mode is run mode, which is ideal for local development and testing. In this mode, the Aspire AppHost orchestrates your application model, including processes, containers, and cloud emulators, to facilitate fast and iterative development. Resources behave like real runtime entities with lifecycles that mirror production. With a simple F5, the AppHost launches everything in your [app model](xref:Aspire.Hosting.ApplicationModel.DistributedApplicationModel)—storage, databases, caches, messaging, jobs, APIs, frontends—all fully configured and ready to debug locally. Let's considering the app model from the previous section—where AppHost would orchestrate the following resources locally:
-
-
-
-:::image type="content" source="media/local-app-topology-thumb.png" alt-text="Local app topology for dev-time orchestration" lightbox="media/local-app-topology.png":::
-
-For more information on how run mode works, see [Dev-time orchestration](#dev-time-orchestration).
-
-#### Publish mode
-
-The publish mode generates deployment-ready artifacts tailored to your target environment. The Aspire AppHost compiles your app model into outputs like Kubernetes manifests, Terraform configs, Bicep/ARM templates, Docker Compose files, or CDK constructs—ready for integration into any deployment pipeline. The output format depends on the chosen publisher, giving you flexibility across deployment scenarios. When you consider the app model from the previous section, the AppHost doesn't orchestrate anything—instead, it emits publish artifacts that can be used to deploy your application to a cloud provider. For example, let's assume you want to deploy to Azure—the AppHost would emit Bicep templates that define the following resources:
-
-
-
-:::image type="content" source="media/publish-app-topology-thumb.png" alt-text="Published app topology" lightbox="media/publish-app-topology.png":::
-
-For more information on how to use publish mode, see [Aspire deployments](https://aspire.dev/deployment/overview/).
-
-## Dev-time orchestration
-
-In run mode, [the AppHost orchestrates](https://aspire.dev/get-started/app-host/) all resources defined in your app model. But how does it achieve this?
-
-> [!IMPORTANT]
-> The AppHost isn't a production runtime. It's a development-time orchestration tool that simplifies the process of running and debugging your application locally.
-
-In this section, several key questions are answered to help you understand how the AppHost orchestrates your app model:
-
-- **What powers the orchestration?**
-
- Orchestration is delegated to the [Microsoft Developer Control Plane](#developer-control-plane) (DCP), which manages resource lifecycles, startup order, dependencies, and network configurations across your app topology.
-
-- **How is the app model used?**
-
- The app model defines all resources via implementations of , including containers, processes, databases, and external services—forming the blueprint for orchestration.
-
-- **What role does the AppHost play?**
-
- The AppHost provides a high-level declaration of the desired application state. It delegates execution to DCP, which interprets the app model and performs orchestration accordingly.
-
-- **What resources are monitored?**
-
- All declared resources—including containers, executables, and integrations—are monitored to ensure correct behavior and to support a fast and reliable development workflow.
-
-- **How are containers and executables managed?**
-
- Containers and processes are initialized with their configurations and launched concurrently, respecting the dependency graph defined in the app model. DCP ensures their readiness and connectivity during orchestration, starting resources as quickly as possible while maintaining the correct order dictated by their dependencies.
-
-- **How are resource dependencies handled?**
-
- Dependencies are defined in the app model and evaluated by DCP to determine correct startup sequencing, ensuring resources are available before dependents start.
-
-- **How is networking configured?**
-
- Networking—such as port bindings—is autoconfigured unless explicitly defined. DCP resolves conflicts and ensures availability, enabling seamless communication between services.
-
-The orchestration process follows a layered architecture. At its core, the AppHost represents the developer's desired view of the distributed application's resources. DCP ensures that this desired state is realized by orchestrating the resources and maintaining consistency.
-
-The [app model](https://aspire.dev/get-started/app-host/#define-the-app-model) serves as a blueprint for DCP to orchestrate your application. Under the hood, the AppHost is a .NET console application powered by the [📦 Aspire.Hosting.AppHost](https://www.nuget.org/packages/Aspire.Hosting.AppHost) NuGet package. This package includes build targets that register orchestration dependencies, enabling seamless dev-time orchestration.
-
-DCP is a Kubernetes-compatible API server, meaning it uses the same network protocols and conventions as Kubernetes. This compatibility allows the Aspire AppHost to leverage existing Kubernetes libraries for communication. Specifically, the AppHost contains an implementation of the `k8s.KubernetesClient` (from the [📦 KubernetesClient](https://www.nuget.org/packages/KubernetesClient) NuGet package), which is a .NET client for Kubernetes. This client is used to communicate with the DCP API server, enabling the AppHost to delegate orchestration tasks to DCP.
-
-When you run the AppHost, it performs the first step of "lowering" by translating the general-purpose Aspire app model into a DCP-specific model tailored for local execution in run mode. This DCP model is then handed off to DCP, which evaluates it and orchestrates the resources accordingly. This separation ensures that the AppHost focuses on adapting the Aspire app model for local execution, while DCP specializes in executing the tailored model. The following diagram helps to visualize this orchestration process:
-
-
-
-:::image type="content" source="media/app-host-dcp-flow-thumb.png" alt-text="A flow diagram depicting how the AppHost delegates to DCP." lightbox="media/app-host-dcp-flow.png":::
-
-For more information on the AppHost and APIs for building the app model, see [Aspire orchestration overview](https://aspire.dev/get-started/app-host/).
-
-### Developer Control Plane
-
-DCP is at the core of the Aspire AppHost orchestration functionality. It's responsible for orchestrating all resources defined in your app model, starting the developer dashboard, ensuring that everything is set up correctly for local development and testing. DCP manages the lifecycle of resources, applies network configurations, and resolves dependencies.
-
-DCP is written in Go, aligning with Kubernetes and its ecosystem, which are also Go-based. This choice enables deep, native integration with Kubernetes APIs, efficient concurrency, and access to mature tooling like Kubebuilder. DCP is delivered as two executables:
-
-- `dcp.exe`: API server that exposes a Kubernetes-like API endpoint for the AppHost to communicate with. Additionally, it exposes log streaming to the AppHost, which ultimately streams logs to the developer dashboard.
-- `dcpctrl.exe`: Controller that monitors the API server for new objects and changes, ensuring that the real-world environment matches the specified model.
-
-> [!NOTE]
-> DCP operates on the principle of "eventual consistency," meaning that changes to the model and the real-world environment are applied asynchronously. While this approach may introduce noticeable delays, DCP is designed to diligently synchronize both states. Unlike a "strongly consistent" system that might fail immediately on encountering issues, DCP persistently retries until the desired state is achieved or an error is conclusively determined, often resulting in a more robust alignment between the model and the real world.
-
-When the AppHost runs, it uses Kubernetes client libraries to communicate with DCP. It translates the app model into a format DCP can process by converting the model's resources into specifications. Specifically, this involves generating Kubernetes Custom Resource Definitions (CRDs) that represent the application's desired state.
-
-DCP performs the following tasks:
-
-- Prepares the resources for execution:
- - Configures service endpoints.
- - Assigns names and ports dynamically, unless explicitly set (DCP ensures that the ports are available and not in use by other processes).
- - Initializes container networks.
- - Pulls container images based on their applied [pull policy](xref:Aspire.Hosting.ApplicationModel.ImagePullPolicy).
- - Creates and starts containers.
- - Runs executables with the required arguments and environment variables.
-- Monitors resources:
- - Provides change notifications about objects managed within DCP, including process IDs, running status, and exit codes (the AppHost subscribes to these changes to manage the [application's lifecycle](https://aspire.dev/app-host/eventing/) effectively).
-- Starts the developer dashboard.
-
-Continuing from the [diagram in the previous](#app-host-dcp-flow) section, consider the following diagram that helps to visualize the responsibilities of DCP:
-
-
-
-:::image type="content" source="media/dcp-architecture-thumb.png" alt-text="A diagram depicting the architecture of the Developer Control Plane (DCP)." lightbox="media/dcp-architecture.png":::
-
-DCP logs are streamed back to the AppHost, which then forwards them to the developer dashboard. While the developer dashboard exposes commands such as start, stop, and restart, these commands are not part of DCP itself. Instead, they are implemented by the app model runtime, specifically within its "dashboard service" component. These commands operate by manipulating DCP objects—creating new ones, deleting old ones, or updating their properties. For example, restarting a .NET project involves stopping and deleting the existing representing the project and creating a new one with the same specifications.
-
-For more information on container networking, see [How container networks are managed](https://aspire.dev/fundamentals/networking-overview/#how-container-networks-are-managed).
-
-## Developer dashboard
-
-The [Aspire developer dashboard](https://aspire.dev/dashboard/overview/) is a powerful tool designed to simplify local development and resource management. It also supports a [standalone mode](https://aspire.dev/dashboard/standalone/) and integrates seamlessly when publishing to Azure Container Apps. With its intuitive interface, the dashboard empowers developers to monitor, manage, and interact with application resources effortlessly.
-
-### Monitor and manage resources
-
-The dashboard provides a user-friendly interface for inspecting resource states, viewing logs, and executing commands. Whether you're debugging locally or deploying to the cloud, the dashboard ensures you have full visibility into your application's behavior.
-
-### Built-in and custom commands
-
-The dashboard provides a set of commands for managing resources, such as start, stop, and restart. While commands appear as intuitive actions in the dashboard UI, under the hood, they operate by manipulating DCP objects. For more information, see [Stop or Start a resource](https://aspire.dev/dashboard/explore/#stop-or-start-a-resource).
-
-In addition to these built-in commands, you can define custom commands tailored to your application's needs. These custom commands are registered in the app model and seamlessly integrated into the dashboard, providing enhanced flexibility and control. Learn more about custom commands in [Custom resource commands in Aspire](https://aspire.dev/fundamentals/custom-resource-commands/).
-
-### Real-time log streaming
-
-Stay informed with the dashboard's [real-time log streaming](https://aspire.dev/dashboard/explore/#console-logs-page) feature. Logs from all resources in your app model are streamed from DCP to the AppHost and displayed in the dashboard. With advanced filtering options—by resource type, severity, and more—you can quickly pinpoint relevant information and troubleshoot effectively.
-
-The developer dashboard is more than just a tool—it's your command center for building, debugging, and managing Aspire applications with confidence and ease.
-
-## See also
-
-- [Orchestration overview](https://aspire.dev/get-started/app-host/)
-- [Explore the Aspire dashboard](https://aspire.dev/dashboard/explore/)
diff --git a/docs/deployment/docker-integration.md b/docs/deployment/docker-integration.md
index 98136680d1..d585675359 100644
--- a/docs/deployment/docker-integration.md
+++ b/docs/deployment/docker-integration.md
@@ -130,6 +130,6 @@ The Docker hosting integration captures environment variables from your app mode
- [Deploy Aspire projects to Azure Container Apps using the Aspire CLI](https://aspire.dev/deployment/azure/aca-deployment-aspire-cli/)
- [Building custom deployment pipelines](https://aspire.dev/deployment/custom-deployments/)
-- [Docker Compose to AppHost API reference](../get-started/docker-compose-to-apphost-reference.md)
+- [Docker Compose to AppHost API reference](https://aspire.dev/app-host/docker-compose-to-apphost-reference/)
- [Aspire integrations](https://aspire.dev/integrations/overview/)
- [Aspire GitHub repo](https://github.com/dotnet/aspire)
diff --git a/docs/fundamentals/telemetry.md b/docs/fundamentals/telemetry.md
deleted file mode 100644
index b5b871f8e0..0000000000
--- a/docs/fundamentals/telemetry.md
+++ /dev/null
@@ -1,64 +0,0 @@
----
-title: Aspire telemetry
-description: Learn about essential telemetry concepts for Aspire.
-ms.date: 07/17/2025
----
-
-# Aspire telemetry
-
-One of the primary objectives of Aspire is to ensure that apps are straightforward to debug and diagnose. Aspire integrations automatically set up Logging, Tracing, and Metrics configurations, which are sometimes known as the pillars of observability, using the [.NET OpenTelemetry SDK](https://github.com/open-telemetry/opentelemetry-dotnet).
-
-- **[Logging](/dotnet/core/diagnostics/logging-tracing)**: Log events describe what's happening as an app runs. A baseline set is enabled for Aspire integrations by default and more extensive logging can be enabled on-demand to diagnose particular problems.
-
-- **[Tracing](/dotnet/core/diagnostics/distributed-tracing)**: Traces correlate log events that are part of the same logical activity (e.g. the handling of a single request), even if they're spread across multiple machines or processes.
-
-- **[Metrics](/dotnet/core/diagnostics/metrics)**: Metrics expose the performance and health characteristics of an app as simple numerical values. As a result, they have low performance overhead and many services configure them as always-on telemetry. This also makes them suitable for triggering alerts when potential problems are detected.
-
-Together, these types of telemetry allow you to gain insights into your application's behavior and performance using various monitoring and analysis tools. Depending on the backing service, some integrations may only support some of these features.
-
-## Aspire OpenTelemetry integration
-
-The [.NET OpenTelemetry SDK](https://github.com/open-telemetry/opentelemetry-dotnet) includes features for gathering data from several .NET APIs, including , , , and . These APIs correspond to telemetry features like logging, tracing, and metrics. Aspire projects define OpenTelemetry SDK configurations in the _ServiceDefaults_ project. For more information, see [Aspire service defaults](https://aspire.dev/fundamentals/service-defaults/).
-
-By default, the `ConfigureOpenTelemetry` method enables logging, tracing, and metrics for the app. It also adds exporters for these data points so they can be collected by other monitoring tools.
-
-## Export OpenTelemetry data for monitoring
-
-Aspire enables export of telemetry data to a data store or reporting tool. The telemetry export mechanism relies on the [OpenTelemetry protocol (OTLP)](https://opentelemetry.io/docs/specs/otel/protocol), which serves as a standardized approach for transmitting telemetry data through REST or gRPC. The `ConfigureOpenTelemetry` method also registers exporters to provide your telemetry data to other monitoring tools, such as Prometheus or Azure Monitor. For more information, see [OpenTelemetry configuration](https://aspire.dev/fundamentals/service-defaults/#opentelemetry-configuration).
-
-## OpenTelemetry environment variables
-
-OpenTelemetry has a [list of known environment variables](https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/) that configure the most important behavior for collecting and exporting telemetry. OpenTelemetry SDKs, including the .NET SDK, support reading these variables.
-
-Aspire projects launch with environment variables that configure the name and ID of the app in exported telemetry and set the address endpoint of the OTLP server to export data. For example:
-
-- `OTEL_SERVICE_NAME` = myfrontend
-- `OTEL_RESOURCE_ATTRIBUTES` = service.instance.id=1a5f9c1e-e5ba-451b-95ee-ced1ee89c168
-- `OTEL_EXPORTER_OTLP_ENDPOINT` = `http://localhost:4318`
-
-The environment variables are automatically set in local development.
-
-## Aspire local development
-
-When you create an Aspire project, the Aspire dashboard provides a UI for viewing app telemetry by default. Telemetry data is sent to the dashboard using OTLP, and the dashboard implements an OTLP server to receive telemetry data and store it in memory. The Aspire debugging workflow is as follows:
-
-- Developer starts the Aspire project with debugging, presses F5.
-- Aspire dashboard and developer control plane (DCP) start.
-- App configuration is run in the _AppHost_ project.
- - OpenTelemetry environment variables are automatically added to .NET projects during app configuration.
- - DCP provides the name (`OTEL_SERVICE_NAME`) and ID (`OTEL_RESOURCE_ATTRIBUTES`) of the app in exported telemetry.
- - The OTLP endpoint is an HTTP/2 port started by the dashboard. This endpoint is set in the `OTEL_EXPORTER_OTLP_ENDPOINT` environment variable on each project. That tells projects to export telemetry back to the dashboard.
- - Small export intervals (`OTEL_BSP_SCHEDULE_DELAY`, `OTEL_BLRP_SCHEDULE_DELAY`, `OTEL_METRIC_EXPORT_INTERVAL`) so data is quickly available in the dashboard. Small values are used in local development to prioritize dashboard responsiveness over efficiency.
-- The DCP starts configured projects, containers, and executables.
-- Once started, apps send telemetry to the dashboard.
-- Dashboard displays near real-time telemetry of all Aspire projects.
-
-All of these steps happen internally, so in most cases the developer simply needs to run the app to see this process in action.
-
-## Aspire deployment
-
-Aspire deployment environments should configure OpenTelemetry environment variables that make sense for their environment. For example, `OTEL_EXPORTER_OTLP_ENDPOINT` should be configured to the environment's local OTLP collector or monitoring service.
-
-Aspire telemetry works best in environments that support OTLP. OTLP exporting is disabled if `OTEL_EXPORTER_OTLP_ENDPOINT` isn't configured.
-
-For more information, see [Aspire deployments](https://aspire.dev/deployment/overview/).
diff --git a/docs/get-started/docker-compose-to-apphost-reference.md b/docs/get-started/docker-compose-to-apphost-reference.md
deleted file mode 100644
index 4efec3d9f1..0000000000
--- a/docs/get-started/docker-compose-to-apphost-reference.md
+++ /dev/null
@@ -1,189 +0,0 @@
----
-title: Docker Compose to Aspire AppHost API reference
-description: Quick reference for converting Docker Compose YAML syntax to Aspire C# API calls.
-ms.date: 06/26/2025
-ms.topic: reference
-ai-usage: ai-generated
----
-
-# Docker Compose to Aspire AppHost API reference
-
-This reference provides systematic mappings from Docker Compose YAML syntax to equivalent Aspire C# API calls. Use these tables as a quick reference when converting your existing Docker Compose files to Aspire application host configurations. Each section covers a specific aspect of container orchestration, from basic service definitions to advanced networking and resource management.
-
-## Service definitions
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `services:` | `var builder = DistributedApplication.CreateBuilder(args)` | Root application builder used for adding and representing resources. |
-| `service_name:` | `builder.Add*("service_name")` | Service name becomes resource name. |
-
-**Related links:**
-
-- [Docker Compose services reference](https://docs.docker.com/compose/compose-file/05-services/)
--
-
-## Images and builds
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `image: nginx:latest` | `builder.AddContainer("name", "nginx:latest")` | Direct image reference. |
-| `build: .` | `builder.AddDockerfile("name", ".")` | Build from Dockerfile. |
-| `build: ./path` | `builder.AddDockerfile("name", "./path")` | Build from specific path. |
-| `build.context: ./app` | `builder.AddDockerfile("name", "./app")` | Build context. |
-| `build.dockerfile: Custom.dockerfile` | `builder.Add*("name").WithDockerfile("Custom.dockerfile")` | Custom Dockerfile name. |
-
-**Related links:**
-
-- [Docker Compose build reference](https://docs.docker.com/compose/compose-file/build/)
--
--
-
-## .NET projects
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `build: ./MyApi` (for .NET) | `builder.AddProject("myapi")` | Direct .NET project reference. |
-
-**Related links:**
-
-- [Docker Compose build reference](https://docs.docker.com/compose/compose-file/build/)
--
-
-## Port mappings
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `ports: ["8080:80"]` | `.WithHttpEndpoint(port: 8080, targetPort: 80)` | HTTP endpoint mapping. Ports are optional; dynamic ports are used if omitted. |
-| `ports: ["443:443"]` | `.WithHttpsEndpoint(port: 443, targetPort: 443)` | HTTPS endpoint mapping. Ports are optional; dynamic ports are used if omitted. |
-| `expose: ["8080"]` | `.WithEndpoint(port: 8080)` | Internal port exposure. Ports are optional; dynamic ports are used if omitted. |
-
-**Related links:**
-
-- [Docker Compose ports reference](https://docs.docker.com/compose/compose-file/05-services/#ports)
--
--
--
-
-## Environment variables
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `environment: KEY=value` | `.WithEnvironment("KEY", "value")` | Static environment variable. |
-| `environment: KEY=${HOST_VAR}` | `.WithEnvironment(context => context.EnvironmentVariables["KEY"] = hostVar)` | Environment variable with callback context. |
-| `env_file: .env` | Not supported | Environment file (custom implementation). |
-
-**Related links:**
-
-- [Docker Compose environment reference](https://docs.docker.com/compose/compose-file/05-services/#environment)
--
-
-## Volumes and storage
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `volumes: ["data:/app/data"]` | `.WithVolume("data", "/app/data")` | Named volume. |
-| `volumes: ["./host:/container"]` | `.WithBindMount("./host", "/container")` | Bind mount. |
-| `volumes: ["./config:/app:ro"]` | `.WithBindMount("./config", "/app", isReadOnly: true)` | Read-only bind mount. |
-
-**Related links:**
-
-- [Docker Compose volumes reference](https://docs.docker.com/compose/compose-file/05-services/#volumes)
--
--
-
-## Dependencies and ordering
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `depends_on: [db]` | `.WithReference(db)` | Service dependency with connection. |
-| `depends_on: db: condition: service_started` | `.WaitFor(db)` | Wait for service start. |
-| `depends_on: db: condition: service_healthy` | `.WaitForCompletion(db)` | Wait for health check. |
-
-**Related links:**
-
-- [Docker Compose depends_on reference](https://docs.docker.com/compose/compose-file/05-services/#depends_on)
--
--
--
-
-## Networks
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `networks: [backend]` | Automatic | Aspire handles networking automatically. |
-| Custom networks | Not needed | Service discovery handles inter-service communication. |
-
-**Related links:**
-
-- [Docker Compose networks reference](https://docs.docker.com/compose/compose-file/05-services/#networks)
-- [Aspire service discovery](https://aspire.dev/fundamentals/service-discovery/)
-
-## Resource limits
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `deploy.resources.limits.memory: 512m` | Not supported | Resource limits aren't supported in Aspire. |
-| `deploy.resources.limits.cpus: 0.5` | Not supported | Resource limits aren't supported in Aspire. |
-
-**Related links:**
-
-- [Docker Compose deploy reference](https://docs.docker.com/compose/compose-file/deploy/)
-
-## Health checks
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `healthcheck.test: ["CMD", "curl", "http://localhost/health"]` | Built-in for integrations. | Aspire integrations include health checks. |
-| `healthcheck.interval: 30s` | Configurable in integration. | Health check configuration varies by resource type. |
-
-**Related links:**
-
-- [Docker Compose healthcheck reference](https://docs.docker.com/compose/compose-file/05-services/#healthcheck)
-- [Aspire health checks](https://aspire.dev/fundamentals/health-checks/)
-
-## Restart policies
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `restart: unless-stopped` | Not supported | Restart policies aren't supported in Aspire. |
-| `restart: always` | Not supported | Restart policies aren't supported in Aspire. |
-| `restart: no` | Default | No restart policy. |
-
-**Related links:**
-
-- [Docker Compose restart reference](https://docs.docker.com/compose/compose-file/05-services/#restart)
-
-## Logging
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `logging.driver: json-file` | Built-in | Aspire provides integrated logging. |
-| `logging.options.max-size: 10m` | Dashboard configuration | Managed through Aspire dashboard. |
-
-**Related links:**
-
-- [Docker Compose logging reference](https://docs.docker.com/compose/compose-file/05-services/#logging)
-- [Aspire telemetry](../fundamentals/telemetry.md)
-
-## Database services
-
-| Docker Compose | Aspire | Notes |
-|----------------|-------------|-------|
-| `image: postgres:15` | `builder.AddPostgres("name")` | PostgreSQL with automatic configuration. |
-| `image: mysql:8` | `builder.AddMySql("name")` | MySQL with automatic configuration. |
-| `image: redis:7` | `builder.AddRedis("name")` | Redis with automatic configuration. |
-| `image: mongo:latest` | `builder.AddMongoDB("name")` | MongoDB with automatic configuration. |
-
-**Related links:**
-
-- [Docker Compose services reference](https://docs.docker.com/compose/compose-file/05-services/)
--
--
--
--
-
-## See also
-
-- [Migrate from Docker Compose to Aspire](migrate-from-docker-compose.md)
-- [Aspire orchestration overview](https://aspire.dev/get-started/app-host/)
-- [Add Dockerfiles to your .NET app model](https://aspire.dev/app-host/withdockerfile/)
diff --git a/docs/get-started/migrate-from-docker-compose.md b/docs/get-started/migrate-from-docker-compose.md
deleted file mode 100644
index 06feb2ec7b..0000000000
--- a/docs/get-started/migrate-from-docker-compose.md
+++ /dev/null
@@ -1,389 +0,0 @@
----
-title: Migrate from Docker Compose to Aspire
-description: Learn how to migrate your Docker Compose applications to Aspire and understand the key conceptual differences.
-ms.date: 06/26/2025
-ms.topic: how-to
-ai-usage: ai-generated
----
-
-# Migrate from Docker Compose to Aspire
-
-This guide helps you understand how to migrate applications from Docker Compose to Aspire, highlighting the key conceptual differences and providing practical examples for common migration scenarios.
-
-## Understand the differences
-
-While Docker Compose and Aspire might seem similar at first glance, they serve different purposes and operate at different levels of abstraction.
-
-### Docker Compose vs Aspire
-
-| | Docker Compose | Aspire |
-|--|--|--|
-| **Primary purpose** | Container orchestration | Development-time orchestration and app composition. |
-| **Scope** | Container-focused | Multi-resource (containers, .NET projects, cloud resources). |
-| **Configuration** | YAML-based | C#-based, strongly typed. |
-| **Target environment** | Any Docker runtime | Development and cloud deployment. |
-| **Service discovery** | DNS-based container discovery | Built-in service discovery with environment variables. |
-| **Development experience** | Manual container management | Integrated tooling, dashboard, and telemetry. |
-
-For more information, see [Docker Compose to Aspire AppHost API reference](docker-compose-to-apphost-reference.md).
-
-### Key conceptual shifts
-
-When migrating from Docker Compose to Aspire, consider these conceptual differences:
-
-- **From YAML to C#**: Configuration moves from declarative YAML to imperative, strongly-typed C# code.
-- **From containers to resources**: Aspire manages not just containers, but .NET projects, executables, parameters, all as resources.
-- **From manual networking to service discovery**: Aspire automatically configures service discovery and connection strings.
-- **From development gaps to integrated experience**: Aspire provides dashboard, telemetry, and debugging integration.
-
-For a comprehensive reference mapping Docker Compose YAML syntax to Aspire C# API calls, see [Docker Compose to Aspire AppHost API reference](docker-compose-to-apphost-reference.md).
-
-**Related links:**
-
-- [Docker Compose overview](https://docs.docker.com/compose/)
-- [Aspire overview](https://aspire.dev/get-started/what-is-aspire/)
-- [Aspire orchestration overview](https://aspire.dev/get-started/app-host/)
-
-## Common migration patterns
-
-This section demonstrates practical migration scenarios that you'll likely encounter when moving from Docker Compose to Aspire. Each pattern shows a complete Docker Compose example alongside its Aspire equivalent, highlighting the key differences and benefits of the migration.
-
-The patterns covered include:
-
-- **Multi-service web applications** with frontend, API, and database components.
-- **Container-based services** using existing Docker images.
-- **Environment variables and configuration** management strategies.
-- **Custom networks and volumes** for data persistence and service isolation.
-
-These examples represent the most common use cases, but Aspire's flexibility allows for many other scenarios. If your specific use case isn't covered here, you can combine these patterns or refer to the comprehensive API reference above.
-
-### Multi-service web application
-
-**Docker Compose example:**
-
-```yaml
-version: '3.8'
-services:
- frontend:
- build: ./frontend
- ports:
- - "3000:3000"
- depends_on:
- - api
- environment:
- - API_URL=http://api:5000
-
- api:
- build: ./api
- ports:
- - "5000:5000"
- depends_on:
- - database
- environment:
- - ConnectionStrings__DefaultConnection=Host=database;Database=myapp;Username=postgres;Password=secret
-
- database:
- image: postgres:15
- environment:
- - POSTGRES_DB=myapp
- - POSTGRES_USER=postgres
- - POSTGRES_PASSWORD=secret
- volumes:
- - postgres_data:/var/lib/postgresql/data
-
-volumes:
- postgres_data:
-```
-
-**Aspire equivalent:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Add the database
-var database = builder.AddPostgres("postgres")
- .WithEnvironment("POSTGRES_DB", "myapp")
- .AddDatabase("myapp");
-
-// Add the API project
-var api = builder.AddProject("api")
- .WithReference(database);
-
-// Add the frontend project
-var frontend = builder.AddProject("frontend")
- .WithReference(api);
-
-builder.Build().Run();
-```
-
-**Key differences:**
-
-- **Service dependencies**: `depends_on` becomes `WithReference()` which also configures service discovery.
-- **Environment variables**: Connection strings are automatically generated and injected.
-- **Build context**: Build context is capable of using Dockerfiles, .NET projects, Node.js apps, and more instead of just Dockerfile builds.
-- **Data persistence**: Volumes are automatically managed by Aspire.
-
-### Container-based services
-
-**Docker Compose example:**
-
-```yaml
-version: '3.8'
-services:
- web:
- build: .
- ports:
- - "8080:8080"
- depends_on:
- - redis
- - postgres
-
- redis:
- image: redis:7
- ports:
- - "6379:6379"
-
- postgres:
- image: postgres:15
- environment:
- POSTGRES_PASSWORD: secret
- volumes:
- - postgres_data:/var/lib/postgresql/data
-
-volumes:
- postgres_data:
-```
-
-**Aspire equivalent:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Add backing services
-var cache = builder.AddRedis("redis");
-var database = builder.AddPostgres("postgres", password: "secret")
- .AddDatabase("main");
-
-// Add the containerized web application
-var web = builder.AddContainer("web", "myapp:latest")
- .WithHttpEndpoint(port: 8080, targetPort: 8080)
- .WithReference(cache)
- .WithReference(database);
-
-builder.Build().Run();
-```
-
-### Environment variables and configuration
-
-**Docker Compose approach:**
-
-```yaml
-services:
- app:
- image: myapp:latest
- environment:
- - DATABASE_URL=postgresql://user:pass@db:5432/myapp
- - REDIS_URL=redis://cache:6379
- - API_KEY=${API_KEY}
- - LOG_LEVEL=info
-```
-
-**Aspire approach:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Add external parameter
-var apiKey = builder.AddParameter("apiKey", secret: true);
-
-var database = builder.AddPostgres("db")
- .AddDatabase("myapp");
-
-var cache = builder.AddRedis("cache");
-
-var app = builder.AddContainer("app", "myapp:latest")
- .WithReference(database) // Automatically sets DATABASE_URL
- .WithReference(cache) // Automatically sets REDIS_URL
- .WithEnvironment("API_KEY", apiKey)
- .WithEnvironment("LOG_LEVEL", "info");
-
-builder.Build().Run();
-```
-
-**Key differences:**
-
-- **Automatic connection strings**: Database and cache URLs are automatically generated.
-- **Typed parameters**: External configuration uses strongly-typed parameters instead of environment variable substitution.
-- **Service discovery**: References automatically configure the correct service endpoints.
-
-### Custom networks and volumes
-
-**Docker Compose example:**
-
-```yaml
-version: '3.8'
-services:
- app:
- image: myapp:latest
- volumes:
- - app_data:/data
- - ./config:/app/config:ro
- networks:
- - backend
-
- worker:
- image: myworker:latest
- volumes:
- - app_data:/shared
- networks:
- - backend
-
-networks:
- backend:
-
-volumes:
- app_data:
-```
-
-**Aspire equivalent:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Create a named volume
-var appData = builder.AddVolume("app-data");
-
-var app = builder.AddContainer("app", "myapp:latest")
- .WithVolume(appData, "/data")
- .WithBindMount("./config", "/app/config", isReadOnly: true);
-
-var worker = builder.AddContainer("worker", "myworker:latest")
- .WithVolume(appData, "/shared");
-
-builder.Build().Run();
-```
-
-**Key differences:**
-
-- **Simplified networking**: Aspire automatically handles container networking.
-- **Volume management**: Named volumes are created and managed through the resource model.
-- **Bind mounts**: Host directories can be mounted with `WithBindMount()`.
-
-**Related links:**
-
-- [Docker Compose specification](https://docs.docker.com/compose/compose-file/)
-- [Aspire AppHost overview](https://aspire.dev/get-started/app-host/)
-- [Add Dockerfiles to your .NET app model](https://aspire.dev/app-host/withdockerfile/)
-
-## Migration strategy
-
-Successfully migrating from Docker Compose to Aspire requires a systematic approach. The following steps provide a proven methodology for moving your applications while minimizing disruption and ensuring all components work correctly in the new environment.
-
-### 1. Assess your current setup
-
-Before migrating, inventory your Docker Compose setup:
-
-- **Services**: Identify all services including databases, caches, APIs, and web applications.
-- **Dependencies**: Map out service dependencies from `depends_on` declarations.
-- **Data persistence**: Catalog all volumes and bind mounts used for data storage.
-- **Environment variables**: List all configuration variables and secrets.
-- **Custom networks**: Identify any custom networking requirements and configurations.
-
-### 2. Create the Aspire AppHost
-
-Start by creating a new Aspire project:
-
-```bash
-dotnet new aspire-apphost -o MyApp.AppHost
-```
-
-### 3. Migrate services incrementally
-
-Migrate services one by one, starting with backing services (databases, caches) and then applications:
-
-1. **Add backing services** like PostgreSQL, Redis, and other infrastructure components.
-1. **Convert .NET applications** to project references for better integration.
-1. **Convert other containers** using `AddContainer()` for existing Docker images.
-1. **Configure dependencies** with `WithReference()` to establish service relationships.
-1. **Set up environment variables** and parameters for configuration management.
-
-### 4. Handle data migration
-
-For persistent data:
-
-- Use `WithVolume()` for named volumes that need to persist data.
-- Use `WithBindMount()` for host directory mounts when you need direct access to host files.
-- Consider using `WithDataVolume()` for database persistence with automatic volume management.
-
-### 5. Test and validate
-
-- Start the Aspire AppHost and verify all services start correctly.
-- Check the dashboard to confirm service health and connectivity status.
-- Validate that inter-service communication works as expected.
-- Test with your existing client applications to ensure compatibility.
-
-**Related links:**
-
-- [Docker Compose migration checklist](https://docs.docker.com/compose/migrate/)
-- [Build your first Aspire app](https://aspire.dev/get-started/first-app/)
-- [Aspire testing overview](https://aspire.dev/testing/overview/)
-
-## Migration troubleshooting
-
-When migrating from Docker Compose to Aspire, you might encounter some common challenges. This section provides solutions to frequently encountered issues and guidance on how to troubleshoot problems that arise during the migration process.
-
-### Common issues and solutions
-
-**Service discovery not working**
-
-- Ensure you're using `WithReference()` to establish dependencies between services.
-- Check that services are using the correct environment variable names for connections.
-- Review the dashboard to verify environment variables are injected correctly.
-
-**Database connections failing**
-
-- Verify the database is fully started before dependent services attempt to connect.
-- Use `WaitFor()` to ensure proper startup ordering:
-
- ```csharp
- var api = builder.AddProject("api")
- .WithReference(database)
- .WaitFor(database);
- ```
-
-**Volume mounting issues**
-
-- Use absolute paths for bind mounts to avoid path resolution issues.
-- Ensure the host directory exists and has proper permissions before mounting.
-- Consider using named volumes instead of bind mounts where possible for better portability.
-
-**Port conflicts**
-
-- Aspire automatically assigns ports to avoid conflicts between services.
-- Use `WithHttpEndpoint()` to specify custom ports if needed for external access.
-- Check the dashboard for actual assigned ports during development.
-
-**Related links:**
-
-- [Docker Compose FAQ](https://docs.docker.com/compose/faq/)
-- [Container runtime unhealthy](../troubleshooting/container-runtime-unhealthy.md)
-- [Container runtime 'podman' could not be found in WSL](../troubleshooting/podman-wsl-not-found.md)
-- [Aspire dashboard overview](https://aspire.dev/dashboard/overview/)
-
-## Next steps
-
-After migrating to Aspire:
-
-- Explore [Aspire integrations](https://aspire.dev/integrations/overview/) to replace custom container configurations.
-- Set up [health checks](https://aspire.dev/fundamentals/health-checks/) for better monitoring.
-- Configure [telemetry](../fundamentals/telemetry.md) for observability.
-- Learn about [deployment options](https://aspire.dev/deployment/overview/) for production environments.
-- Consider [testing](https://aspire.dev/testing/overview/) your distributed application.
-
-## See also
-
-- [Aspire overview](https://aspire.dev/get-started/what-is-aspire/)
-- [AspiriFridays stream](https://www.youtube.com/@aspiredotdev)
-- [Aspire orchestration overview](https://aspire.dev/get-started/app-host/)
-- [Docker Compose enhancements in Aspire 9.3](../whats-new/dotnet-aspire-9.3.md#-docker-compose-enhancements)
-- [Add Dockerfiles to your .NET app model](https://aspire.dev/app-host/withdockerfile/)
diff --git a/docs/toc.yml b/docs/toc.yml
index ba50d573a8..32452d889b 100644
--- a/docs/toc.yml
+++ b/docs/toc.yml
@@ -4,13 +4,6 @@ items:
- name: Get Started
items:
- - name: Migrate to Aspire
- items:
- - name: From Docker Compose
- href: get-started/migrate-from-docker-compose.md
- displayName: docker compose,migration,migrate
- - name: Docker Compose to AppHost API reference
- href: get-started/docker-compose-to-apphost-reference.md
- name: Setup and tooling
items:
- name: Overview
@@ -33,9 +26,6 @@ items:
- name: AppHost
items:
- - name: Architecture overview
- displayName: aspire architecture,aspire app,aspire apphost,aspire app model
- href: architecture/overview.md
- name: Locally orchestrate
items:
- name: Resources in Aspire
@@ -64,9 +54,6 @@ items:
href: https://aspire.dev/fundamentals/service-defaults/
- name: Launch profiles
href: https://aspire.dev/fundamentals/launch-profiles/
- - name: Telemetry
- displayName: otel,otlp,telemetry,grpc,opentelemetry,protobuf,traceparent
- href: fundamentals/telemetry.md
- name: Health checks
href: https://aspire.dev/fundamentals/health-checks/
diff --git a/docs/whats-new/dotnet-aspire-9.1.md b/docs/whats-new/dotnet-aspire-9.1.md
deleted file mode 100644
index bf16ce850d..0000000000
--- a/docs/whats-new/dotnet-aspire-9.1.md
+++ /dev/null
@@ -1,329 +0,0 @@
----
-title: What's new in Aspire 9.1
-description: Learn what's new in the official general availability release of Aspire 9.1.
-ms.date: 10/01/2025
----
-
-# What's new in Aspire 9.1
-
-📢 Aspire 9.1 is the next minor version release of Aspire; it supports _both_:
-
-- .NET 8.0 Long Term Support (LTS) _or_
-- .NET 9.0 Standard Term Support (STS).
-
-> [!NOTE]
-> You're able to use Aspire 9.1 with either .NET 8 or .NET 9!
-
-As always, we focused on highly requested features and pain points from the community. Our theme for 9.1 was "polish, polish, polish"—so you see quality of life fixes throughout the whole platform. Some highlights from this release are resource relationships in the dashboard, support for working in GitHub Codespaces, and publishing resources as a Dockerfile.
-
-If you have feedback, questions, or want to contribute to Aspire, collaborate with us on [:::image type="icon" source="../media/github-mark.svg" border="false"::: GitHub](https://github.com/dotnet/aspire) or join us on [:::image type="icon" source="../media/discord-icon.svg" border="false"::: Discord](https://discord.com/invite/h87kDAHQgJ) to chat with team members.
-
-Whether you're new to Aspire or have been with us since the preview, it's important to note that Aspire releases out-of-band from .NET releases. While major versions of Aspire align with .NET major versions, minor versions are released more frequently. For more details on .NET and Aspire version support, see:
-
-- [.NET support policy](https://dotnet.microsoft.com/platform/support/policy): Definitions for LTS and STS.
-- [Aspire support policy](https://dotnet.microsoft.com/platform/support/policy/aspire): Important unique product life cycle details.
-
-## ⬆️ Upgrade to Aspire 9.1
-
-Moving between minor releases of Aspire is simple:
-
-1. In your AppHost project file (that is, _MyApp.AppHost.csproj_), update the [📦 Aspire.AppHost.Sdk](https://www.nuget.org/packages/Aspire.AppHost.Sdk) NuGet package to version `9.1.0`:
-
- ```xml
-
-
-
-
-
-
-
- ```
-
- For more information, see [Aspire SDK](xref:dotnet/aspire/sdk).
-
-1. Check for any NuGet package updates, either using the NuGet Package Manager in Visual Studio or the **Update NuGet Package** command in VS Code.
-1. Update to the latest [Aspire templates](../fundamentals/aspire-sdk-templates.md) by running the following .NET command line:
-
- ```dotnetcli
- dotnet new update
- ```
-
- > [!NOTE]
- > The `dotnet new update` command updates all of your templates to the latest version.
-
-If your AppHost project file doesn't have the `Aspire.AppHost.Sdk` reference, you might still be using Aspire 8. To upgrade to 9.0, you can follow [the documentation from last release](../get-started/upgrade-to-aspire-9.md).
-
-## 🌱 Improved onboarding experience
-
-The onboarding experience for Aspire is improved with 9.1. The team worked on creating a GitHub Codespaces template that installs all the necessary dependencies for Aspire, making it easier to get started, including the templates and the ASP.NET Core developer certificate. Additionally, there's support for Dev Containers. For more information, see:
-
-- [Aspire and GitHub Codespaces](../get-started/github-codespaces.md)
-- [Aspire and Visual Studio Code Dev Containers](../get-started/dev-containers.md)
-
-## 🔧 Dashboard UX and customization
-
-With every release of Aspire, the [dashboard](https://aspire.dev/dashboard/overview/) gets more powerful and customizable, this release is no exception. The following features were added to the dashboard in Aspire 9.1:
-
-### 🧩 Resource relationships
-
-The dashboard now supports "parent" and "child" resource relationships. For instance, when you create a Postgres instance with multiple databases, these databases are nested under the same instance on the **Resource** page.
-
-:::image type="content" source="media/dashboard-parentchild.png" lightbox="media/dashboard-parentchild.png" alt-text="A screenshot of the Aspire dashboard showing the Postgres resource with a database nested underneath it.":::
-
-For more information, see [Explore the Aspire dashboard](https://aspire.dev/dashboard/explore/).
-
-### 🔤 Localization overrides
-
-The dashboard defaults to the language set in your browser. This release introduces the ability to override this setting and change the dashboard language independently from the browser language. Consider the following screen capture that demonstrates the addition of the language dropdown in the dashboard:
-
-:::image type="content" source="media/dashboard-language.png" lightbox="media/dashboard-language.png" alt-text="A screenshot of the Aspire dashboard showing the new flyout menu to change language.":::
-
-### 🗑️ Clear logs and telemetry from the dashboard
-
-New buttons were added to the **Console logs**, **Structured logs**, **Traces** and **Metrics** pages to clear data. There's also a "Remove all" button in the settings popup to remove everything with one action.
-
-Now you use this feature to reset the dashboard to a blank slate, test your app, view only the relevant logs and telemetry, and repeat.
-
-:::image type="content" source="media/dashboard-remove-telemetry.png" lightbox="media/dashboard-remove-telemetry.png" alt-text="A screenshot of the Aspire dashboard showing the remove button on the structured logs page.":::
-
-We 💜 love the developer community and thrive on its feedback, collaboration, and contributions. This feature is a community contribution from [@Daluur](https://github.com/Daluur). Join us in celebrating their contribution by using the feature!
-
-> [!TIP]
-> If you're interested in contributing to Aspire, look for issues labeled with [good first issue](https://github.com/dotnet/aspire/issues?q=is%3Aissue%20state%3Aopen%20label%3A%22good%20first%20issue%22) and follow the [contributor guide](https://github.com/dotnet/aspire/blob/main/docs/contributing.md).
-
-### 🔢 New filtering
-
-You can now filter what you see in the **Resource** page by **Resource type**, **State**, and **Health state**. Consider the following screen capture, which demonstrates the addition of the filter options in the dashboard:
-
-:::image type="content" source="media/dashboard-filter.png" lightbox="media/dashboard-filter.png" alt-text="A screenshot of the Aspire dashboard showing the new filter options.":::
-
-### 📝 More resource details
-
-When you select a resource in the dashboard, the details pane now displays new data points, including **References**, **Back references**, and **Volumes** with their mount types. This enhancement provides a clearer and more comprehensive view of your resources, improving the overall user experience by making relevant details more accessible.
-
-:::image type="content" source="media/dashboard-resourcedetails.png" lightbox="media/dashboard-resourcedetails.png" alt-text="A screenshot of the Aspire dashboard with references and back references showing.":::
-
-For more information, see [Aspire dashboard: Resources page](https://aspire.dev/dashboard/explore/#resources-page).
-
-### 🛡️ CORS support for custom local domains
-
-You can now set the `ASPIRE_DASHBOARD_CORS_ALLOWED_ORIGINS` environment variable to allow the dashboard to receive telemetry from other browser apps, such as if you have resources running on custom localhost domains.
-
-For more information, see [Aspire AppHost: Dashboard configuration](https://aspire.dev/app-host/configuration/#dashboard).
-
-### 🪵 Flexibility with console logs
-
-The console log page has two new options. You're now able to download your logs so you can view them in your own diagnostics tools. Plus, you can turn timestamps on or off to reduce visual clutter when needed.
-
-:::image type="content" source="media/consolelogs-download.png" lightbox="media/consolelogs-download.png" alt-text="A screenshot of the console logs page with the download button, turn off timestamps button, and logs that don't show timestamps.":::
-
-For more information, see [Aspire dashboard: Console logs page](https://aspire.dev/dashboard/explore/#console-logs-page).
-
-### 🎨 Various UX improvements
-
-Several new features in Aspire 9.1 enhance and streamline the following popular tasks:
-
-- ▶️ Resource commands, such as **Start** and **Stop** buttons, are now available on the **Console logs** page.
-- 🔍 Single selection to open in the _text visualizer_.
-- 🔗 URLs within logs are now automatically clickable, with commas removed from endpoints.
-
-Additionally, the 🖱️ scroll position resets when switching between different resources—this helps to visually reset the current resource view.
-
-For more details on the latest dashboard enhancements, check out [James Newton-King on :::image type="icon" source="../media/bluesky-icon.svg" border="false"::: Bluesky](https://bsky.app/profile/james.newtonking.com), where he's been sharing new features daily.
-
-## ⚙️ Local development enhancements
-
-In Aspire 9.1, several improvements to streamline your local development experience were an emphasis. These enhancements are designed to provide greater flexibility, better integration with Docker, and more efficient resource management. Here are some of the key updates:
-
-### ▶️ Start resources on demand
-
-You can now tell resources not to start with the rest of your app by using on the resource in your AppHost. Then, you can start it whenever you're ready from inside the dashboard.
-
-For more information, see [Configure explicit resource start](../fundamentals/orchestrate-resources.md#configure-explicit-resource-start).
-
-### 🐳 Better Docker integration
-
-The `PublishAsDockerfile()` feature was introduced for all projects and executable resources. This enhancement allows for complete customization of the Docker container and Dockerfile used during the publish process.
-
-While this API was available in previous versions, it couldn't be used with or types.
-
-### 🧹 Cleaning up Docker networks
-
-In 9.1, we addressed a persistent issue where Docker networks created by Aspire would remain active even after the application was stopped. This bug, tracked in [Aspire GitHub issue #6504](https://github.com/dotnet/aspire/issues/6504), is resolved. Now, Docker networks are properly cleaned up, ensuring a more efficient and tidy development environment.
-
-### ✅ Socket address issues fixed
-
-Several users reported issues ([#6693](https://github.com/dotnet/aspire/issues/6693), [#6704](https://github.com/dotnet/aspire/issues/6704), [#7095](https://github.com/dotnet/aspire/issues/7095)) with restarting the Aspire AppHost, including reconciliation errors and "address already in use" messages.
-
-This release introduces a more robust approach to managing socket addresses, ensuring only one instance of each address is used at a time. Additionally, improvements were made to ensure proper project restarts and resource releases, preventing hanging issues. These changes enhance the stability and reliability of the AppHost, especially during development and testing.
-
-## 🔌 Integration updates
-
-Aspire continues to excel through its [integrations](https://aspire.dev/integrations/overview/) with various platforms. This release includes numerous updates to existing integrations and details about ownership migrations, enhancing the overall functionality and user experience.
-
-### ☁️ Azure updates
-
-This release also focused on improving various [Azure integrations](https://aspire.dev/integrations/cloud/azure/overview/):
-
-#### 🆕 New emulators
-
-We're excited to bring new emulators for making local development easier. The following integrations got new emulators in this release:
-
-- [Azure Service Bus](https://aspire.dev/integrations/cloud/azure/azure-service-bus/#add-azure-service-bus-emulator-resource)
-- [Azure Cosmos DB Linux-based (preview)](https://aspire.dev/integrations/cloud/azure/azure-cosmos-db/#use-linux-based-emulator-preview)
-- [Azure SignalR](https://aspire.dev/integrations/cloud/azure/azure-signalr/#add-an-azure-signalr-service-emulator-resource)
-
-```csharp
-var serviceBus = builder.AddAzureServiceBus("servicebus")
- .RunAsEmulator();
-
-#pragma warning disable ASPIRECOSMOSDB001
-var cosmosDb = builder.AddAzureCosmosDB("cosmosdb")
- .RunAsPreviewEmulator();
-
-var signalr = builder.AddAzureSignalR("signalr", AzureSignalRServiceMode.Serverless)
- .RunAsEmulator();
-```
-
-These new emulators work side-by-side with the existing emulators for:
-
-- [Azure Storage](https://aspire.dev/integrations/cloud/azure/azure-storage-blobs/)
-- [Azure Event Hubs](https://aspire.dev/integrations/cloud/azure/azure-event-hubs/#add-azure-event-hubs-emulator-resource)
-- [Azure Cosmos DB](https://aspire.dev/integrations/cloud/azure/azure-cosmos-db/#add-azure-cosmos-db-emulator-resource)
-
-#### 🌌 Cosmos DB
-
-Along with support for the new emulator, Cosmos DB added the following features.
-
-##### 🔒 Support for Entra ID authentication by default
-
-Previously, the Cosmos DB integration used access keys and a Key Vault secret to connect to the service. Aspire 9.1 added support for using more secure authentication using managed identities by default. If you need to keep using access key authentication, you can get back to the previous behavior by calling .
-
-##### 💽 Support for modeling Database and Containers in the AppHost
-
-You can define a Cosmos DB database and containers in the AppHost and these resources are available when you run the application in both the emulator and in Azure. This allows you to define these resources up front and no longer need to create them from the application, which might not have permission to create them.
-
-For example API usage to add database and containers, see the following related articles:
-
-- [Aspire Azure Cosmos DB integration](https://aspire.dev/integrations/cloud/azure/azure-cosmos-db/#add-azure-cosmos-db-database-and-container-resources)
-- [Aspire Cosmos DB Entity Framework Core integration](https://aspire.dev/integrations/cloud/azure/azure-cosmos-db/#add-azure-cosmos-db-database-and-container-resources)
-
-##### ⚡ Support for Cosmos DB-based triggers in Azure Functions
-
-The was modified to support consumption in Azure Functions applications that uses the Cosmos DB trigger. A Cosmos DB resource can be initialized and added as a reference to an Azure Functions resource with the following code:
-
-```csharp
-var cosmosDb = builder.AddAzureCosmosDB("cosmosdb")
- .RunAsEmulator();
-var database = cosmosDb.AddCosmosDatabase("mydatabase");
-database.AddContainer("mycontainer", "/id");
-
-var funcApp = builder.AddAzureFunctionsProject("funcapp")
- .WithReference(cosmosDb)
- .WaitFor(cosmosDb);
-```
-
-The resource can be used in the Azure Functions trigger as follows:
-
-```csharp
-public class MyCosmosDbTrigger(ILogger logger)
-{
- [Function(nameof(MyCosmosDbTrigger))]
- public void Run([CosmosDBTrigger(
- databaseName: "mydatabase",
- containerName: "mycontainer",
- CreateLeaseContainerIfNotExists = true,
- Connection = "cosmosdb")] IReadOnlyList input)
- {
- logger.LogInformation(
- "C# cosmosdb trigger function processed: {Count} messages",
- input.Count);
- }
-}
-```
-
-For more information using Azure Functions with Aspire, see [Aspire Azure Functions integration (Preview)](https://aspire.dev/integrations/cloud/azure/azure-functions/).
-
-#### 🚚 Service Bus and Event Hubs
-
-Similar to Cosmos DB, the Service Bus and Event Hubs integrations now allow you to define Azure Service Bus queues, topics, subscriptions, and Azure Event Hubs instances and consumer groups directly in your AppHost code. This enhancement simplifies your application logic by enabling the creation and management of these resources outside the application itself.
-
-For more information, see the following updated articles:
-
-- [Aspire Azure Service Bus integration](https://aspire.dev/integrations/cloud/azure/azure-service-bus/)
-- [Aspire Azure Event Hubs integration](https://aspire.dev/integrations/cloud/azure/azure-event-hubs/)
-
-#### ♻️ Working with existing resources
-
-There's consistent feedback about making it easier to connect to existing Azure resources in Aspire. With 9.1, you can now easily connect to an existing Azure resource either directly by `string` name, or with [app model parameters](https://aspire.dev/fundamentals/external-parameters/) which can be changed at deployment time. For example to connect to an Azure Service Bus account, we can use the following code:
-
-```csharp
-var existingServiceBusName = builder.AddParameter("serviceBusName");
-var existingServiceBusResourceGroup = builder.AddParameter("serviceBusResourceGroup");
-
-var serviceBus = builder.AddAzureServiceBus("messaging")
- .AsExisting(existingServiceBusName, existingServiceBusResourceGroup);
-```
-
-The preceding code reads the name and resource group from the parameters, and connects to the existing resource when the application is run or deployed. For more information, see [use existing Azure resources](https://aspire.dev/integrations/cloud/azure/overview/#use-existing-azure-resources).
-
-#### 🌍 Azure Container Apps
-
-Experimental support for configuring custom domains in Azure Container Apps (ACA) was added. For example:
-
-```csharp
-#pragma warning disable ASPIREACADOMAINS001
-
-var customDomain = builder.AddParameter("customDomain");
-var certificateName = builder.AddParameter("certificateName");
-
-builder.AddProject("api")
- .WithExternalHttpEndpoints()
- .PublishAsAzureContainerApp((infra, app) =>
- {
- app.ConfigureCustomDomain(customDomain, certificateName);
- });
-```
-
-For more information, see [Aspire diagnostics overview](https://aspire.dev/diagnostics/overview/).
-
-### ➕ Even more integration updates
-
-- OpenAI now supports the [📦 Microsoft.Extensions.AI](https://www.nuget.org/packages/Microsoft.Extensions.AI) NuGet package.
-- RabbitMQ updated to version 7, and MongoDB to version 3. These updates introduced breaking changes, leading to the release of new packages with version-specific suffixes. The original packages continue to use the previous versions, while the new packages are as follows:
- - [📦 Aspire.RabbitMQ.Client.v7](https://www.nuget.org/packages/Aspire.RabbitMQ.Client.v7) NuGet package. For more information, see the [Aspire RabbitMQ client integration](https://aspire.dev/integrations/messaging/rabbitmq/#client-integration) documentation.
- - [📦 Aspire.MongoDB.Driver.v3](https://www.nuget.org/packages/Aspire.MongoDB.Driver.v3) NuGet package. For more information, see the [Aspire MongoDB client integration](https://aspire.dev/integrations/databases/mongodb/#client-integration) documentation.
-- Dapr migrated to the [CommunityToolkit](https://github.com/CommunityToolkit/Aspire/tree/main/src/CommunityToolkit.Aspire.Hosting.Dapr) to facilitate faster innovation.
-- Numerous other integrations received updates, fixes, and new features. For detailed information, refer to our [GitHub release notes](https://github.com/dotnet/aspire/releases).
-
-The [📦 Aspire.Hosting.AWS](https://www.nuget.org/packages/Aspire.Hosting.AWS) NuGet package and source code migrated under [Amazon Web Services (AWS)) ownership](https://github.com/aws/integrations-on-dotnet-aspire-for-aws). This migration happened as part of Aspire 9.0, we're just restating that change here.
-
-## 🧪 Testing in Aspire
-
-Aspire 9.1 simplifies writing cross-functional integration tests with a robust approach. The AppHost allows you to create, evaluate, and manage containerized environments seamlessly within a test run. This functionality supports popular testing frameworks like xUnit, NUnit, and MSTest, enhancing your testing capabilities and efficiency.
-
-Now, you're able to disable port randomization or enable the [dashboard](https://aspire.dev/dashboard/overview/). For more information, see [Aspire testing overview](https://aspire.dev/testing/overview/). Additionally, you can now [Pass arguments to your AppHost](https://aspire.dev/testing/manage-app-host/#pass-arguments-to-your-apphost).
-
-Some of these enhancements were introduced as a result of stability issues that were reported, such as [Aspire GitHub issue #6678](https://github.com/dotnet/aspire/issues/6678)—where some resources failed to start do to "address in use" errors.
-
-## 🚀 Deployment
-
-Significant improvements to the Azure Container Apps (ACA) deployment process are included in Aspire 9.1, enhancing both the `azd` CLI and AppHost options. One of the most requested features—support for deploying `npm` applications to ACA—is now implemented. This new capability allows `npm` apps to be deployed to ACA just like other resources, streamlining the deployment process and providing greater flexibility for developers.
-
-We recognize there's more work to be done in the area of deployment. Future releases will continue to address these opportunities for improvement. For more information on deploying Aspire to ACA, see [Deploy an Aspire project to Azure Container Apps](../deployment/azure/aca-deployment.md).
-
-## ⚠️ Breaking changes
-
-Aspire is moving quickly, and with that comes breaking changes. Breaking are categorized as either:
-
-- **Binary incompatible**: The assembly version has changed, and you need to recompile your code.
-- **Source incompatible**: The source code has changed, and you need to change your code.
-- **Behavioral change**: The code behaves differently, and you need to change your code.
-
-Typically APIs are decorated with the giving you a warning when you compile, and an opportunity to adjust your code. For an overview of breaking changes in Aspire 9.1, see [Breaking changes in Aspire 9.1](../compatibility/9.1/index.md).
-
-## 🎯 Upgrade today
-
-Follow the directions outlined in the [Upgrade to Aspire 9.1](#-upgrade-to-aspire-91) section to make the switch to 9.1 and take advantage of all these new features today! As always, we're listening for your feedback on [GitHub](https://github.com/dotnet/aspire/issues)-and looking out for what you want to see in 9.2 ☺️.
-
-For a complete list of issues addressed in this release, see [Aspire GitHub repository—9.1 milestone](https://github.com/dotnet/aspire/issues?q=is%3Aissue%20state%3Aclosed%20milestone%3A9.1%20).
diff --git a/docs/whats-new/dotnet-aspire-9.2.md b/docs/whats-new/dotnet-aspire-9.2.md
deleted file mode 100644
index ae8df554db..0000000000
--- a/docs/whats-new/dotnet-aspire-9.2.md
+++ /dev/null
@@ -1,510 +0,0 @@
----
-title: What's new in Aspire 9.2
-description: Learn what's new in the official general availability release of Aspire 9.2.
-ms.date: 04/10/2025
----
-
-# What's new in Aspire 9.2
-
-📢 Aspire 9.2 is the next minor version release of Aspire; it supports:
-
-- .NET 8.0 Long Term Support (LTS)
-- .NET 9.0 Standard Term Support (STS)
-
-If you have feedback, questions, or want to contribute to Aspire, collaborate with us on [:::image type="icon" source="../media/github-mark.svg" border="false"::: GitHub](https://github.com/dotnet/aspire) or join us on [:::image type="icon" source="../media/discord-icon.svg" border="false"::: Discord](https://discord.com/invite/h87kDAHQgJ) to chat with team members.
-
-It's important to note that Aspire releases out-of-band from .NET releases. While major versions of Aspire align with .NET major versions, minor versions are released more frequently. For more information on .NET and Aspire version support, see:
-
-- [.NET support policy](https://dotnet.microsoft.com/platform/support/policy): Definitions for LTS and STS.
-- [Aspire support policy](https://dotnet.microsoft.com/platform/support/policy/aspire): Important unique product life cycle details.
-
-## ⬆️ Upgrade to Aspire 9.2
-
-> [!IMPORTANT]
-> If you are using `azd` to deploy Azure PostgreSQL or Azure SQL Server, you now have to configure Azure Managed Identities. For more information, see [🛡️ Improved Managed Identity defaults](#improved-managed-identity-defaults).
-
-Moving between minor releases of Aspire is simple:
-
-1. In your AppHost project file (that is, _MyApp.AppHost.csproj_), update the [📦 Aspire.AppHost.Sdk](https://www.nuget.org/packages/Aspire.AppHost.Sdk) NuGet package to version `9.2.0`:
-
- ```diff
-
-
-
-
-
- Exe
- net9.0
- - true
-
-
-
-
-
-
-
-
-
- ```
-
- > [!IMPORTANT]
- > The `IsAspireHost` property is no longer required in the project file. For more information, see [🚧 Project file changes](#project-file-changes).
-
- For more information, see [Aspire SDK](xref:dotnet/aspire/sdk).
-
-1. Check for any NuGet package updates, either using the NuGet Package Manager in Visual Studio or the **Update NuGet Package** command in VS Code.
-1. Update to the latest [Aspire templates](../fundamentals/aspire-sdk-templates.md) by running the following .NET command line:
-
- ```dotnetcli
- dotnet new update
- ```
-
- > [!IMPORTANT]
- > The `dotnet new update` command updates all of your templates to the latest version.
-
-If your AppHost project file doesn't have the `Aspire.AppHost.Sdk` reference, you might still be using Aspire 8. To upgrade to 9.0, follow [the upgrade guide](../get-started/upgrade-to-aspire-9.md).
-
-## 🖥️ AppHost enhancements
-
-The [AppHost](https://aspire.dev/get-started/app-host/) is the core of Aspire, providing the local hosting environment for your distributed applications. In Aspire 9.2, we've made several improvements to the AppHost:
-
-### 🚧 Project file changes
-
-
-
-The Aspire AppHost project file no longer requires the `IsAspireHost` property. This property was moved to the `Aspire.AppHost.Sdk` SDK, therefore, you can remove it from your project file. For more information, see [dotnet/aspire issue #8144](https://github.com/dotnet/aspire/pull/8144).
-
-### 🔗 Define custom resource URLs
-
-Resources can now define custom URLs. This makes it easier to build custom experiences for your resources. For example, you can define a custom URL for a database resource that points to the database management console. This makes it easier to access the management console directly from the dashboard, you can even give it a friendly name.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var catalogDb = builder.AddPostgres("postgres")
- .WithDataVolume()
- .WithPgAdmin(resource =>
- {
- resource.WithUrlForEndpoint("http", u => u.DisplayText = "PG Admin");
- })
- .AddDatabase("catalogdb");
-```
-
-The preceding code sets the display text for the `PG Admin` URL to `PG Admin`. This makes it easier to access the management console directly from the dashboard.
-
-For more information, see [Define custom resource URLs](https://aspire.dev/fundamentals/custom-resource-urls/).
-
-## 🔧 Dashboard user experience improvements
-
-Aspire 9.2 adds new features to the [dashboard](https://aspire.dev/dashboard/overview/), making it a more powerful developer tool than ever. The following features were added to the dashboard in Aspire 9.2:
-
-### 🧩 Resource graph
-
-The resource graph is a new way to visualize the resources in your apps. It displays a graph of resources, linked by relationships. Click the 'Graph' tab on the Resources page to view the resource graph. See it in action on [James's BlueSky](https://bsky.app/profile/james.newtonking.com/post/3lj7odu4re22p).
-
-For more information, see [Aspire dashboard: Resources page](https://aspire.dev/dashboard/explore/#resources-page).
-
-### 🎨 Resource icons
-
-We've added resource icons to the resources page. The icon color matches the resource's telemetry in structured logs and traces.
-
-:::image type="content" source="media/dashboard-resource-icons.png" lightbox="media/dashboard-resource-icons.png" alt-text="Screenshot of dashboard resource's page showing the new resource icons.":::
-
-### ⏯️ Pause and resume telemetry
-
-New buttons were added to the **Console logs**, **Structured logs**, **Traces** and **Metrics** pages to pause collecting telemetry. Click the pause button again to resume collecting telemetry.
-
-This feature allows you to pause telemetry in the dashboard while continuing to interact with your app.
-
-:::image type="content" source="media/dashboard-pause-telemetry.png" lightbox="media/dashboard-pause-telemetry.png" alt-text="Screenshot of the dashboard showing the pause button.":::
-
-### ❤️🩹 Metrics health warning
-
-The dashboard now warns you when a metric exceeds the configured cardinality limit. Once exceeded, the metric no longer provides accurate information.
-
-:::image type="content" source="media/dashboard-cardinality-limit.png" lightbox="media/dashboard-cardinality-limit.png" alt-text="Screenshot of a metric with the cardinality limit warning.":::
-
-### 🕰️ UTC Console logs option
-
-Console logs now supports UTC timestamps. The setting is accessible via the console logs options button.
-
-:::image type="content" source="media/dashboard-console-logs-utc.png" lightbox="media/dashboard-console-logs-utc.png" alt-text="Screenshot of console logs page showing the UTC timestamps option.":::
-
-### 🔎 Trace details search text box
-
-We've added a search text box to trace details. Now you can quickly filter large traces to find the exact span you need. See it in action on [BluSky](https://bsky.app/profile/james.newtonking.com/post/3llunn7fc4s2p).
-
-### 🌐 HTTP-based resource command functionality
-
-[Custom resource commands](https://aspire.dev/fundamentals/custom-resource-commands/) now support HTTP-based functionality with the addition of the `WithHttpCommand` API, enabling you to define endpoints for tasks like database migrations or resets. These commands can be run directly from the Aspire dashboard.
-
-Adds WithHttpCommand(), which lets you define a resource command that sends an HTTP request to your app during development. Useful for triggering endpoints like seed or reset from the dashboard.
-
-```csharp
-if (builder.Environment.IsDevelopment())
-{
- var resetDbKey = Guid.NewGuid().ToString();
-
- catalogDbApp.WithEnvironment("DatabaseResetKey", resetDbKey)
- .WithHttpCommand("/reset-db", "Reset Database",
- commandOptions: new()
- {
- Description = "Reset the catalog database to its initial state. This will delete and recreate the database.",
- ConfirmationMessage = "Are you sure you want to reset the catalog database?",
- IconName = "DatabaseLightning",
- PrepareRequest = requestContext =>
- {
- requestContext.Request.Headers.Add("Authorization", $"Key {resetDbKey}");
- return Task.CompletedTask;
- }
- });
-}
-```
-
-For more information, see [Custom HTTP commands in Aspire](https://aspire.dev/fundamentals/http-commands/).
-
-### 🗂️ Connection string resource type
-
-We've introduced a new `ConnectionStringResource` type that makes it easier to build dynamic connection strings without defining a separate resource type. This makes it easier to work with and build dynamic parameterized connection strings.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var apiKey = builder.AddParameter("apiKey");
-var cs = builder.AddConnectionString("openai",
- ReferenceExpression.Create($"Endpoint=https://api.openai.com/v1;AccessKey={apiKey};"));
-
-var api = builder.AddProject("api")
- .WithReference(cs);
-```
-
-### 📥 Container resources can now specify an image pull policy
-
-Container resources can now specify an `ImagePullPolicy` to control when the image is pulled. This is useful for resources that are updated frequently or that have a large image size. The following policies are supported:
-
-- `Default`: Default behavior (which is the same as `Missing` in 9.2).
-- `Always`: Always pull the image.
-- `Missing`: Ensures the image is always pulled when the container starts.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var cache = builder.AddRedis("cache")
- .WithImageTag("latest")
- .WithImagePullPolicy(ImagePullPolicy.Always)
- .WithRedisInsight();
-```
-
-The `ImagePullPolicy` is set to `Always`, which means the image will always be pulled when the resource is created. This is useful for resources that are updated frequently.
-
-### 📂 New container files API
-
-In Aspire 9.2, we've added a new `WithContainerFiles` API, a way to create files and folders inside a container at runtime by defining them in code. Under the hood, it uses `docker cp` / `podman cp` to copy the files in. Supports setting contents, permissions, and ownership—no bind mounts or temp files needed.
-
-## 🤝 Integrations updates
-
-Integrations are a key part of Aspire, allowing you to easily add and configure services in your app. In Aspire 9.2, we've made several updates to integrations:
-
-### 🔐 Redis/Valkey/Garnet: Password support enabled by default
-
-The Redis, Valkey, and Garnet containers enable password authentication by default. This is part of our goal to be secure by default—protecting development environments with sensible defaults while still making them easy to configure. Passwords can be set explicitly or generated automatically if not provided.
-
-### 💾 Automatic database creation support
-
-There's [plenty of feedback and confusion](https://github.com/dotnet/aspire/issues/7101) around the `AddDatabase` API. The name implies that it adds a database, but it didn't actually create the database. In Aspire 9.2, the `AddDatabase` API now creates a database for the following hosting integrations:
-
-| Hosting integration | API reference |
-|--|--|
-| [📦 Aspire.Hosting.SqlServer](https://www.nuget.org/packages/Aspire.Hosting.SqlServer) | |
-| [📦 Aspire.Hosting.PostgreSql](https://www.nuget.org/packages/Aspire.Hosting.PostgreSql) | |
-
-The Azure SQL and Azure PostgreSQL hosting integrations also expose `AddDatabase` APIs which work with their respective `RunAsContainer` methods. For more information, see [Understand Azure integration APIs](https://aspire.dev/integrations/cloud/azure/overview/#understand-azure-integration-apis).
-
-By default, Aspire will create an empty database if it doesn't exist. You can also optionally provide a custom script to run during creation for advanced setup or seeding.
-
-Example using Postgres:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var postgres = builder.AddPostgres("pg1");
-
-postgres.AddDatabase("todoapp")
- .WithCreationScript($$"""
- CREATE DATABASE {{databaseName}}
- ENCODING = 'UTF8';
- """);
-```
-
-For more information and examples of using the `AddDatabase` API, see:
-
-- [Add PostgreSQL resource with database scripts](https://aspire.dev/integrations/databases/postgres/postgres-host/#add-postgresql-resource-with-database-scripts)
-- [Add SQL Server resource with database scripts](https://aspire.dev/integrations/databases/sql-server/#add-sql-server-resource-with-database-scripts)
-
-The following hosting integrations don't currently support database creation:
-
-- [📦 Aspire.Hosting.MongoDb](https://www.nuget.org/packages/Aspire.Hosting.MongoDb)
-- [📦 Aspire.Hosting.MySql](https://www.nuget.org/packages/Aspire.Hosting.MySql)
-- [📦 Aspire.Hosting.Oracle](https://www.nuget.org/packages/Aspire.Hosting.Oracle)
-
-## ☁️ Azure integration updates
-
-In Aspire 9.2, we've made significant updates to Azure integrations, including:
-
-### ⚙️ Configure Azure Container Apps environments
-
-Aspire 9.2 introduces `AddAzureContainerAppEnvironment`, allowing you to define an Azure Container App environment directly in your app model. This adds an `AzureContainerAppsEnvironmentResource` that lets you configure the environment and its supporting infrastructure (like container registries and volume file shares) using C# and the APIs—without relying on `azd` for infrastructure generation.
-
-> [!IMPORTANT]
-> This uses a different resource naming scheme than `azd`. If you're upgrading an existing deployment, this may create duplicate resources. To avoid this, you can opt into `azd`'s naming convention:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddAzureContainerAppEnvironment("my-env")
- .WithAzdResourceNaming();
-```
-
-For more information, see [Configure Azure Container Apps environments](https://aspire.dev/integrations/cloud/azure/configure-container-apps/).
-
-### 🆕 New Client integrations: Azure PostgreSQL (Npgsql & EF Core)
-
-Aspire 9.2 adds client integrations for working with **Azure Database for PostgreSQL**, supporting both local development and secure cloud deployment.
-
-These integrations automatically use **Managed Identity (Entra ID)** in the cloud and during local development by default. They also support username/password, if configured in your AppHost. No application code changes are required to switch between authentication models.
-
-- [📦 Aspire.Azure.Npgsql](https://www.nuget.org/packages/Aspire.Azure.Npgsql)
-- [📦 Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL](https://www.nuget.org/packages/Aspire.Azure.Npgsql.EntityFrameworkCore.PostgreSQL)
-
-**In AppHost:**
-
-```csharp
-var postgres = builder.AddAzurePostgresFlexibleServer("pg")
- .AddDatabase("postgresdb");
-
-builder.AddProject()
- .WithReference(postgres);
-```
-
-**In MyService:**
-
-```csharp
-builder.AddAzureNpgsqlDbContext("postgresdb");
-```
-
-### 🖇️ Resource Deep Linking for Cosmos DB, Event Hubs, Service Bus, and OpenAI
-
-CosmosDB databases and containers, EventHub hubs, ServiceBus queues/topics, and Azure OpenAI deployments now support **resource deep linking**. This allows connection information to target specific child resources—like a particular **Cosmos DB container**, **Event Hubs**, or **OpenAI deployment**—rather than just the top-level account or namespace.
-
-Hosting integrations preserve the full resource hierarchy in connection strings, and client integrations can resolve and inject clients scoped to those specific resources.
-
-**AppHost:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var cosmos = builder.AddAzureCosmosDB("cosmos")
- .RunAsPreviewEmulator(e => e.WithDataExplorer());
-
-var db = cosmos.AddCosmosDatabase("appdb");
-db.AddContainer("todos", partitionKey: "/userId");
-db.AddContainer("users", partitionKey: "/id");
-
-builder.AddProject("api")
- .WithReference(db);
-```
-
-**In the API project:**
-
-```csharp
-var builder = WebApplication.CreateBuilder(args);
-
-builder.AddAzureCosmosDatabase("appdb")
- .AddKeyedContainer("todos")
- .AddKeyedContainer("users");
-
-app.MapPost("/todos", async ([FromKeyedServices("todos")] Container container, TodoItem todo) =>
-{
- todo.Id = Guid.NewGuid().ToString();
- await container.CreateItemAsync(todo, new PartitionKey(todo.UserId));
- return Results.Created($"/todos/{todo.Id}", todo);
-});
-```
-
-This makes it easy and convenient to use the SDKs to interact with specific resources directly—without extra wiring or manual configuration. It's especially useful in apps that deal with multiple containers or Azure services.
-
-### 🛡️ Improved Managed Identity defaults
-
-
-
-Starting in **Aspire 9.2**, each Azure Container App now gets its **own dedicated managed identity** by default. This is a significant change from previous versions, where all apps shared a single, highly privileged identity.
-
-This change strengthens Aspire's *secure by default* posture:
-
-- Each app only gets access to the Azure resources it needs.
-- It enforces the principle of least privilege.
-- It provides better isolation between apps in multi-service environments.
-
-By assigning identities individually, Aspire can now scope role assignments more precisely—improving security, auditability, and alignment with Azure best practices.
-
-This is a **behavioral breaking change** and may impact apps using:
-
-- **Azure SQL Server** - Azure SQL only supports one Azure AD admin. With multiple identities, only the *last deployed app* will be granted admin access by default. Other apps will need explicit users and role assignments.
-
-- **Azure PostgreSQL** - The app that creates the database becomes the owner. Other apps (like those running migrations or performing data operations) will need explicit `GRANT` permissions to access the database correctly.
-
-See the [breaking changes](../compatibility/9.2/index.md) page for more details.
-
-This new identity model is an important step toward more secure and maintainable applications in Aspire. While it introduces some setup considerations, especially for database integrations, it lays the groundwork for better default security across the board.
-
-### 🔑 Least-privilege role assignment functionality
-
-Aspire now supports APIs for modeling **least-privilege role assignments** when referencing Azure resources. This enables more secure defaults by allowing you to define exactly which roles each app needs for specific Azure resources.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var storage = builder.AddAzureStorage("storage")
- .RunAsEmulator(c => c.WithLifetime(ContainerLifetime.Persistent));
-
-var blobs = storage.AddBlobs("blobs");
-
-builder.AddProject("api")
- .WithExternalHttpEndpoints()
- .WithReference(blobs)
- .WithRoleAssignments(storage, StorageBuiltInRole.StorageBlobDataContributor);
-```
-
-In this example, the API project is granted **Storage Blob Data Contributor** only for the referenced storage account. This avoids over-provisioning permissions and helps enforce the principle of least privilege.
-
-Each container app automatically gets its own **managed identity**, and Aspire now generates the necessary role assignment infrastructure for both default and per-reference roles. When targeting existing Azure resources, role assignments are scoped correctly using separate Bicep resources.
-
-### 1️⃣ First-class Azure Key Vault Secret support
-
-Aspire now supports `IAzureKeyVaultSecretReference`, a new primitive for modeling secrets directly in the app model. This replaces `BicepSecretOutputReference` and gives finer grain control over Key Vault creation when using `AzureBicepResource`.
-
-You can now:
-
-- Add a shared Key Vault in C#
-- Configure services that support keys (e.g., Redis, Cosmos DB) to store their secrets there
-- Reference those secrets in your app as environment variables or via the Key Vault config provider
-
-Use KeyVault directly in the "api" project:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var vault = builder.AddAzureKeyVault("kv");
-
-var redis = builder.AddAzureRedis("redis")
- .WithAccessKeyAuthentication(vault);
-
-builder.AddProject("api")
- .WithReference(vault);
-```
-
-Let the compute environment handle the secret management for you:
-
-```csharp
-var redis = builder.AddAzureRedis("redis")
- .WithAccessKeyAuthentication();
-
-builder.AddProject("api")
- .WithReference(redis);
-```
-
-**Previous behavior:**
-
- `azd` created and managed secret outputs using a key vault per resource, with no visibility in the app model. These Key Vault resources were handled implicitly and couldn't be customized in C#.
-
-**New behavior in 9.2:**
-
- Calling `WithKeyAccessAuthentication` or `WithPasswordAuthentication` now creates an actual `AzureKeyVaultResource` (or accepts a reference to one), and stores connection strings there. Secret names follow the pattern `connectionstrings--{resourcename}` to prevent naming conflicts with other vault entries.
-
-### 🔒 Improved default permissions for Azure Key Vault references
-
-When referencing a Key Vault, Aspire previously granted the broad **Key Vault Administrator** role by default. In 9.2, this has been changed to **Key Vault Secrets User**, which provides read-only access to secrets—suitable for most application scenarios.
-
-This update continues the security-focused improvements in this release.
-
-## 🚀 Deployment improvements
-
-We're excited to announce several new deployment features in Aspire 9.2, including:
-
-### 📦 Publishers (Preview)
-
-Publishers are a new extensibility point in Aspire that allow you to define how your distributed application gets transformed into deployable assets. Rather than relying on an [intermediate manifest format](https://aspire.dev/deployment/manifest-format/), publishers can now plug directly into the application model to generate Docker Compose files, Kubernetes manifests, Azure resources, or whatever else your environment needs.
-
-When Aspire launched, it introduced a deployment manifest format—a serialized snapshot of the application model. While useful it burdened deployment tools with interpreting the manifest and resource authors with ensuring accurate serialization. This approach also complicated schema evolution and target-specific behaviors.
-
-Publishers simplify this process by working directly with the full application model in-process, enabling richer, more flexible, and maintainable publishing experiences.
-
-The following NuGet packages expose preview publishers:
-
-- [📦 Aspire.Hosting.Azure](https://www.nuget.org/packages/Aspire.Hosting.Azure)
-- [📦 Aspire.Hosting.Docker (Preview)](https://www.nuget.org/packages/Aspire.Hosting.Docker)
-- [📦 Aspire.Hosting.Kubernetes (Preview)](https://www.nuget.org/packages/Aspire.Hosting.Kubernetes)
-
-> [!IMPORTANT]
-> The Docker and Kubernetes publishers were contributed by community contributor, [Dave Sekula](https://github.com/Prom3theu5)—a great example of the community stepping up to extend the model. 💜 Thank you, Dave!
-
-To use a publisher, add the corresponding NuGet package to your AppHost project file and then call the `Add[Name]Publisher()` method in your AppHost builder.
-
-```csharp
-builder.AddDockerComposePublisher();
-```
-
-> [!TIP]
-> Publisher registration methods follow the `Add[Name]Publisher()` convention.
-
-You can also build your own publisher by implementing the publishing APIs and calling your custom registration method. Some publishers are still in preview, and the APIs are subject to change. The goal is to provide a more flexible and extensible way to publish distributed applications, making it easier to adapt to different deployment environments and scenarios.
-
-### 🆕 Aspire CLI (Preview)
-
-Aspire 9.2 introduces the new **`aspire` CLI**, a tool for creating, running, and publishing Aspire applications from the command line. It provides a rich, interactive experience tailored for Aspire users.
-
-The CLI is available as a .NET tool and can be installed with:
-
-```bash
-dotnet tool install --global aspire.cli --prerelease
-```
-
-#### Example usage:
-
-```bash
-aspire new
-aspire run
-aspire add redis
-aspire publish --publisher docker-compose
-```
-
-#### Available commands:
-
-- `new ` – Create a new Aspire sample project
-- `run` – Run an Aspire AppHost in development mode
-- `add ` – Add an integration to your project
-- `publish` – Generate deployment artifacts from your AppHost
-
-🧪 The CLI is **preview**. We're exploring how to make it a first-class experience for Aspire users—your feedback is welcome!
-
-## 🧪 Testing template updates
-
-The xUnit testing project template now supports a version selector, allowing the user to select either:
-
-- `v2`: The previous xUnit testing experience.
-- `v3`: The new xUnit testing experience and template.
-- `v3 with Microsoft Test Platform`: The next xUnit testing experience, template and uses the [Microsoft Testing Platform](/dotnet/core/testing/microsoft-testing-platform-intro).
-
-By default, to the `v3` experience. For more information, see:
-
-- [What's new in xUnit v.3](https://xunit.net/docs/getting-started/v3/whats-new)
-- [Microsoft Testing Platform support in xUnit.net v3](https://xunit.net/docs/getting-started/v3/microsoft-testing-platform)
-
-> [!NOTE]
-> Both `v3` versions are only supported with Aspire 9.2 or later.
-
-## 💔 Breaking changes
-
-With every release, we strive to make Aspire better. However, some changes may break existing functionality. The following breaking changes are introduced in Aspire 9.2:
-
-- [Breaking changes in Aspire 9.2](../compatibility/9.2/index.md)
diff --git a/docs/whats-new/dotnet-aspire-9.3.md b/docs/whats-new/dotnet-aspire-9.3.md
deleted file mode 100644
index b5ee05ec8b..0000000000
--- a/docs/whats-new/dotnet-aspire-9.3.md
+++ /dev/null
@@ -1,959 +0,0 @@
----
-title: What's new in Aspire 9.3
-description: Learn what's new in the official general availability release of Aspire 9.3.
-ms.date: 05/18/2025
----
-
-# What's new in Aspire 9.3
-
-📢 Aspire 9.3 is the next minor version release of Aspire. It supports:
-
-- .NET 8.0 Long Term Support (LTS)
-- .NET 9.0 Standard Term Support (STS)
-
-If you have feedback, questions, or want to contribute to Aspire, collaborate with us on [:::image type="icon" source="../media/github-mark.svg" border="false"::: GitHub](https://github.com/dotnet/aspire) or join us on [:::image type="icon" source="../media/discord-icon.svg" border="false"::: Discord](https://aka.ms/dotnet-discord) to chat with team members.
-
-It's important to note that Aspire releases out-of-band from .NET releases. While major versions of Aspire align with major .NET versions, minor versions are released more frequently. For more information on .NET and Aspire version support, see:
-
-- [.NET support policy](https://dotnet.microsoft.com/platform/support/policy): Definitions for LTS and STS.
-- [Aspire support policy](https://dotnet.microsoft.com/platform/support/policy/aspire): Important unique product life cycle details.
-
-## 🖥️ App model enhancements
-
-### ✨ Zero-friction container configuration
-
-Many container integrations now expose **first-class helpers** to set ports, usernames, and passwords without digging through internal properties.
-All three settings can be supplied **securely via parameters**, keeping secrets out of source:
-
-```csharp
-var pgPwd = builder.AddParameter("pg-pwd", secret: true);
-
-builder.AddPostgres("pg")
- .WithHostPort(6045) // choose the host-side port
- .WithPassword(pgPwd) // reference a secret parameter
-```
-
-The new `WithHostPort`, `WithPassword`, and `WithUserName` (or equivalent per-service) extension methods are available on **PostgreSQL**, **SQL Server**, **Redis**, and several other container resources, giving you consistent, declarative control across the stack.
-
-### 🔗 Streamlined custom URLs
-
-9.3 makes resource links both **smarter** and **easier** to place:
-
-- **Pick where a link appears** – each link now carries a `UrlDisplayLocation` (`SummaryAndDetails` or `DetailsOnly`), so you can keep diagnostic links out of the main grid yet still see them in the details pane.
-- **Relative paths are auto-resolved** – hand the helper `"/health"` and Aspire rewrites it to the full host-qualified URL when the endpoint is allocated.
-- **Multiple links per endpoint** – an overload of `WithUrlForEndpoint` lets you attach extra URLs (docs, admin UIs, probes) to the same endpoint without redefining it.
-- **Endpoint helper inside callbacks** – `context.GetEndpoint("https")` fetches the fully-resolved endpoint so you can build custom links programmatically.
-- **Custom URLs for any resource** – `WithUrl*` also works for custom resources.
-
-```csharp
-var frontend = builder.AddProject("frontend")
-
- // Hide the plain-HTTP link from the Resources grid
- .WithUrlForEndpoint("http",
- url => url.DisplayLocation = UrlDisplayLocation.DetailsOnly)
-
- // Add an extra link under the HTTPS endpoint that points to /health
- .WithUrlForEndpoint("https", ep => new()
- {
- Url = "/health", // relative path supported
- DisplayText = "Health",
- DisplayLocation = UrlDisplayLocation.DetailsOnly
- });
-```
-
-With these tweaks you can further customize your local dev stack by surfacing the right links in the right place.
-
-### 🙈 Hide resources without "faking" their state
-
-Historically the only way to keep a resource out of the Dashboard was to put it in the **`Hidden`** *state*—a hack that also made the resource look "terminal" to APIs such as `WaitForResourceAsync`. In 9.3 every snapshot now carries a **boolean `IsHidden` flag**, completely decoupling *visibility* from *lifecycle state*.
-
-- **Cleaner defaults** – low-level helpers like `AddParameter` and `AddConnectionString` mark themselves hidden so they don't clutter the UI:
-
- ```csharp
- var apiKey = builder.AddParameter("api-key", secret: true); // IsHidden = true ✔
- ```
-
-- **Accurate waits & health flows** – `WaitForResourceAsync` was updated to treat `IsHidden` as a separate predicate, so hidden resources can still be awaited or surfaced programmatically without special-casing states.
-
-This small change removes ambiguity in the model while giving you precise control over what shows up in the Dashboard.
-
-### 🔔 New lifecycle events
-
-Aspire 9.3 introduces two new lifecycle events that make it easier to build custom resources with predictable behavior—without relying on hacks like or polling:
-
-#### `InitializeResourceEvent`
-
-This event fires **after a resource is added**, but **before endpoints are allocated**. It's especially useful for custom resources that don't have a built-in lifecycle (like containers or executables), giving you a clean place to kick off background logic, set default state, or wire up behavior.
-
-For example, this minimal custom resource publishes a running state when initialized:
-
-```csharp
-var myCustom = new MyCustomResource("my-resource");
-
-builder.AddResource(myCustom);
-builder.Eventing.Subscribe(myCustom, async (e, ct) =>
-{
- await e.Notifications.PublishUpdateAsync(e.Resource,
- s => s with { State = KnownResourceStates.Running });
-});
-```
-
-This replaces awkward patterns like `Task.Run` inside constructors or `Configure()` methods. You can see a more complex version in the [TalkingClock sample](https://github.com/dotnet/aspire-samples/tree/3dee8cd7c7880fe421ea61ba167301eb1369000a/samples/CustomResources/CustomResources.AppHost) in the official Aspire samples repo.
-
-#### `ResourceEndpointsAllocatedEvent`
-
-This event fires once a resource's endpoints have been assigned (e.g., after port resolution or container allocation). It's scoped per resource, so you can safely get an and build derived URLs or diagnostics.
-
-```csharp
-builder.Eventing.Subscribe((e, ct) =>
-{
- if (e.Resource is IResourceWithEndpoints resource)
- {
- var http = resource.GetEndpoint("http");
-
- Console.WriteLine($"Endpoint http - Allocated {http.IsAllocated}, Port: {http.Port}");
- }
-
- return Task.CompletedTask;
-});
-```
-
-These events make resource authoring smoother, safer, and more deterministic—no lifecycle guesswork needed.
-
-### 🌐 YARP Integration (Preview)
-
-Aspire 9.3 introduces **preview support for [YARP](https://aka.ms/yarp)** (Yet Another Reverse Proxy)—a long-requested addition that brings reverse proxying into the Aspire application model.
-
-This integration makes it easy to add a lightweight proxy container to your distributed app, powered by the official [YARP container image](https://yarp.dot.net). It currently supports **configuration-based routing only**, using a JSON file you supply.
-
-#### Add a reverse proxy to your Aspire app:
-
-```csharp
-builder.AddYarp("apigateway")
- .WithConfigFile("yarp.json")
- .WithReference(basketService)
- .WithReference(catalogService);
-```
-
-The config file is mounted into the container and used as the runtime YARP configuration.
-
-#### Example _yarp.json_:
-
-```json
-{
- "ReverseProxy": {
- "Routes": {
- "catalog": {
- "ClusterId": "catalog",
- "Match": {
- "Path": "/catalog/{**catch-all}"
- }
- },
- "basket": {
- "ClusterId": "basket",
- "Match": {
- "Path": "/basket/{**catch-all}"
- }
- }
- },
- "Clusters": {
- "catalog": {
- "Destinations": {
- "catalog/d1": {
- "Address": "http://catalog/"
- }
- }
- },
- "basket": {
- "Destinations": {
- "basket/d1": {
- "Address": "http://basket/"
- }
- }
- }
- }
- }
-}
-```
-
-The `.WithReference(...)` calls automatically ensure that the proxy container can resolve the referenced services by name (`catalog`, `basket`), using Aspire's internal network graph.
-
-#### ⚠️ Known limitations in this preview
-
-- **Only configuration-based routing is supported**. Code-based or programmatic route generation is not available yet.
-- **The configuration file is not deployed** as part of publish operations—you must manage the file manually.
-- **Routing from containers to projects will not work on Podman**, due to host-to-container networking limitations.
-
-> [!TIP]
-> 💡 Want to learn more about authoring YARP configs? See the official [YARP documentation](https://aka.ms/yarp).
-> 🧪 This integration is in preview—APIs and behavior may evolve. Feedback welcome!
-
-### 🐬 MySQL `AddDatabase` now creates the database
-
-In Aspire 9.3, the MySQL integration now supports **automatic database creation** via the `AddDatabase` API—matching the behavior already available for SQL Server and PostgreSQL.
-
-Previously, calling `.AddDatabase("dbname")` on a MySQL resource only created a logical reference in Aspire's app model—it did **not** create the database on the server. This mismatch caused confusion, especially when users expected Aspire to provision the database like it does for other integrations.
-
-#### ✅ New behavior in 9.3:
-
-```csharp
-var mysql = builder.AddMySql("db");
-
-mysql.AddDatabase("appdb");
-```
-
-At runtime, Aspire now executes a `CREATE DATABASE` command for `"appdb"` against the running MySQL container or server. If the database already exists, the command is skipped safely.
-
-This brings MySQL in line with the broader Aspire database ecosystem:
-
-| Integration | Automatically creates database? |
-|-------------|-------------------------------------------|
-| SQL Server | ✅ Yes |
-| PostgreSQL | ✅ Yes |
-| **MySQL** | ✅ **Yes (new in 9.3)** |
-| MongoDB | ❌ No (not needed; created on first write) |
-| Oracle | ❌ No (not supported yet) |
-
-No additional configuration is required—the same `AddDatabase` call you already use now provisions the database for you behind the scenes.
-
-## 📊 Dashboard delights
-
-### ✨ GitHub Copilot in the dashboard
-
-Introducing GitHub Copilot in the Aspire dashboard! GitHub Copilot is your new AI debugging assistant.
-
-GitHub Copilot supercharges the dashboard's OpenTelemetry debugging and diagnostics experience. With AI, you can:
-
-- Review hundreds of log messages with a single click
-- Investigate the root cause of errors across multiple apps
-- Highlight performance issues in traces
-- Explain obscure error codes using AI's huge knowledge repository
-
-You'll have access to Copilot in the dashboard when you launch your app from VS Code or Visual Studio.
-
-:::image type="content" source="media/dashboard-copilot.png" lightbox="media/dashboard-copilot.png" alt-text="Screenshot of dashboard with GitHub Copilot chat open.":::
-
-For more details on requirements and how to get started, see [GitHub Copilot in the Aspire dashboard](https://aspire.dev/dashboard/copilot/).
-
-### 🧠 Remembers your filter settings
-
-The Aspire dashboard now **remembers your resource filter settings** between sessions. Previously, if you filtered the Resources view (for example, to hide support services or highlight only frontend apps), those filters were reset on page reload.
-
-As of 9.3, filter state is **persisted in local storage**, so your selections stick across refreshes and restarts. This small improvement makes it easier to focus on the parts of your app that matter most—especially in large graphs with many supporting services like Redis, SQL, or queues.
-
-:::image type="content" source="media/dashboard-filter.png" lightbox="media/dashboard-filter.png" alt-text="Screenshot of dashboard resource's page showing the filter popup.":::
-
-### 🧵 Uninstrumented resources now appear in Traces
-
-In 9.3, the dashboard can now **visualize outgoing calls to resources that don't emit their own telemetry**—such as databases, caches, and other infrastructure components that lack built-in tracing.
-
-Previously, these dependencies were invisible in the **Traces** view unless they were emitting OTLP traces. Now, if your app makes an HTTP, SQL, or Redis call to a **modeled Aspire resource** that doesn't emit spans itself, Aspire still shows it as a **referenced peer** in the trace timeline.
-
-This helps you:
-
-- Understand the full chain of dependencies—even if some components are passive
-- Debug latency or failures in calls to uninstrumented services
-- Keep the trace UI consistent across infrastructure types
-
-> [!IMPORTANT]
-> 💡 This is especially useful for services like SQL Server, PostgreSQL, Redis, or blob storage where outgoing client telemetry exists, but the service itself doesn't participate in distributed tracing.
-
-🧪 No instrumentation changes are needed—Aspire infers the mapping based on resource references.
-
-:::image type="content" source="media/dashboard-traces-uninstrumented-resources.png" lightbox="media/dashboard-traces-uninstrumented-resources.png" alt-text="Screenshot of dashboard traces's page showing added resources in results.":::
-
-### 🖱️ Resource context menus & quick-launch actions
-
-Aspire 9.3 makes the dashboard more interactive and easier to navigate by introducing new **context menus** and enhancing how **resource URLs** are surfaced across views.
-
-:::image type="content" source="media/dashboard-context-menu.png" lightbox="media/dashboard-context-menu.png" alt-text="Screenshot of dashboard resource graph view with a context menu.":::
-
-#### 🧭 Right-click context menus in the graph
-
-You can now **right-click any resource node** in the **Resource Graph** view to bring up a context menu with quick actions:
-
-- Open structured logs, console logs, traces, or metrics for that resource
-- Launch external URLs associated with the resource (like PGAdmin, Swagger, or Grafana)
-- Jump directly to the resource's detail pane
-
-This reduces the number of clicks and lets you stay in the graph while investigating specific services.
-
-#### 🔗 Resource URLs in console log actions
-
-Resource URLs defined via `WithUrlForEndpoint(...)` are now **more prominently integrated** into the dashboard UI. They appear:
-
-- In the **console logs view** action bar
-- In the new **right-click menus**
-- On the **resource detail pane**, as before
-
-This makes common destinations—like admin UIs, health checks, and docs—instantly accessible wherever you're working.
-
-Together, these improvements turn the Aspire dashboard into a true control plane for navigating your distributed app—**less friction, more focus.**
-
-### ⏸️ Metrics pause warning
-
-The dashboard now shows a **warning banner** when metrics collection is paused. This makes it clear that data may be stale if you've temporarily halted telemetry.
-
-:::image type="content" source="media/dashboard-metrics-warning.png" lightbox="media/dashboard-metrics-warning.png" alt-text="Screenshot of dashboard metrics page with a pause warning.":::
-
-### 📝 Friendly names in console logs
-
-When a resource has only **one replica**, the Aspire dashboard now uses the **friendly resource name** (like `frontend`, `apigateway`, or `redis`) instead of the replica ID (like `frontend-0`) in the **console logs view**.
-
-This small change makes logs easier to read and reduces visual noise—especially in common single-instance setups during development.
-
-> [!NOTE]
-> In multi-replica scenarios, Aspire still uses full replica IDs so you can distinguish between instances.
-
-## 🚀 Deployment & publish
-
-### 🏗️ Improvements to in-preview publisher model & compute environment support
-
-In 9.2, we shipped our first iteration of "publishers", a flexible way to configure deployments to any cloud in the AppHost. To ensure more flexibility, Aspire 9.3 includes a **new and improved** publisher model that distributes publishing behavior across your application graph instead of relying on a single top-level publisher.
-
-Rather than selecting a target environment (like Docker or Azure) by calling `AddDockerComposePublisher()` or similar, Aspire now includes a **built-in publisher** that looks for a `PublishingCallbackAnnotation` on each resource. This annotation describes how that resource should be published—for example, as a Docker Compose service, Kubernetes manifest, or Azure Bicep module.
-
-> [!TIP]
-> ✅ This architectural shift lays the groundwork for **hybrid and heterogeneous deployments**, where different services within the same app can be deployed to different targets (cloud, edge, local).
-
-#### Most apps only need one environment
-
-In typical apps, you only need to add a **single compute environment**, like:
-
-```csharp
-builder.AddAzureContainerAppEnvironment("env");
-```
-
-In this case, Aspire applies the correct publishing behavior to all compute resources in your app model—no extra configuration needed.
-
-#### Multiple environments require disambiguation
-
-If you add **multiple compute environments**, Aspire needs to know which resource goes where. Compute environments apply their transformations to **all applicable compute resources** (projects, containers, executables). If more than one environment matches a given resource, Aspire throws an **ambiguous environment exception** at publish time.
-
-You can resolve this by using `WithComputeEnvironment(...)`:
-
-```csharp
-var k8s = builder.AddKubernetesEnvironment("k8s-env");
-var compose = builder.AddDockerComposeEnvironment("docker-env");
-
-builder.AddProject("api")
- .WithComputeEnvironment(compose);
-
-builder.AddProject("frontend")
- .WithComputeEnvironment(k8s);
-```
-
-This (contrived) example shows how you could explicitly map services to different compute targets—modeling, for example, a frontend in Kubernetes and a backend in Docker Compose.
-
-> [!NOTE]
-> 💡 Imagine a real-world case where your frontend is deployed to a CDN or GitHub Pages, and your backend runs in Azure Container Apps. This new model makes that future possible.
-
-⚠️ All previous publisher registration APIs (like `AddDockerComposePublisher()`) have been removed in favor of this new model.
-
-#### Supported compute environments
-
-Aspire 9.3 has preview support for the following environment resources:
-
-- `AddDockerComposeEnvironment(...)`
-- `AddKubernetesEnvironment(...)`
-- `AddAzureContainerAppEnvironment(...)`
-- `AddAzureAppServiceEnvironment(...)` — [see new App Service support →](#-azure-app-service-preview-support)
-
-These represent deployment targets that can transform and emit infrastructure-specific artifacts from your app model.
-
-### 🐳 Docker Compose enhancements
-
-Aspire 9.3 introduces powerful new capabilities for customizing Docker Compose output using strongly typed, C#-based configuration. You can now declaratively configure both the **global Compose file** and individual **services** directly from the Aspire app model—making your deployment output easy to reason about, customize, and automate.
-
-#### 🛠️ Customize the Compose file and service definitions
-
-You can now programmatically configure the top-level Compose file and the behavior of each individual service using two new APIs:
-
-- `ConfigureComposeFile(...)` — customize the `docker-compose.yml` metadata
-- `PublishAsDockerComposeService(...)` — modify the generated service for any compute resource (like a container or project)
-
-```csharp
-builder.AddDockerComposeEnvironment("env")
- .WithProperties(env =>
- {
- env.BuildContainerImages = false; // skip image build step
- })
- .ConfigureComposeFile(file =>
- {
- file.Name = "aspire-ai-chat"; // sets the file name
- });
-
-// Add a container to the app
-builder.AddContainer("service", "nginx")
- .WithEnvironment("ORIGINAL_ENV", "value")
- .PublishAsDockerComposeService((resource, service) =>
- {
- service.Labels["custom-label"] = "test-value";
- service.AddEnvironmentalVariable("CUSTOM_ENV", "custom-value");
- service.Restart = "always";
- });
-```
-
-These APIs give you a structured, strongly typed way to mutate the generated output—enabling richer CI automation, custom tooling, and environment-specific adjustments without editing YAML manually.
-
-#### 🔗 Map parameters and expressions into Docker Compose
-
-Aspire now supports **binding values from the app model**—like parameters and references—into the Docker Compose definition via environment variable placeholders.
-
-This makes it easy to flow dynamic configuration (e.g., from the CI pipeline or secret store) directly into the final output.
-
-```csharp
-builder.AddDockerComposeEnvironment("docker-compose");
-
-var containerNameParam = builder.AddParameter("param-1", "default-name", publishValueAsDefault: true);
-
-builder.AddContainer("service", "nginx")
- .WithEnvironment("ORIGINAL_ENV", "value")
- .PublishAsDockerComposeService((resource, service) =>
- {
- service.ContainerName = containerNameParam.AsEnvironmentPlaceholder(resource);
- });
-```
-
-The key API here is `.AsEnvironmentPlaceholder(...)`, which tells Aspire to emit a Compose variable like `${PARAM_1}` and register the mapping so the `.env` file is updated accordingly.
-
-> [!TIP]
-> 🧠 This tightly couples your infrastructure parameters with the Docker Compose model—without hardcoding values—unlocking composability across environments.
-
-These enhancements make Docker Compose a **fully programmable publishing target**, ideal for local development, container-based CI workflows, and teams that need structured control without brittle YAML overlays.
-
-### ☸️ Kubernetes manifest customization
-
-Aspire 9.3 adds support for **programmatically customizing generated Kubernetes manifests** as part of the publish process. This gives you fine-grained control over the YAML artifacts Aspire emits—without writing raw manifest overlays or patches.
-
-Like Docker Compose, Aspire now supports both **global environment-level settings** and **per-resource customization**.
-
-#### 🛠️ Configure global and per-resource settings
-
-You can use the following APIs to configure Kubernetes output in C#:
-
-- `WithProperties(...)` on the compute environment to set global behaviors
-- `PublishAsKubernetesService(...)` on compute resources to modify their specific Kubernetes resources
-
-```csharp
-builder.AddKubernetesEnvironment("env")
- .WithProperties(env =>
- {
- env.DefaultImagePullPolicy = "Always"; // e.g., Always, IfNotPresent
- });
-
-builder.AddContainer("service", "nginx")
- .WithEnvironment("ORIGINAL_ENV", "value")
- .PublishAsKubernetesService(resource =>
- {
- // Add custom deployment-level settings
- resource.Deployment!.Spec.RevisionHistoryLimit = 5;
- });
-```
-
-This gives you fully typed access to the Kubernetes object model, enabling powerful modifications like:
-
-- Overriding container image pull policies
-- Customizing replica counts or deployment strategies
-- Injecting labels or annotations into Services, Deployments, or ConfigMaps
-
-> [!IMPORTANT]
-> 🧠 Aspire emits standard Kubernetes manifests under the hood—you can still use `kubectl`, `helm`, or GitOps workflows to deploy them, but now you can shape them directly from your app definition.
-
-## 🖥️ Aspire CLI enhancements
-
-🧪 The Aspire CLI is **still in preview** and under active development. Expect more features and polish in future releases.
-
-📦 To install:
-
-```bash
-dotnet tool install --global aspire.cli --prerelease
-```
-
-> [!NOTE]
-> ⚠️ **The Aspire 9.3 CLI is not compatible with Aspire 9.2 projects.**
-> You must upgrade your project to Aspire 9.3+ in order to use the latest CLI features.
-
-#### 🔍 Smarter AppHost discovery
-
-The CLI now **walks upward** from your current directory, **recursively searching each level** for the AppHost project. Once located, it caches the result in a `.aspire` folder to speed up future commands.
-
-You can now run commands like `aspire run`, `aspire add`, or `aspire publish` from **any directory within your solution**, and the CLI will resolve the AppHost automatically.
-
-For example:
-
-```bash
-cd src/frontend
-aspire run
-```
-
-#### ⏳ Health-aware dashboard launch
-
-The CLI now **waits for the dashboard to become responsive** before printing its URL to the terminal. This ensures the link works immediately when opened—no more blank pages or retry loops.
-
-These updates make the Aspire CLI more reliable, script-friendly, and aligned with how developers move across folders and projects during daily development.
-
-## ☁️ Azure goodies
-
-### 🌐 Azure App Service (Preview support)
-
-Aspire 9.3 introduces **preview support for deploying .NET projects to Azure App Service**—one of the most requested features from developers using Aspire with existing Azure environments.
-
-This integration lets you deploy your project as a **containerized Linux Web App**, modeled directly in your Aspire AppHost using a new `AddAzureAppServiceEnvironment(...)` API.
-
-#### 🚧 Current limitations (Preview)
-
-This first release is scoped to the most common use cases:
-
-- Supports **.NET projects only** (via `AddProject(...)`)
-- Each project must expose a **single public HTTP endpoint**
-- **Projects are published as containers** to Azure Container Registry
-- **Containers within the AppHost** are not supported
-- **Existing App Service Plans are not supported**
-- The Aspire **dashboard is not hosted** in App Service yet
-
-> [!IMPORTANT]
-> 📢 Hosted dashboard support is coming soon—we're actively developing this. Feedback is welcome!
-
-#### Example: Deploy to Azure App Service
-
-```csharp
-builder.AddAzureAppServiceEnvironment("env");
-
-builder.AddProject("api")
- .WithExternalHttpEndpoints()
- .PublishAsAzureAppServiceWebsite((infra, site) =>
- {
- site.SiteConfig.IsWebSocketsEnabled = true;
- });
-```
-
-In this example:
-
-- Aspire provisions an App Service Plan and a Web App
-- Your project is built as a container and published to **Azure Container Registry**
-- The container is deployed to App Service with the configuration you provide
-
-> 🧠 Use `PublishAsAzureAppServiceWebsite(...)` to customize settings like site config, authentication, or SKU.
-
-💬 This feature is in **preview**—we're looking for your feedback as we expand support!
-
-### 📤 Use an existing Azure Container Registry (ACR)
-
-Aspire 9.3 adds support for modeling an existing **Azure Container Registry (ACR)** using the new `AddAzureContainerRegistry(...)` API. This enables you to **push images to an ACR you already manage**—without Aspire provisioning a new one.
-
-This is ideal for teams that:
-
-- Share a centralized registry across environments
-- Integrate with existing CI/CD pipelines and promotion workflows
-- Require fine-grained control over image publishing
-
-#### Example: associate ACR with an Azure Container Apps environment
-
-```csharp
-var acr = builder.AddAzureContainerRegistry("my-acr");
-
-builder.AddAzureContainerAppEnvironment("env")
- .WithAzureContainerRegistry(acr);
-
-builder.AddProject("api")
- .WithExternalHttpEndpoints();
-```
-
-In this example:
-
-- The ACR is modeled in Aspire and used by the container apps environment
-- Aspire publishes the built image to `my-acr` and configures Azure Container Apps to pull from it
-
-#### ACR works with multiple compute environments
-
-You can associate an `AzureContainerRegistryResource` with:
-
-- `AddAzureContainerAppEnvironment(...)`
-- `AddAzureAppServiceEnvironment(...)`
-
-This gives you consistent control over where images are published, even across different compute targets.
-
-> 💡 Use `.RunAsExisting()` or `.PublishAsExisting()` on the ACR resource to reference an existing registry without provisioning one.
-
-### 🖇️ Resource Deep Linking for Blob Containers
-
-Aspire 9.3 expands **resource deep linking** to include **Azure Blob Storage containers**, building on the model already used for Cosmos DB, Event Hubs, Service Bus, and Azure OpenAI.
-
-You can now model individual blob containers directly in your AppHost, then inject scoped `BlobContainerClient` instances into your services—making it easy to read or write blobs without manually configuring connection strings or access.
-
-**AppHost:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Add Azure Storage Emulator
-var storage = builder.AddAzureStorage("storage").RunAsEmulator();
-
-// Add a blob group and a container
-var blobs = storage.AddBlobs("blobs");
-var container = blobs.AddBlobContainer("images", blobContainerName: "image-uploads");
-
-// Add the API project and reference the container
-builder.AddProject("api")
- .WithExternalHttpEndpoints()
- .WithReference(container);
-
-builder.Build().Run();
-```
-
-**In the API project:**
-
-```csharp
-using Azure.Storage.Blobs;
-
-var builder = WebApplication.CreateBuilder(args);
-
-// Register the blob container client
-builder.AddAzureBlobContainerClient("images");
-
-var app = builder.Build();
-
-// Minimal POST endpoint for image upload
-app.MapPost("/upload", async (
- IFormFile file,
- BlobContainerClient container) =>
-{
- await container.CreateIfNotExistsAsync();
-
- var blob = container.GetBlobClient(file.FileName);
- using var stream = file.OpenReadStream();
- await blob.UploadAsync(stream, overwrite: true);
-
- return Results.Ok(new { Url = blob.Uri });
-});
-
-app.Run();
-```
-
-This pattern provides clean separation of concerns, secure container scoping, and minimal ceremony—ideal for microservices that interact with specific blob containers.
-
-### 🔐 Expanded Azure Key Vault client integrations
-
-Aspire 9.3 expands Azure Key Vault support with new client integration APIs for **keys** and **certificates**, allowing you to inject typed Azure SDK clients directly into your services:
-
-- `AddAzureKeyVaultKeyClient(...)`
-- `AddAzureKeyVaultCertificateClient(...)`
-- `AddKeyedAzureKeyVaultKeyClient(...)`
-- `AddKeyedAzureKeyVaultCertificateClient(...)`
-
-These APIs complement the existing `AddAzureKeyVaultClient(...)` and provide easy access to `KeyClient` and `CertificateClient` from the Azure SDK for .NET.
-
-```csharp
-var builder = WebApplication.CreateBuilder(args);
-
-// Register default clients
-builder.AddAzureKeyVaultKeyClient("kv");
-builder.AddAzureKeyVaultCertificateClient("kv");
-
-// Register named (keyed) clients
-builder.AddKeyedAzureKeyVaultCertificateClient("kv", "signing-cert");
-```
-
-The **keyed overloads** allow you to register multiple clients scoped to the same Key Vault resource—useful when accessing multiple certificates or keys by purpose.
-
-> 🙌 This feature was contributed by [@james-gould](https://github.com/james-gould). Thank you!
-
-### 🔑 Use Key Vault secrets in environment variables
-
-Aspire 9.3 adds support for wiring **Key Vault secrets directly into environment variables** using a new overload of `WithEnvironment(...)` that accepts an `IAzureKeyVaultSecretReference`.
-
-This makes it easy to securely reference secrets from a modeled Key Vault without hardcoding secret values—and ensures those references flow correctly into deployment outputs like Azure Bicep.
-
-```csharp
-var kv = builder.AddAzureKeyVault("myKeyVault");
-
-var secretRef = kv.Resource.GetSecret("mySecret");
-
-builder.AddContainer("myContainer", "nginx")
- .WithEnvironment("MY_SECRET", secretRef);
-```
-
-#### 🧩 Reference secrets from existing Key Vaults
-
-You can also use this with **existing Azure Key Vaults** by marking the resource with `AsExisting(...)`, `RunAsExisting(...)`, or `PublishAsExisting(...)`. This lets you consume secrets from **already-provisioned vaults**—perfect for shared environments or team-managed infrastructure.
-
-```csharp
-var keyVaultNameParam = builder.AddParameter("key-vault-name");
-var keyVaultResourceGroupParam = builder.AddParameter("key-vault-rg");
-
-var existingVault = builder.AddAzureKeyVault("sharedVault")
- .AsExisting(keyVaultNameParam, keyVaultResourceGroupParam);
-
-var apiKey = existingVault.Resource.GetSecret("stripe-api-key");
-
-builder.AddContainer("billing", "mycompany/billing")
- .WithEnvironment("STRIPE_API_KEY", apiKey);
-```
-
-This pattern ensures Aspire:
-
-- Doesn't attempt to re-provision the Key Vault
-- Emits references to the correct existing resources in publish mode
-- Still enables secret injection and secure scoping via environment variables
-
-📖 See also: [Use existing Azure resources](https://aspire.dev/integrations/cloud/azure/#use-existing-azure-resources).
-
-### 🧠 Azure AI Inference client integration (Preview)
-
-Aspire 9.3 adds **client-only support for Azure-hosted Chat Completions endpoints** using the library and the abstractions.
-
-This integration simplifies calling Azure OpenAI or Azure AI Inference services from your application—whether you prefer working directly with the SDK or using abstraction-friendly interfaces.
-
-#### Use `ChatCompletionsClient` with the Azure SDK
-
-```csharp
-builder.AddAzureChatCompletionsClient("connectionName");
-
-app.MapPost("/chat-raw", (
- ChatCompletionsClient client,
- ChatRequest message) =>
-{
- // Use the client
-});
-```
-
-#### Use `IChatClient` via `Microsoft.Extensions.AI`
-
-```csharp
-builder.AddAzureChatCompletionsClient("inference")
- .AddChatClient();
-```
-
-Once registered, you can inject using standard dependency injection:
-
-```csharp
-app.MapPost("/chat", async (
- IChatClient chatClient,
- ChatRequest message) =>
-{
- var result = await chatClient.GetResponseAsync(message.Input);
- return result;
-});
-```
-
-This setup integrates seamlessly with frameworks like [Semantic Kernel](https://github.com/microsoft/semantic-kernel), and works well in modular or pluggable AI systems.
-
-🔗 Learn more about [Microsoft.Extensions.AI](/dotnet/ai/microsoft-extensions-ai) and [ChatCompletionsClient](/dotnet/api/azure.ai.inference.chatcompletionsclient).
-
-### ⚙️ Azure App Configuration client integration
-
-Aspire 9.3 adds support for **Azure App Configuration** via a new client integration, [📦 Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration](https://www.nuget.org/packages/Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration) NuGet package.
-
-This makes it easy to connect to centralized configuration using the official Azure SDK and the `Microsoft.Extensions.Configuration.AzureAppConfiguration` provider—no manual setup required.
-
-```csharp
-builder.AddAzureAppConfiguration("appconfig");
-```
-
-Once registered, Aspire automatically wires Azure App Configuration into your application's configuration pipeline.
-
-#### Example: bind Azure App Configuration to app settings
-
-```csharp
-var builder = WebApplication.CreateBuilder(args);
-
-builder.AddAzureAppConfiguration("appconfig");
-
-var app = builder.Build();
-
-app.MapGet("/feature", (IConfiguration config) =>
-{
- var isEnabled = config.GetValue("FeatureFlag:Enabled");
- return Results.Ok(new { Enabled = isEnabled });
-});
-
-app.Run();
-```
-
-This enables:
-
-- Dynamic feature flag evaluation
-- Centralized configuration management across environments
-- Secure integration into the Aspire hosting model
-
-> 🔐 Like all Azure integrations in Aspire, the App Configuration client defaults to using **Managed Identity** for secure access—no connection strings required.
-
-📦 NuGet package: [`Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration`](https://www.nuget.org/packages/Aspire.Microsoft.Extensions.Configuration.AzureAppConfiguration)
-🔗 Learn more about [Azure App Configuration](/azure/azure-app-configuration/overview)
-
-### 🛡️ Secure multi-app access to Azure SQL (Breaking change)
-
-In Aspire 9.2, using **multiple projects with the same Azure SQL Server** inside an **Azure Container Apps environment** could silently break your app's identity model.
-
-Each app was assigned its own **managed identity**, but Aspire granted **admin access** to the last app deployed—overwriting access for any previously deployed apps. This led to confusing failures where only one app could talk to the database at a time.
-
-#### ✅ New behavior in 9.3
-
-Aspire 9.3 fixes this by:
-
-1. Assigning **one identity** as the **SQL Server administrator**
-2. Emitting a **SQL script** that:
-
- - Creates a **user** for each additional managed identity
- - Assigns each user the **`db_owner`** role on the target database
-
-This ensures every app that references the database gets **full access** without conflicting with other apps.
-
-#### Why this matters
-
-- Supports **multiple apps accessing the same SQL Server** securely
-- Preserves **least-privilege separation** across app identities
-- Avoids the brittle “last one wins” admin behavior from earlier releases
-- Enables richer deployment scenarios in cloud-native environments like Azure Container Apps
-
-#### ⚠️ Breaking change
-
-If your deployment relied on Aspire setting the managed identity as the SQL Server **admin**, you'll need to review your access model. Apps now receive **explicit role-based access (`db_owner`)** instead of broad admin rights.
-
-📖 Related: [dotnet/aspire#8381](https://github.com/dotnet/aspire/issues/8381) and [dotnet/aspire#8389](https://github.com/dotnet/aspire/issues/8389)
-
-### 💸 Default Azure SQL SKU now uses the Free Offer (Breaking change)
-
-Aspire 9.3 changes the default SKU used when provisioning **Azure SQL databases** to the **GP_S_Gen5_2** (General Purpose Serverless) tier with the [**Free Offer**](/azure/azure-sql/database/free-offer?view=azuresql&preserve-view=true). This helps reduce unexpected costs during development and experimentation.
-
-Previously, Aspire defaulted to the **General Purpose (GP)** tier *without* the Free Offer, which could incur charges even for small or test apps.
-
-#### What's new
-
-When you provision a SQL database like this:
-
-```csharp
-var sql = builder.AddAzureSqlServer("sqlserver");
-
-sql.AddDatabase("appdb");
-```
-
-Aspire now automatically uses the **Free Offer** for `appdb`, which will deploy a **GP_S_Gen5_2** (General Purpose Serverless), unless you override it.
-
-#### How to restore the previous behavior
-
-If your app requires the performance or features of the General Purpose paid tier, you can opt out of the new default using:
-
-```csharp
-sql.AddDatabase("appdb")
- .WithDefaultAzureSku(); // Uses the previous (General Purpose) default
-```
-
-If you want to specify what SKU to use, you the `ConfigureInfrastructure` method as explained here: [Setting a specific SKU](https://github.com/dotnet/aspire/tree/main/src/Aspire.Hosting.Azure.Sql#setting-a-specific-sku).
-
-#### ⚠️ Breaking change
-
-This change affects cost, performance, and available features in new deployments. If your app depends on higher-tier capabilities, be sure to configure the SKU accordingly.
-
-🔧 Use `.WithDefaultAzureSku()` on the **database** to revert to the old behavior
-
-
-
-## 🚀 AZD: Major Improvements to CI/CD for Aspire Apps
-
-We've dramatically improved how `azd` configures CI/CD pipelines for Aspire-based applications. These updates directly address one of the most frustrating pain points reported by the community: managing environment parameters and secrets securely and predictably across environments.
-
-Aspire apps are increasingly parameter-driven — using infrastructure-defined settings like connection strings, runtime versions, API keys, and feature flags. Getting those values safely and consistently into CI pipelines like GitHub Actions has historically been difficult. This release fixes that.
-
-### 🧠 Smarter Parameter Handling — No More `AZD_INITIAL_ENVIRONMENT_CONFIG`
-
-Previously, Aspire apps that required infrastructure parameters relied on a hidden environment variable called `AZD_INITIAL_ENVIRONMENT_CONFIG`. This variable was a large JSON blob containing all local environment configuration. It had to be passed manually into CI pipelines, was difficult to inspect, and introduced friction when sharing or updating environments.
-
-**Now:** `azd` extracts Aspire parameters directly from your infrastructure definitions and exposes them as named environment variables or secrets in your pipeline — **securely and explicitly**.
-
-For example:
-
-```bicep
-param openaiKey string
-param dbPassword string
-```
-
-become:
-
-```yaml
-AZURE_OPENAI_KEY: ${{ secrets.AZURE_OPENAI_KEY }}
-AZURE_DB_PASSWORD: ${{ secrets.AZURE_DB_PASSWORD }}
-```
-
-This means no more bundling, no more fragile config hacks, and no more guessing how your environment is configured in CI.
-
-### 🔤 Consistent, Predictable Parameter Naming
-
-Aspire parameters are mapped to environment variable names using a clear rule:
-
-1. Convert `camelCase` to `SNAKE_CASE`
-2. Replace dashes (`-`) with underscores (`_`)
-3. Uppercase everything
-4. Prefix with `AZURE_`
-
-| Parameter name | Env var vame |
-|------------------------|------------------------------|
-| `openaiKey` | `AZURE_OPENAI_KEY` |
-| `dbPassword` | `AZURE_DB_PASSWORD` |
-| `storage-account-name` | `AZURE_STORAGE_ACCOUNT_NAME` |
-
-This naming consistency means Aspire deployment targets like Azure Container Apps can resolve configuration without custom mappings — locally or in the cloud.
-
-### 📦 Aspire Parameters Automatically Exported to CI
-
-Aspire apps often define required parameters in Bicep or infrastructure modules — including things like API keys, credentials, or runtime configuration. These are now automatically exported to your pipeline configuration using the naming rules above.
-
-You no longer need to:
-
-- Manually configure these in _.azure/env-name/config.json_
-- Inject them into CI via complex JSON blobs
-- Worry about missing or mismatched configuration between local and cloud
-
-Secure parameters (like `openaiKey` or `dbPassword`) are automatically treated as CI secrets, while others are injected as variables — all handled by `azd`.
-
-### 🧼 Interactive Secret Management in GitHub Actions
-
-When you run `azd pipeline config`, `azd` will now detect and prompt you if a secret already exists in your GitHub repo or if a secret is no longer used:
-
-#### Existing Secret Prompt:
-
-```
-The secret AZURE_OPENAI_KEY already exists. What would you like to do?
- [1] Keep it
- [2] Keep ALL existing secrets
- [3] Overwrite it
- [4] Overwrite ALL secrets
-```
-
-#### Unused Secret Prompt:
-
-```
-The secret AZURE_OLD_SECRET is no longer used. What would you like to do?
- [1] Keep it
- [2] Keep ALL unused secrets
- [3] Delete it
- [4] Delete ALL unused secrets
-```
-
-This ensures:
-
-- You're never surprised by secret overwrites
-- You can keep your repo clean of stale configuration
-- CI reflects your actual infrastructure setup
-
-### 🔄 End-to-End, Repeatable Aspire Deployment
-
-With these changes, the local-to-cloud workflow for Aspire apps is now consistent and automated:
-
-1. You define infrastructure parameters as part of your Aspire app.
-2. `azd` captures them during provisioning.
-3. `azd pipeline config` maps them into your GitHub Actions or Azure DevOps pipeline.
-4. Your pipeline runs securely with all the same inputs as your local environment — no manual steps required.
-
-No more `AZD_INITIAL_ENVIRONMENT_CONFIG`. No more brittle overrides. Just clear, secure, parameterized deployment.
-
-These changes unlock a smoother, safer CI/CD experience for Aspire projects — reducing manual configuration, improving security, and aligning your local development setup with your production pipeline.
-
-## 💔 Breaking changes
-
-With every release, we strive to make Aspire better. However, some changes may break existing functionality. The following breaking changes are introduced in Aspire 9.3:
-
-- [Breaking changes in Aspire 9.3](../compatibility/9.3/index.md)
diff --git a/docs/whats-new/dotnet-aspire-9.4.md b/docs/whats-new/dotnet-aspire-9.4.md
deleted file mode 100644
index 863b16c72d..0000000000
--- a/docs/whats-new/dotnet-aspire-9.4.md
+++ /dev/null
@@ -1,1873 +0,0 @@
----
-title: What's new in Aspire 9.4
-description: Learn what's new in the official general availability release of Aspire 9.4.
-ms.date: 10/01/2025
----
-
-# What's new in Aspire 9.4
-
-📢 Aspire 9.4 is the next minor version release of Aspire. It supports:
-
-- .NET 8.0 Long Term Support (LTS)
-- .NET 9.0 Standard Term Support (STS)
-- .NET 10.0 Preview 6
-
-If you have feedback, questions, or want to contribute to Aspire, collaborate with us on [:::image type="icon" source="../media/github-mark.svg" border="false"::: GitHub](https://github.com/dotnet/aspire) or join us on our new [:::image type="icon" source="../media/discord-icon.svg" border="false"::: Discord](https://aka.ms/aspire-discord) to chat with the team and other community members.
-
-It's important to note that Aspire releases out-of-band from .NET releases. While major versions of Aspire align with major .NET versions, minor versions are released more frequently. For more information on .NET and Aspire version support, see:
-
-- [.NET support policy](https://dotnet.microsoft.com/platform/support/policy): Definitions for LTS and STS.
-- [Aspire support policy](https://dotnet.microsoft.com/platform/support/policy/aspire): Important unique product lifecycle details.
-
-## ⬆️ Upgrade to Aspire 9.4
-
-Moving between minor releases of Aspire is simple:
-
-1. In your AppHost project file (that is, _MyApp.AppHost.csproj_), update the [📦 Aspire.AppHost.Sdk](https://www.nuget.org/packages/Aspire.AppHost.Sdk) NuGet package to version `9.4.0`:
-
- ```xml
-
- ```
-
- For more information, see [Aspire SDK](xref:dotnet/aspire/sdk).
-
-1. Check for any NuGet package updates, either using the NuGet Package Manager in Visual Studio or the **Update NuGet Package** command from C# Dev Kit in VS Code.
-1. Update to the latest [Aspire templates](../fundamentals/aspire-sdk-templates.md) by running the following .NET command line:
-
- ```dotnetcli
- dotnet new install Aspire.ProjectTemplates
- ```
-
- > The `dotnet new install` command will update existing Aspire templates to the latest version if they are already installed.
-
-If your AppHost project file doesn't have the `Aspire.AppHost.Sdk` reference, you might still be using Aspire 8. To upgrade to 9, follow [the upgrade guide](../get-started/upgrade-to-aspire-9.md).
-
-## 🛠️ Aspire CLI is generally available
-
-With the release of Aspire 9.4, the Aspire CLI is generally available. To install the Aspire CLI as an AOT compiled binary, use the following helper scripts:
-
-```bash
-# Bash
-curl -sSL https://aspire.dev/install.sh | bash
-
-# PowerShell
-iex "& { $(irm https://aspire.dev/install.ps1) }"
-```
-
-This will install the CLI and put it on your PATH (the binaries are placed in the `$HOME/.aspire/bin` path). If you choose you can also install the CLI as a non-AOT .NET global tool using:
-
-```dotnetcli
-dotnet tool install -g Aspire.Cli
-```
-
-For more information, see [Install Aspire CLI](https://aspire.dev/reference/cli/overview/) and [aspire-install script reference](https://aspire.dev/reference/cli/overview/).
-
-> [!NOTE]
-> ⚠️ **The Aspire 9.4 CLI is not compatible with Aspire 9.3 projects.**
-> You must upgrade your project to Aspire 9.4+ in order to use the latest CLI features.
-
-### 🎯 CLI Commands
-
-The Aspire CLI has the following [commands](../cli-reference/aspire.md):
-
-- `aspire new`: Creates a new Aspire project from templates.
-- `aspire run`: Finds and runs the existing apphost from anywhere in the repo.
-- `aspire add`: Adds a hosting integration package to the apphost.
-- `aspire config [get|set|delete|list]`: Configures Aspire settings and feature flags.
-- `aspire publish` (Preview): Generates deployment artifacts based on the apphost.
-
-In addition to these core commands, we have two beta commands behind [feature flags](../cli-reference/aspire-config.md):
-
-- `aspire exec`: Invokes an arbitrary command in the context of an executable resource defined in the apphost (ie, inheriting its environment variables).
-- `aspire deploy`: Extends the capabilities of `aspire publish` to actively deploy to a target environment.
-
-#### `aspire exec`
-
-The new `exec` command allows you to execute commands within the context of your Aspire application environment:
-
-```bash
-# Execute commands, like migrations, with environment variables from your app model
-aspire exec --resource my-api -- dotnet ef database update
-
-# Run scripts with access to application context
-aspire exec --start-resource my-worker -- npm run build
-
-# The exec command automatically provides environment variables
-# from your Aspire application resources to the executed command
-```
-
-**Key capabilities**:
-
-- **Environment variable injection** from your app model resources
-- **Resource targeting** with `--resource` or `--start-resource` options
-- **Command execution** in the context of your Aspirified application
-
-[!INCLUDE [aspire exec feature flag note](../cli/includes/exec-feature-flag-note.md)]
-
-#### `aspire deploy`
-
-The `aspire deploy` command supports extensible deployment workflows through the new [`DeployingCallbackAnnotation`](https://aspire.dev/fundamentals/annotations-overview/), enabling custom pre/post-deploy logic and richer integration with external systems during deployment operations.
-
-**Key capabilities:**
-
-- **Custom deployment hooks** using to execute custom logic during the `aspire deploy` command
-- **Workflow activity reporting** via the to support progress notifications and prompting in commmands
-- **Integration with publish** - `aspire deploy` runs `Aspire.Hosting.Publishing.PublishingCallbackAnnotations` to support deploying artifacts emitted by publish steps, if applicable
-
-The example below demonstrates using the `DeployingCallbackAnnotation` to register custom deployment behavior and showcases [CLI-based prompting](#-enhanced-publish-and-deploy-output) and progress notifications.
-
-```csharp
-#pragma warning disable ASPIREPUBLISHERS001
-#pragma warning disable ASPIREINTERACTION001
-
-using Aspire.Hosting.Publishing;
-using Microsoft.Extensions.DependencyInjection;
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Custom deployment step defined below
-builder.AddDataSeedJob("SeedInitialData", seedDataPath: "data/seeds");
-
-builder.Build().Run();
-
-internal class DataSeedJobResource(string name, string seedDataPath)
- : Resource(name)
-{
- public string SeedDataPath { get; } = seedDataPath;
-}
-
-internal static class DataSeedJobBuilderExtensions
-{
- public static IResourceBuilder AddDataSeedJob(
- this IDistributedApplicationBuilder builder,
- string name,
- string seedDataPath = "data/seeds")
- {
- var job = new DataSeedJobResource(name, seedDataPath);
- var resourceBuilder = builder.AddResource(job);
-
- // Attach a DeployingCallbackAnnotation that will be invoked on `aspire deploy`
- job.Annotations.Add(new DeployingCallbackAnnotation(async ctx =>
- {
- CancellationToken ct = ctx.CancellationToken;
-
- // Prompt the user for a confirmation using the interaction service
- var interactionService = ctx.Services.GetRequiredService();
-
- var envResult = await interactionService.PromptInputAsync(
- "Environment Configuration",
- "Please enter the target environment name:",
- new InteractionInput
- {
- Label = "Environment Name",
- InputType = InputType.Text,
- Required = true,
- Placeholder = "dev, staging, prod"
- },
- cancellationToken: ct);
-
-
- // Use the ActivityReporter to report progress on the seeding process
- var reporter = ctx.ActivityReporter;
-
- var step = await reporter.CreateStepAsync("Seeding data", ct);
- var task = await step.CreateTaskAsync($"Loading seed data from {seedDataPath}", ct);
-
- try
- {
- // Do some work here
- await Task.Delay(3000);
-
- await task.SucceedAsync("Seed data loaded", ct);
- await step.SucceedAsync("Data seeding completed", ct);
- }
- catch (Exception ex)
- {
- await task.FailAsync(ex.Message, ct);
- await step.FailAsync("Data seeding failed", ct);
- throw;
- }
- }));
-
- return resourceBuilder;
- }
-}
-```
-
-This custom deployment logic executes as follows from the `aspire deploy` command.
-
-
-
-Now, integration owners can create sophisticated `aspire deploy` workflows. This work also provides a foundation for advanced deployment automation scenarios.
-
-> [!NOTE]
-> While the API is available in Aspire 9.4, there are currently no built-in resources that natively support deployment callbacks. Built-in resource support for deployment callbacks will be added in the next version of Aspire.
-
-> [!IMPORTANT]
-> 🧪 **Feature Flag**: The `aspire deploy` command is behind a feature flag and **disabled by default** in this release. It must be explicitly enabled for use with `aspire config set features.deployCommandEnabled true`
-
-### 📃 Enhanced publish and deploy output
-
-Aspire 9.4 significantly improves the feedback and progress reporting during publish and deploy operations, providing clearer visibility into what's happening during deployment processes.
-
-**Key improvements:**
-
-- **Enhanced progress reporting** with detailed step-by-step feedback during publishing
-- **Cleaner output formatting** that makes it easier to follow deployment progress
-- **Better error messaging** with more descriptive information when deployments fail
-- **Improved publishing context** that tracks and reports on resource deployment status
-- **Container build logs** provide clear status updates during container operations
-
-These improvements make it much easier to understand what's happening during `aspire deploy` and `aspire publish` operations, helping developers debug issues more effectively and gain confidence in their deployment processes.
-
-The enhanced output is particularly valuable for:
-
-- **CI/CD pipelines** where clear logging is essential for troubleshooting
-- **Complex deployments** with multiple resources and dependencies
-- **Container-based deployments** where build and push operations need clear status reporting
-- **Team environments** where deployment logs need to be easily interpreted by different team members
-
-For more information about publishing and deploying Aspire apps, see [aspire deploy](../cli-reference/aspire-deploy.md).
-
-## 🖥️ App model enhancements
-
-### 🎛️ Interaction service
-
-Aspire 9.4 introduces the [interaction service](https://aspire.dev/extensibility/interaction-service/), a general service that allows developers to build rich experiences at runtime by extending the dashboard UX and at publish and deploy time using the Aspire CLI. It allows you to build complex interactions where input is required from the user.
-
-> [!IMPORTANT]
-> 🧪 This feature is experimental and may change in future releases.
-
-:::image type="content" source="media/dashboard-interaction-service.gif" lightbox="media/dashboard-interaction-service.gif" alt-text="Recording of using the interaction service in the dashboard.":::
-
-The interaction system supports:
-
-- Confirmation prompts for destructive operations
-- Input collection with validation
-- Multi-step workflows
-- Dashboard interactions during run mode
-- CLI interactions during deploy and publish operations
-
-```csharp
-// Example usage of IInteractionService APIs
-public class DeploymentService
-{
- private readonly IInteractionService _interactionService;
-
- public DeploymentService(IInteractionService interactionService)
- {
- _interactionService = interactionService;
- }
-
- public async Task DeployAsync()
- {
- // Prompt for confirmation before destructive operations
- var confirmResult = await _interactionService.PromptConfirmationAsync(
- "Confirm Deployment",
- "This will overwrite the existing deployment. Continue?");
-
- if (confirmResult.Canceled || !confirmResult.Data)
- {
- return;
- }
-
- // Collect multiple inputs with validation
- var regionInput = new InteractionInput { Label = "Region", InputType = InputType.Text, Required = true };
- var instanceCountInput = new InteractionInput { Label = "Instance Count", InputType = InputType.Number, Required = true };
- var enableMonitoringInput = new InteractionInput { Label = "Enable Monitoring", InputType = InputType.Boolean };
-
- var multiInputResult = await _interactionService.PromptInputsAsync(
- "Advanced Configuration",
- "Configure deployment settings:",
- [regionInput, instanceCountInput, enableMonitoringInput],
- new InputsDialogInteractionOptions
- {
- ValidationCallback = async context =>
- {
- if (!IsValidRegion(regionInput.Value))
- {
- context.AddValidationError(regionInput, "Invalid region specified");
- }
- }
- });
-
- if (multiInputResult.Canceled)
- {
- return;
- }
-
- await RunDeploymentAsync(
- region: regionInput.Value,
- instanceCount: instanceCountInput.Value,
- enableMonitoring: enableMonitoringInput.Value);
-
- // Show progress notifications
- await _interactionService.PromptNotificationAsync(
- "Deployment Status",
- "Deployment completed successfully!",
- new NotificationInteractionOptions
- {
- Intent = MessageIntent.Success,
- LinkText = "View Dashboard",
- LinkUrl = "https://portal.azure.com"
- });
- }
-
- private bool IsValidRegion(string? region)
- {
- // Validation logic here
- return !string.IsNullOrEmpty(region);
- }
-}
-```
-
-**Input types supported:**
-
-- `Text` - Standard text input
-- `SecretText` - Password/secret input (masked)
-- `Choice` - Dropdown selection
-- `Boolean` - Checkbox input
-- `Number` - Numeric input
-
-**Advanced features:**
-
-- **Validation callbacks** for complex input validation
-- **Markdown support** for rich text descriptions
-- **Custom button text** and dialog options
-- **Intent-based styling** for different message types
-- **Link support** in notifications
-
-These interactions work seamlessly whether you're running your application through the [Aspire dashboard](#-dashboard-improvements) or deploying via the CLI with `aspire deploy` and `aspire publish` commands.
-
-### 🔄 Interactive parameter prompting during run mode
-
-Aspire 9.4 introduces interactive parameter prompting, automatically collecting missing parameter values in the dashboard during application startup through the new [interaction service](#-interaction-service).
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Parameters without default values will trigger prompts
-var apiKey = builder.AddParameter("api-key", secret: true);
-var dbPassword = builder.AddParameter("db-password", secret: true);
-
-// This also works for values that could be defined in appsettings.json
-var environment = builder.AddParameterFromConfiguration("environment", "ENVIRONMENT_VARIABLE");
-
-// Application will prompt for these values if not provided
-var database = builder.AddPostgres("postgres", password: dbPassword);
-var api = builder.AddProject("api")
- .WithEnvironment("API_KEY", apiKey)
- .WithEnvironment("ENVIRONMENT", environment)
- .WithReference(database);
-
-builder.Build().Run();
-```
-
-**Interactive experience:**
-
-- **Automatically detects parameters** that are missing so there aren't startup failures
-- **Dashboard prompts** with interactive forms and Markdown-enabled parameter descriptions
-- **Validation support** for enforcing rules (required, length, casing, etc)
-- **Secret masking** so sensitive input isn't shown while being entered
-- **Save to user secrets** for persistent per-project value storage outside of source control
-
-This feature eliminates the need to pre-configure all parameters in appsettings.json or .env files before running your Aspirified application, so you can clone, run, and be guided through what values are needed to run the full stack.
-
-#### 📝 Enhanced parameter descriptions and custom input rendering
-
-Building on the interactive parameter prompting capabilities and the new [interaction service](#-interaction-service), Aspire 9.4 introduces rich parameter descriptions and custom input rendering to provide better user guidance and specialized input controls during parameter collection.
-
-- **Aspire.Hosting.ParameterResourceBuilderExtensions.WithDescription** - Add helpful descriptions to guide users during parameter input
-- **Markdown support** - Rich text descriptions with links, formatting, and lists using `enableMarkdown: true`
-- **Aspire.Hosting.ParameterResourceBuilderExtensions.WithCustomInput** - Create specialized input controls for specific parameter types
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Parameters with descriptions provide better user guidance
-var apiKey = builder.AddParameter("api-key", secret: true)
- .WithDescription("API key for external service authentication");
-
-var environment = builder.AddParameter("environment")
- .WithDescription("Target deployment environment (dev, staging, prod)");
-
-// Parameters with rich markdown descriptions
-var configValue = builder.AddParameter("config-value")
- .WithDescription("""
- Configuration value with detailed instructions:
-
- - Use **development** for local testing
- - Use **staging** for pre-production validation
- - Use **production** for live deployments
-
- See [configuration guide](https://docs.company.com/config) for details.
- """, enableMarkdown: true);
-
-// Custom input rendering for specialized scenarios
-var workerCount = builder.AddParameter("worker-count")
- .WithDescription("Number of background worker processes")
- .WithCustomInput(p => new InteractionInput
- {
- InputType = InputType.Number,
- Label = "Worker Count",
- Placeholder = "Enter number (1-10)",
- Description = p.Description
- });
-
-var deploymentRegion = builder.AddParameter("region")
- .WithDescription("Azure region for deployment")
- .WithCustomInput(p => new InteractionInput
- {
- InputType = InputType.Choice,
- Label = "Deployment Region",
- Description = p.Description,
- Options = new[]
- {
- KeyValuePair.Create("eastus", "East US"),
- KeyValuePair.Create("westus", "West US"),
- KeyValuePair.Create("northeurope", "North Europe"),
- KeyValuePair.Create("southeastasia", "Southeast Asia")
- }
- });
-
-var api = builder.AddProject("api")
- .WithEnvironment("API_KEY", apiKey)
- .WithEnvironment("ENVIRONMENT", environment)
- .WithEnvironment("CONFIG_VALUE", configValue)
- .WithEnvironment("WORKER_COUNT", workerCount)
- .WithEnvironment("REGION", deploymentRegion);
-
-builder.Build().Run();
-```
-
-For more information, including supported input types, see the [Interaction Service section](#-interaction-service) below or the full [interaction service docs](https://aspire.dev/extensibility/interaction-service/).
-
-### 🌐 External service modeling
-
-Modern applications frequently need to integrate with external APIs, third-party services, or existing infrastructure that isn't managed by Aspire. Aspire 9.4 introduces first-class support for [modeling external services](../fundamentals/orchestrate-resources.md#express-external-service-resources) as resources in your application graph.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Reference an external service by URL
-var externalApi = builder.AddExternalService("external-api", "https://api.company.com");
-
-// Or use a parameter for dynamic configuration
-var apiUrl = builder.AddParameter("api-url");
-var externalDb = builder.AddExternalService("external-db", apiUrl)
- .WithHttpHealthCheck("/health");
-
-var myService = builder.AddProject("my-service")
- .WithReference(externalApi)
- .WithReference(externalDb);
-
-builder.Build().Run();
-```
-
-External services appear in the Aspire dashboard with health status, can be referenced like any other resource, and support the same configuration patterns as internal resources.
-
-### 🔗 Enhanced endpoint URL support
-
-Aspire 9.4 introduces support for [non-localhost URLs](https://aspire.dev/fundamentals/networking-overview/), making it easier to work with custom domains and network configurations. This includes support for `*.localhost` subdomains and automatic generation of multiple URL variants for endpoints listening on multiple addresses.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Endpoints targeting all addresses automatically get multiple URL variants
-var api = builder.AddProject("api")
- .WithEndpoint("https", e => e.TargetHost = "0.0.0.0");
-
-// Machine name URLs for external access
-var publicService = builder.AddProject("public")
- .WithEndpoint("https", e => e.TargetHost = "0.0.0.0");
-
-builder.Build().Run();
-```
-
-**Key capabilities:**
-
-- **Custom `*.localhost` subdomain support** that maintains localhost behavior
-- **Automatic endpoint URL generation** for endpoints listening on multiple addresses, with both localhost and machine name URLs (such as Codespaces)
-- **All URL variants** appear in the Aspire dashboard for easy access
-- **Network flexibility** for development scenarios requiring specific network configurations
-- **Launch profile configuration support** so custom URLs can also be configured via launch profiles in `launchSettings.json`:
-
-```json
-{
- "profiles": {
- "https": {
- "commandName": "Project",
- "dotnetRunMessages": true,
- "launchBrowser": true,
- "applicationUrl": "https://*:7001;http://*:5001",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- }
- }
-}
-```
-
-This simplifies development workflows where custom domains or external network access is needed while maintaining the familiar localhost development experience. A popular example includes SaaS solutions which use custom domains per-tenant.
-
-### 🐳 Enhanced persistent container support
-
-Aspire 9.4 improves support for [persistent containers](https://aspire.dev/app-host/persistent-containers/) with better lifecycle management and networking capabilities, ensuring containers can persist across application restarts while maintaining proper connectivity.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Persistent containers with improved lifecycle support
-var database = builder.AddPostgres("postgres")
- .WithLifetime(ContainerLifetime.Persistent)
- .WithExplicitStart(); // Better support for explicit start with persistent containers
-
-// Persistent containers automatically also get persistent networking
-var redis = builder.AddRedis("redis")
- .WithLifetime(ContainerLifetime.Persistent);
-
-var api = builder.AddProject("api")
- .WithReference(database)
- .WithReference(redis);
-
-builder.Build().Run();
-```
-
-**Enhanced capabilities:**
-
-- **Improved lifecycle coordination** between and `ContainerLifetime.Persistent`
-- **Automatic persistent networking** spun up when persistent containers are detected
-- **Container delay start** for more reliable startup sequencing
-- **Network isolation** between persistent and session-scoped containers, which now use separate networks for better resource management
-
-This will greatly improve your experience while building stateful services that persist beyond individual application runs.
-
-### 🎛️ Resource command service
-
-Aspire 9.4 introduces , an API for executing commands against resources. You can now easily execute the commands that appear in the dashboard programmatically. For example, when writing unit tests for commands, or having other integrations in Aspire execute commands.
-
-The example below uses `ResourceCommandService` to have a command execute other commands.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var database = builder.AddPostgres("postgres")
- .WithHttpCommand("admin-restart", "Restart Database",
- commandName: "db-restart",
- commandOptions: new HttpCommandOptions
- {
- Method = HttpMethod.Post,
- Description = "Restart the PostgreSQL database"
- });
-
-var cache = builder.AddRedis("cache")
- .WithHttpCommand("admin-flush", "Flush Cache",
- commandName: "cache-flush",
- commandOptions: new HttpCommandOptions
- {
- Method = HttpMethod.Delete,
- Description = "Clear all cached data"
- });
-
-// Add a composite command that coordinates multiple operations
-var api = builder.AddProject("api")
- .WithReference(database)
- .WithReference(cache)
- .WithCommand("reset-all", "Reset Everything", async (context, ct) =>
- {
- var logger = context.ServiceProvider.GetRequiredService>();
- var commandService = context.ServiceProvider.GetRequiredService();
-
- logger.LogInformation("Starting full system reset...");
-
- try
- {
- var flushResult = await commandService.ExecuteCommandAsync(cache.Resource, "cache-flush", ct);
- var restartResult = await commandService.ExecuteCommandAsync(database.Resource, "db-restart", ct);
- if (!restartResult.Success || !flushResult.Success)
- {
- return CommandResults.Failure($"System reset failed");
- }
-
- logger.LogInformation("System reset completed successfully");
- return CommandResults.Success();
- }
- catch (Exception ex)
- {
- logger.LogError(ex, "System reset failed");
- return CommandResults.Failure(ex);
- }
- },
- displayDescription: "Reset cache and restart database in coordinated sequence",
- iconName: "ArrowClockwise");
-
-builder.Build().Run();
-```
-
-`ResourceCommandService` can also be used in unit tests:
-
-```csharp
-[Fact]
-public async Task Should_ResetCache_WhenTestStarts()
-{
- var builder = DistributedApplication.CreateBuilder();
-
- // Add cache with reset command for testing
- var cache = builder.AddRedis("test-cache")
- .WithHttpCommand("reset", "Reset Cache",
- commandName: "reset-cache",
- commandOptions: new HttpCommandOptions
- {
- Method = HttpMethod.Delete,
- Description = "Clear all cached test data"
- });
-
- var api = builder.AddProject("test-api")
- .WithReference(cache);
-
- await using var app = builder.Build();
- await app.StartAsync();
-
- // Reset cache before running test
- var result = await app.ResourceCommands.ExecuteCommandAsync(
- cache.Resource,
- "reset-cache",
- CancellationToken.None);
-
- Assert.True(result.Success, $"Failed to reset cache: {result.ErrorMessage}");
-}
-```
-
-### 🔄 Resource lifecycle events
-
-Aspire 9.4 introduces convenient extension methods on that make it much easier to subscribe to [lifecycle events](https://aspire.dev/app-host/eventing/#apphost-life-cycle-events) directly on resources, providing a cleaner and more intuitive API.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var database = builder.AddPostgres("postgres")
- .AddDatabase("mydb")
- .OnConnectionStringAvailable(async (resource, evt, cancellationToken) =>
- {
- // Log when connection strings are resolved
- var logger = evt.Services.GetRequiredService>();
- logger.LogInformation("Connection string available for {Name}", resource.Name);
- });
-
-var api = builder.AddProject("api")
- .WithReference(database)
- .OnInitializeResource(async (resource, evt, cancellationToken) =>
- {
- // Early resource initialization
- var logger = evt.Services.GetRequiredService>();
- logger.LogInformation("Initializing resource {Name}", resource.Name);
- })
- .OnBeforeResourceStarted(async (resource, evt, cancellationToken) =>
- {
- // Pre-startup validation or configuration
- var serviceProvider = evt.Services;
- // Additional validation logic here
- })
- .OnResourceEndpointsAllocated(async (resource, evt, cancellationToken) =>
- {
- // React to endpoint allocation
- var logger = evt.Services.GetRequiredService>();
- logger.LogInformation("Endpoints allocated for {Name}", resource.Name);
- })
- .OnResourceReady(async (resource, evt, cancellationToken) =>
- {
- // Resource is fully ready
- var logger = evt.Services.GetRequiredService>();
- logger.LogInformation("Resource {Name} is ready", resource.Name);
- });
-
-// Example: Database seeding using OnResourceReady
-var db = builder.AddMongoDB("mongo")
- .WithMongoExpress()
- .AddDatabase("db")
- .OnResourceReady(async (db, evt, ct) =>
- {
- // Seed the database with initial data
- var connectionString = await db.ConnectionStringExpression.GetValueAsync(ct);
- using var client = new MongoClient(connectionString);
-
- var myDb = client.GetDatabase("db");
- await myDb.CreateCollectionAsync("entries", cancellationToken: ct);
-
- // Insert sample data
- for (int i = 0; i < 10; i++)
- {
- await myDb.GetCollection("entries").InsertOneAsync(new Entry(), cancellationToken: ct);
- }
- });
-
-builder.Build().Run();
-```
-
-**Available lifecycle events:**
-
-- - Called during early resource initialization
-- - Called before the resource starts
-- - Called when connection strings are resolved (requires `IResourceWithConnectionString`)
-- - Called when resource endpoints are allocated (requires `IResourceWithEndpoints`)
-- - Called when the resource is fully ready
-
-The new chainable fluent API, strongly-typed callbacks, and simplified syntax make it intuitive to hook into your resource lifecycles for interactions, commands, custom scripts, and more.
-
-**Migration from manual eventing:**
-
-```csharp
-// ❌ Before (manual eventing subscription):
-builder.Eventing.Subscribe(db.Resource, async (evt, ct) =>
-{
- // Manual event handling with no type safety
- var cs = await db.Resource.ConnectionStringExpression.GetValueAsync(ct);
- // Process event...
-});
-
-// ✅ After (fluent extension methods):
-var db = builder.AddMongoDB("mongo")
- .AddDatabase("db")
- .OnResourceReady(async (db, evt, ct) =>
- {
- // Direct access to strongly-typed resource
- var cs = await db.ConnectionStringExpression.GetValueAsync(ct);
- // Process event...
- });
-```
-
-The new extension methods make it much easier to implement common patterns like database seeding, configuration validation, and resource health checks. Note that the old mechanism is not being deprecated, the new methods simply provide a more natural programming model when using the builder pattern.
-
-### 📁 Enhanced container file mounting
-
-Configuring container file systems often requires understanding complex Docker volume syntax and managing file permissions manually. Aspire 9.4 introduces enhanced file mounting APIs that handle common scenarios with sensible defaults.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Simple file copying from local source to container
-var myContainer = builder.AddContainer("myapp", "myapp:latest")
- .WithContainerFiles("/app/config", "./config-files")
- .WithContainerFiles("/app/data", "./data", defaultOwner: 1000, defaultGroup: 1000)
- .WithContainerFiles("/app/scripts", "./scripts", umask: UnixFileMode.UserRead | UnixFileMode.UserWrite);
-
-// You can also use the callback approach for dynamic file generation
-var dynamicContainer = builder.AddContainer("worker", "worker:latest")
- .WithContainerFiles("/app/runtime-config", async (context, ct) =>
- {
- // Generate configuration files dynamically
- var configFile = new ContainerFileSystemItem
- {
- Name = "app.json",
- Contents = JsonSerializer.SerializeToUtf8Bytes(new { Environment = "Production" })
- };
-
- return new[] { configFile };
- });
-
-builder.Build().Run();
-```
-
-The [enhanced APIs](https://aspire.dev/fundamentals/persist-data-volumes/) handle file permissions, ownership, and provide both static and dynamic file mounting capabilities while maintaining the flexibility to customize when needed.
-
-### ✨ Advanced YARP routing with transform APIs (Preview)
-
-> [!NOTE]
-> The [YARP integration](https://aspire.dev/integrations/reverse-proxies/yarp/) is currently in preview and APIs may change in future releases.
-
-Building sophisticated reverse proxy configurations has traditionally required deep knowledge of YARP's transform system and manual JSON configuration. Aspire 9.4 introduces a comprehensive set of fluent APIs that make advanced routing transformations accessible through strongly-typed C# code.
-
-**Breaking change in 9.4:** The `WithConfigFile()` method has been removed and replaced with a code-based configuration model. This new approach works seamlessly with deployment scenarios as the strongly-typed configuration methods translate directly into the appropriate environment variables.
-
-You can now programmatically configure request/response transformations, header manipulation, path rewriting, and query string handling directly from your app model—no more wrestling with complex configuration files.
-
-**Example 1: Simple path-based routing with path prefix removal**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var apiV1 = builder.AddProject("api-v1");
-var apiV2 = builder.AddProject("api-v2");
-
-var yarp = builder.AddYarp("gateway")
- .WithConfiguration(yarpBuilder =>
- {
- // Route /v1/* requests to api-v1, removing the /v1 prefix
- yarpBuilder.AddRoute("/v1/{**catch-all}", apiV1)
- .WithTransformPathRemovePrefix("/v1");
-
- // Route /v2/* requests to api-v2, removing the /v2 prefix
- yarpBuilder.AddRoute("/v2/{**catch-all}", apiV2)
- .WithTransformPathRemovePrefix("/v2");
- });
-
-builder.Build().Run();
-```
-
-**Example 2: Host-based routing**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var adminApi = builder.AddProject("admin-api");
-var publicApi = builder.AddProject("public-api");
-
-var yarp = builder.AddYarp("gateway")
- .WithConfiguration(yarpBuilder =>
- {
- // Route admin.example.com to admin API
- yarpBuilder.AddRoute(adminApi)
- .WithMatchHosts("admin.example.com");
-
- // Route api.example.com to public API
- yarpBuilder.AddRoute(publicApi)
- .WithMatchHosts("api.example.com");
-
- // Default route for any other host
- yarpBuilder.AddRoute("/{**catch-all}", publicApi);
- });
-
-builder.Build().Run();
-```
-
-**Example 3: Advanced routing with comprehensive transforms**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var backendApi = builder.AddProject("backend-api");
-var identityService = builder.AddProject("identity-service");
-
-var yarp = builder.AddYarp("gateway")
- .WithConfiguration(yarpBuilder =>
- {
- // Configure sophisticated routing with transforms
- yarpBuilder.AddRoute("/api/v1/{**catch-all}", backendApi)
- .WithTransformPathPrefix("/v2") // Rewrite /api/v1/* to /v2/*
- .WithTransformRequestHeader("X-API-Version", "2.0")
- .WithTransformForwarded(useHost: true, useProto: true)
- .WithTransformResponseHeader("X-Powered-By", "Aspire Gateway");
-
- // Advanced header and query manipulation
- yarpBuilder.AddRoute("/auth/{**catch-all}", identityService)
- .WithTransformClientCertHeader("X-Client-Cert")
- .WithTransformQueryValue("client_id", "aspire-app")
- .WithTransformRequestHeadersAllowed("Authorization", "Content-Type")
- .WithTransformUseOriginalHostHeader(false);
- });
-
-builder.Build().Run();
-```
-
-#### Migration from YARP 9.3 to 9.4
-
-If you were using `WithConfigFile()` in Aspire 9.3, you'll need to migrate to the new code-based configuration model shown above. The strongly-typed APIs provide better IntelliSense support and work seamlessly with deployment scenarios.
-
-> [!NOTE]
-> We are working on a more general-purpose solution for file-based configuration during deployment. File-based configuration support will return in a future version of Aspire.
-
-This eliminates the need for complex YARP configuration files while providing complete access to YARP's powerful transformation pipeline through a fluent API.
-
-### 🔒 Enhanced Docker Compose deployment security
-
-Aspire 9.4 improves [Docker Compose publish](https://aspire.dev/deployment/overview/) security with smart port mapping - only external endpoints are exposed to the host while internal services use Docker's internal networking.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var compose = builder.AddDockerComposeEnvironment("production");
-
-// Add a service with both internal and external endpoints
-var webService = builder.AddContainer("webservice", "nginx")
- .WithEndpoint(scheme: "http", port: 8080, name: "internal") // Internal endpoint
- .WithEndpoint(scheme: "http", port: 8081, name: "api", isExternal: true); // External endpoint
-
-builder.Build().Run();
-```
-
-**Generated Docker Compose output:**
-
-```yaml
-services:
- webservice:
- image: "nginx:latest"
- ports:
- - "8081:8001" # Only external endpoints get port mappings (host:container)
- expose:
- - "8000" # Internal endpoints use expose (container port only)
- networks:
- - "aspire"
-```
-
-Now, only `isExternal: true` endpoints are exposed to host, and internal endpoints use Docker's `expose` for container-to-container communication.
-
-## 🎨 Dashboard improvements
-
-> [!TIP]
-> For a bite sized look at many of the 9.4 dashboard changes, James Newton-King has kept up his tradition of posting one new dashboard feature a day leading up to an Aspire release on his [BlueSky](https://bsky.app/profile/james.newtonking.com)!
-
-### 🔔 Automatic upgrade check notifications
-
-Aspire 9.4 includes an update notification system that automatically checks for newer versions and notifies developers when updates are available, making sure you stay current with the latest improvements and security updates.
-
-When a newer version is detected, a friendly notification appears in the Aspire dashboard:
-
-:::image type="content" source="media/dashboard-update-notification.png" lightbox="media/dashboard-update-notification.png" alt-text="Screenshot of dashboard showing an update notification.":::
-
-Aspire only shows notifications when a newer version is available, and the checks happen in the background without impacting application startup or performance. The upgrade check system can be disabled by setting the `ASPIRE_VERSION_CHECK_DISABLED` environment variable to `true`. For more information, see [Aspire version update notifications](https://aspire.dev/app-host/configuration/#aspire-version-update-notifications).
-
-### 📋 Parameters and connection strings visible in dashboard
-
-Aspire 9.4 makes parameters and connection strings visible in the Aspire dashboard, providing better visibility into your application's configuration and connectivity status during development.
-
-Connection strings:
-
-- Appear in the **resource details** panel for any resource that implements
-- Values are marked as **sensitive** and can be toggled for visibility in the dashboard
-- Supports all resource types including databases, message brokers, and custom resources
-
-:::image type="content" source="media/dashboard-connection-strings.png" lightbox="media/dashboard-connection-strings.png" alt-text="Screenshot of dashboard showing connection string.":::
-
-External parameters are no longer hidden. The parameter state and value is visible in the dashboard.
-
-:::image type="content" source="media/dashboard-parameters.png" lightbox="media/dashboard-parameters.png" alt-text="Screenshot of dashboard showing parameters.":::
-
-For more information, see [external parameters](/dotnet/aspire/fundamentals/external-parameters).
-
-### 🔗 Enhanced dashboard peer visualization for uninstrumented resources
-
-Aspire 9.4 lets you observe connections between resources even when they aren't instrumented with telemetry.
-
-For example, the screenshot below shows a call to a GitHub model resolving to the model resource in Aspire:
-
-:::image type="content" source="media/dashboard-tracing-peers.png" lightbox="media/dashboard-tracing-peers.png" alt-text="Screenshot of a span linked to a GitHub model resource defined in Aspire.":::
-
-OpenTelemetry spans can now resolve to peers that are defined by parameters, connection strings, GitHub Models, and external services:
-
-- **Connection string parsing** supports SQL Server, PostgreSQL, MySQL, MongoDB, Redis, and many other connection string formats
-- **Visualize parameters** with URLs or connection strings and how they connect to services
-- **GitHub Models integration** for GitHub-hosted AI models with proper state management
-- **External service mapping** between your services and external dependencies
-
-### 📋 Console logs text wrapping control
-
-Aspire 9.4 introduces a new toggle option in the dashboard console logs to control text wrapping behavior, giving you better control over how long log lines are displayed.
-
-:::image type="content" source="media/dashboard-console-logs-wrapping.gif" lightbox="media/dashboard-console-logs-wrapping.gif" alt-text="Recording of toggling line wrapping on console logs page.":::
-
-Some Aspire users have run into trouble with viewing large console logs, which is tracked in this GitHub issue: [Console logs not showing, plus browser window size affecting displayed logs #7969](https://github.com/dotnet/aspire/issues/7969). If you're having trouble with logs please try experimenting with disabling wrapping and see whether it improves your user experience. Feedback on this issue would be very helpful.
-
-### 👁️ Show/hide hidden resources in dashboard
-
-Aspire 9.4 introduces the ability to show or hide hidden resources in the dashboard, giving you complete visibility into your application's infrastructure components and internal resources that are normally hidden from view.
-
-:::image type="content" source="media/dashboard-hidden-resources.png" lightbox="media/dashboard-hidden-resources.png" alt-text="Dashboard resources page with the show/hide hidden resources UI visible.":::
-
-If there are no hidden resources in your Aspire app then the show/hide UI is disabled.
-
-### 🏗️ Enhanced dashboard infrastructure with proxied endpoints
-
-Aspire 9.4 introduces significant infrastructure improvements to the dashboard system, implementing proxied endpoints that make dashboard launching more reliable and avoiding port reuse problems. This architectural enhancement resolves issues with dashboard connectivity during application startup and shutdown scenarios. The UI when the dashboard is attempting to reconnect has also been updated to be more reliable and with a new cohesive look and animation.
-
-### 🐳 Docker Compose with integrated Aspire Dashboard
-
-Managing observability in Docker Compose environments often requires running separate monitoring tools or losing the rich insights that Aspire provides during development. Aspire 9.4 introduces native Aspire Dashboard integration for Docker Compose environments.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var compose = builder.AddDockerComposeEnvironment("production")
- .WithDashboard(dashboard => dashboard.WithHostPort(8080)); // Configure dashboard with specific port
-
-// Add services that will automatically report to the dashboard
-builder.AddProject("frontend");
-builder.AddProject("api");
-
-builder.Build().Run();
-```
-
-## 🔗 Updated integrations
-
-### 🐙 GitHub Models integration
-
-Aspire 9.4 introduces support for [GitHub Models](https://docs.github.com/en/github-models), enabling easy integration with AI models hosted on GitHub's platform. This provides a simple way to incorporate AI capabilities into your applications using GitHub's model hosting service.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Add GitHub Model - API key parameter is automatically created
-var model = builder.AddGitHubModel("chat-model", "gpt-4o-mini");
-
-// You can also specify an API key explicitly if needed
-var apiKey = builder.AddParameter("github-api-key", secret: true);
-var explicitModel = builder.AddGitHubModel("explicit-chat", "gpt-4o-mini")
- .WithApiKey(apiKey);
-
-// Use the model in your services
-var chatService = builder.AddProject("chat")
- .WithReference(model);
-
-builder.Build().Run();
-```
-
-The [GitHub Models integration](https://aspire.dev/integrations/ai/github-models/) provides:
-
-- **Simple model integration** with GitHub's hosted AI models
-- **Automatic API key parameter creation** with the pattern `{name}-gh-apikey`
-- **Explicit API key support** using `WithApiKey()` for custom scenarios
-- **GITHUB_TOKEN fallback** when no explicit API key is provided
-- **Built-in health checks** for model availability
-
-### 🤖 Azure AI Foundry integration
-
-Aspire 9.4 introduces comprehensive [Azure AI Foundry](https://ai.azure.com/) support, bringing enterprise AI capabilities directly into your distributed applications. This integration simplifies working with AI models and deployments through the Azure AI platform, supporting both Azure-hosted deployments and local development with [Foundry Local](https://github.com/microsoft/Foundry-Local).
-
-#### Hosting configuration
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Add Azure AI Foundry project
-var foundry = builder.AddAzureAIFoundry("foundry");
-
-// Add specific model deployments
-var chat = foundry.AddDeployment("chat", "qwen2.5-0.5b", "1", "Microsoft");
-var embedding = foundry.AddDeployment("embedding", "text-embedding-ada-002", "2", "OpenAI");
-
-// Connect your services to AI capabilities
-var webService = builder.AddProject("webservice")
- .WithReference(chat)
- .WaitFor(chat);
-
-builder.Build().Run();
-```
-
-##### Azure AI Foundry Local support
-
-[Azure AI Foundry Local](/azure/ai-foundry/foundry-local/) is an on-device AI inference solution that runs models locally on your hardware, providing performance, privacy, and cost advantages without requiring an Azure subscription. It's ideal for scenarios requiring data privacy, offline operation, cost reduction, or low-latency responses.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// For local development, run with Foundry Local
-var localFoundry = builder.AddAzureAIFoundry("foundry")
- .RunAsFoundryLocal()
- .AddDeployment("chat", "phi-3.5-mini", "1", "Microsoft");
-
-var webService = builder.AddProject("webservice")
- .WithReference(localFoundry)
- .WaitFor(localFoundry);
-
-builder.Build().Run();
-```
-
-#### Client integration
-
-Once you've configured the [Azure AI Foundry resource](https://aspire.dev/integrations/cloud/azure/azure-ai-foundry/) in your AppHost, consume it in your services using the [Azure AI Inference SDK](https://aspire.dev/integrations/cloud/azure/azure-ai-inference/) or [OpenAI SDK](https://aspire.dev/integrations/cloud/azure/azure-openai/) for compatible models:
-
-**Using Azure AI Inference SDK:**
-
-```csharp
-// In Program.cs
-var builder = WebApplication.CreateBuilder(args);
-
-builder.AddAzureChatCompletionsClient("chat")
- .AddChatClient();
-
-var app = builder.Build();
-
-// Minimal API endpoint for chat completion
-app.MapPost("/generate", async (IChatClient chatClient, ChatRequest request) =>
-{
- var messages = new List
- {
- new(ChatRole.System, "You are a helpful assistant."),
- new(ChatRole.User, request.Prompt)
- };
-
- var response = await chatClient.GetResponseAsync(messages);
- return Results.Ok(new { Response = response.Text });
-});
-
-app.Run();
-
-public record ChatRequest(string Prompt);
-```
-
-**Using OpenAI SDK (for compatible models):**
-
-```csharp
-// In Program.cs
-var builder = WebApplication.CreateBuilder(args);
-
-builder.AddOpenAIClient("chat")
- .AddChatClient();
-
-// Usage is identical to the Azure AI Inference SDK example above
-```
-
-**Key differences between Azure AI Foundry and Foundry Local:**
-
-- **Azure AI Foundry** - Cloud-hosted models with enterprise-grade scaling, supports all Azure AI model deployments
-- **Foundry Local** - On-device inference with different model selection optimized for local hardware, no Azure subscription required
-
-The `RunAsFoundryLocal()` method enables local development scenarios using [Azure AI Foundry Local](/azure/ai-foundry/foundry-local/), allowing you to test AI capabilities without requiring cloud resources during development. This supports automatic model downloading, loading, and management through the integrated Foundry Local runtime.
-
-### 🗄️ Database hosting improvements
-
-Several database integrations have been updated with **improved initialization patterns**:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// MongoDB - new WithInitFiles method (replaces WithInitBindMount)
-var mongo = builder.AddMongoDB("mongo")
- .WithInitFiles("./mongo-init"); // Initialize with scripts
-
-// MySQL - improved initialization with better file handling
-var mysql = builder.AddMySql("mysql", password: builder.AddParameter("mysql-password"))
- .WithInitFiles("./mysql-init"); // Initialize with SQL scripts
-
-// Oracle - enhanced setup capabilities with consistent API
-var oracle = builder.AddOracle("oracle")
- .WithInitFiles("./oracle-init"); // Initialize with Oracle scripts
-
-builder.Build().Run();
-```
-
-All database providers now support `WithInitFiles()` method, replacing the more complex `WithInitBindMount()` method and enabling better error handling.
-
-## ☁️ Azure goodies
-
-### 🏷️ Consistent resource name exposure
-
-Aspire 9.4 now consistently exposes the actual names of all Azure resources through the `NameOutputReference` property. This enables applications to access the real Azure resource names that get generated during deployment, which is essential for scenarios requiring direct Azure resource coordination. This is particularly valuable for external automation scripts and monitoring and alerting systems that reference resources by their actual names.
-
-### 🗄️ Azure Cosmos DB
-
-#### Hierarchical partition keys
-
-Aspire 9.4 introduces support for **hierarchical partition keys** (subpartitioning) in Azure Cosmos DB, enabling multi-level partitioning for better data distribution and query performance.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var cosmos = builder.AddAzureCosmosDB("cosmos");
-var database = cosmos.AddCosmosDatabase("ecommerce");
-
-// Traditional single partition key
-var ordersContainer = database.AddContainer("orders", "/customerId");
-
-// New hierarchical partition keys (up to 3 levels)
-var productsContainer = database.AddContainer("products",
- ["/category", "/subcategory", "/brand"]);
-
-// Multi-tenant scenario
-var eventsContainer = database.AddContainer("events",
- ["/tenantId", "/userId", "/sessionId"]);
-
-builder.Build().Run();
-```
-
-**Key benefits:**
-
-- **Scale beyond 20GB per logical partition** through multi-level distribution
-- **Improved query performance** with efficient routing to relevant partitions
-- **Better data distribution** for multi-dimensional datasets
-- **Enhanced scalability** up to 10,000+ RU/s per logical partition prefix
-
-For detailed guidance on design patterns and best practices, see the [Azure Cosmos DB hierarchical partition keys documentation](/azure/cosmos-db/hierarchical-partition-keys).
-
-#### Serverless support
-
-Azure Cosmos DB accounts now default to serverless mode for cost optimization with consumption-based billing.
-
-```csharp
-// Default behavior: Creates serverless account (new in 9.4)
-var cosmos = builder.AddAzureCosmosDB("cosmos");
-
-// Explicitly enable provisioned throughput mode
-var provisionedCosmos = builder.AddAzureCosmosDB("cosmos")
- .WithDefaultAzureSku(); // Uses provisioned throughput instead of serverless
-```
-
-**Serverless benefits:**
-
-- **Pay-per-use** - Only charged for consumed Request Units and storage
-- **No minimum costs** - Ideal for intermittent or unpredictable workloads
-- **Automatic scaling** - No capacity planning required
-- **Perfect for development/testing** environments
-
-**Use serverless for:** Variable workloads, development/testing, applications with low average-to-peak traffic ratios.
-**Use provisioned throughput for:** Sustained traffic requiring predictable performance guarantees.
-
-For detailed comparison and limits, see [Azure Cosmos DB serverless documentation](/azure/cosmos-db/serverless).
-
-### 🆔 Consistent user-assigned managed identity support
-
-Aspire 9.4 introduces comprehensive support for Azure user-assigned managed identities, providing enhanced security and consistent identity management across your Azure infrastructure:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Create a user-assigned managed identity
-var appIdentity = builder.AddAzureUserAssignedIdentity("app-identity");
-
-// Create the container app environment
-var containerEnv = builder.AddAzureContainerAppEnvironment("container-env");
-
-// Apply the identity to compute resources
-var functionApp = builder.AddAzureFunctionsProject("functions")
- .WithAzureUserAssignedIdentity(appIdentity);
-
-// The identity can be shared across multiple resources
-var webApp = builder.AddProject("webapp")
- .WithAzureUserAssignedIdentity(appIdentity);
-
-// Use the same identity for accessing Azure services
-var keyVault = builder.AddAzureKeyVault("secrets");
-var storage = builder.AddAzureStorage("storage");
-
-// Services using the shared identity can access resources securely
-var processor = builder.AddProject("processor")
- .WithAzureUserAssignedIdentity(appIdentity)
- .WithReference(keyVault)
- .WithReference(storage);
-
-builder.Build().Run();
-```
-
-This approach provides:
-
-- **Flexible identity control** - Override Aspire's secure defaults when you need specific identity configurations
-- **Consistent identity management** across all compute resources
-
-#### 🔐 Disabled local authentication to enforce managed identity
-
-Aspire 9.4 automatically disables local authentication for [Azure EventHubs](https://aspire.dev/integrations/cloud/azure/azure-event-hubs/) and [Azure Web PubSub](https://aspire.dev/integrations/cloud/azure/azure-web-pubsub/) resources, enforcing managed identity authentication by default.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Azure EventHubs with automatic local auth disabled
-var eventHubs = builder.AddAzureEventHubs("eventhubs");
-var hub = eventHubs.AddEventHub("orders");
-
-// Azure Web PubSub with automatic local auth disabled
-var webPubSub = builder.AddAzureWebPubSub("webpubsub");
-
-// Services connect using managed identity automatically
-var processor = builder.AddProject("processor")
- .WithReference(hub)
- .WithReference(webPubSub);
-
-builder.Build().Run();
-```
-
-This change automatically applies to all Azure EventHubs and Web PubSub resources, ensuring secure-by-default behavior.
-
-### 🔐 Azure Key Vault enhancements
-
-Aspire 9.4 introduces significant improvements to the [Azure Key Vault integration](https://aspire.dev/integrations/cloud/azure/azure-key-vault/) with new secret management APIs that provide strongly typed access to secrets:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var secrets = builder.AddAzureKeyVault("secrets");
-
-// Add a secret from a parameter
-var connectionStringParam = builder.AddParameter("connectionString", secret: true);
-var connectionString = secrets.AddSecret("connection-string", connectionStringParam);
-
-// Add a secret with custom secret name in Key Vault
-var apiKeyParam = builder.AddParameter("api-key", secret: true);
-var apiKey = secrets.AddSecret("api-key", "ApiKey", apiKeyParam);
-
-// Get a secret reference for consumption (for existing secrets)
-var existingSecret = secrets.GetSecret("ExistingSecret");
-
-// Use in your services
-var webApi = builder.AddProject("webapi")
- .WithEnvironment("CONNECTION_STRING", connectionString)
- .WithEnvironment("API_KEY", apiKey)
- .WithEnvironment("EXISTING_SECRET", existingSecret);
-```
-
-**Key features**:
-
-- method for adding new secrets to Key Vault from parameters or expressions
-- method for referencing existing secrets in Key Vault
-- **Strongly-typed secret references** that can be used with `WithEnvironment()` for environment variables
-- **Custom secret naming** support with optional `secretName` parameter
-
-#### 📥Resource Deep Linking for Azure Storage Queues
-
-Aspire 9.4 expands resource deep linking to include Azure Queue Storage queues, building on the model already used for Azure Blob Storage, Cosmos DB, etc.
-
-You can now model individual storage queues directly in your AppHost, then inject scoped QueueClient instances into your services—making it easy to interact with queues without manually configuring connection strings or access.
-
-**AppHost:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var storage = builder.AddAzureStorage("storage");
-
-// Model individual queues as first-class resources
-var orderQueue = storage.AddQueue("orders", "order-processing");
-var notificationQueue = storage.AddQueue("notifications", "user-notifications");
-
-// Services get scoped access to specific queues
-builder.AddProject("order-processor")
- .WithReference(orderQueue); // Only has access to order-processing queue
-
-builder.AddProject("notifications")
- .WithReference(notificationQueue); // Only has access to user-notifications queue
-
-builder.Build().Run();
-```
-
-**In the OrderProcessor project:**
-
-```csharp
-using Azure.Storage.Queues;
-
-var builder = WebApplication.CreateBuilder(args);
-
-// Register the queue client
-builder.AddAzureQueue("orders");
-
-var app = builder.Build();
-
-// Minimal POST endpoint for image upload
-app.MapPost("/process-order", async (QueueClient ordersQueue) =>
-{
- // read a message for the queue
- var message = await ordersQueue.ReceiveMessageAsync();
- ProcessMessage(message);
-
- return Results.Ok();
-});
-
-app.Run();
-```
-
-This approach provides clean separation of concerns, secure container scoping, and minimal ceremony—ideal for microservices that interact with specific storage queues.
-
-### 📡 OpenTelemetry tracing support for Azure App Configuration
-
-Aspire 9.4 introduces **OpenTelemetry tracing support** for [Azure App Configuration](https://aspire.dev/integrations/cloud/azure/azure-app-configuration/), completing the observability story for this integration. The Azure App Configuration integration now automatically instruments configuration retrieval operations and refresh operations with distributed tracing.
-
-```csharp
-var builder = WebApplication.CreateBuilder(args);
-
-// Azure App Configuration now includes automatic tracing
-builder.AddAzureAppConfiguration("config", settings =>
-{
- settings.Endpoint = new Uri("https://myconfig.azconfig.io");
- // Tracing is enabled by default - traces configuration operations
-});
-
-// Optionally disable tracing for specific scenarios
-builder.AddAzureAppConfiguration("sensitive-config", settings =>
-{
- settings.DisableTracing = true; // Disable OpenTelemetry tracing
-});
-
-var app = builder.Build();
-```
-
-**What gets traced:**
-
-- **Configuration retrieval operations** - When configuration values are loaded from Azure App Configuration
-- **Configuration refresh operations** - When the configuration is refreshed in the background
-- **Activity source**: `Microsoft.Extensions.Configuration.AzureAppConfiguration` - for filtering and correlation
-
-Tracing can be disabled using `DisableTracing = true` for sensitive scenarios.
-
-This enhancement brings Azure App Configuration in line with other Azure components that support comprehensive observability, providing developers with better insights into configuration-related performance and behavior.
-
-### ⚙️ Enhanced Azure provisioning interaction
-
-Aspire 9.4 significantly improves the Azure provisioning experience by leveraging the interaction services to streamline Azure subscription and resource group configuration during deployment workflows.
-
-The enhanced Azure provisioning system:
-
-- **Automatically prompts for missing Azure configuration** during deploy operations
-- **Saves configuration to user secrets** for future deployments
-- **Provides smart defaults** like auto-generated resource group names
-- **Includes validation callbacks** for Azure-specific inputs like subscription IDs and locations
-- **Supports rich HTML prompts** with links to create free Azure accounts
-
-This enhancement makes Azure deployment significantly more user-friendly, especially for developers new to Azure or setting up projects for the first time. The interaction system ensures that all necessary Azure configuration is collected interactively and stored securely for subsequent deployments.
-
-### 🐳 Azure App Service container support
-
-Aspire 9.4 introduces support for deploying containerized applications with Dockerfiles to Azure App Service environments. This enables a seamless transition from local container development to Azure App Service deployment.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Create an Azure App Service environment
-builder.AddAzureAppServiceEnvironment("app-service-env");
-
-// Add a containerized project with Dockerfile
-var containerApp = builder.AddContainer("my-app", "my-app:latest")
- .WithDockerfile("./Dockerfile");
-
-// Or add a project that builds to a container
-var webApp = builder.AddProject("webapp");
-
-builder.Build().Run();
-```
-
-This feature bridges the gap between container development and Azure App Service deployment, allowing developers to use the same container-based workflows they use locally in production Azure environments.
-
-### 🏗️ Improvements to the Azure Container Apps integration
-
-Managing complex Azure Container Apps environments often requires integrating with existing Azure resources like Log Analytics workspaces. Aspire 9.4 enhances the [Container Apps integration](https://aspire.dev/integrations/cloud/azure/configure-container-apps/) with support for existing Azure resources and improved configuration.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Reference existing Log Analytics workspace
-var workspaceName = builder.AddParameter("workspace-name");
-var workspaceRg = builder.AddParameter("workspace-rg");
-
-var logWorkspace = builder.AddAzureLogAnalyticsWorkspace("workspace")
- .AsExisting(workspaceName, workspaceRg);
-
-var containerEnv = builder.AddAzureContainerAppEnvironment("production")
- .WithAzureLogAnalyticsWorkspace(logWorkspace);
-
-builder.AddProject("api")
- .WithComputeEnvironment(containerEnv);
-
-builder.Build().Run();
-```
-
-This also helps manage cost control by reusing existing resources like Log Analytics.
-
-#### 🛡️ Automatic DataProtection configuration for .NET on ACA
-
-Aspire 9.4 automatically configures DataProtection for .NET projects deployed to Azure Container Apps, ensuring applications work correctly when scaling beyond a single instance.
-
-When ASP.NET Core applications scale to multiple instances, they need shared DataProtection keys to decrypt cookies, authentication tokens, and other protected data across all instances. Without proper configuration, users experience authentication issues and data corruption when load balancers route requests to different container instances.
-
-Aspire now automatically enables `autoConfigureDataProtection` for all .NET projects deployed to Azure Container Apps:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddAzureContainerAppEnvironment("production");
-
-// DataProtection is automatically configured for scaling
-var api = builder.AddProject("api");
-
-var frontend = builder.AddProject("frontend");
-
-builder.Build().Run();
-```
-
-This enhancement aligns Aspire-generated deployments with Azure Developer CLI (`azd`) behavior and resolves common production scaling issues without requiring manual DataProtection configuration.
-
-### ⚡ Azure Functions Container Apps integration
-
-Aspire 9.4 improves Azure Functions deployment to Azure Container Apps by automatically setting the correct function app kind. This ensures Azure Functions are properly recognized and managed within the Azure Container Apps environment.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddAzureContainerAppEnvironment("functions-env");
-
-// Azure Functions project deployed to Container Apps
-var functionsApp = builder.AddAzureFunctionsProject("functions");
-
-builder.Build().Run();
-```
-
-This change resolves issues where Azure Functions deployed to Container Apps weren't properly recognized by Azure tooling and monitoring systems, providing a more seamless serverless experience.
-
-## 📋 Project template improvements
-
-Aspire 9.4 introduces enhancements to project templates, including .NET 10 support and improved file naming conventions.
-
-### 🚀 .NET 10 framework support
-
-All Aspire project templates now support .NET 10 with framework selection. .NET 9.0 remains the default target framework.
-
-```bash
-# Create a new Aspire project targeting .NET 10
-dotnet new aspire --framework net10.0
-
-# Create an AppHost project targeting .NET 10
-dotnet new aspire-apphost --framework net10.0
-```
-
-### 📝 Improved file naming convention
-
-The `aspire-apphost` template now uses a more descriptive file naming convention making it easier to distinguish AppHost files in multi-project solutions. Instead of `Program.cs`, the main program file is now named `AppHost.cs`.
-
-The content and functionality remain unchanged — only the filename has been updated to be more descriptive.
-
-## 💔 Breaking changes
-
-### 🔑 Azure Key Vault secret reference changes
-
-Azure Key Vault secret handling has been updated with improved APIs that provide better type safety and consistency:
-
-```csharp
-// ❌ Before (obsolete):
-var keyVault = builder.AddAzureKeyVault("secrets");
-var secretOutput = keyVault.GetSecretOutput("ApiKey"); // Obsolete
-var secretRef = new BicepSecretOutputReference(secretOutput); // Obsolete - class removed
-
-// ✅ After (recommended):
-var keyVault = builder.AddAzureKeyVault("secrets");
-var secretRef = keyVault.GetSecret("ApiKey"); // New strongly-typed API
-
-// For environment variables:
-// ❌ Before (obsolete):
-builder.AddProject("api")
- .WithEnvironment("API_KEY", secretRef); // Using BicepSecretOutputReference
-
-// ✅ After (recommended):
-builder.AddProject("api")
- .WithEnvironment("API_KEY", secretRef); // Using IAzureKeyVaultSecretReference
-```
-
-**Migration impact**: Replace `GetSecretOutput()` and `BicepSecretOutputReference` usage with the new `GetSecret()` method that returns `IAzureKeyVaultSecretReference`.
-
-### 📦 Azure Storage blob container creation changes
-
-Azure Storage blob container creation has been moved from specialized blob storage resources to the main storage resource for better consistency:
-
-```csharp
-// ❌ Before (obsolete):
-var storage = builder.AddAzureStorage("storage");
-var blobs = storage.AddBlobs("blobs");
-var container = blobs.AddBlobContainer("images"); // Obsolete
-
-// ✅ After (recommended):
-var storage = builder.AddAzureStorage("storage");
-var container = storage.AddBlobContainer("images"); // Direct on storage resource
-```
-
-**Migration impact**: Use `AddBlobContainer()` directly on `AzureStorageResource` instead of on specialized blob storage resources.
-
-### 🔐 Keycloak realm import simplification
-
-The `WithRealmImport` method signature has been **simplified by removing the confusing `isReadOnly` parameter**:
-
-```csharp
-// ❌ Before (deprecated):
-var keycloak = builder.AddKeycloak("keycloak")
- .WithRealmImport("./realm.json", isReadOnly: false); // Confusing parameter
-
-// ✅ After (recommended):
-var keycloak = builder.AddKeycloak("keycloak")
- .WithRealmImport("./realm.json"); // Clean, simple API
-
-// If you need explicit read-only control:
-var keycloak = builder.AddKeycloak("keycloak")
- .WithRealmImport("./realm.json", isReadOnly: true); // Still available as overload
-```
-
-**Migration impact**: Remove the `isReadOnly` parameter from single-parameter `WithRealmImport()` calls - the method now defaults to appropriate behavior. Use the two-parameter overload if explicit control is needed.
-
-### 🔧 Milvus configuration method updates
-
-Milvus configuration has been updated with more descriptive method names:
-
-```csharp
-// ❌ Before (deprecated):
-var milvus = builder.AddMilvus("milvus")
- .WithConfigurationBindMount("./milvus.yaml"); // Old method name
-
-// ✅ After (recommended):
-var milvus = builder.AddMilvus("milvus")
- .WithConfigurationFile("./milvus.yaml"); // Method renamed for clarity
-```
-
-**Migration impact**: Update method calls to use `WithConfigurationFile` instead of `WithConfigurationBindMount` for Milvus configuration.
-
-### 🔄 Azure Storage client registration updates
-
-Client registration methods for Azure Storage have been standardized with new naming conventions:
-
-```csharp
-// ❌ Before (obsolete):
-builder.AddAzureTableClient("tables"); // Obsolete
-builder.AddKeyedAzureTableClient("tables"); // Obsolete
-builder.AddAzureBlobClient("blobs"); // Obsolete
-builder.AddKeyedAzureBlobClient("blobs"); // Obsolete
-builder.AddAzureQueueClient("queues"); // Obsolete
-builder.AddKeyedAzureQueueClient("queues"); // Obsolete
-
-// ✅ After (recommended):
-builder.AddAzureTableServiceClient("tables"); // Standardized naming
-builder.AddKeyedAzureTableServiceClient("tables"); // Standardized naming
-builder.AddAzureBlobServiceClient("blobs"); // Standardized naming
-builder.AddKeyedAzureBlobServiceClient("blobs"); // Standardized naming
-builder.AddAzureQueueServiceClient("queues"); // Standardized naming
-builder.AddKeyedAzureQueueServiceClient("queues"); // Standardized naming
-```
-
-**Migration impact**: Update all client registration calls to use the new `*ServiceClient` naming convention.
-
-### 🗄️ Database initialization method changes
-
-Several database resources have **deprecated `WithInitBindMount` in favor of the more consistent `WithInitFiles`**:
-
-```csharp
-// ❌ Before (deprecated):
-var mongo = builder.AddMongoDB("mongo")
- .WithInitBindMount("./init", isReadOnly: true); // Complex parameters
-
-var mysql = builder.AddMySql("mysql")
- .WithInitBindMount("./mysql-scripts", isReadOnly: false);
-
-var oracle = builder.AddOracle("oracle")
- .WithInitBindMount("./oracle-init", isReadOnly: true);
-
-var postgres = builder.AddPostgres("postgres")
- .WithInitBindMount("./postgres-init", isReadOnly: true);
-
-// ✅ After (recommended):
-var mongo = builder.AddMongoDB("mongo")
- .WithInitFiles("./init"); // Simplified, consistent API
-
-var mysql = builder.AddMySql("mysql")
- .WithInitFiles("./mysql-scripts"); // Same pattern across all providers
-
-var oracle = builder.AddOracle("oracle")
- .WithInitFiles("./oracle-init"); // Unified approach
-
-var postgres = builder.AddPostgres("postgres")
- .WithInitFiles("./postgres-init"); // Consistent across all databases
-```
-
-**Affected database providers**: MongoDB, MySQL, Oracle, and PostgreSQL
-
-**Migration impact**: Replace `WithInitBindMount()` calls with `WithInitFiles()` - the new method handles read-only mounting automatically and provides better error handling.
-
-### Resource lifecycle event updates
-
-The generic `AfterEndpointsAllocatedEvent` has been deprecated in favor of more specific, type-safe events:
-
-```csharp
-// ❌ Before (deprecated):
-builder.Services.AddSingleton();
-
-public class MyLifecycleHook : IDistributedApplicationLifecycleHook
-{
- public Task AfterEndpointsAllocatedAsync(DistributedApplicationModel appModel, CancellationToken cancellationToken)
- {
- // Generic event handling - deprecated
- return Task.CompletedTask;
- }
-}
-
-// ✅ After (recommended):
-var api = builder.AddProject("api")
- .OnBeforeResourceStarted(async (resource, evt, cancellationToken) =>
- {
- // Resource-specific event handling
- })
- .OnResourceEndpointsAllocated(async (resource, evt, cancellationToken) =>
- {
- // Endpoint-specific event handling
- });
-```
-
-**Migration impact**: Replace usage of `AfterEndpointsAllocatedEvent` with resource-specific lifecycle events like `OnBeforeResourceStarted` or `OnResourceEndpointsAllocated` for better type safety and clarity.
-
-### 🧊 Azure Container Apps hybrid mode removal
-
-Azure Container Apps hybrid mode support has been **removed** to simplify the deployment model and improve consistency. Previously, `PublishAsAzureContainerApp` would automatically create Azure infrastructure, but this behavior has been streamlined.
-
-```csharp
-// ❌ Before (hybrid mode - no longer supported):
-// In hybrid mode, this would automatically add Azure Container Apps infrastructure
-var api = builder.AddProject("api")
- .PublishAsAzureContainerApp((infrastructure, containerApp) =>
- {
- app.Template.Scale.MinReplicas = 0;
- });
-
-// The hybrid approach mixed azd-generated environments with Aspire-managed infrastructure
-// This caused confusion and maintenance complexity
-
-// ✅ After (required approach):
-// Explicitly add Azure Container App Environment first
-var containerAppEnvironment = builder.AddAzureContainerAppEnvironment("cae");
-
-// When coming from hybrid mode, the names of the resources will change
-// WithAzdResourceNaming will keep the older naming convention that azd uses
-// while making this transition to aspire owned infrastructure.
-containerAppEnvironment.WithAzdResourceNaming();
-
-// Then use PublishAsAzureContainerApp for customization only (same API)
-var api = builder.AddProject("api")
- .PublishAsAzureContainerApp((infrastructure, containerApp) =>
- {
- app.Template.Scale.MinReplicas = 0;
- });
-```
-
-**Key changes:**
-
-- `PublishAsAzureContainerApp()` **no longer automatically creates infrastructure** - it only adds customization annotations
-- **BicepSecretOutput APIs have been removed** from the Azure Container Apps logic for simplified secret handling
-
-**Migration impact:**
-
-1. **Add explicit Azure Container App Environment**: Use `builder.AddAzureContainerAppEnvironment("name")` before calling `PublishAsAzureContainerApp()`
-2. **Update secret references**: Replace any `BicepSecretOutputReference` usage with proper Azure Key Vault resources using `IAzureKeyVaultSecretReference`
-3. **Review infrastructure setup**: Ensure your Bicep templates or infrastructure setup properly creates the Container App Environment that your apps will deploy to
-
-This change provides **clearer separation** between infrastructure provisioning (handled by explicit resource creation) and application deployment configuration (handled by `PublishAsAzureContainerApp`), making the deployment process more predictable and easier to understand.
-
-### ⚠️ Known parameter deprecations
-
-Several auto-injected known parameters have been deprecated and removed from Azure resources in favor of explicit resource modeling:
-
-**Deprecated parameters:**
-
-- `AzureBicepResource.KnownParameters.KeyVaultName`
-- `AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId`
-
-#### KeyVaultName parameter deprecation
-
-The `AzureBicepResource.KnownParameters.KeyVaultName` parameter is now obsolete. Previously, this parameter was automatically injected into Azure resources to reference Key Vault instances for storing secrets.
-
-```csharp
-// ❌ Before (deprecated):
-var customResource = builder.AddAzureInfrastructure("custom", infra =>
-{
- // Custom Bicep template that expected keyVaultName parameter to be auto-filled
- var kvNameParam = new ProvisioningParameter(AzureBicepResource.KnownParameters.KeyVaultName, typeof(string));
- infra.Add(kvNameParam);
-
- var keyVault = KeyVaultService.FromExisting("keyVault");
- keyVault.Name = kvNameParam; // This was auto-populated by Aspire
- infra.Add(keyVault);
-
- // Store secrets in the auto-injected Key Vault
- var secret = new KeyVaultSecret("mySecret", keyVault)
- {
- Properties = { Value = "sensitive-value" }
- };
- infra.Add(secret);
-});
-
-// ✅ After (recommended):
-var keyVault = builder.AddAzureKeyVault("secrets");
-var customResource = builder.AddAzureInfrastructure("custom", infra =>
-{
- // Use explicit Key Vault resource reference
- var existingKeyVault = (KeyVaultService)keyVault.Resource.AddAsExistingResource(infra);
-
- var secret = new KeyVaultSecret("mySecret", existingKeyVault)
- {
- Properties = { Value = "sensitive-value" }
- };
- infra.Add(secret);
-});
-```
-
-#### LogAnalyticsWorkspaceId parameter deprecation
-
-The `AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId` parameter is now obsolete. Application Insights resources will now automatically create their own Log Analytics workspace or use explicitly provided ones.
-
-```csharp
-// ❌ Before (deprecated):
-var appInsights = builder.AddAzureApplicationInsights("ai")
- .WithParameter(AzureBicepResource.KnownParameters.LogAnalyticsWorkspaceId, workspaceId);
-
-// ✅ After (recommended):
-// Option 1: Auto-generated workspace (default behavior)
-var appInsights = builder.AddAzureApplicationInsights("ai");
-
-// Option 2: Explicit workspace resource
-var workspace = builder.AddAzureLogAnalyticsWorkspace("workspace");
-var appInsights = builder.AddAzureApplicationInsights("ai")
- .WithLogAnalyticsWorkspace(workspace);
-
-// Option 3: Reference existing workspace from another resource
-var env = builder.AddAzureContainerAppEnvironment("env");
-var appInsights = builder.AddAzureApplicationInsights("ai")
- .WithLogAnalyticsWorkspace(env.GetOutput("AZURE_LOG_ANALYTICS_WORKSPACE_ID"));
-```
-
-#### Container App Environment parameter changes
-
-Previously, container app environment properties (managed identity, workspace ID) were automatically injected into other Azure resources. These are no longer auto-injected as Aspire now supports multiple compute environments.
-
-```csharp
-// ❌ Before (auto-injection):
-// These properties were automatically available in other resources:
-// - MANAGED_IDENTITY_NAME
-// - MANAGED_IDENTITY_PRINCIPAL_ID
-// - logAnalyticsWorkspaceId
-
-// ✅ After (explicit references):
-var env = builder.AddAzureContainerAppEnvironment("env");
-var resource = builder.AddAzureInfrastructure("custom", infra =>
-{
- // Use explicit references when needed
- var managedEnv = (ContainerAppManagedEnvironment)env.Resource.AddAsExistingResource(infra);
- // Access properties through the bicep resource directly
-});
-```
-
-**Migration impact**: Replace auto-injected parameters with explicit resource modeling for better resource graph representation and support for multiple Azure compute environments. See [Azure resource customization docs](/dotnet/aspire/azure/customize-azure-resources) for more details.
-
-### 🔧 ParameterResource.Value synchronous behavior change
-
-The `ParameterResource.Value` property now blocks synchronously when waiting for parameter value resolution, which can potentially cause deadlocks in async contexts. The new `GetValueAsync()` method should be used instead for proper async handling.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Parameters that need resolution
-var apiKey = builder.AddParameter("api-key", secret: true);
-var connectionString = builder.AddParameter("connection-string", secret: true);
-
-// ❌ Before (can cause deadlocks in async contexts):
-builder.AddProject("api")
- .WithEnvironment("API_KEY", apiKey.Resource.Value) // Blocks synchronously - can deadlock
- .WithEnvironment("CONNECTION_STRING", connectionString.Resource.Value);
-
-// ✅ After (recommended for async contexts):
-// Use the parameter resources directly with WithEnvironment - they handle async resolution internally
-builder.AddProject("api")
- .WithEnvironment("API_KEY", apiKey) // Let Aspire handle async resolution
- .WithEnvironment("CONNECTION_STRING", connectionString);
-
-// Or if you need the actual value in custom code with WithEnvironment callback:
-builder.AddProject("api")
- .WithEnvironment("API_KEY", async (context, cancellationToken) =>
- {
- return await apiKey.Resource.GetValueAsync(cancellationToken); // Proper async handling
- })
- .WithEnvironment("CONNECTION_STRING", async (context, cancellationToken) =>
- {
- return await connectionString.Resource.GetValueAsync(cancellationToken);
- });
-
-// For non-async contexts where blocking is acceptable:
-var syncValue = apiKey.Resource.Value; // Still works but may block
-```
-
-**Migration impact**: When working with `ParameterResource` values in async contexts, use the new `GetValueAsync()` method instead of the `Value` property to avoid potential deadlocks. For `WithEnvironment()` calls, prefer passing the parameter resource directly rather than accessing `.Value` synchronously.
-
-With every release, we strive to make Aspire better. However, some changes may break existing functionality. For complete details on breaking changes in this release, see:
-
-- [Breaking changes in Aspire 9.4](../compatibility/9.4/index.md)
-
-## 🎯 Upgrade today
-
-Follow the directions outlined in the [Upgrade to Aspire 9.4](#-upgrade-to-aspire-94) section to make the switch to 9.4 and take advantage of all these new features today! As always, we're listening for your feedback on [GitHub](https://github.com/dotnet/aspire/issues)—and looking out for what you want to see in 9.5 ☺️.
-
-For a complete list of issues addressed in this release, see [Aspire GitHub repository—9.4 milestone](https://github.com/dotnet/aspire/issues?q=is%3Aissue%20state%3Aclosed%20milestone%3A9.4%20).
diff --git a/docs/whats-new/dotnet-aspire-9.5.md b/docs/whats-new/dotnet-aspire-9.5.md
deleted file mode 100644
index a753b27012..0000000000
--- a/docs/whats-new/dotnet-aspire-9.5.md
+++ /dev/null
@@ -1,1136 +0,0 @@
----
-title: What's new in Aspire 9.5
-description: Learn what's new in Aspire 9.5.
-ms.date: 09/25/2025
----
-
-# What's new in Aspire 9.5
-
-📢 Aspire 9.5 is the next minor version release of Aspire. It supports:
-
-- .NET 8.0 Long Term Support (LTS).
-- .NET 9.0 Standard Term Support (STS).
-- .NET 10.0 Release Candidate (RC) 1.
-
-If you have feedback, questions, or want to contribute to Aspire, collaborate with us on [:::image type="icon" source="../media/github-mark.svg" border="false"::: GitHub](https://github.com/dotnet/aspire) or join us on [:::image type="icon" source="../media/discord-icon.svg" border="false"::: Discord](https://aka.ms/aspire-discord) to chat with the team and other community members.
-
-It's important to note that Aspire releases are out-of-band from .NET releases. While major versions of Aspire align with major .NET versions, minor versions are released more frequently. For more information on .NET and Aspire version support, see:
-
-- [.NET support policy](https://dotnet.microsoft.com/platform/support/policy): Definitions for LTS and STS.
-- [Aspire support policy](https://dotnet.microsoft.com/platform/support/policy/aspire): Important unique product lifecycle details.
-
-## ⬆️ Upgrade to Aspire 9.5
-
-> [!NOTE]
-> Try out `aspire update`!
-> Aspire 9.5 brings a new preview CLI command - [aspire update](#new-aspire-update-command-preview) - that can update your AppHost and its packages for you. Get the latest CLI if you want to try to give us feedback about it on [GitHub](https://github.com/dotnet/aspire/issues)!
-
-Moving between minor releases of Aspire is simple:
-
-1. Get the latest release of the Aspire CLI:
-
- ```bash
- curl -sSL https://aspire.dev/install.sh | bash
- ```
-
- ```powershell
- iex "& { $(irm https://aspire.dev/install.ps1) }"
- ```
-
-1. In your AppHost project file (that is, _MyApp.AppHost.csproj_), update the [📦 Aspire.AppHost.Sdk](https://www.nuget.org/packages/Aspire.AppHost.Sdk) package to version `9.5.2`:
-
- ```xml
-
- ```
-
- For more information, see [Aspire SDK](xref:dotnet/aspire/sdk).
-
-1. Check for any NuGet package updates, either using the NuGet Package Manager in Visual Studio or the **Update NuGet Package** command from C# Dev Kit in Visual Studio (VS) Code.
-
-1. Update to the latest [Aspire templates](../fundamentals/aspire-sdk-templates.md) by running the following .NET command line:
-
- ```dotnetcli
- dotnet new install Aspire.ProjectTemplates
- ```
-
- > [!NOTE]
- > The `dotnet new install` command updates existing Aspire templates to the latest version if they're already installed.
-
-If your AppHost project file doesn't have the `Aspire.AppHost.Sdk` reference, you might still be using Aspire 8. To upgrade to 9, follow [the upgrade guide](../get-started/upgrade-to-aspire-9.md).
-
-## 🛠️ CLI and tooling
-
-Aspire 9.5 adds targeted CLI and tooling updates that speed up setup and maintenance.
-
-**Key improvements:**
-
-- Channel-aware package selection in `aspire add` so you can choose stable, daily, or custom builds.
-- Preview `aspire update` command that scans your AppHost, validates versions, and applies safe upgrades.
-- Experimental single-file AppHost (`apphost.cs`) behind a feature flag.
-- SSH Remote port forwarding support in VS Code, matching Dev Container and Codespaces behavior.
-- Enhanced `aspire exec` with `--workdir`, clearer help, and early argument validation.
-- Performance refinements: package search disk cache, cleaner debug output, clearer status messages, and faster repeat package resolution.
-
-Run `aspire update` to upgrade, enable the single-file AppHost to experiment with a minimal setup, and use `aspire exec` to script tasks with inherited environment context.
-
-### Channel-aware `aspire add` and templating
-
-You can now pick packages from different channels or versions during `aspire add`. Additionally, friendly name generation is now more flexible for searching packages. When adding packages, you should use versions that are aligned to the `Aspire.Hosting.AppHost` package that you're using. To update your entire AppHost and its referenced project, you can use the `aspire update` command as described in the following section.
-
-### New `aspire update` command (preview)
-
-The new `aspire update` command helps you keep your Aspire projects current by automatically detecting and updating outdated packages and templates.
-
-```Aspire
-# Analyze and update out-of-date Aspire packages & templates
-aspire update
-```
-
-:::image type="content" source="media/aspire-update.gif" lightbox="media/aspire-update.gif" alt-text="Recording of aspire update running on eShop sample.":::
-
-This command updates your SDK, AppHost packages, and any Aspire client integrations used in the app. It validates package compatibility and asks for confirmation before applying changes. Like `add`, `update` is channel aware, so you can choose to update to stable, daily, or your own configuration of builds.
-
-> [!IMPORTANT]
-> 🧪 **Preview feature**: The `aspire update` command is in preview and might change before general availability. The `aspire update` command makes changes to project files, central package management, and NuGet.config files. We recommend using version control and inspecting changes after `aspire update` is run to verify the changes.
-
-### File-based AppHost support (preview)
-
-Aspire 9.5 introduces infrastructure for .NET 10's new file-based apps feature, meaning you only need one file — and no project file — for your Aspire Apphost. The new capabilities are currently behind a feature flag that elevates the minimum .NET SDK requirement to prepare for upcoming file-based app execution scenarios.
-
-```Aspire
-# Enable file-based AppHost ("apphost.cs") support
-aspire config set features.singlefileAppHostEnabled true
-# Disable the minimum SDK version check
-aspire config set features.minimumSdkCheckEnabled false
-```
-
-For more information, see [aspire config set command](../cli-reference/aspire-config-set.md).
-
-**SDK version requirements:**
-
-- **Feature enabled**: Requires .NET SDK 10.0.100 RC1 or later
-- **Override support**: Manual SDK version overrides continue to work with highest precedence
-
-You can use `aspire new` to create a new, blank file-based AppHost. Select the _Single-file AppHost (experimental)_ option from the project template list:
-
-```csharp
-#:sdk Aspire.AppHost.Sdk@9.5.2
-
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.Build().Run();
-```
-
-Then add some resources, use `aspire add` the same as you would with a project-based Apphost, and `aspire run` to start!
-
-### SSH Remote support for port forwarding in VS Code
-
-Aspire 9.5 adds SSH Remote support in VS Code. Ports forward automatically in SSH Remote sessions the same way they do in Dev Containers and GitHub Codespaces.
-
-### `aspire exec` command (preview) enhancements
-
-The `aspire exec` command allows you to execute commands within the context of your Aspire application environment, inheriting environment variables, and configuration from your app model resources.
-
-Aspire 9.5 builds on the 9.4 preview and adds several key improvements:
-
-- `--workdir` (`-w`) flag to run commands inside a specific working directory.
-- Fail-fast argument validation with clearer error messages.
-- Improved help and usage text for better developer experience.
-
-For more information, see [aspire exec command](../cli-reference/aspire-exec.md) reference.
-
-#### Basic usage examples
-
-```Aspire
-# Execute database migrations with environment variables from your app model
-aspire exec --resource my-api -- dotnet ef database update
-
-# Run commands in a specific working directory
-aspire exec --resource worker --workdir /app/tools -- dotnet run
-
-# Wait for resource to start before executing command
-aspire exec --start-resource my-worker -- npm run build
-```
-
-#### Command syntax
-
-- Use `--resource` to execute immediately when AppHost starts.
-- Use `--start-resource` to wait for the resource to be running first.
-- Use `--workdir` to specify the working directory for the command.
-- Use `--` to separate `aspire` options from the command to execute.
-
-> [!NOTE]
-> This command is disabled by default. To use it, turn on the feature toggle by running:
->
-> ```Aspire
-> aspire config set features.execCommandEnabled true
-> ```
->
-> For more information, see [aspire config command](../cli-reference/aspire-config.md).
-
-### Other tweaks
-
-- Relative path included in AppHost status messages.
-- Clean CLI debug logging with reduced noise.
-- Directory safety check for `aspire new` and consistent template inputs.
-- Refactored NuGet prefetch architecture reducing UI lag during `aspire new`.
-- Package search disk cache to speed up `aspire new | add | update` commands.
-- Context-sensitive completion messages for publish/deploy.
-
-## 📊 Dashboard enhancements
-
-### Generative AI visualizer
-
-Aspire 9.5 introduces the GenAI visualizer, which collates, summarizes, and visualizes LLM-centric calls within your app:
-
-- 🗃️ Explore input and output messages.
-- 🚀 JSON/XML payloads highlighted and indented.
-- 🖼️ Preview Markdown and multimodal content (for example, images).
-
-If GenAI-specific telemetry is found in an OpenTelemetry (OTEL) span, a sparkle (✨) icon appears next to its name in the Traces view. Clicking the icon launches the visualizer dialog.
-
-The [GenAI telemetry semantic conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/) are evolving rapidly. The visualizer supports multiple versions of the telemetry, and we update it as the conventions move toward a stable release.
-
-:::image type="content" source="media/dashboard-geni-visualizer.gif" lightbox="media/dashboard-geni-visualizer.gif" alt-text="Recording of the GenAI visualizer.":::
-
-### Rich property grid content
-
-In the Aspire 9.5 Dashboard, there are icons and clickable buttons in property grids in resource details, log entry details, and span details.
-
-- **Icons** improve visual clarity. For example, quickly see that a resource isn't in a healthy state if the icon is red or yellow.
-- **Clickable buttons** improve navigation. For example, select a resource name or telemetry ID to navigate to a different page for more information.
-
-:::image type="content" source="media/dashboard-rich-property-grid.png" lightbox="media/dashboard-rich-property-grid.png" alt-text="Screenshot of property grid with icons.":::
-
-### Multi-resource console logs
-
-A new "All" option in the console logs view streams logs from every running resource simultaneously.
-
-- **Unified log stream**: See logs from all resources in chronological order.
-- **Color-coded prefixes**: Each resource gets a deterministic color for easy identification.
-
-:::image type="content" source="media/console-logs-all.png" lightbox="media/console-logs-all.png" alt-text="Screenshot of the console logs page displaying (All) logs.":::
-
-### Custom resource icons
-
-Resources can now specify custom icons and their variant (Filled, which is the default, or Regular) using `WithIconName()` for better visual identification in dashboard views. Any [Fluent UI system icons](https://github.com/microsoft/fluentui-system-icons/blob/main/icons_filled.md) can be used.
-
-```csharp
-var postgres = builder.AddPostgres("database")
- .WithIconName("database");
-
-var redis = builder.AddRedis("cache")
- .WithIconName("memory");
-
-var api = builder.AddProject("api")
- .WithIconName("webAsset", ApplicationModel.IconVariant.Regular);
-```
-
-This iconography helps teams quickly identify different types of resources in complex applications with many services. Custom resource icons now also apply to project and container resources through unified annotation, providing consistent visual identification across all resource types.
-
-### Reverse proxy support
-
-The dashboard now properly handles reverse proxy scenarios with explicit forwarded header mapping when enabled. This fixes common issues with authentication redirects and URL generation behind proxies like YARP.
-
-```bash
-# Enable forwarded headers processing
-export ASPIRE_DASHBOARD_FORWARDEDHEADERS_ENABLED=true
-```
-
-This is useful for deployment scenarios where the dashboard is accessed through a load balancer or reverse proxy.
-
-### Container runtime notifications
-
-Notifications now appear when Docker or Podman is installed but unhealthy, with automatic dismissal when the runtime recovers. This provides immediate feedback when your container runtime needs attention, helping diagnose startup issues faster.
-
-:::image type="content" source="media/dashboard-container-warning.png" lightbox="media/dashboard-container-warning.png" alt-text="Screenshot of the dashboard showing the container runtime warning.":::
-
-### Trace filtering
-
-The Traces page now has a type filter, a quick way to find traces and spans for the selected operation type.
-
-For example, choose Messaging 📬 to see only traces from your app that interact with RabbitMQ, Azure Service Bus, etc.
-
-:::image type="content" source="media/dashboard-trace-type.png" lightbox="media/dashboard-trace-type.png" alt-text="Screenshot of the traces page showing the type filter.":::
-
-### Trace detail improvements
-
-The trace detail page includes several quality-of-life improvements:
-
-🏷️ Span names are clearer, with resources split into their own column
-🪵 Logs are now shown in the waterfall chart—hover for a tooltip, or select for full details
-↕️ New "Expand all" and "Collapse all" buttons
-
-:::image type="content" source="media/dashboard-trace-detail-logs.png" lightbox="media/dashboard-trace-detail-logs.png" alt-text="Screenshot of trace details showing the new resources column and log tooltips.":::
-
-### Other improvements
-
-- Resource action menus now use submenus to prevent overflow on complex apps.
-- Projects show their associated launch profiles.
-- Error spans use consistent error styling.
-- Better default icons for parameters and services.
-- Enhanced port parsing.
-- Message truncation for long log entries.
-- Optional log line wrapping.
-- Improved text visualizer dialog.
-- Comprehensive dashboard localization improvements including localized Launch Profile names.
-- Embedded log entries within trace spans.
-- Better span timing calculations.
-- Accessibility improvements with better toolbar/menu overflow handling, improved keyboard navigation, semantic headings, and mobile navigation scroll fixes.
-
-## 📦 Integration changes and additions
-
-### OpenAI hosting integration
-
-The new `AddOpenAI` integration provides first-class support for modeling OpenAI endpoints and their associated models within your Aspire application model. For more information, see [Aspire OpenAI integration (Preview)](https://aspire.dev/integrations/ai/openai/).
-
-**Features:**
-
-- **Single OpenAI endpoint** resource with child model resources using `AddModel`.
-- **Resource referencing** so other projects automatically receive connection information.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var openai = builder.AddOpenAI("openai");
-
-var chatModel = openai.AddModel("chat", "gpt-4o-mini");
-
-var api = builder.AddProject("api")
- .WithReference(chatModel);
-
-builder.Build().Run();
-```
-
-**Local development scenario:**
-
-```csharp
-// Use with local OpenAI-compatible services
-var localOpenAI = builder.AddOpenAI("local-openai")
- .WithApiKey(builder.AddParameter("local-api-key"))
- .WithEndpoint("http://localhost:11434"); // Ollama or similar
-
-var localModel = localOpenAI.AddModel("local-chat", "llama3.2");
-```
-
-### GitHub Models and Azure AI Foundry typed catalogs
-
-Aspire 9.5 introduces a typed catalog for GitHub and Azure-hosted models, providing IntelliSense support and refactoring safety when working with AI models. This brings type safety and IntelliSense support for the ever-increasing AI model catalog, and takes the guesswork out of version and "format" strings. The catalog is updated daily.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Before: String-based approach (error-prone)
-var model = builder.AddGitHubModel("chat", "gpt-4o-mini"); // Typos not caught
-
-// After: Typed catalog approach
-var chatModel = builder.AddGitHubModel("chat", GitHubModel.OpenAI.OpenAIGPT4oMini);
-
-// IntelliSense shows all available models grouped by provider
-var embeddingModel = builder.AddGitHubModel("embeddings", GitHubModel.OpenAI.OpenAITextEmbedding3Large);
-```
-
-For more information, see:
-
-- [Aspire GitHub Models integration (Preview)](https://aspire.dev/integrations/ai/github-models/).
-- [Aspire Azure AI Foundry integration (Preview)](https://aspire.dev/integrations/cloud/azure/azure-ai-foundry/).
-
-### Dev Tunnels hosting integration
-
-Aspire 9.5 introduces first-class support for Dev Tunnels, enabling seamless integration of secure public tunnels for your applications during development and testing scenarios.
-
-**Features:**
-
-- **Secure public tunnels**: Create public HTTPS endpoints for applications running locally.
-- **Automatic tunnel management**: Tunnels are created, configured, and cleaned up automatically.
-- **Private and anonymous tunnels**: Support for both authenticated private tunnels and public anonymous access.
-- **Development workflow integration**: Perfect for webhook testing, mobile app development, and external service integration.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Add a basic Dev Tunnel resource (default: private access)
-var tunnel = builder.AddDevTunnel("dev-tunnel");
-
-// Add your web application
-var webApp = builder.AddProject("webapp");
-
-// Connect the tunnel to the web application endpoint
-tunnel.WithReference(webApp);
-
-builder.Build().Run();
-```
-
-The Dev Tunnels integration automatically handles Azure authentication, tunnel lifecycle management, and provides public or private URLs (depending on configuration) to connected resources, making it easy to expose local development services securely to external consumers. Dev Tunnels also improves support for mobile dev, such as .NET MAUI, making it easy to launch both your backend and mobile app at once without complex dev-time config. For more information, see [Aspire Dev Tunnels integration (Preview)](../extensibility/dev-tunnels-integration.md).
-
-### YARP static files support
-
-Aspire 9.5 adds comprehensive static file serving capabilities to the YARP integration, enabling you to serve static assets directly from YARP alongside reverse proxy functionality. This is perfect for single-page applications, frontend assets, and hybrid scenarios where you need both static content and API proxying.
-
-**Features:**
-
-- **Direct static file serving**: Serve HTML, CSS, JS, and other static assets from YARP.
-- **Flexible source options**: Bind mount local directories or use Docker multi-stage builds.
-- **Automatic configuration**: Simple API enables static files with minimal setup.
-- **Production ready**: Works in both development and publish scenarios.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Enable static file serving (serves from wwwroot folder)
-var yarp = builder.AddYarp("gateway")
- .WithStaticFiles();
-
-builder.Build().Run();
-```
-
-**Docker multi-stage build scenario:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Use Dockerfile to build and copy static assets
-var frontend = builder.AddYarp("frontend")
- .WithStaticFiles()
- .WithDockerFile("../react-app");
-
-builder.Build().Run();
-```
-
-For more information, see [Multi-stage Docker builds](https://aspire.dev/integrations/reverse-proxies/yarp/#multi-stage-docker-builds).
-
-**Hybrid static + API gateway:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var backendApi = builder.AddProject("api");
-var authService = builder.AddProject("auth");
-
-// YARP serves static files AND proxies API requests
-var gateway = builder.AddYarp("app-gateway")
- .WithStaticFiles("./frontend/dist")
- .WithConfiguration(yarp =>
- {
- // API routes
- yarp.AddRoute("/api/{**catch-all}", backendApi)
- .WithTransformPathRemovePrefix("/api");
-
- // Auth routes
- yarp.AddRoute("/auth/{**catch-all}", authService)
- .WithTransformPathRemovePrefix("/auth");
-
- // Static files are served for all other routes
- });
-
-builder.Build().Run();
-```
-
-This feature enables modern web application architectures where YARP acts as both a reverse proxy for backend services and a static file server for frontend assets, providing a unified entry point for your distributed application.
-
-For more information, see [Aspire YARP integration](https://aspire.dev/integrations/reverse-proxies/yarp/).
-
-### Azure Kusto / Azure Data Explorer
-
-A new **preview** package `Aspire.Hosting.Azure.Kusto` has been added. Once the package has been added to the AppHost, it's possible to start a Kusto emulator with just a few lines of code:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var db = builder.AddAzureKustoCluster("kusto")
- .RunAsEmulator()
- .AddReadWriteDatabase("sensorreadings");
-
-builder.Build().Run();
-```
-
-### RabbitMQ auto activation
-
-RabbitMQ client connections now support auto activation to prevent startup deadlocks and improve application reliability. Auto activation is disabled by default in 9.5, but planned to be enabled by default in a future release.
-
-```csharp
-var builder = WebApplication.CreateBuilder(args);
-
-// Auto activation is disabled by default for RabbitMQ, enable using DisableAutoActivation=false
-builder.AddRabbitMQClient("messaging", o => o.DisableAutoActivation = false);
-```
-
-### Redis integration improvements
-
-#### Auto activation
-
-Redis client connections also now support auto activation, and are also disabled by default, but planned to be enabled by default in a future release.
-
-```csharp
-var builder = WebApplication.CreateBuilder(args);
-
-// Auto activation is disabled by default for Redis, enable using DisableAutoActivation=false
-var redisClient = builder.AddRedisClient("redis", c => c.DisableAutoActivation = false);
-```
-
-#### Client builder pattern
-
-Aspire 9.5 introduces a new Redis client builder pattern that provides a fluent, type-safe approach to configuring Redis clients with integrated support for distributed caching, output caching, and Azure authentication.
-
-Basic usage:
-
-```csharp
-var builder = WebApplication.CreateBuilder(args);
-
-builder.AddRedisClientBuilder("redis")
- .WithDistributedCache(options =>
- {
- options.InstanceName = "MyApp";
- });
-```
-
-To enable Azure authentication, add a reference to the new `Aspire.Microsoft.Azure.StackExchangeRedis` package, and chain a call to `.WithAzureAuthentication()`:
-
-```csharp
-builder.AddRedisClientBuilder("redis")
- .WithAzureAuthentication()
- .WithDistributedCache(options =>
- {
- options.InstanceName = "MyApp";
- });
-```
-
-### Azure Redis Enterprise support
-
-Aspire 9.5 introduces first-class support for [Azure Redis Enterprise](/azure/redis/overview), providing a high-performance, fully managed Redis service with enterprise-grade features. Azure Redis Enterprise provides advanced caching capabilities with clustering, high availability, and enterprise security features while maintaining compatibility with the standard Redis APIs.
-
-The new `AddAzureRedisEnterprise` extension method enables Redis Enterprise resource modeling:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Add Azure Redis Enterprise resource
-var redisEnterprise = builder.AddAzureRedisEnterprise("redis-enterprise");
-
-// Use in your applications
-var api = builder.AddProject("api")
- .WithReference(redisEnterprise);
-
-builder.Build().Run();
-```
-
-**Local development with container emulation:**
-
-```csharp
-var redisEnterprise = builder.AddAzureRedisEnterprise("redis-enterprise")
- .RunAsContainer(container => container
- .WithHostPort(6379));
-```
-
-**Authentication options:**
-
-Like other Azure integrations, Azure Redis Enterprise uses Microsoft Entra ID authentication by default. This is the recommended authentication strategy since secrets aren't used. To enable access key authentication, you can use the following:
-
-```csharp
-// With access key authentication (default)
-var redisEnterprise = builder.AddAzureRedisEnterprise("redis-enterprise")
- .WithAccessKeyAuthentication();
-
-// With Key Vault integration for access keys
-var keyVault = builder.AddAzureKeyVault("keyvault");
-var redisEnterprise = builder.AddAzureRedisEnterprise("redis-enterprise")
- .WithAccessKeyAuthentication(keyVault);
-```
-
-For more information, see [Aspire Azure Managed Redis integration](https://aspire.dev/integrations/cloud/azure/azure-cache-redis/).
-
-### Azure App Configuration emulator (preview)
-
-Aspire 9.5 adds preview support for running an Azure App Configuration emulator as part of your distributed application model. The emulator lets you develop locally with full feature parity for key/value configuration data—without provisioning a live Azure resource.
-
-Container image (preview): `mcr.microsoft.com/azure-app-configuration/app-configuration-emulator:1.0.0-preview`
-
-You can use this container **with or without Aspire**—it's just a normal container image. Aspire adds first-class resource modeling, lifecycle management, environment wiring, and (optionally) persistent storage.
-
-**Features:**
-
-- Local development parity for Azure App Configuration scenarios.
-- Built-in browser UI for CRUD (create, read, update, delete) of configuration entries.
-- Persistent data via a mounted volume (optional).
-- Seamless integration with other Aspire resources via `WithReference`.
-- Supports inner-loop testing without network latency or secrets in Azure.
-
-**Add emulator via Aspire:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var appConfig = builder.AddAzureAppConfiguration("config")
- .RunAsEmulator(emulator => emulator
- .WithDataVolume()); // Persists configuration across restarts
-
-var api = builder.AddProject("api")
- .WithReference(appConfig);
-
-builder.Build().Run();
-```
-
-**Accessing the UI:**
-
-When running under Aspire, the emulator dashboard (configuration explorer) is exposed as a normal endpoint. Open it from the Aspire Dashboard resource details panel to manage key-values interactively.
-
-**Standalone (without Aspire):**
-
-```bash
-docker run --rm -p 8080:8080 \
- mcr.microsoft.com/azure-app-configuration/app-configuration-emulator:1.0.0-preview
-```
-
-Then browse to `http://localhost:8080` to launch the UI and manage configuration entries.
-
-> [!IMPORTANT]
-> The Azure App Configuration emulator is in **preview**. Behavior, image tags, and API surface may change before general availability.
-
-**Typical project configuration usage:**
-
-```csharp
-var builder = WebApplication.CreateBuilder(args);
-
-builder.AddAzureAppConfiguration("config");
-
-var app = builder.Build();
-
-app.MapGet("/message", (IConfiguration config) =>
-{
- var message = config["Message"];
- return new { Message = message };
-});
-app.Run();
-```
-
-This enables fast local iteration with a real UI and no external dependencies, while keeping deployment parity with Azure-hosted configuration.
-
-### Azure Storage emulator improvements
-
-Aspire now pulls Azurite version 3.35.0 by default, resolving health check issues that previously returned HTTP 400 responses. This improves the reliability of Azure Storage emulator health checks during development.
-
-### MySQL password improvements
-
-The MySQL integration added support for specifying a password parameter:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Secure password parameter
-var password = builder.AddParameter("mysql-password", secret: true);
-
-var mysql = builder.AddMySql("mysql")
- .WithPassword(password);
-
-
-builder.Build().Run();
-```
-
-### Other improvements
-
-- New reference properties have been added to Azure PostgreSQL and Redis resources for custom connection string composition and individual component access.
-- OpenTelemetry Protocols (OTLP) support now has protocol selection capabilities, allowing you to choose between gRPC and HTTP protobuf transports for telemetry data.
-
-## 🧩 App model enhancements
-
-### Resource lifecycle events
-
-Aspire 9.5 introduces new resource lifecycle event APIs that allow you to register callbacks for when resources stop, providing better control over cleanup and coordination during application shutdown.
-
-The new `OnResourceStopped` extension method allows you to register callbacks that execute when a resource enters the stopped state:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var invoicing = builder.AddPostgres("postgres", "mypostgres").AddDatabase("invoicing");
-
-var api = builder.AddProject("api")
- .OnResourceStopped(async (resource, stoppedEvent, cancellationToken) =>
- {
- // Use events to clean up the system to allow rapid
- // inner loop debugging.
-
- await ResetSystemState();
- })
- .WithReference(invoicing);
-
-builder.Build().Run();
-```
-
-**Resource stopped event details:**
-
-The `ResourceStoppedEvent` provides information about the stopping event:
-
-```csharp
-// Register detailed stopped event handler
-var redis = builder.AddRedis("cache")
- .OnResourceStopped(async (resource, stoppedEvent, cancellationToken) =>
- {
- // Access event details
- Console.WriteLine($"Resource: {resource.Name}");
- Console.WriteLine($"Event timestamp: {stoppedEvent.Snapshot.StopTimeStamp}");
- Console.WriteLine($"Exit code: {stoppedEvent.Snapshot.ExitCode}");
-
- // Perform async cleanup with cancellation support
- await CleanupCacheConnections(cancellationToken);
- });
-```
-
-### Context-based endpoint resolution
-
-**Breaking change**: Endpoint resolution in `WithEnvironment` callbacks now correctly resolves container hostnames instead of always using "localhost."
-
-```csharp
-var redis = builder.AddRedis("redis");
-
-// Another container getting endpoint info from Redis container
-var rabbitmq = builder.AddContainer("myapp", "mycontainerapp")
- .WithEnvironment(context =>
- {
- var endpoint = redis.GetEndpoint("tcp");
- var redisHost = endpoint.Property(EndpointProperty.Host);
- var redisPort = endpoint.Property(EndpointProperty.Port);
-
- // Previously: redisHost would always resolve to "localhost"
- // Now: redisHost correctly resolves to "redis" (container name)
- context.EnvironmentVariables["REDIS_HOST"] = redisHost;
- context.EnvironmentVariables["REDIS_PORT"] = redisPort;
- })
- .WithReference(redis);
-```
-
-**What you need to review:**
-
-- **Container deployments**: Your apps will now receive correct container hostnames.
-- **Local development**: Localhost behavior is preserved for noncontainerized scenarios.
-- **Connection strings**: Automatic connection strings continue to work as expected.
-- **Manual environment**: Review custom `WithEnvironment` calls that assume localhost.
-
-### HTTP health probes for resources
-
-Aspire 9.5 introduces comprehensive HTTP health probe support that allows you to configure startup, readiness, and liveness probes for your resources, providing better health monitoring and deployment coordination.
-
-**Features:**
-
-- **Multiple probe types**: Configure startup, readiness, and liveness probes independently.
-- **Flexible endpoint targeting**: Probe any HTTP endpoint with custom paths and configurations.
-- **Configurable timing**: Control probe intervals, timeouts, and failure thresholds.
-- **Kubernetes alignment**: Probe semantics align with Kubernetes health check concepts.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Add readiness probe to ensure service is ready before routing traffic
-var api = builder.AddProject("api")
- .WithHttpProbe(ProbeType.Readiness, "/health/ready");
-
-// Add liveness probe to detect if service needs restart
-var worker = builder.AddProject("worker")
- .WithHttpProbe(ProbeType.Liveness, "/health/live");
-
-builder.Build().Run();
-```
-
-**Advanced probe configuration:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Comprehensive probe setup with custom timing
-var api = builder.AddProject("api")
- .WithHttpProbe(
- type: ProbeType.Startup,
- path: "/health/startup",
- initialDelaySeconds: 30, // Wait 30s before first probe
- periodSeconds: 10, // Probe every 10 seconds
- timeoutSeconds: 5, // 5 second timeout per probe
- failureThreshold: 5, // Consider failed after 5 failures
- successThreshold: 1 // Consider healthy after 1 success
- );
-
-builder.Build().Run();
-```
-
-**Integration with resource dependencies:**
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var database = builder.AddPostgres("postgres");
-var cache = builder.AddRedis("redis");
-
-// API with probes that check dependencies
-var api = builder.AddProject("api")
- .WithHttpProbe(ProbeType.Readiness, "/health/ready") // Checks DB & Redis connectivity
- .WaitFor(database) // Wait for database startup
- .WaitFor(cache) // Wait for cache startup
- .WithReference(database)
- .WithReference(cache);
-
-// Frontend waits for API to be ready (not just started)
-var frontend = builder.AddProject("frontend")
- .WaitFor(api) // Waits for API readiness probe to pass
- .WithReference(api);
-
-builder.Build().Run();
-```
-
-This feature enhances deployment reliability by providing fine-grained health monitoring that integrates seamlessly with Aspire's resource orchestration and dependency management.
-
-### Enhanced resource waiting patterns
-
-New `WaitForStart` method provides granular control over startup ordering, complementing existing `WaitFor` semantics. It also pairs with improved `ExternalService` health honoring which ensures dependents truly wait for external resources to be healthy.
-
-**Understanding wait behaviors:**
-
-- **`WaitFor`**: Waits for dependency to be Running AND pass all health checks.
-- **`WaitForStart`**: Waits only for dependency to reach Running (ignores health checks).
-- **`WaitForCompletion`**: Waits for dependency to reach a terminal state.
-
-```csharp
-var postgres = builder.AddPostgres("postgres");
-var redis = builder.AddRedis("redis");
-
-var api = builder.AddProject("api")
- .WaitForStart(postgres) // New: startup only
- .WaitFor(redis) // Healthy state
- .WithReference(postgres)
- .WithReference(redis);
-```
-
-**ExternalService health integration:**
-
-`WaitFor` now honors `ExternalService` health checks. Previously a dependent could start even if the external target failed its readiness probe.
-
-```csharp
-var externalApi = builder.AddExternalService("backend-api", "http://api.company.com")
- .WithHttpHealthCheck("/health/ready");
-
-var frontend = builder.AddProject("frontend")
- .WaitFor(externalApi) // Now waits for healthy external API
- .WithReference(externalApi);
-```
-
-If you need the old (lenient) behavior:
-
-```csharp
-// Do not wait for health
-var frontend = builder.AddProject("frontend")
- .WithReference(externalApi);
-
-// Or only wait for startup
-var frontend2 = builder.AddProject("frontend2")
- .WaitForStart(externalApi)
- .WithReference(externalApi);
-```
-
-### Enhanced resource lifetime support
-
-**Breaking change**: Resources like `ParameterResource`, `ConnectionStringResource`, and GitHub Model resources now participate in lifecycle operations and support `WaitFor`.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var connectionString = builder.AddConnectionString("database");
-var apiKey = builder.AddParameter("api-key", secret: true);
-
-var api = builder.AddProject("api")
- .WaitFor(connectionString)
- .WaitFor(apiKey)
- .WithEnvironment("DB_CONNECTION", connectionString)
- .WithEnvironment("API_KEY", apiKey);
-
-var github = builder.AddGitHubModels("github");
-var model = github.AddModel("gpt4", GitHubModel.OpenAI.Gpt4o);
-
-var aiService = builder.AddProject("ai-service")
- .WaitFor(model)
- .WithReference(model);
-
-builder.Build().Run();
-```
-
-These resources no longer implement `IResourceWithoutLifetime`; they surface as Running and can be waited on just like services.
-
-## ☁️ Publishing and deployment
-
-### Azure Container App Jobs support
-
-Aspire 9.5 introduces comprehensive support for Azure Container App Jobs, allowing you to deploy both project and container resources as background job workloads that can run on schedules, in response to events, or be triggered manually. For more information, see [Azure Container App Jobs](https://aspire.dev/integrations/cloud/azure/container-app-jobs/)
-
-Container App Jobs complement the existing Container Apps functionality by providing a dedicated way to run finite workloads like data processing, ETL operations, batch jobs, and scheduled maintenance tasks.
-
-#### Publishing resources as Container App Jobs
-
-Use the new `PublishAsAzureContainerAppJob` extension method to publish resources as jobs:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Publish a project as a Container App Job
-var dataProcessor = builder.AddProject("data-processor")
- .PublishAsAzureContainerAppJob(); // Deploys as a job which must be manually started.
-
-builder.Build().Run();
-```
-
-Or use the `PublishAsScheduledAzureContainerAppJob` extension method to publish a resource as a job that runs on a schedule:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Publish a project as a Container App Job
-var dataProcessor = builder.AddProject("data-processor")
- .PublishAsScheduledAzureContainerAppJob("0 0 * * *"); // Every day at midnight
-
-builder.Build().Run();
-```
-
-#### Job customization and configuration
-
-Use the callback on the `PublishAsAzureContainerAppJob(...)` method to customize the job:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Publish a project as a Container App Job
-var dataProcessor = builder.AddProject("data-processor")
- .PublishAsAzureContainerAppJob((infrastructure, job) => {
- job.Configuration.ReplicaTimeout = 3600; // 1 hour
- });
-
-builder.Build().Run();
-```
-
-### Built-in Azure deployment with Aspire CLI
-
-Aspire 9.5 delivers the first iteration of a unified Azure provisioning and deployment pipeline through the `aspire deploy` command. The deployment experience features graph-based dependency planning through `ResourceDeploymentGraph` for correct resource provisioning order and maximum parallelism, support for interactive prompting to gather values required for deployment, and enhanced error reporting for identifying issues during deployment. The AppHost integrates Azure provisioning prompts into the standard interaction system for consistent UX, providing deployment-time flexibility with automatic infrastructure provisioning, container image building and registry pushing, and compute resource deployment to Azure Container Apps—all orchestrated through a single command with real-time progress monitoring and comprehensive error reporting.
-
-For more information on deploying to Azure with the Aspire CLI, read [the official documentation](https://aspire.dev/deployment/azure/aca-deployment-aspire-cli/).
-
-### Executable resource configuration APIs
-
-Enhanced APIs for configuring executable resources with command and working directory specifications.
-
-#### WithCommand and WithWorkingDirectory APIs
-
-New extension methods enable fluent, mutable configuration of executable resources, allowing you to modify command and working directory after initial setup:
-
-```csharp
-// Configure executable with custom command and working directory
-var processor = builder.AddExecutable("data-processor", "python", "/app/data-processing")
- .WithCommand("main.py --batch-size 100")
- .WithArgs("--config", "production.json");
-
-// Change working directory after initial configuration
-var buildTool = builder.AddExecutable("build-tool", "npm", ".")
- .WithCommand("run build:production")
- .WithWorkingDirectory("./frontend");
-```
-
-#### Enhanced CommandLineArgsCallbackContext
-
-The `CommandLineArgsCallbackContext` now includes resource information for context-aware argument building:
-
-```csharp
-var worker = builder.AddExecutable("worker", "dotnet", ".")
- .WithArgs(context =>
- {
- // Access to the resource instance for dynamic configuration
- var resourceName = context.Resource.Name;
- var environment = context.ExecutionContext.IsRunMode ? "Development" : "Production";
-
- context.Args.Add("--resource-name");
- context.Args.Add(resourceName);
- context.Args.Add("--environment");
- context.Args.Add(environment);
- });
-```
-
-These APIs provide fine-grained control over executable resource configuration, enabling complex deployment scenarios and dynamic argument construction based on execution context.
-
-#### InteractionInputCollection enhancements
-
-Enhanced parameter input handling with the new `InteractionInputCollection` type:
-
-```csharp
-// Enhanced interaction service with typed input collection
-public async Task> ProcessParametersAsync()
-{
- var inputs = new List
- {
- new() { Name = "username", Label = "Username", InputType = InputType.Text },
- new() { Name = "password", Label = "Password", InputType = InputType.Password },
- new() { Name = "environment", Label = "Environment", InputType = InputType.Select,
- Options = new[] { ("dev", "Development"), ("prod", "Production") } }
- };
-
- var result = await interactionService.PromptInputsAsync(
- "Configure Parameters",
- "Enter application configuration:",
- inputs);
-
- if (result.Success)
- {
- // Access inputs by name with type safety
- var username = result.Value["username"].Value;
- var password = result.Value["password"].Value;
- var environment = result.Value["environment"].Value;
- }
-
- return result;
-}
-```
-
-The `InteractionInputCollection` provides indexed access by name and improved type safety for parameter processing workflows.
-
-### Docker Compose Aspire Dashboard forwarding headers
-
-`AddDockerComposeEnvironment(...).WithDashboard()` gained `WithForwardedHeaders()` to enable forwarded `Host` and `Proto` handling for dashboard scenarios behind reverse proxies or compose networks. This mirrors the standalone dashboard forwarded header support and fixes auth redirect edge cases.
-
-```csharp
-builder.AddDockerComposeEnvironment("env")
- .WithDashboard(d => d.WithForwardedHeaders());
-```
-
-### Container build customization
-
-`ContainerBuildOptions` support enables customizing the underlying `dotnet publish` invocation when Aspire builds project-sourced container images (for example to change configuration, trimming, or pass other MSBuild properties). Use the new options hook on the project container image configuration to set MSBuild properties instead of maintaining a custom Dockerfile. (Exact API surface is intentionally summarized here to avoid drift; see API docs for `ContainerBuildOptions` in the hosting namespace for usage.)
-
-### Deployment image tag callbacks
-
-Aspire 9.5 introduces powerful deployment image tag callback APIs that allow dynamic generation of container image tags at deployment time, supporting both synchronous and asynchronous scenarios.
-
-#### Deployment tag callback features
-
-- **Dynamic tag generation**: Calculate image tags based on deployment context, git commits, build numbers, or timestamps.
-- **Async callback support**: Perform asynchronous operations like API calls or file system access during tag generation.
-- **Deployment context access**: Access the deployment environment, resource information, and configuration.
-- **Flexible callback types**: Support simple lambdas, context-aware callbacks, and async operations.
-
-#### Basic deployment tag examples
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-// Simple static tag callback
-var api = builder.AddProject("api")
- .WithDeploymentImageTag(() => "v1.2.3-stable");
-
-// Dynamic tag with timestamp
-var worker = builder.AddProject("worker")
- .WithDeploymentImageTag(() => $"build-{DateTime.UtcNow:yyyyMMdd-HHmm}");
-
-builder.Build().Run();
-```
-
-#### Context-aware deployment tags
-
-```csharp
-// Access deployment context for dynamic tag generation
-var api = builder.AddProject("api")
- .WithDeploymentImageTag(context =>
- {
- // Access resource information
- var resourceName = context.Resource.Name;
- var environment = context.Environment;
-
- return $"{resourceName}-{environment}-{GetBuildNumber()}";
- });
-
-// Git-based tagging
-var frontend = builder.AddProject("frontend")
- .WithDeploymentImageTag(context =>
- {
- var gitCommit = GetGitCommitHash();
- var branch = GetCurrentBranch();
- return $"{branch}-{gitCommit[..8]}";
- });
-```
-
-#### Async deployment tag callbacks
-
-```csharp
-// Async callback for complex tag generation
-var database = builder.AddProject("database")
- .WithDeploymentImageTag(async context =>
- {
- // Perform async operations during deployment
- var buildInfo = await GetBuildInfoFromApi();
- var version = await ReadVersionFromFile();
-
- return $"db-{version}-build{buildInfo.Number}";
- });
-
-// API-based version lookup
-var api = builder.AddProject("api")
- .WithDeploymentImageTag(async context =>
- {
- using var client = new HttpClient();
- var latestTag = await client.GetStringAsync("https://api.company.com/latest-tag");
- return $"api-{latestTag.Trim()}";
- });
-```
-
-#### Advanced deployment scenarios
-
-```csharp
-// Environment-specific tagging
-var service = builder.AddProject("service")
- .WithDeploymentImageTag(context =>
- {
- return context.Environment switch
- {
- "Production" => $"prod-{GetReleaseVersion()}",
- "Staging" => $"staging-{GetBuildNumber()}",
- "Development" => $"dev-{DateTime.UtcNow:yyyyMMdd}",
- _ => "latest"
- };
- });
-
-// Multi-resource coordination
-var sharedVersion = await GetSharedVersionAsync();
-
-var frontend = builder.AddProject("frontend")
- .WithDeploymentImageTag(() => $"frontend-{sharedVersion}");
-
-var backend = builder.AddProject("backend")
- .WithDeploymentImageTag(() => $"backend-{sharedVersion}");
-```
-
-## 💔 Breaking changes
-
-For the complete listing, see [Breaking changes in Aspire 9.5](../compatibility/9.5/index.md).
-
-### InteractionInput API requires Name property
-
-**Breaking change**: `InteractionInput` now requires a `Name` property, while `Label` becomes optional ([#10835](https://github.com/dotnet/aspire/pull/10835)).
-
-#### Migration example
-
-```csharp
-// Before (9.4 and earlier)
-var input = new InteractionInput
-{
- Label = "Database Password",
- InputType = InputType.SecretText,
- Required = true
-};
-
-// After (9.5+)
-var input = new InteractionInput
-{
- Name = "database_password", // Required field identifier
- Label = "Database Password", // Optional (defaults to Name)
- InputType = InputType.SecretText,
- Required = true
-};
-```
-
-This change enables better form serialization and integration with interactive parameter processing.
-
-### Notification terminology renamed from MessageBar
-
-**Breaking change**: Notification terminology has been updated, with MessageBar renamed to use new notification terminology ([#10449](https://github.com/dotnet/aspire/pull/10449)).
-
-This change affects APIs and terminology used in the notification system, requiring updates to code that references the old MessageBar naming conventions.
diff --git a/docs/whats-new/dotnet-aspire-9.md b/docs/whats-new/dotnet-aspire-9.md
deleted file mode 100644
index 5c666d1d36..0000000000
--- a/docs/whats-new/dotnet-aspire-9.md
+++ /dev/null
@@ -1,699 +0,0 @@
----
-title: What's new in Aspire 9.0
-description: Learn what's new in the official general availability version of Aspire 9.0.
-ms.date: 11/13/2024
-ms.custom: sfi-ropc-nochange
----
-
-# What's new in Aspire 9.0
-
-📢 Aspire 9.0 is the next major general availability (GA) release of Aspire; it supports _both_:
-
-- .NET 8.0 Long Term Support (LTS) _or_
-- .NET 9.0 Standard Term Support (STS).
-
-> [!NOTE]
-> You're able to use Aspire 9.0 with either .NET 8 or .NET 9!
-
-This release addresses some of the most highly requested features and pain points from the community. The best features are community-driven! To join the community on, visit us on [:::image type="icon" source="../media/discord-icon.svg" border="false"::: Discord](https://discord.com/invite/h87kDAHQgJ) to chat with team members and collaborate with us on [:::image type="icon" source="../media/github-mark.svg" border="false"::: GitHub](https://github.com/dotnet/aspire).
-
-For more information on the official .NET version and Aspire version support, see:
-
-- [.NET support policy](https://dotnet.microsoft.com/platform/support/policy): Definitions for LTS and STS.
-- [Aspire support policy](https://dotnet.microsoft.com/platform/support/policy/aspire): Important unique product life cycle details.
-
-## Upgrade to Aspire 9
-
-To upgrade from earlier versions of Aspire to Aspire 9, follow the instructions in the official [Upgrade to Aspire 9](../get-started/upgrade-to-aspire-9.md) guide. The guide provides detailed instructions on how to upgrade your existing Aspire solutions to Aspire 9. Regardless of you're doing it manually, or using the Upgrade Assistant, the guide makes short work of the process.
-
-### Tooling improvements
-
-Aspire 9 makes it simpler to configure your environment to develop Aspire applications. You no longer need a .NET workload. Instead, you install the new [Aspire SDK](../fundamentals/dotnet-aspire-sdk.md) into the AppHost project of your Aspire solutions. For more information, see [Aspire setup and tooling](../fundamentals/setup-tooling.md).
-
-### Templates have moved
-
-Aspire 9 is moving the contents that used to be installed via the workload into separate NuGet packages. This includes the templates for creating new Aspire projects and solutions. These templates are installed using the [`dotnet new install` command](/dotnet/core/tools/dotnet-new). These can be installed by running the following command:
-
-```dotnetcli
-dotnet new install Aspire.ProjectTemplates::9.0.0
-```
-
-For more information, see [Aspire templates](../fundamentals/aspire-sdk-templates.md).
-
-## Dashboard UX enhancements and new interactivity features
-
-The [Aspire dashboard](https://aspire.dev/dashboard/overview/) continues to improve with each release.
-
-### Manage resource lifecycle
-
-The most requested feature for the dashboard is to manage the life-cycles of your orchestrated named resources. Specifically, the ability to stop, start, and restart resources. This feature works for projects, containers, and executables. It enables restarting individual resources without having to restart the entire AppHost. For project resources, when the debugger is attached, it's reattached on restart. For more information, see [Aspire dashboard: Stop or Start a resource](https://aspire.dev/dashboard/explore/#stop-or-start-a-resource).
-
-### Mobile and responsive support
-
-The Aspire dashboard is now mobile-friendly, responsively adapting to a wide range of screen sizes and enabling on-the-go management of deployed Aspire applications. Other accessibility improvements were made, including the display of settings and content overflow on mobile.
-
-### Sensitive properties, volumes, and health checks in resource details
-
-The display of resource details contains several improvements:
-
-- Properties can be marked as sensitive, automatically masking them in the dashboard UI. This security feature helps to avoid accidentally disclosing keys or passwords when screen sharing the dashboard with other people. For example, container arguments could pass sensitive information and so are masked by default.
-
-- Configured container volumes are listed in resource details.
-
-- Aspire 9 adds support for health checks. Detailed information about these checks can now be viewed in the resource details pane, showing why a resource might be marked as unhealthy or degraded. For more information, see [Resource health check](#resource-health-checks).
-
-### Colorful console log
-
-[ANSI escape codes](https://wikipedia.org/wiki/ANSI_escape_code) format text in terminals by controlling colors (foreground and background) and styles like bold, underline, and italics. Previously, the dashboard's console logs page could only render one ANSI escape code at a time, failing when multiple codes were combined. For example, it could display red text, but not text that was both red and bold.
-
-A community contribution from [@mangeg](https://github.com/mangeg) improved support for ANSI escape codes and removed this limitation.
-
-:::image type="content" source="media/console-logs-ansi-text-format.png" lightbox="media/console-logs-ansi-text-format.png" alt-text="Colorful console logs":::
-
-Another improvement to console logs is hiding unsupported escape codes. Codes that aren't related to displaying text, such as positioning the cursor or communicating with the operating system don't make sense in this UI, and are hidden.
-
-## Telemetry user-centric additions
-
-[Telemetry](../fundamentals/telemetry.md) remains a vital aspect of Aspire. In Aspire 9, many new features were introduced to the Telemetry service.
-
-### Improved telemetry filtering
-
-Traces can be filtered with attribute values. For example, if you only want to view traces for one endpoint in your app, the `http.route` attribute on HTTP requests can be filtered to a specified value.
-
-Telemetry filtering also supports autocomplete of existing values. The **Add filter** dialog provides a combo box for selecting from values that dashboard has available. This feature makes it much easier to filter to real data and helps avoid typos by entered a value yourself.
-
-For more information, see [Aspire dashboard: Filter traces](https://aspire.dev/dashboard/explore/#filter-traces).
-
-### Combine telemetry from multiple resources
-
-When a resource has multiple replicas, you can now filter telemetry to view data from all instances at once. Select the parent resource, labeled `(application)`. For more information, see [Aspire dashboard: Combine telemetry from multiple resources](https://aspire.dev/dashboard/explore/#combine-telemetry-from-multiple-resources).
-
-### Browser telemetry support
-
-The dashboard supports OpenTelemetry Protocol (OTLP) over HTTP and cross-origin resource sharing (CORS). These features unlock the ability to send OpenTelemetry from browser apps to the Aspire dashboard.
-
-For example, a browser-based single page app (SPA) can configure the [JavaScript OpenTelemetry SDK](https://opentelemetry.io/docs/languages/js/getting-started/browser/) to send structured logs, traces, and metrics created in the browser to the dashboard. Browser telemetry is displayed alongside server telemetry.
-
-:::image type="content" source="media/dashboard-browser-telemetry.png" lightbox="media/dashboard-browser-telemetry.png" alt-text="Trace detail page with browser telemetry":::
-
-For more information on configuring browser telemetry, see [Enable browser telemetry](https://aspire.dev/dashboard/enable-browser-telemetry/) documentation.
-
-## AppHost (Orchestration)
-
-The [Aspire AppHost](https://aspire.dev/get-started/app-host/) is one of the **most important** features of Aspire. In Aspire 9, several new features were added specific to the AppHost.
-
-### Waiting for dependencies
-
-If you've been following along with Aspire, you already know that your AppHost project is where you define your app model. You create a distributed application builder, add and configure resources, and express their dependencies. Now, you can specify that a resource should _wait_ for another resource before starting. This can help avoid connection errors during startup by only starting resources when their dependencies are "ready."
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var rabbit = builder.AddRabbitMQ("rabbit");
-
-builder.AddProject("api")
- .WithReference(rabbit)
- .WaitFor(rabbit); // Don't start "api" until "rabbit" is ready...
-
-builder.Build().Run();
-```
-
-When the AppHost starts, it waits for the `rabbit` resource to be ready before starting the `api` resource.
-
-There are two methods exposed to wait for a resource:
-
-- : Wait for a resource to be ready before starting another resource.
-- : Wait for a resource to complete before starting another resource.
-
-For more information, see [Aspire AppHost: Waiting for resources](../fundamentals/orchestrate-resources.md#waiting-for-resources).
-
-#### Resource health checks
-
-The `WaitFor` API uses standard [.NET health checks](https://aspire.dev/fundamentals/health-checks/) to determine if a resource is ready. But what does "a resource being ready" mean? The best part is, that's configurable by the consumer beyond their default values.
-
-When a resource doesn't expose any health checks (no health checks registered in the app), the AppHost waits for the resource to be in the state before starting the dependent resource.
-
-For resources that expose HTTP endpoints, you can easily add a health check that polls a specific path for an HTTP 200 response.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var catalogApi = builder.AddContainer("catalog-api", "catalog-api")
- .WithHttpEndpoint(targetPort: 8080)
- .WithHttpHealthCheck("/health");
-
-builder.AddProject("store")
- .WithReference(catalogApi.GetEndpoint("http"))
- .WaitFor(catalogApi);
-
-builder.Build().Run();
-```
-
-The preceding example adds a health check to the `catalog-api` resource. The AppHost waits for the health check to return a healthy status before starting the `store` resource. It determines that the resource is ready when the `/health` endpoint returns an HTTP 200 status code.
-
-While `store` is waiting for `catalog-api` to become healthy, the resources in the dashboard appear as:
-
-:::image type="content" source="media/waiting-for-unhealthy-resource.png" lightbox="media/waiting-for-unhealthy-resource.png" alt-text="Waiting for an unhealthy resource before starting":::
-
-The AppHost's health check mechanism builds upon the implementation from the namespace.
-
-Health checks report data, which is displayed in the dashboard:
-
-:::image type="content" source="media/health-check-details.png" lightbox="media/health-check-details.png" alt-text="Health check details in the dashboard's resource details view":::
-
-Creating a custom health check is straightforward. Start by defining the health check, then associate its name with any resources it applies to.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var healthyAfter = DateTime.Now.AddSeconds(20);
-
-builder.Services.AddHealthChecks().AddCheck(
- "delay20secs",
- () => DateTime.Now > healthyAfter
- ? HealthCheckResult.Healthy()
- : HealthCheckResult.Unhealthy()
- );
-
-var cache = builder.AddRedis("cache")
- .WithHealthCheck("delay20secs");
-
-builder.AddProject("myapp")
- .WithReference(cache)
- .WaitFor(cache);
-```
-
-The preceding example adds a health check to the `cache` resource, which reports it as unhealthy for the first 20 seconds after the AppHost starts. So, the `myapp` resource waits for 20 seconds before starting, ensuring the `cache` resource is healthy.
-
-The and methods provide a simple mechanism to create health checks and associate them with specific resources.
-
-### Persistent containers
-
-The AppHost now supports _persistent_ containers. Persistent containers deviate from the [typical container life cycle of Aspire orchestrated apps](../fundamentals/orchestrate-resources.md#container-resource-lifecycle). While they're _created_ and _started_ (when not already available) by the Aspire orchestrator, they're not destroyed by Aspire.
-
-This is useful when you want to keep the container running even after the AppHost has stopped.
-
-> [!IMPORTANT]
-> To delete these containers, you must manually stop them using the container runtime.
-
-To define an `IResourceBuilder` with a persistent lifetime, call the method and pass in :
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var queue = builder.AddRabbitMQ("rabbit")
- .WithLifetime(ContainerLifetime.Persistent);
-
-builder.AddProject("api")
- .WithReference(queue)
- .WaitFor(queue);
-
-builder.Build().Run();
-```
-
-The dashboard shows persistent containers with a pin icon:
-
-:::image type="content" source="media/persistent-container.png" lightbox="media/persistent-container.png" alt-text="Persistent containers":::
-
-After the AppHost is stopped, the container will continue to run:
-
-:::image type="content" source="media/persistent-container-docker-desktop.png" lightbox="media/persistent-container-docker-desktop.png" alt-text="Docker desktop showing RabbitMQ.":::
-
-The container persistence mechanism attempts to identify when you might wish to recreate the container. For example, if the environment for the container changes, then the container is restarted so that you don't need to manually stop the container if the input configuration for the resource has changed.
-
-### Resource commands
-
-The AppHost supports adding custom commands to resources. This is useful when you want to add custom functionality that is not natively supported by the AppHost. There's likely many opportunities where exposing custom extension methods on resources will be useful. The [Aspire Community Toolkit](https://aspire.dev/integrations/overview/) might be a good place to share these extensions.
-
-When you define a custom command, it's available in the dashboard as a user experience feature.
-
-> [!IMPORTANT]
-> These Aspire dashboard commands are only available when running the dashboard locally. They're not available when running the dashboard in Azure Container Apps.
-
-For more information on creating custom resource commands, see [How-to: Create custom resource commands in Aspire](https://aspire.dev/fundamentals/custom-resource-commands/).
-
-### Container networking
-
-The AppHost now adds all containers to a common network named `default-aspire-network`. This is useful when you want to communicate between containers without going through the host network. This also makes it easier to migrate from docker compose to the AppHost, as containers can communicate with each other using the container name.
-
-### Eventing model
-
-The eventing model allows developers to hook into the lifecycle of the application and resources. This is useful for running custom code at specific points in the application lifecycle. There are various ways to subscribe to events, including global events and per-resource events.
-
-**Global events:**
-
-- : An event that is triggered before the application starts. This is the last place that changes to the app model are observed. This runs in both "Run" and "Publish" modes. This is a blocking event, meaning that the application doesn't start until all handlers have completed.
-- : An event that is triggered after the resources are created. This runs in Run mode only.
-- : An event that is triggered after the endpoints are allocated for all resources. This runs in Run mode only.
-
-The global events are analogous to the AppHost life cycle events. For more information, see [AppHost life cycles](https://aspire.dev/app-host/eventing/#apphost-life-cycle-events).
-
-**Per-resource events:**
-
-- : An event that is triggered before a single resource starts. This runs in Run mode only. This is a blocking event, meaning that the resource doesn't start until all handlers complete.
-- : An event that is triggered when a connection string is available for a resource. This runs in Run mode only.
-- : An event that is triggered when a resource is ready to be used. This runs in Run mode only.
-
-For more information, see [Eventing in Aspire](https://aspire.dev/app-host/eventing/).
-
-## Integrations
-
-Aspire continues to add integrations that make it easy to get started with your favorite services and tools. For more information, see [Aspire integrations overview](https://aspire.dev/integrations/overview/).
-
-### Redis Insight
-
-Support for [Redis Insights](https://redis.io/insight/) is available on a Redis resource:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddRedis("redis")
- .WithRedisInsight(); // Starts a Redis Insight container image
- // that is pre-configured to work with the
- // Redis instance.
-```
-
-The extension method can be applied to multiple Redis resources and they'll each be visible on the Redis Insight dashboard.
-
-:::image type="content" source="media/redis-insight.png" lightbox="media/redis-insight.png" alt-text="Redis Insight dashboard showing multiple Redis instances":::
-
-For more information, see [Add Redis resource with Redis Insights](https://aspire.dev/integrations/caching/redis/?pivots=redis#add-redis-resource-with-redis-insights).
-
-### OpenAI (Preview)
-
-Starting with Aspire 9, an additional OpenAI integration is available which allows to use the latest official OpenAI dotnet library directly. The client integration registers the [OpenAIClient](https://github.com/openai/openai-dotnet?tab=readme-ov-file#using-the-openaiclient-class) as a singleton service in the service collection. The client can be used to interact with the OpenAI REST API.
-
-- [📦 Aspire.OpenAI (Preview)](https://www.nuget.org/packages/Aspire.OpenAI/9.0.0)
-
-Moreover, the already available [Aspire Azure OpenAI integration](https://aspire.dev/integrations/cloud/azure/azure-openai/) was improved to provide a flexible way to configure an `OpenAIClient` for either an Azure AI OpenAI service or a dedicated OpenAI REST API one with the new builder method. The following example detects if the connection string is for an Azure AI OpenAI service and registers the most appropriate `OpenAIClient` instance automatically.
-
-```csharp
-builder.AddOpenAIClientFromConfiguration("openai");
-```
-
-For instance, if the `openai` connection looked like `Endpoint=https://{account}.azure.com;Key={key};` it would guess it can register an Azure AI OpenAI client because of the domain name. Otherwise a common `OpenAIClient` would be used.
-
-Read [Azure-agnostic client resolution](https://github.com/dotnet/aspire/blob/release/9.0/src/Components/Aspire.Azure.AI.OpenAI/README.md#azure-agnostic-client-resolution) for more details.
-
-### MongoDB
-
-Added support for specifying the MongoDB username and password when using the extension method. If not specified, a random username and password is generated but can be manually specified using parameter resources.
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var username = builder.AddParameter("mongousername");
-var password = builder.AddParameter("mongopassword", secret: true);
-
-var db = builder.AddMongo("db", username, password);
-```
-
-### Important Azure improvements
-
-The following sections describe Azure improvements added in Aspire 9. For a complete listing of all the breaking changes, see [Breaking changes in Aspire 9](../compatibility/9.0/index.md).
-
-#### Azure resource customization
-
-In Aspire 8, customizing Azure resources were marked experimental because the underlying `Azure.Provisioning` libraries were new and gathering feedback before they could be marked stable. In Aspire 9 these APIs were updated and removes the experimental attribute.
-
-**Azure Resource naming breaking change**
-
-As part of the update to the libraries, the default naming scheme for Azure resources was updated with better support for various naming policies. However, this update resulted in a change to how resources are named. The new naming policy might result in the existing Azure resources being abandoned and new Azure resources being created, after updating your Aspire application from 8 to 9. To keep using the same naming policies from Aspire 8, you can add the following code to your AppHost _Program.cs_:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.Services.Configure(options =>
-{
- options.ProvisioningBuildOptions.InfrastructureResolvers.Insert(0, new AspireV8ResourceNamePropertyResolver());
-});
-```
-
-#### Azure SQL, PostgreSQL, and Redis Update
-
-Azure SQL, PostgreSQL, and Redis resources are different than other Azure resources because there are local container resources for these technologies. In Aspire 8, in order to create these Azure resources you needed to start with a local container resource and then either "As" or "PublishAs" it to an Azure resource. This design introduced problems and didn't fit with other APIs.
-
-For example, you might have this code in Aspire 8:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var sql = builder.AddSqlServer("sql")
- .PublishAsAzureSqlDatabase();
-
-var pgsql = builder.AddPostgres("pgsql")
- .PublishAsAzurePostgresFlexibleServer();
-
-var cache = builder.AddRedis("cache")
- .PublishAsAzureSqlDatabase();
-```
-
-In Aspire 9 these APIs were marked as obsolete and a new API pattern implemented:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var sql = builder.AddAzureSqlServer("sql")
- .RunAsContainer();
-
-var pgsql = builder.AddAzurePostgresFlexibleServer("pgsql")
- .RunAsContainer();
-
-var cache = builder.AddAzureRedis("cache")
- .RunAsContainer();
-```
-
-##### Microsoft Entra ID by default
-
-In order to make Aspire applications more secure, Azure Database for PostgreSQL and Azure Cache for Redis resources were updated to use Microsoft Entra ID by default. This requires changes to applications that need to connect to these resources. See the following for updating applications to use Microsoft Entra ID to connect to these resources:
-
-- [Azure Database for PostgreSQL](https://devblogs.microsoft.com/dotnet/using-postgre-sql-with-dotnet-and-entra-id/)
-- [Azure Cache for Redis](https://github.com/Azure/Microsoft.Azure.StackExchangeRedis)
-
-The following examples demonstrate how to configure your application to connect to the Azure resources using Microsoft Entra ID:
-
-- [Aspire: Azure PostgreSQL hosting integration](https://aspire.dev/integrations/cloud/azure/azure-postgresql/).
-- [Aspire: Azure Redis hosting integration](https://aspire.dev/integrations/cloud/azure/azure-cache-redis/#hosting-integration).
-
-If you need to use password or access key authentication (not recommended), you can opt-in with the following code:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var pgsql = builder.AddAzurePostgresFlexibleServer("pgsql")
- .WithPasswordAuthentication();
-
-var cache = builder.AddAzureRedis("cache")
- .WithAccessKeyAuthentication();
-```
-
-#### Support for Azure Functions (Preview)
-
-Support for [Azure Functions](/azure/azure-functions/functions-overview?pivots=programming-language-csharp) is one of the most widely requested features on the Aspire issue tracker and we're excited to introduce preview support for it in this release. To demonstrate this support, let's use Aspire to create and deploy a webhook.
-
-To get started, create a new Azure Functions project using the **Visual Studio New Project** dialog. When prompted, select the **Enlist in Aspire orchestration** checkbox when creating the project.
-
-:::image type="content" source="media/functions-step-1.gif" lightbox="media/functions-step-1.gif" alt-text="Create new Aspire Azure Functions project.":::
-
-In the AppHost project, observe that there's a `PackageReference` to the new [📦 Aspire.Hosting.Azure.Functions](https://www.nuget.org/packages/Aspire.Hosting.Azure.Functions) NuGet package:
-
-```xml
-
-
-
-
-```
-
-This package provides an API that can be invoked in the AppHost to configure Azure Functions projects within an Aspire host:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-builder.AddAzureFunctionsProject("piglatinapp");
-
-builder.Build().Run();
-```
-
-In this example, the webhook is responsible for translating an input string into Pig Latin. Update the contents of our trigger with the following code:
-
-```csharp
-using Microsoft.AspNetCore.Http;
-using Microsoft.AspNetCore.Mvc;
-using Microsoft.Azure.Functions.Worker;
-using Microsoft.Extensions.Logging;
-using System.Text;
-using FromBodyAttribute = Microsoft.Azure.Functions.Worker.Http.FromBodyAttribute;
-
-namespace PigLatinApp;
-
-public class Function1(ILogger logger)
-{
- public record InputText(string Value);
- public record PigLatinText(string Value);
-
- [Function("Function1")]
- public IActionResult Run(
- [HttpTrigger(AuthorizationLevel.Anonymous, "post")] HttpRequest req,
- [FromBody] InputText inputText)
- {
- logger.LogInformation("C# HTTP trigger function processed a request.");
-
- var result = TranslateToPigLatin(inputText.Value);
-
- return new OkObjectResult(new PigLatinText(result));
- }
-
- private static string TranslateToPigLatin(string input)
- {
- if (string.IsNullOrEmpty(input))
- {
- return input;
- }
-
- var words = input.Split(' ');
- StringBuilder pigLatin = new();
-
- foreach (string word in words)
- {
- if (IsVowel(word[0]))
- {
- pigLatin.Append(word + "yay ");
- }
- else
- {
- int vowelIndex = FindFirstVowelIndex(word);
- if (vowelIndex is -1)
- {
- pigLatin.Append(word + "ay ");
- }
- else
- {
- pigLatin.Append(
- word.Substring(vowelIndex) + word.Substring(0, vowelIndex) + "ay ");
- }
- }
- }
-
- return pigLatin.ToString().Trim();
- }
-
- private static int FindFirstVowelIndex(string word)
- {
- for (var i = 0; i < word.Length; i++)
- {
- if (IsVowel(word[i]))
- {
- return i;
- }
- }
- return -1;
- }
-
- private static bool IsVowel(char c) =>
- char.ToLower(c) is 'a' or 'e' or 'i' or 'o' or 'u';
-}
-```
-
-Set a breakpoint on the first `logger.LogInformation` line of the `Run` method and press F5 to start the Functions host. Once the Aspire dashboard launches, you observe the following:
-
-:::image type="content" source="media/functions-dashboard-screenshot.png" lightbox="media/functions-dashboard-screenshot.png" alt-text="Screenshot of the Aspire running with an Azure Function app.":::
-
-Aspire has:
-
-- Configured an emulated Azure Storage resource to be used for bookkeeping by the host.
-- Launched the Functions host locally with the target as the Functions project registered.
-- Wired the port defined in _launchSettings.json_ of the functions project for listening.
-
-Use your favorite HTTP client of choice to send a request to the trigger and observe the inputs bound from the request body in the debugger.
-
-## [Unix](#tab/unix)
-
-```bash
-curl --request POST \
- --url http://localhost:7282/api/Function1 \
- --header 'Content-Type: application/json' \
- --data '{
- "value": "Welcome to Azure Functions"
-}'
-```
-
-## [Windows](#tab/windows)
-
-```powershell
-curl --request POST `
- --url http://localhost:7282/api/Function1 `
- --header 'Content-Type: application/json' `
- --data '{
- "value": "Welcome to Azure Functions"
-}'
-```
-
----
-
-:::image type="content" source="media/functions-debug-screenshot.png" lightbox="media/functions-debug-screenshot.png" alt-text="Screenshot of the Aspire dashboard: Debugging an Azure Function app.":::
-
-Now you're ready to deploy our application to Azure Container Apps (ACA). Deployment currently depends on preview builds of Azure Functions Worker and Worker SDK packages. If necessary, upgrade the versions referenced in the Functions project:
-
-```xml
-
-
-
-
-```
-
-You also need to expose a public endpoint for our Azure Functions project so that requests can be sent to our HTTP trigger:
-
-```csharp
-builder.AddAzureFunctionsProject("piglatinapp")
- .WithExternalHttpEndpoints();
-```
-
-To deploy the application with [the `azd` CLI](/azure/developer/azure-developer-cli/install-azd), you need get the latest version first. To install the latest version, you see a warning if your version is out of date. Follow the instructions to update to the latest version.
-
-After it's installed, navigate to the folder containing the AppHost project and run `azd init`:
-
-```azdeveloper
-$ azd init
-
-Initializing an app to run on Azure (azd init)
-
-? How do you want to initialize your app? Use code in the current directory
-
- (✓) Done: Scanning app code in current directory
-
-Detected services:
-
- .NET (Aspire)
- Detected in: ./PigLatinApp/PigLatinApp.AppHost/PigLatinApp.AppHost.csproj
-
-azd will generate the files necessary to host your app on Azure using Azure Container Apps.
-
-? Select an option Confirm and continue initializing my app
-? Enter a new environment name: azfunc-piglatin
-
-Generating files to run your app on Azure:
-
- (✓) Done: Generating ./azure.yaml
- (✓) Done: Generating ./next-steps.md
-
-SUCCESS: Your app is ready for the cloud!
-```
-
-Then, deploy the application by running `azd up`:
-
-```azdeveloper
-$ azd up
-? Select an Azure Subscription to use: 130. [redacted]
-? Select an Azure location to use: 50. (US) West US 2 (westus2)
-
-Packaging services (azd package)
-
-
-Provisioning Azure resources (azd provision)
-Provisioning Azure resources can take some time.
-
-Subscription: [redacted]
-Location: West US 2
-
- You can view detailed progress in the Azure Portal:
- [redacted]
-
- (✓) Done: Resource group: rg-azfunc-piglatin (967ms)
- (✓) Done: Container Registry: [redacted] (13.316s)
- (✓) Done: Log Analytics workspace: [redacted] (16.467s)
- (✓) Done: Container Apps Environment: [redacted] (1m35.531s)
- (✓) Done: Storage account: [redacted] (21.37s)
-
-Deploying services (azd deploy)
-
- (✓) Done: Deploying service piglatinapp
- - Endpoint: {{endpoint-url}}
-
- Aspire Dashboard: {{dashboard-url}}
-```
-
-Finally, test your deployed Functions application using your favorite HTTP client:
-
-## [Unix](#tab/unix)
-
-```bash
-curl --request POST \
- --url {{endpoint-url}}/api/Function1 \
- --header 'Content-Type: application/json' \
- --data '{
- "value": "Welcome to Azure Functions"
-}'
-```
-
-## [Windows](#tab/windows)
-
-```powershell
-curl --request POST `
- --url {{endpoint-url}}/api/Function1 `
- --header 'Content-Type: application/json' `
- --data '{
- "value": "Welcome to Azure Functions"
-}'
-```
-
----
-
-Support for Azure Functions in Aspire is still in preview with support for a limited set of triggers including:
-
-- [HTTP triggers](/azure/azure-functions/functions-triggers-bindings?pivots=programming-language-csharp#supported-bindings)
-- [Azure Storage Queue triggers](/azure/azure-functions/functions-bindings-storage-queue?pivots=programming-language-csharp)
-- [Azure Storage Blob triggers](/azure/azure-functions/functions-bindings-storage-blob?pivots=programming-language-csharp)
-- [Azure Service Bus triggers](/azure/azure-functions/functions-bindings-service-bus?pivots=programming-language-csharp)
-- [Azure Event Hubs triggers](/azure/azure-functions/functions-bindings-event-hubs?pivots=programming-language-csharp)
-
-For more information, see the official [Aspire Azure Functions integration (Preview)](https://aspire.dev/integrations/cloud/azure/azure-functions/).
-
-#### Customization of Azure Container Apps
-
-One of the most requested features is the ability to customize the Azure Container Apps that the AppHost creates without touching Bicep. This is possible by using the and APIs in the `Aspire.Hosting.Azure.AppContainers` namespace. These methods customizes the Azure Container App definition that the AppHost creates.
-
-Add the package reference to your project file:
-
-```xml
-
-
-
-```
-
-The following example demonstrates how to scale an Azure Container App to zero (`0`) replicas:
-
-```csharp
-var builder = DistributedApplication.CreateBuilder(args);
-
-var db = builder.AddAzurePostgresFlexibleServer("pg")
- .RunAsContainer()
- .AddDatabase("db");
-
-// Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
-#pragma warning disable AZPROVISION001
-
-builder.AddProject("api")
- .WithReference(db)
- .PublishAsAzureContainerApp((module, containerApp) =>
- {
- // Scale to 0
- containerApp.Template.Value!.Scale.Value!.MinReplicas = 0;
- });
-
-#pragma warning restore AZPROVISION001
-
-builder.Build().Run();
-```
-
-The preceding code example defers generation of the Azure Container App definition to the AppHost. This allows you to customize the Azure Container App definition without needing to run `azd infra synth` and unsafely modifying the generated bicep files.
-
-## See also
-
-- [Aspire setup and tooling](../fundamentals/setup-tooling.md)
-- [Aspire SDK](../fundamentals/dotnet-aspire-sdk.md)
-- [Aspire templates](../fundamentals/aspire-sdk-templates.md)
-- [Aspire orchestration overview](https://aspire.dev/get-started/app-host/)
-- [Eventing in Aspire](https://aspire.dev/app-host/eventing/)
-- [Aspire dashboard overview](https://aspire.dev/dashboard/overview/)
-- [Explore the Aspire dashboard](https://aspire.dev/dashboard/explore/)
diff --git a/docs/whats-new/dotnet-docs-aspire-mod0.md b/docs/whats-new/dotnet-docs-aspire-mod0.md
deleted file mode 100644
index c0064a518b..0000000000
--- a/docs/whats-new/dotnet-docs-aspire-mod0.md
+++ /dev/null
@@ -1,77 +0,0 @@
----
-title: "Aspire docs: What's new for June 2025"
-description: "What's new in the Aspire docs for June 2025."
-ms.custom: June-2025
-ms.date: 07/01/2025
----
-
-# Aspire docs: What's new for June 2025
-
-Welcome to what's new in the Aspire docs for June 2025. This article lists some of the major changes to docs during this period.
-
-## Get started
-
-### Updated articles
-
-- [Upgrade to Aspire 9](../get-started/upgrade-to-aspire-9.md) - Add instructions to get rid of Aspire 8 before upgrading to 9
-
-## Fundamentals
-
-### Updated articles
-
-- [Standalone Aspire dashboard](https://aspire.dev/dashboard/standalone/) - Update container version for standalone dashboard examples
-
-## Database
-
-### Updated articles
-
-- [Aspire MongoDB database integration](https://aspire.dev/integrations/databases/mongodb/) - Documents the issue with deploying data volumes to ACA.
-- [Apply Entity Framework Core migrations in Aspire](https://aspire.dev/integrations/databases/efcore/migrations/)
- - Altered EF Core Migrations tutorial to ensure that API waits for the migrations to complete
- - Add Microsoft.EntityFrameworkCore.Tools package guidance to EF Core migrations documentation
-- [Seed data in a database using Aspire](https://aspire.dev/integrations/databases/efcore/seed-database/) - Update seeding data article to Aspire 9.3
-
-## Messaging
-
-### Updated articles
-
-- [Aspire Azure Event Hubs integration](https://aspire.dev/integrations/cloud/azure/azure-event-hubs/)
- - Move the "Infrastructure as code" section of the Azure Overview article into a separate article
- - Recommend AsExisting() for Azure Integrations
-- [Aspire Azure Service Bus integration](https://aspire.dev/integrations/cloud/azure/azure-service-bus/)
- - Move the "Infrastructure as code" section of the Azure Overview article into a separate article
- - Recommend AsExisting() for Azure Integrations
-- [Aspire Azure Web PubSub integration](https://aspire.dev/integrations/cloud/azure/azure-web-pubsub/)
- - Move the "Infrastructure as code" section of the Azure Overview article into a separate article
- - Recommend AsExisting() for Azure Integrations
-
-## Security
-
-### Updated articles
-
-- [Aspire Azure Key Vault integration](https://aspire.dev/integrations/cloud/azure/azure-key-vault/)
- - Move the "Infrastructure as code" section of the Azure Overview article into a separate article
- - Recommend AsExisting() for Azure Integrations
-
-## Deployment
-
-### New articles
-
-- [Customize Aspire Azure deployments](../deployment/azure/customize-deployments.md)
-
-### Updated articles
-
-- [Deploy an Aspire project to Azure Container Apps](../deployment/azure/aca-deployment.md) - Optimize ACA deployment docs workflow and content structure
-- [Deploy an Aspire project to Azure Container Apps using the Azure Developer CLI (in-depth guide)](../deployment/azure/aca-deployment-azd-in-depth.md)
- - Optimize ACA deployment docs workflow and content structure
- - Update aca-deployment-azd-in-depth.md
-- [Deploy an Aspire project to Azure Container Apps using Visual Studio](../deployment/azure/aca-deployment-visual-studio.md) - Optimize ACA deployment docs workflow and content structure
-- [Tutorial: Deploy an Aspire project using the Azure Developer CLI](../deployment/azure/aca-deployment-github-actions.md) - Add troubleshooting guidance for Azure DevOps pipeline "azd init" errors
-
-## Community contributors
-
-The following people contributed to the Aspire docs during this period. Thank you! Learn how to contribute by following the links under "Get involved" in the [what's new landing page](index.yml).
-
-- [Alirexaa](https://github.com/Alirexaa) - Alireza Baloochi 
-- [Depechie](https://github.com/Depechie) - Glenn Versweyveld 
-- [philip-reed](https://github.com/philip-reed) - Phil Reed 
diff --git a/docs/whats-new/dotnet-docs-aspire-mod1.md b/docs/whats-new/dotnet-docs-aspire-mod1.md
deleted file mode 100644
index b9ea5c8420..0000000000
--- a/docs/whats-new/dotnet-docs-aspire-mod1.md
+++ /dev/null
@@ -1,100 +0,0 @@
----
-title: "Aspire docs: What's new for April 2025"
-description: "What's new in the Aspire docs for April 2025."
-ms.custom: April-2025
-ms.date: 05/01/2025
----
-
-# Aspire docs: What's new for April 2025
-
-Welcome to what's new in the Aspire docs for April 2025. This article lists some of the major changes to docs during this period.
-
-## Get started
-
-### Updated articles
-
-- [Orchestrate Python apps in Aspire](https://aspire.dev/get-started/first-app/?lang=python)
- - Initial draft of diagnostic redesign
- - Fix the Python article
-- [Quickstart: Build your first Aspire solution](https://aspire.dev/get-started/first-app/) - Split content
-- [Tutorial: Add Aspire to an existing .NET app](https://aspire.dev/get-started/add-aspire-existing-app/) - Update the add aspire to existing tutorial
-
-## Fundamentals
-
-### New articles
-
-- [Orchestrate resources in Aspire](../fundamentals/orchestrate-resources.md)
-
-### Updated articles
-
-- [Aspire and launch profiles](https://aspire.dev/fundamentals/launch-profiles/) - Rename configs-replace prefix
-- [Aspire orchestration overview](https://aspire.dev/get-started/app-host/) - Split content
-- [Aspire service defaults](https://aspire.dev/fundamentals/service-defaults/) - Update service defaults and add filtering details
-- [Aspire setup and tooling](../fundamentals/setup-tooling.md) - Rename configs-replace prefix
-- [Aspire templates](../fundamentals/aspire-sdk-templates.md) - Add dev-cert details to templates content
-- [Custom HTTP commands in Aspire](https://aspire.dev/fundamentals/http-commands/) - Split content
-- [Dashboard configuration](https://aspire.dev/dashboard/configuration/) - Rename configs-replace prefix
-- [Enable browser telemetry](https://aspire.dev/dashboard/enable-browser-telemetry/) - Rename configs-replace prefix
-- [Explore the Aspire dashboard](https://aspire.dev/dashboard/explore/) - Update the Explore the Aspire Dashboard article for v9.2.0
-- [External parameters](https://aspire.dev/fundamentals/external-parameters/) - #3063 - Rename parameter name to not be 'value'
-- [Orchestrate resources in Aspire](../fundamentals/orchestrate-resources.md)
- - Initial draft of diagnostic redesign
- - Split content
-- [Persist Aspire project data using volumes or bind mounts](https://aspire.dev/fundamentals/persist-data-volumes/) - Update the "Persist Aspire project data using volumes" article
-- [Security considerations for running the Aspire dashboard](https://aspire.dev/dashboard/security-considerations/) - Rename configs-replace prefix
-- [Standalone Aspire dashboard](https://aspire.dev/dashboard/standalone/) - Rename configs-replace prefix
-
-## Database
-
-### Updated articles
-
-- [Aspire Milvus database integration](https://aspire.dev/integrations/databases/milvus/) - Split content
-- [Aspire MongoDB database integration](https://aspire.dev/integrations/databases/mongodb/) - Split content
-- [Aspire Oracle Entity Framework Core integration](https://aspire.dev/integrations/databases/oracle/) - Split content
-- [Aspire Qdrant integration](https://aspire.dev/integrations/databases/qdrant/) - Split content
-- [Tutorial: Deploy an Aspire project with a SQL Server Database to Azure](https://aspire.dev/integrations/databases/sql-server/) - Update the Tutorial: Deploy an Aspire project with a SQL Server Database to Azure
-
-## Messaging
-
-### Updated articles
-
-- [Aspire Apache Kafka integration](https://aspire.dev/integrations/messaging/apache-kafka/) - Split content
-- [Aspire Azure Event Hubs integration](https://aspire.dev/integrations/cloud/azure/azure-event-hubs/) - Removes obsolete API: Add breaking changes for `AzureOpenAIDeployment` obsoletion
-- [Aspire Azure Service Bus integration](https://aspire.dev/integrations/cloud/azure/azure-service-bus/)
- - Split content
- - Removes obsolete API: Add breaking changes for `AzureOpenAIDeployment` obsoletion
-- [Aspire Azure Web PubSub integration](https://aspire.dev/integrations/cloud/azure/azure-web-pubsub/) - Removes obsolete API: Add breaking changes for `AzureOpenAIDeployment` obsoletion
-- [Aspire NATS integration](https://aspire.dev/integrations/messaging/nats/) - Split content
-- [Aspire RabbitMQ integration](https://aspire.dev/integrations/messaging/rabbitmq/)
- - Split content
- - Clarify how to set credentials for the RabbitMQ management plugin
-
-## Caching
-
-### Updated articles
-
-- [Aspire Redis® distributed caching integration](https://aspire.dev/integrations/caching/redis-distributed/) - Correct keyed IDistributedCache registration and usage
-
-## Security
-
-### Updated articles
-
-- [Aspire Azure Key Vault integration](https://aspire.dev/integrations/cloud/azure/azure-key-vault/) - Removes obsolete API: Add breaking changes for `AzureOpenAIDeployment` obsoletion
-
-## Deployment
-
-### Updated articles
-
-- [Deploy an Aspire project to Azure Container Apps using the Azure Developer CLI (in-depth guide)](../deployment/azure/aca-deployment-azd-in-depth.md) - Terminate inline azd code snippet
-
-## Community contributors
-
-The following people contributed to the Aspire docs during this period. Thank you! Learn how to contribute by following the links under "Get involved" in the [what's new landing page](index.yml).
-
-- [alistairmatthews](https://github.com/alistairmatthews) - Alistair Matthews 
-- [a510](https://github.com/a510) - Ahmad Ibrahim 
-- [dracan](https://github.com/dracan) - Dan Clarke 
-- [gabynevada](https://github.com/gabynevada) - Elvis Nieves 
-- [mip1983](https://github.com/mip1983) - Matthew Paul 
-- [paulomorgado](https://github.com/paulomorgado) - Paulo Morgado 
-- [ryanspain](https://github.com/ryanspain) - Ryan Spain 
diff --git a/docs/whats-new/dotnet-docs-aspire-mod2.md b/docs/whats-new/dotnet-docs-aspire-mod2.md
deleted file mode 100644
index 894d2164cc..0000000000
--- a/docs/whats-new/dotnet-docs-aspire-mod2.md
+++ /dev/null
@@ -1,52 +0,0 @@
----
-title: "Aspire docs: What's new for May 2025"
-description: "What's new in the Aspire docs for May 2025."
-ms.custom: May-2025
-ms.date: 06/01/2025
----
-
-# Aspire docs: What's new for May 2025
-
-Welcome to what's new in the Aspire docs for May 2025. This article lists some of the major changes to docs during this period.
-
-## Get started
-
-### Updated articles
-
-- [Orchestrate Node.js apps in Aspire](https://aspire.dev/integrations/frameworks/javascript/) - Fix errors in seed-database-data.md
-
-## Fundamentals
-
-### Updated articles
-
-- [Aspire integrations overview](https://aspire.dev/integrations/overview/) - Documentation for Aspire RavenDB Integration
-- [Aspire setup and tooling](../fundamentals/setup-tooling.md)
- - Add Rancher Desktop details
- - Update setup-tooling.md to latest Aspire version
-- [External parameters](https://aspire.dev/fundamentals/external-parameters/) - Add ReferenceExpression to the External Parameters article
-- [Tutorial: Use the Aspire dashboard with Python apps](https://aspire.dev/dashboard/standalone-for-python/) - Update standalone-for-python.md
-
-## Database
-
-### New articles
-
-- [Aspire Azure SQL Entity Framework Core integration](https://aspire.dev/integrations/cloud/azure/azure-sql-database/)
-- [Aspire Azure SQL integration](https://aspire.dev/integrations/cloud/azure/azure-sql-database/)
-
-### Updated articles
-
-- [Aspire SQL Server Entity Framework Core integration](https://aspire.dev/integrations/databases/sql-server/) - Add Azure SQL integration articles
-- [Aspire SQL Server integration](https://aspire.dev/integrations/databases/sql-server/) - Add Azure SQL integration articles
-- [Apply Entity Framework Core migrations in Aspire](https://aspire.dev/integrations/databases/efcore/migrations/) - Add explanatory notes to the EF Core Migrations tutorial.
-- [Seed data in a database using Aspire](https://aspire.dev/integrations/databases/efcore/seed-database/)
- - Fix errors in seed-database-data.md
- - Update Seed data in database article to 9.2
-
-## Community contributors
-
-The following people contributed to the Aspire docs during this period. Thank you! Learn how to contribute by following the links under "Get involved" in the [what's new landing page](index.yml).
-
-- [alistairmatthews](https://github.com/alistairmatthews) - Alistair Matthews 
-- [Alirexaa](https://github.com/Alirexaa) - Alireza Baloochi 
-- [crisweber2600](https://github.com/crisweber2600) - Cris Weber 
-- [shiranshalom](https://github.com/shiranshalom) - shiranshalom 
diff --git a/docs/whats-new/index.yml b/docs/whats-new/index.yml
index 72db2317c8..e08dc67a1a 100644
--- a/docs/whats-new/index.yml
+++ b/docs/whats-new/index.yml
@@ -12,20 +12,10 @@ landingContent:
linkLists:
- linkListType: whats-new
links:
+ - text: What's new in Aspire 13.1
+ url: https://aspire.dev/whats-new/aspire-13-1/
- text: What's new in Aspire 13.0
url: https://aspire.dev/whats-new/aspire-13/
- - text: What's new in Aspire 9.5
- url: dotnet-aspire-9.5.md
- - text: What's new in Aspire 9.4
- url: dotnet-aspire-9.4.md
- - text: What's new in Aspire 9.3
- url: dotnet-aspire-9.3.md
- - text: What's new in Aspire 9.2
- url: dotnet-aspire-9.2.md
- - text: What's new in Aspire 9.1
- url: dotnet-aspire-9.1.md
- - text: What's new in Aspire 9.0
- url: dotnet-aspire-9.md
- text: Announcing Aspire 8.2
url: https://devblogs.microsoft.com/dotnet/announcing-dotnet-aspire-8-2/
- text: What's new in Aspire 8.1
@@ -60,12 +50,8 @@ landingContent:
linkLists:
- linkListType: whats-new
links:
- - text: June 2025
- url: dotnet-docs-aspire-mod0.md
- - text: May 2025
- url: dotnet-docs-aspire-mod2.md
- - text: April 2025
- url: dotnet-docs-aspire-mod1.md
+ - text: Documentation updates
+ url: https://aspire.dev/whats-new/aspire-13-1/
- title: Find language updates
linkLists:
- linkListType: whats-new
diff --git a/docs/whats-new/toc.yml b/docs/whats-new/toc.yml
index cbd0e2a7cc..3d29027fe0 100644
--- a/docs/whats-new/toc.yml
+++ b/docs/whats-new/toc.yml
@@ -6,20 +6,10 @@ items:
- name: Latest product updates
expanded: true
items:
+ - name: What's new in Aspire 13.1
+ href: https://aspire.dev/whats-new/aspire-13-1/
- name: What's new in Aspire 13.0
href: https://aspire.dev/whats-new/aspire-13/
- - name: What's new in Aspire 9.5
- href: dotnet-aspire-9.5.md
- - name: What's new in Aspire 9.4
- href: dotnet-aspire-9.4.md
- - name: What's new in Aspire 9.3
- href: dotnet-aspire-9.3.md
- - name: What's new in Aspire 9.2
- href: dotnet-aspire-9.2.md
- - name: What's new in Aspire 9.1
- href: dotnet-aspire-9.1.md
- - name: What's new in Aspire 9.0
- href: dotnet-aspire-9.md
- name: Announcing Aspire 8.2
href: https://devblogs.microsoft.com/dotnet/announcing-dotnet-aspire-8-2/
- name: What's new in Aspire 8.1
@@ -53,9 +43,5 @@ items:
- name: Latest documentation updates
expanded: true
items:
- - name: June 2025
- href: dotnet-docs-aspire-mod0.md
- - name: May 2025
- href: dotnet-docs-aspire-mod2.md
- - name: April 2025
- href: dotnet-docs-aspire-mod1.md
+ - name: Documentation updates
+ href: https://aspire.dev/whats-new/aspire-13-1/