microsoft / microsoft/aspire

Project resource waits on itself when referencing its own container-to-host endpoint

Open
#19,896 1 comment 0 reactions 0 assignees View on GitHub
area-integrations
Dominant language
C#
Stars
6.3k
Forks
991
Avg merge
2d 12h
Merged PRs (30d)
201

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 have a peculiar use case. We have used Consul for service discovery and now continue using it with Aspire.

I have built a sample repo to illustrate the use case - https://github.com/Niksson/AspireProjectContainerEndpointSelfReferenceSample

There are 3 services in the host model:
1. Consul itself as `ContainerResource`
2. A `gateway` that uses Consul to forward the request to another downstream service
3. An actual `weather` service that serves the request

If you start the AppHost project, the `weather` service will hang in `Starting` state, with the following message:
```
Waiting for endpoint 'http' on resource 'weather' for the 'aspire-container-network' network
```

### Describe the solution you'd like

In this case I want to inject a project's own container-to-host endpoint as environment variable. Otherwise I need to inject a hardcoded `host.docker.internal`, see explanation below.

### Additional context

Suppose we register service in consul like this:
```csharp
string serviceHost = app.Configuration["Consul:ServiceHost"];
int servicePort = app.Configuration.GetSection("Consul:ServicePort").Get();

string healthCheckScheme = app.Configuration["Consul:HealthCheckScheme"];
string healthCheckHost = app.Configuration["Consul:HealthCheckHost"];
int healthCheckPort = app.Configuration.GetSection("Consul:HealthCheckPort").Get();

string healthCheckUri = $"{healthCheckScheme}://{healthCheckHost}:{healthCheckPort}/health";

IConsulClient consulClient = app.Services.GetRequiredService();

var registration = new AgentServiceRegistration()
{
ID = "gateway-1",
Name = "gateway",
Address = serviceHost,
Port = servicePort,
Tags = [],
Checks =
[
new AgentCheckRegistration()
{
HTTP = healthCheckUri,
// ...
}
]
};
```

Initially I injected the variables as follows, and it works as expected - host will be `localhost` and port will be whatever Aspire assigns:
```csharp
var weatherEndpoint= weather.GetEndpoint("http");
weather
.WithEnvironment("Consul:ServiceHost", weatherEndpoint.Property(EndpointProperty.Host))
.WithEnvironment("Consul:ServicePort", weatherEndpoint.Property(EndpointProperty.Port))
.WithEnvironment("Consul:HealthCheckScheme", "http")
.WithEnvironment("Consul:HealthCheckHost", "host.docker.internal")
.WithEnvironment("Consul:HealthCheckPort", weatherEndpoint.Property(EndpointProperty.Port));

```

What I tried to do to get rid of hardcoded `host.docker.internal` is to get the endpoint references with explicit network IDs:

```csharp
var weather = builder.AddProject("weather")
.WithHttpHealthCheck("/health")
.WithReference(consul);

// Inject host-to-host endpoint
var weatherLocalhostEndpoint = weather.GetEndpoint("http", KnownNetworkIdentifiers.LocalhostNetwork);
weather
.WithEnvironment("Consul:ServiceHost", weatherLocalhostEndpoint.Property(EndpointProperty.Host))
.WithEnvironment("Consul:ServicePort", weatherLocalhostEndpoint.Property(EndpointProperty.Port));

// Inject container-to-host endpoint
var weatherContainerEndpoint = weather.GetEndpoint("http", KnownNetworkIdentifiers.DefaultAspireContainerNetwork);
weather
.WithEnvironment("Consul:HealthCheckScheme", weatherContainerEndpoint.Property(EndpointProperty.Scheme))
.WithEnvironment("Consul:HealthCheckHost", weatherContainerEndpoint.Property(EndpointProperty.Host))
.WithEnvironment("Consul:HealthCheckPort", weatherContainerEndpoint.Property(EndpointProperty.Port));
```

And this doesn't work as I hoped it would, unfortunately

Contributor guide

Open the contributing guide

Research direction

Start by running the linked sample repository's AppHost project and inspect the resource definitions using GetEndpoint, KnownNetworkIdentifiers, and WithEnvironment. Trace why the weather resource waits on its own container-to-host endpoint. Done means the self-reference resolves without leaving weather in Starting, while preserving the intended Consul health-check host and port behavior.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.