Skip to content

Support Kestrel endpoint configuration for Aspire-defined endpoints #18847

Description

@egorov-denis

Is there an existing issue for this?

  • 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:

builder.AddProject<Projects.WebApi>("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:

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:

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:

var app = builder.AddProject<Projects.WebApplication3>("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 #3456, specifically in #3456 (comment).

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-app-modelIssues pertaining to the APIs in Aspire.Hosting, e.g. DistributedApplicationtriage:bot-seenAspire triage bot has seen this issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions