-
Notifications
You must be signed in to change notification settings - Fork 847
Description
As part of building out the HealthChecksUI sample and the addition of the EndpointAnnotation.IsExternal flag in preview.5, it's become clear we need to improve how we model a resource's endpoints such that another resource can explicitly reference its internal or external endpoint in cases where they differ.
In short, we should ensure that external endpoints are explicitly modeled in a consistent manner and our default experiences for resources result in discrete external endpoints being modeled (in addition to the default endpoints) when that resource is marked as external.
Strawman for proposed changes:
-
Add a new
AsExternal()extension method toIResourceBuilder<T> where T : IResourceWithEndpointsthat creates copies of all the resource's non-external endpoints but marked as external and named for the original endpoint but with a-externalsuffix. This can be used to easily expose external endpoints for any resource, e.g.:builder.AddProject<Projects.MyFrontend>("frontend") .WithReference(basketService) .WithReference(catalogService) .AsExternal();
Assuming an ASP.NET Core project has a launch profile
"https"with two endpoints defined in its"applicationUrl"property (one for https, one for http), and the AppHost project was launched using a launch profile named"https", the above would result in four endpoints being modeled for the project:- "https":
IsExternal = false - "http":
IsExternal = false - "https-external":
IsExternal = true - "http-external":
IsExternal = true
- "https":
-
Update the
Dcp.ApplicationExecutorsuch that resource endpoints withIsExternalandIsProxiedset totrueresult in DCP launching the proxy configured to listen on the additional port for that "external" endpoint, but resolve to the usual target port for the application instance(s), i.e. the proxy terminates all endpoints marked asIsExternaland forwards them to the application instance(s) listen port(s). -
Update the
Dcp.ApplicationExecutorsuch that the logic for injecting the endpoint port into the application instance(s) is based on whether theEnivonrmentVariableproperty on the endpoint is set and some way for the resource to specialize how the value should be written to the variable. The default would be to group endpoint ports into a semi-colon delimited string for each environment variable specified but theProjectResourcewould implement the hook (interface or annotation) to specify it wants the full endpoint URL written via a semi-colon delimited list if the environment variable isASPNETCORE_URLS. The goal here is to remove all the custom logic inApplicationExecutorfor how the endpoint details are written into the environment variables. -
Consider updating
EndpointReferenceand adding convenience methods to allow easily retrieving the desired external endpoint for a resource, e.g.GetExternalEndpoint(string name)which will look for an endpoint where(Name == name || Name ==$"{name}-external") && IsExternal == true`.- ❓ Should there be a concept of getting the "default" endpoint so that I can simply ask for a resource's default endpoint without needing to know its name? Maybe just
GetExternalEndpoints()andGetEndpoints()that returns anIEnumerable<EndpointReference>would be enough, along withWithReference(IEnumerable<EndpointReference> endpoints), then one could do.WithReference(frontend.GetExternalEndpoints())
- ❓ Should there be a concept of getting the "default" endpoint so that I can simply ask for a resource's default endpoint without needing to know its name? Maybe just
-
Update
WithReference(IResourceBuilder<IResourceWithEndpoints> resource)to use only the non-external endpoints of the passed resource. Resources wishing to reference another resource's external endpoint will need to pass theEndpointReferenceof the external endpoint explicitly (see suggestion forGeExternalndpointabove), e.g.:builder.AddProject<Projects.MyFrontend>("frontend") .WithReference(basketService) .WithReference(catalogService) .AsExternal(); builder.AddAvailabilityChecker("availabilitychecker") .WithReference(frontend.GetExternalEndpoint("http")); // See point above about whether we should introduce concept of "default" endpoint so names don't have to be hard-coded like this
-
❓ Are any updates to manifest writing for endpoints needed (and by extension AZD)? e.g. how to make AZD understand that a reference to
{frontend.bindings.http-external.url}means the externally resolvable FQDN assigned by ACA needs to be used?- I hit a couple of issues in AZD when building out the sample:
- When trying to set the environment variable of a resource to just the
hostportion of another resource's endpoint, e.g. the manifest contained"env": { "AllowedHosts": "{apiservice.bindings.http.host};{apiservice.bindings.https.host}" ..., this resulted in the environment variable being set to just"apiservice;apiservice"rather than the full internal hostname from the binding URL. - For a container resource that had environment variable expressions that referenced other resources, it looked like AZD's own yaml templating syntax was being written into the
resources.bicepfile that's used to deploy the container resource, which resulted in that expression not being processed and just being directly to the ACA app environment variables config.
- When trying to set the environment variable of a resource to just the
- I hit a couple of issues in AZD when building out the sample:
Related #2099