microsoft / microsoft/aspire

Support Kestrel endpoint configuration for Aspire-defined endpoints

Open
#18,847 1 comment 0 reactions 0 assignees View on GitHub
area-app-model triage:bot-seen
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 15h
Merged PRs (30d)
196

Description

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Is your feature request related to a problem? Please describe the problem.

I'm using Aspire to configure multiple named endpoints for an ASP.NET Core application:

```csharp
builder.AddProject("webapi")
.WithEndpoint("Api", scheme: "https")
.WithEndpoint("Management", scheme: "https");
````

The application relies on named Kestrel endpoints (for example to distinguish logical endpoints such as "Api" and "Management" inside the application).

Today Aspire only generates the following environment variables:

```
Kestrel__Endpoints__{Name}__Url
```

when Kestrel endpoints already exist in the application's configuration (appsettings.json).

Internally this happens because `SetKestrelUrlOverrideEnvVariables()` only runs when `ProjectResource.HasKestrelEndpoints` is true. `HasKestrelEndpoints` is currently derived from Kestrel endpoints discovered in configuration:

```csharp
internal bool HasKestrelEndpoints => KestrelEndpointAnnotationHosts.Count > 0;
```

As a result, applications that define endpoints entirely in Aspire never receive any `Kestrel__Endpoints__*__Url` environment variables.

This makes it impossible to configure named Kestrel endpoints purely from Aspire, even though the endpoint information already exists in the Aspire application model.

The current workaround is to manually generate these environment variables:

```csharp
app.WithEnvironment(context =>
{
foreach (var endpoint in app.Resource.GetEndpoints())
{
var url = ReferenceExpression.Create(
$"{endpoint.EndpointAnnotation.UriScheme}://localhost:{endpoint.Property(EndpointProperty.TargetPort)}");

context.EnvironmentVariables[
$"Kestrel__Endpoints__{endpoint.EndpointAnnotation.Name}__Url"] = url;
}
})
.WithEnvironment("ASPNETCORE_URLS", "");
```

This works correctly, but duplicates logic that Aspire already contains internally.

### Describe the solution you'd like

I'd like Aspire to provide an official way to generate Kestrel endpoint override environment variables for endpoints defined with `WithEndpoint(...)`, even when no `Kestrel:Endpoints` section exists in the application's configuration.

One possible approach would be introducing an opt-in API, for example:

```csharp
var app = builder.AddProject("webapplication3", options =>
{
options.GenerateKestrelEndpoints = true;
})
.WithEndpoint(name: "Api", scheme: "https")
.WithEndpoint(name: "Management", scheme: "https");
```

or a similar option that enables generation of:

```
Kestrel__Endpoints__Api__Url
Kestrel__Endpoints__Management__Url
```

from the Aspire endpoint model.

Keeping this behavior opt-in would avoid changing existing Aspire applications while allowing applications to be configured entirely from Aspire without requiring duplicate Kestrel configuration in appsettings.json.

### Additional context

I investigated the implementation and found that Aspire already contains almost all of the required logic.

`SetKestrelUrlOverrideEnvVariables()` already generates the correct environment variables, but it only executes when `ProjectResource.HasKestrelEndpoints` is true.

`HasKestrelEndpoints` is currently based on endpoints discovered from the application's `Kestrel:Endpoints` configuration.

In other words, if endpoints are defined only via `WithEndpoint(...)`, Aspire already knows about them but intentionally skips generating the Kestrel override environment variables.

An opt-in mechanism to reuse the existing implementation for code-defined Aspire endpoints would solve this scenario without changing the default behavior.

A related discussion was already raised in https://github.com/microsoft/aspire/issues/3456, specifically in https://github.com/microsoft/aspire/issues/3456#issuecomment-2114393059.

That discussion focused on the interaction between Aspire endpoint management and existing Kestrel endpoint configuration. The main point was that Kestrel endpoints have higher priority over `ASPNETCORE_URLS`, and when Kestrel endpoints are explicitly configured, they become the source of truth for the addresses Kestrel listens on.

In Aspire, this creates a challenge because Aspire normally provides dynamically assigned ports through `ASPNETCORE_URLS` and uses its own endpoint model/reverse proxy layer. If an application defines Kestrel endpoints, Aspire needs to synchronize those endpoints with the application to ensure the proxy and the actual Kestrel listeners remain aligned.

The issue described here is related but focuses on the opposite direction: when endpoints are defined only through Aspire (`WithEndpoint(...)`) and no `Kestrel:Endpoints` configuration exists, Aspire already has the endpoint metadata but does not expose it to the application as Kestrel endpoint configuration.

Providing an opt-in mechanism to generate Kestrel endpoint override environment variables from Aspire-defined endpoints would make these two models work consistently and allow applications to use named Kestrel endpoints without duplicating configuration in appsettings.json.

Contributor guide

Open the contributing guide

Research direction

Start with SetKestrelUrlOverrideEnvVariables(), ProjectResource.HasKestrelEndpoints, and KestrelEndpointAnnotationHosts, then trace how AddProject() and WithEndpoint() populate the application model. Confirm the existing behavior for configuration-defined Kestrel endpoints, then verify that an opt-in path generates Kestrel__Endpoints__{Name}__Url for Aspire-defined endpoints without changing the default behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend, cloud
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.