dotnet / aspire

Tools, templates, and packages to accelerate building observable, production-ready apps
https://learn.microsoft.com/dotnet/aspire
MIT License
3.82k stars 453 forks source link

Executable Azure Function not correctly load environments #5248

Closed petrkasnal closed 1 month ago

petrkasnal commented 2 months ago

Is there an existing issue for this?

Describe the bug

Hi I use Aspire and find it to be a super tool. I've only encountered one problem. Unfortunately there is no option to add Azure Function in Aspire. I have made the following extension method that triggers the Azure Function.

public static class Extension
    {
        public static IResourceBuilder<ExecutableResource> AddAzureFunction<TServiceMetadata>(
            this IDistributedApplicationBuilder builder,
            string name,
            int port,
            int debugPort)
            where TServiceMetadata : IProjectMetadata, new()
        {
            var serviceMetadata = new TServiceMetadata();
            var projectPath = serviceMetadata.ProjectPath;
            var projectDirectory = Path.GetDirectoryName(projectPath)!;

            var args = new[]
            {
            "host",
            "start",
            "--port",
            port.ToString(),
            "--nodeDebugPort",
            debugPort.ToString(),
            "--pause-on-error",
            "–-dotnet-isolated-debug",
            "--debug",
            "--inspect=5858"
        };

            return builder.AddExecutable(name, "func", projectDirectory, args)
                .WithEnvironment("ASPNETCORE_ENVIRONMENT", "Aspire")
                .WithEnvironment("AZURE_FUNCTIONS_ENVIRONMENT", "Aspire")
                .WithEnvironment("DOTNET_ENVIRONMENT", "Aspire")
                .WithOtlpExporter();
        }
    }

It works pretty well, but I have to manually run the debug no big deal. However, there is one slightly incomprehensible problem. I'm using WithReference to pass connection strings to the Azure Function. However, what happens is that not all connection strings are correct. Sometimes they are taken from Azure Function from local.settings instead of Aspire.

Aspire connection strings:

  "ConnectionStrings": {
    "Test": "Test",
    "Test2": "Test2",
    "Test3": "Test3",
    "Test4": "Test4",
    "Test5": "Test5"
  }

Function connection strings:

  "ConnectionStrings": {
    "Test": "Local",
    "Test2": "Local2",
    "Test3": "Local3",
    "Test4": "Local4",
    "Test5": "Local5",
    "AppBlobStorage": "Lerj"
  }

When you start Aspire and debug the Azure function application, the strangest situation occurs. Once a variable is set by local.settings. Once none or once all. Debug breakpoint is inside scope.

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureAppConfiguration((context, builder) =>
    {
        builder.AddJsonFile("host.json", optional: true);
        builder.AddJsonFile("local.settings.json", true, true);

        builder.AddEnvironmentVariables();

        builder.Build();
    })
    .ConfigureServices(services => {
        using (var scope = services.BuildServiceProvider().CreateScope())
        {
            var conf = scope.ServiceProvider.GetRequiredService<IConfiguration>();

            var test = conf.GetConnectionString("Test");
            var test2 = conf.GetConnectionString("Test2");
            var test3 = conf.GetConnectionString("Test3");
            var test4 = conf.GetConnectionString("Test4");
            var test5 = conf.GetConnectionString("Test5");
            var a = conf.GetConnectionString("AppBlobStorage");
        }
    })
    .Build();

image image image image image image

I have attached the repository where an example is given. https://github.com/petrkasnal/ExampleOfAzureFunction

Thanks

Expected Behavior

I expect loaded all environemntes settings from Aspire.

Steps To Reproduce

Exceptions (if any)

No response

.NET Version info

.NET 8.0 dontet-isolated

Anything else?

No response

eerhardt commented 2 months ago

@petrkasnal - we have a lot of work to do in order to enable Azure Functions + Aspire. There will need to be changes both in Aspire and in Azure Functions.

See https://github.com/dotnet/aspire/issues/920 as well.

cc @captainsafia

captainsafia commented 2 months ago

@petrkasnal Yep -- as @eerhardt mentioned there's some subtleties to sort out with the way that the Azure Functions host and worker consume connection strings so some additional work is required to make WithReference work correctly with Azure Functions.

Out of curiousity: can you share what types of resources you are trying to inject into your worker? Are you just trying to get things working with the Azure Storage instance that the host needs or are you trying to consume Azure Service Bus/Event Hubs/some other resource type?

petrkasnal commented 2 months ago

@eerhardt @captainsafia Thank you for response. I understand that getting Aspire ready for Azure Functions takes a lot of time. That's why I just made this solution for now. But I don't understand why it wouldn't work. I only pass Azure Functions the connection strings and that's it. It looks to me like it's asynchronous code that sometimes manages to execute and sometimes doesn't. I would need to solve this to be able to use them, or is there another solution currently possible?

I'm trying to consume different services not just storage. For example Service Bus, database etc.