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