.NET Aspire orchestration overview
.NET Aspire provides APIs for expressing resources and dependencies within your distributed application. In addition to these APIs, there's tooling that enables some compelling scenarios. The orchestrator is intended for local development purposes.
Before continuing, consider some common terminology used in .NET Aspire:
- App model: A collection of resources that make up your distributed application (DistributedApplication). For a more formal definition, see Define the app model.
- App host/Orchestrator project: The .NET project that orchestrates the app model, named with the *.AppHost suffix (by convention).
- Resource: A resource represents a part of an application whether it be a .NET project, container, or executable, or some other resource like a database, cache, or cloud service (such as a storage service).
- Reference: A reference defines a connection between resources, expressed as a dependency using the
WithReference
API. For more information, see Reference resources.
Note
.NET Aspire's orchestration is designed to enhance your local development experience by simplifying the management of your cloud-native app's configuration and interconnections. While it's an invaluable tool for development, it's not intended to replace production environment systems like Kubernetes, which are specifically designed to excel in that context.
Define the app model
.NET Aspire empowers you to seamlessly build, provision, deploy, configure, test, run, and observe your cloud application. This is achieved through the utilization of an app model that outlines the resources in your app and their relationships. These resources encompass projects, executables, containers, as well as external services and cloud resources that your app depends on. Within every .NET Aspire project, there is a designated App host project, where the app model is precisely defined using methods available on the IDistributedApplicationBuilder. This builder is obtained by invoking DistributedApplication.CreateBuilder.
App host project
The app host project handles running all of the projects that are part of the .NET Aspire project. In other words, it's responsible for orchestrating all apps within the app model. The following code describes an application with two projects and a Redis cache:
var builder = DistributedApplication.CreateBuilder(args);
var cache = builder.AddRedis("cache");
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithReference(cache)
.WithReference(apiservice);
builder.Build().Run();
To help visualize the relationship between the app host project and the resources it describes, consider the following diagram:
Each resource must be uniquely named. This diagram shows each resource and the relationships between them. The container resource is named "cache" and the project resources are named "apiservice" and "webfrontend". The web frontend project references the cache and API service projects. By expressing a reference in this way, the web frontend project is saying that it depends on these two resources.
Built-in resource types
.NET Aspire projects are made up of a set of resources. There are three base types of compute resources:
Method | Resource type | Description |
---|---|---|
AddProject | ProjectResource | A .NET project, for example ASP.NET Core web apps. |
AddContainer | ContainerResource | A container image, such as a Docker image. |
AddExecutable | ExecutableResource | An executable file. |
Project resources are .NET projects that are part of the app model. When you add a project reference to the app host project, the app host generates a type in the Projects
namespace for each referenced project.
To add a project to the app model, use the AddProject method:
// Adds the project "apiservice" of type "Projects.AspireApp_ApiService".
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
Reference resources
A reference represents a dependency between resources. Consider the following:
var cache = builder.AddRedis("cache");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithReference(cache);
The "webfrontend" project resource uses WithReference to add a dependency on the "cache" container resource. These dependencies can represent connection strings or service discovery information. In the preceding example, an environment variable is injected into the "webfronend" resource with the name ConnectionStrings__cache
. This environment variable contains a connection string that the webfrontend can use to connect to redis via the .NET Aspire Redis component, for example, ConnectionStrings__cache="localhost:62354"
.
Connection string and endpoint references
It's also possible to have dependencies between project resources. Consider the following example code:
var cache = builder.AddRedis("cache");
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice");
builder.AddProject<Projects.AspireApp_Web>("webfrontend")
.WithReference(cache)
.WithReference(apiservice);
Project-to-project references are handled differently than resources that have well defined connection strings. Instead of connection string being injected into the "webfrontend" resource, environment variables to support service discovery are injected.
Method | Environment variable |
---|---|
WithReference(cache) |
ConnectionStrings__cache="localhost:62354" |
WithReference(apiservice) |
services__apiservice__http__0="http://localhost:5455" services__apiservice__https__0="https://localhost:7356" |
Adding a reference to the "apiservice" project results in service discovery environment variables being added to the front-end. This is because typically, project to project communication occurs over HTTP/gRPC. For more information, see .NET Aspire service discovery.
It's possible to get specific endpoints from a container or executable using the WithEndpoint and calling the GetEndpoint:
var customContainer = builder.AddContainer("myapp", "mycustomcontainer")
.WithHttpEndpoint(port: 9043, name: "endpoint");
var endpoint = customContainer.GetEndpoint("endpoint");
var apiservice = builder.AddProject<Projects.AspireApp_ApiService>("apiservice")
.WithReference(endpoint);
Method | Environment variable |
---|---|
WithReference(endpoint) |
services__myapp__endpoint__0=https://localhost:9043 |
The port
parameter is the port that the container is listening on. For more information on container ports, see Container ports. For more information on service discovery, see .NET Aspire service discovery.
Service endpoint environment variable format
In the preceding section, the WithReference
method is used to express dependencies between resources. When service endpoints result in environment variables being injected into the dependent resource, the format may not be obvious. This section provides details on this format.
When one resource depends on another resource, the app host injects environment variables into the dependent resource. These environment variables configure the dependent resource to connect to the resource it depends on. The format of the environment variables is specific to .NET Aspire and expresses service endpoints in a way that is compatible with Service Discovery.
Service endpoint environment variables start with services
and are delimited by a double underscore __
. They're prefixed with services__
, followed by the service name, the service endpoint name or protocol, and the index. The index supports multiple endpoints for a single service, starting with 0
for the first endpoint and incrementing for each additional endpoint.
Consider the following environment variable examples:
services__apiservice__http__0
The preceding environment variable expresses the first HTTP endpoint for the apiservice
service. The value of the environment variable is the URL of the service endpoint. A named endpoint might be expressed as follows:
services__apiservice__myendpoint__0
In the preceding example, the apiservice
service has a named endpoint called myendpoint
. The value of the environment variable is the URL of the service endpoint.
APIs for adding and expressing resources
.NET Aspire hosting packages and .NET Aspire components are both delivered as NuGet packages, but they serve different purposes. While components provide client library configuration for consuming apps outside the scope of the app host, hosting packages provide APIs for expressing resources and dependencies within the app host.
Express container resources
To express a container resource, use the AddContainer method:
var builder = DistributedApplication.CreateBuilder(args);
var ollama = builder.AddContainer("ollama", "ollama/ollama")
.WithBindMount("ollama", "/root/.ollama")
.WithBindMount("./ollamaconfig", "/usr/config")
.WithHttpEndpoint(port: 11434, targetPort: 11434, name: "ollama")
.WithEntrypoint("/usr/config/entrypoint.sh")
.WithContainerRunArgs("--gpus=all");
For more information, see GPU support in Docker Desktop.
The preceding code adds a container resource named "ollama" with the image "ollama/ollama". The container resource is configured with multiple bind mounts, a named HTTP endpoint, an entrypoint that resolves to Unix shell script, and container run arguments with the WithContainerRuntimeArgs method.
Beyond the base resource types, ProjectResource, ContainerResource, and ExecutableResource, .NET Aspire provides extension methods to add common resources to your app model. The following table lists the methods and their corresponding resource types:
Cloud-agnostic resources are available in the following NuGet packages:
- 📦 Aspire.Hosting.Kafka
- 📦 Aspire.Hosting.MongoDB
- 📦 Aspire.Hosting.MySql
- 📦 Aspire.Hosting.Nats
- 📦 Aspire.Hosting.NodeJs
- 📦 Aspire.Hosting.Oracle
- 📦 Aspire.Hosting.Orleans
- 📦 Aspire.Hosting.PostgreSQL
- 📦 Aspire.Hosting.RabbitMQ
- 📦 Aspire.Hosting.Redis
- 📦 Aspire.Hosting.Seq
- 📦 Aspire.Hosting.SqlServer
Method | Resource type | Description |
---|---|---|
AddMongoDB(...) |
MongoDBServerResource |
Adds a MongoDB server resource. |
AddMySql(...) |
MySqlServerResource |
Adds a MySql server resource. |
AddNodeApp(...) |
NodeAppResource |
Adds a Node.js app resource. |
AddNpmApp(...) |
NodeAppResource |
Adds a Node.js app resource that wraps an NPM package. |
AddPostgres(...). AddDatabase |
PostgresDatabaseResource | Adds a Postgres database resource. |
AddSqlServer(...). AddDatabase |
SqlServerDatabaseResource | Adds a SQL Server database resource. |
AddPostgres | PostgresServerResource | Adds a Postgres server resource. |
AddRabbitMQ | RabbitMQServerResource | Adds a RabbitMQ server resource. |
AddRedis | RedisResource | Adds a Redis container resource. |
AddSqlServer | SqlServerServerResource | Adds a SQL Server server resource. |
Azure specific resources are available in the following NuGet packages:
- 📦 Aspire.Hosting.Azure.AppConfiguration
- 📦 Aspire.Hosting.Azure.ApplicationInsights
- 📦 Aspire.Hosting.Azure.CognitiveServices
- 📦 Aspire.Hosting.Azure.CosmosDB
- 📦 Aspire.Hosting.Azure.EventHubs
- 📦 Aspire.Hosting.Azure.KeyVault
- 📦 Aspire.Hosting.Azure.OperationalInsights
- 📦 Aspire.Hosting.Azure.PostgreSQL
- 📦 Aspire.Hosting.Azure.Redis
- 📦 Aspire.Hosting.Azure.Search
- 📦 Aspire.Hosting.Azure.ServiceBus
- 📦 Aspire.Hosting.Azure.SignalR
- 📦 Aspire.Hosting.Azure.Sql
- 📦 Aspire.Hosting.Azure.Storage
Method | Resource type | Description |
---|---|---|
AddAzureStorage | AzureStorageResource | Adds an Azure Storage resource. |
AddAzureStorage(...). AddBlobs |
AzureBlobStorageResource | Adds an Azure Blob Storage resource. |
AddAzureStorage(...). AddQueues |
AzureQueueStorageResource | Adds an Azure Queue Storage resource. |
AddAzureStorage(...). AddTables |
AzureTableStorageResource | Adds an Azure Table Storage resource. |
AddAzureCosmosDB | AzureCosmosDBResource | Adds an Azure Cosmos DB resource. |
AddAzureKeyVault | AzureKeyVaultResource | Adds an Azure Key Vault resource. |
AddRedis(...) .AsAzureRedis |
AzureRedisResource | Configures resource to use Azure for local development and when doing a deployment via the Azure Developer CLI. |
AddSqlServer(...) .AsAzureSqlDatabase |
AzureSqlServerResource | Configures SQL Server resource to be deployed as Azure SQL Database (server). |
AddAzureServiceBus | AzureServiceBusResource | Adds an Azure Service Bus resource. |
Important
The .NET Aspire Azure hosting libraries rely on Azure.Provisioning.*
libraries to provision Azure resources. For more information, Azure provisioning libraries.
AWS specific resources are available in the following NuGet package:
For more information, see GitHub: Aspire.Hosting.AWS library.
Execution context
The IDistributedApplicationBuilder exposes an execution context (DistributedApplicationExecutionContext), which provides information about the current execution of the app host. This context can be used to evaluate whether or not the app host is executing as "run" mode, or as part of a publish operation. Consider the following:
- IsRunMode: Returns
true
if the current operation is running. - IsPublishMode: Returns
true
if the current operation is publishing.
This information can be useful when you want to conditionally execute code based on the current operation. Consider the following example that demonstrates using the IsRunMode
property. In this case, an extension method is used to generate a stable node name for RabbitMQ for local development runs.
private static IResourceBuilder<RabbitMQServerResource> RunWithStableNodeName(
this IResourceBuilder<RabbitMQServerResource> builder)
{
if (builder.ApplicationBuilder.ExecutionContext.IsRunMode)
{
builder.WithEnvironment(context =>
{
// Set a stable node name so queue storage is consistent between sessions
var nodeName = $"{builder.Resource.Name}@localhost";
context.EnvironmentVariables["RABBITMQ_NODENAME"] = nodeName;
});
}
return builder;
}
See also
.NET Aspire
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for