dotnet / docs-aspire

This repository contains .NET Aspire documentation.
https://learn.microsoft.com/dotnet/aspire
MIT License
87 stars 113 forks source link

.NET Aspire Preview 4 Release Notes checklist #435

Closed bradygaster closed 8 months ago

bradygaster commented 9 months ago

cc @mitchdenny @eerhardt @davidfowl @IEvangelist @DamianEdwards

This is a checklist issue for us to keep track of all the items we need to document in a single (optimally) release notes post for preview 4. We know this preview will have some significant updates and potential adjustments for customers, so let's use this issue to track the list of things we'll need to cover so we don't forget anything.

davidfowl commented 9 months ago

.NET Aspire preview 4

Toggle Collapse .NET Aspire preview 4 introduces lots of new improvements to various parts of the stack including addressing some of the most requested features from the community. ## Podman support .NET Aspire preview 4 introduces support for running applications using Podman. Podman is a daemonless container engine for developing, managing, and running OCI Containers on your Linux System. It's a great alternative to Docker for Linux users who want to run containers without a daemon. Docker or Podman will be auto-detected; if both are present, Docker is preferred. Podman can be explicitly enabled/forced via an environment variable `DOTNET_ASPIRE_CONTAINER_RUNTIME=podman`. ## Dashboard ### Dashboard face lift ![Dashboard UI](https://github.com/dotnet/docs-aspire/assets/95136/e6bc64bd-b0c2-40ab-abd0-8925406cba38) TODO: Words about the UI changes. ### Running the Aspire dashboard standalone The Aspire dashboard can now be run as a standalone container image. This makes it easier to use the dashboard to manage applications that are running on a different machine or in a different environment. The dashboard can be used as an [OTLP](https://opentelemetry.io/docs/specs/otlp/) collector and viewer for applications that want to send and visualize telemetry data. Here's the command you can run to start the dashboard: ```bash docker run --rm -it -p 18888:18888 -p 4317:18889 -d --name aspire-dashboard mcr.microsoft.com/dotnet/nightly/aspire-dashboard:8.0.0-preview.4 ``` ![Aspire dashboard running in Docker Desktop](https://github.com/dotnet/docs-aspire/assets/95136/084c5bdf-e749-41f8-bbfb-c2ca52060ac6) There are 2 ports that are exposed: 1. The port that serves the dashboard UI (18888) 2. The port that serves the OTLP grpc endpoint (18889) That will bring up a dashboard that you can use view logs, metrics, and traces from your applications. Here's a sample application that sends telemetry data to the dashboard. TODO: Sample pointing to the dashboard. (@drewnoakes @JamesNK @kvenkatrajan) ### Dashboard shortcuts TODO (@adamint @kvenkatrajan @JamesNK) ### Metrics table view TODO (@adamint @kvenkatrajan @JamesNK) ## Entity Framwork and Aspire TODO: Changes to EF based components (@sebastienros @eerhardt) TODO: Migration tooling guidance (@JamesNK) ## New standalone project templates You can now create a .NET Aspire AppHost project and the ServiceDefaults projects. This lets you add either one to an existing project without having to use all of the features of .NET Aspire. **dotnet CLI** ![New project templates CLI](https://github.com/dotnet/docs-aspire/assets/95136/7a6d7a54-1a41-417e-91b8-4d6fe32e06a8) **Visual Studio** ![Visual Studio project templates](https://github.com/dotnet/docs-aspire/assets/95136/162cb0e8-bf0f-4deb-a420-fa47a6dd2a82) ## Changes to container resources In .NET Aspire preview 3 for container resources, we introduced `AddXX` and `AddXXContainer`. We've removed `AddXXContainer` and have a single method `AddXX` to add a container resource: ```C# var builder = DistributedApplication.CreateBuilder(args); var redis = builder.AddRedis("redis"); builder.AddProject("api") .WithReference(redis); builder.Build().Run(); ``` These resources are always containers, they will run locally as containers and will be deployed as containers. We've removed the notion of "abstract resources" that can morph between running locally and deploying. The representation in the manifest for these resources is `container.v0`. ```JSON { "resources": { "redis": { "type": "container.v0", "connectionString": "{redis.bindings.tcp.host}:{redis.bindings.tcp.port}", "image": "redis:7.2.4", "bindings": { "tcp": { "scheme": "tcp", "protocol": "tcp", "transport": "tcp", "containerPort": 6379 } } } } } ``` This makes it easier for deployment tools to support a wide range of scenarios without having to understand the nuances of different resource types. ## Parameters Parameters express the ability to ask for an external value when running the application. Parameters can be used to provide values to the application when running locally, or to prompt for values when deploying. They can be used to model a wide range of scenarios including secrets, connection strings, and other configuration values that might vary between environments. ### Parameter Values Parameter values are read from the "Parameters" section of the apphost's configuration and can be used to provide values to the application when running locally. When deploying the application, the value will be asked for the parameter value. **Program.cs** ```C# var builder = DistributedApplication.CreateBuilder(args); var value = builder.AddParameter("value"); builder.AddProject("api") .WithEnvironment("SOME_VALUE", value); ``` **appsettings.json** ```JSON { "Parameters": { "value": "local-value" } } ``` Parameters are represented in the manifest as a new primitive called `parameter.v0`. ```JSON { "resources": { "value": { "type": "parameter.v0", "value": "{value.inputs.value}", "inputs": { "value": { "type": "string" } } } } } ``` ### Secrets Parameters can be used to model secrets. When a parameter is marked as a secret, this is a hint to the manifest that the value should be treated as a secret. When deploying, the value will be prompted for and stored in a secure location. When running locally, the value will be read from the "Parameters" section of the app host configuration. **Program.cs** ```C# var builder = DistributedApplication.CreateBuilder(args); var secret = builder.AddParameter("secret", secret: true); builder.AddProject("api") .WithEnvironment("SECRET", secret); builder.Build().Run(); ``` **appsettings.json** ```JSON { "Parameters": { "secret": "local-secret" } } ``` Manifest representation: ```JSON { "resources": { "value": { "type": "parameter.v0", "value": "{value.inputs.value}", "inputs": { "value": { "type": "string", "secret": true } } } } } ``` ### Connection Strings Parameters can be used to model connection strings. When deploying, the value will be prompted for and stored in a secure location. When running locally, the value will be read from the "ConnectionStrings" section of the app host configuration. *NOTE: Connection strings are used to represent a wide range of connection information including database connections, message brokers, and other services. In Aspire nomenclature, we use the term "connection string" to represent any kind of connection information.* **Program.cs** ```C# { var builder = DistributedApplication.CreateBuilder(args); var redis = builder.AddConnectionString("redis"); builder.AddProject("api") .WithReference(redis); builder.Build().Run(); } ``` **appsettings.json** ```JSON { "ConnectionStrings": { "redis": "local-connection-string" } } ``` Manifest representation: ```JSON { "resources": { "redis": { "type": "parameter.v0", "connectionString": "{redis.value}", "value": "{redis.inputs.value}", "inputs": { "value": { "type": "string", "secret": true } } } } } ``` ## New Idioms ### DistributedApplicationExecutionContext The `DistributedApplicationExecutionContext` is a new type that provides information about the current execution context. It can be used to determine if the application is being orchestrated running locally or if it is being use to published the manifest. This can be useful when building the application model. For example, you might want to use a different message broker when running locally than when deploying. ```C# var builder = DistributedApplication.CreateBuilder(args); if (builder.ExecutionContext.IsPublishMode) { // Do something when running in publish mode } else { // Do something when running locally } ``` The `DistributedApplicationExecutionContext` is also available in the DI container and can be used to determine the execution context when resolving services. ### PublishAs/RunAs/As .NET Aspire preview 4 introduces new idioms for describing common scenarios for modeling how resources are used when running locally and when deploying. While it's possible to model these scenarios using the `DistributedApplicationExecutionContext`, the new idioms make it easier to express these common scenarios. `RunAsXX` - Only affect the model when running locally. `PublishAsXX` - Only affect the model when publishing the manifest. `AsXX` - Affect the model when running locally and when publishing the manifest. #### Examples The following logic will use a redis container locally and prompt for the connection string when deploying. ```C# var builder = DistributedApplication.CreateBuilder(args); var redis = builder.AddRedis("redis") .PublishAsConnectionString(); builder.AddProject("api") .WithReference(redis); builder.Build().Run(); ``` ## General Application Model Improvements ### Changing container properties We added some new methods to tweak container images, tags and volumes. Here's an example of using the redis image from Microsoft's container registry instead of the default image from DockerHub. ```C# var builder = DistributedApplication.CreateBuilder(args); var redis = builder.AddRedis("redis") .WithImage("mcr.microsoft.com/cbl-mariner/base/redis") .WithImageTag("6.2-cm2.0"); builder.AddProject("api") .WithReference(redis); builder.Build().Run(); ``` ### Splitting bind mounts and volumes into separate methods Splitting bind mounts and volumes into separate methods. Bind mounts are used to mount a file or directory from the host into the container. Volumes are used to mount a volume from the host into the container. Splitting these into separate methods makes it easier to understand how the container is being used. ```C# var builder = DistributedApplication.CreateBuilder(args); var catalogDbName = "catalog"; // MySql database & table names are case-sensitive on non-Windows. var catalogDb = builder.AddMySql("mysql") .WithEnvironment("MYSQL_DATABASE", catalogDbName) .WithBindMount("../MySql.ApiService/data", "/docker-entrypoint-initdb.d") .AddDatabase(catalogDbName); builder.AddProject("api") .WithReference(catalogDb); builder.Build().Run(); ``` ### Addition of more database admin tools .NET Aspire Preview 3 introduced the ability to manage postgres databases using pgAdmin and redis using redis commander. Preview 4 introduces the ability to manage MySql databases using phpMyAdmin, and MongoDB databases using mongo-express. ```C# var builder = DistributedApplication.CreateBuilder(args); var mongo = builder.AddMongoDB("mongo") .WithMongoExpress() .AddDatabase("db"); var mySql = builder.AddMySql("mysql") .WithPhpMyAdmin() .AddDatabase("catalog"); builder.AddProject("api") .WithReference(mongo) .WithReference(mySql); builder.Build().Run(); ``` ## Ability to ignore launch profiles Sometimes you might want to ignore launch profiles when running the application. This can be useful when you want to define your own environment or endpoints when running the application. **NOTE: This will ignore the entire launch profile, including environment variables and other defaults.** ```C# var builder = DistributedApplication.CreateBuilder(args); builder.AddProject("api") .WithEnvironment("ASPNETCORE_ENVIRONMENT", "Development") .WithHttpEndpoint() .ExcludeLaunchProfile(); builder.Build().Run(); ``` ## Ability to disable endpoint proxies Any resource with an endpoint today uses a tcp proxy to route traffic to the resource. This is useful for several reasons: 1. The proxy can be used hold connection until the underlying resource is ready. 2. The proxy can be used to route traffic between different replicas of a resource. This gives consumers a stable endpoint to connect to. Proxies may not always be desirable. If the application already has a port allocated that cannot be configured outside of the application then it's crucial to disable the proxy. ```C# var builder = DistributedApplication.CreateBuilder(args); builder.AddProject("api") .WithEndpoint("http", e => e.IsProxied = false); builder.Build().Run(); ``` The above example will disable the proxy for the http endpoint defined in the launch profile. This means that the application will be responsible for managing the port and ensuring that it is available when the application starts. ## Azure This release saw an overhaul of the Azure resources shipped in .NET Aspire. We've introduced a new bicep resource that makes it easier to model a wide range of Azure services. These changes are encapsulated in the **Aspire.Hosting.Azure** package. ### New Resources and Components We've added a few new Azure based resources: - [Azure SignalR](https://azure.microsoft.com/en-us/services/signalr-service/) - [Azure AI Search](https://azure.microsoft.com/en-us/services/search/) - [Azure Application Insights](https://azure.microsoft.com/en-us/products/monitor/) (@samsp-msft) TODO: Show sample usage of these resources. ### Containers with Azure Resource mappings Several services that are available as containers have fully managed Azure equivalents. We've added the ability to map a container to an Azure resource. This makes it possible to develop and test using a container and then deploy using a fully managed Azure resource that will be provisioned as part of the deployment process. We've enabled this for the following services: - Redis - [Azure Redis](https://azure.microsoft.com/en-us/products/cache/) - Postgres - [Azure Database for PostgreSQL](https://azure.microsoft.com/en-us/services/postgresql/) - SQL Server - [Azure SQL Database](https://azure.microsoft.com/en-us/services/sql-database/) We plan to add support for the following services in the future: - MySql - [Azure Database for MySQL](https://azure.microsoft.com/en-us/services/mysql/) - MongoDb - [Azure Cosmos DB](https://azure.microsoft.com/en-us/services/cosmos-db/) - Kafka - [Azure Event Hubs](https://azure.microsoft.com/en-us/services/event-hubs/) ***Example: Redis*** ```C# var builder = DistributedApplication.CreateBuilder(args); var redis = builder.AddRedis("redis") .PublishAsAzureRedis(); builder.AddProject("api") .WithReference(redis); builder.Build().Run(); ``` NOTE: It is possible to use an existing Azure resource by providing the connection string and using `AddConnectionString`. This assumes that the resource has already been provisioned, that the resource is accessible from the development environment: ```C# var builder = DistributedApplication.CreateBuilder(args); var redis = builder.AddConnectionString("redis"); builder.AddProject("api") .WithReference(redis); builder.Build().Run(); ``` ### Azure Bicep Resource We've introduced a new primitive to model Azure Bicep modules in the application model. This makes it easier to model any set of azure resources that can be modeled using bicep. We've rebuilt the azure resources to use the new bicep primitive. Bicep files can be expressed as literal strings, embedded resources or files on disk (relative to the apphost). You can learn more about bicep [here](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview?tabs=bicep). **Program.cs** ```C# var builder = DistributedApplication.CreateBuilder(args); var bicep = builder.AddBicepTemplateString("bicep", "test.bicep") .WithParameter("param1", "value1") .WithParameter("param2", "value2"); builder.AddProject("api") .WithEnvironment("BICEP_OUTPUT", bicep.GetOutput("both")); builder.Build().Run(); ``` **test.bicep** ```bicep param param1 string param param2 string param location string output both string = '${param1} ${param2}' ``` Manifest representation: ```JSON { "resources": { "bicep": { "type": "azure.bicep.v0", "path": "test.bicep", "parameters": { "param1": "value1", "param2": "value2" } }, "api": { "type": "project.v0", "path": "../WebApplication1/WebApplication1.csproj", "env": { "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true", "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true", "BICEP_OUTPUT": "{bicep.outputs.both}" }, "bindings": { "http": { "scheme": "http", "protocol": "tcp", "transport": "http" }, "https": { "scheme": "https", "protocol": "tcp", "transport": "http" } } } } } ``` As you can see, the manifest captures both the parameters and the usage of the bicep output in the environment variables of the project. ## Emulators In .NET Aspire preview 3, we introduced the ability to run emulators for various services. We've changed the APIs to match with the idioms described earlier in this document: **Azurite: Azure storage emulator** ```C# var builder = DistributedApplication.CreateBuilder(args); var blobs = builder.AddAzureStorage("storage") .RunAsEmulator() .AddBlobs("blobs"); builder.AddProject("api") .WithReference(blobs); builder.Build().Run(); ``` Each `RunAsEmulator` method has a callback that enables customization of the emulator container resource. For example, you can change the image, tag, or add additional volumes. **Azure storage emulator (Azurite)** ```C# var storage = builder.AddAzureStorage("storage").RunAsEmulator(container => { container.UsePersistence(); }); ``` **CosmosDB emulator** ```C# var builder = DistributedApplication.CreateBuilder(args); var db = builder.AddAzureCosmosDB("cosmos") .RunAsEmulator() .AddDatabase("db"); builder.AddProject("api") .WithReference(db); builder.Build().Run(); ``` ## The deployment manifest The aspire manifest has undergone a significant overhaul to support the new primitives and introduced in preview 4. The new manifest focuses on a few key primitives to enable a wide range of scenarios: | Resource Type | Description | | --- | --- | | project.v0 | .NET project files | | container.v0 | Container images | | dockerfile.v0 | Docker files | | parameter.v0 | External Parameters | | value.v0 | References to other resources (or a combination of resources) | ### Azure specific Resources | Resource Type | Description | | --- | --- | | azure.bicep.v0 | Azure Bicep templates | Tool authors can support this very small set of resource types to model lots of different apps! We've deprecated the abstract resource types that were supported in previous versions. Deployment tools may still support those resource types, but they are no longer part of the core manifest schema. ### Visual Studio Publish to Azure This release we've enabled a Visual Studio publish experience for Aspire applications. TODO: Deployment to Azure via Visual Studio support (@bradygaster @timheuer) ## Azure Developer CLI The Azure Developer CLI (azd) has been updated to support the new manifest types introduced in preview 4. Azd supports prompting for parameter resources, and supports the bicep resource which enables deploying any thing can be described using a bicep module. In addition to new features, azd will automatically create secrets in Azure Container Apps for any parameter marked as a secret, and any environment variable that references a secret or uses a connection string. TODO: Expand with images
eerhardt commented 9 months ago

@davidfowl - I removed Azure OpenAI because we added that last time - https://learn.microsoft.com/en-us/dotnet/aspire/whats-new/preview-3

davidfowl commented 9 months ago

Everyone mentioned should add a comment and I can integrate it into the set of notes. We don't need concurrency issues updating this issue 😄

eerhardt commented 9 months ago

Maybe make it a PR with a markdown file, and we don't merge it?

Then people can just add suggestions and merge the separate commits.

davidfowl commented 9 months ago

@IEvangelist can you guide? Where should this go?

eerhardt commented 9 months ago

We have https://github.com/dotnet/docs-aspire/blob/main/docs/whats-new/preview-3.md. Could just make a preview-4.md file there.

IEvangelist commented 9 months ago

See #440