Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

global.json override breaks azure function #7188

Open
1 task done
shinkathe opened this issue Jan 21, 2025 · 3 comments
Open
1 task done

global.json override breaks azure function #7188

shinkathe opened this issue Jan 21, 2025 · 3 comments
Labels
area-integrations Issues pertaining to Aspire Integrations packages azure Issues associated specifically with scenarios tied to using Azure azure-functions Issues related to the Azure Functions integration
Milestone

Comments

@shinkathe
Copy link

shinkathe commented Jan 21, 2025

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Aspire version: 9.0.0+01ed51919f8df692ececce51048a140615dc759d

It's probably good to know that, if you have an azure function that resides in a subfolder that is affected by global.json, for example:

{
    "sdk": {
        "version": "8.0.203",
        "rollForward": "latestFeature"
    }
}

The azure function will not work with aspire, and it will break with the following error:

2025-01-21T13:58:51 System.ArgumentNullException: Value cannot be null. (Parameter 'value')
2025-01-21T13:58:51    at Google.Protobuf.ProtoPreconditions.CheckNotNull[T](T value, String name)
2025-01-21T13:58:51    at Microsoft.Azure.Functions.Worker.Grpc.Messages.StartStream.set_WorkerId(String value) in D:\a\_work\1\s\src\DotNetWorker.Grpc\obj\Release\net8.0\FunctionRpc.cs:line 2055
...

Note, that the azure function in question is running on .NET 8, and the Aspire host is running on .NET 9. I'm a bit unsure, what the global json does in this case 🤔

Expected Behavior

I'm unsure what the interaction of global.json is here for the azure function that is being provisioned.

Steps To Reproduce

Have the following structure:
Test.AppHost
src/TestAzureFunction
src/global.json

Exceptions (if any)

2025-01-21T13:58:51 [13:58:51 ERR] Hosting failed to start

2025-01-21T13:58:51 System.ArgumentNullException: Value cannot be null. (Parameter 'value')
    at Google.Protobuf.ProtoPreconditions.CheckNotNull[T](T value, String name)
    at Microsoft.Azure.Functions.Worker.Grpc.Messages.StartStream.set_WorkerId(String value) in D:\a\_work\1\s\src\DotNetWorker.Grpc\obj\Release\net8.0\FunctionRpc.cs:line 2055
    at Microsoft.Azure.Functions.Worker.Grpc.GrpcWorkerClientFactory.GrpcWorkerClient.SendStartStreamMessageAsync(IClientStreamWriter`1 requestStream) in D:\a\_work\1\s\src\DotNetWorker.Grpc\GrpcWorkerClientFactory.cs:line 74
    at Microsoft.Azure.Functions.Worker.Grpc.GrpcWorkerClientFactory.GrpcWorkerClient.StartAsync(CancellationToken token) in D:\a\_work\1\s\src\DotNetWorker.Grpc\GrpcWorkerClientFactory.cs:line 66
    at Microsoft.Azure.Functions.Worker.WorkerHostedService.StartAsync(CancellationToken cancellationToken) in D:\a\_work\1\s\src\DotNetWorker.Core\WorkerHostedService.cs:line 25
    at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
    at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)

2025-01-21T13:58:51 Unhandled exception. System.ArgumentNullException: Value cannot be null. (Parameter 'value')
    at Google.Protobuf.ProtoPreconditions.CheckNotNull[T](T value, String name)
    at Microsoft.Azure.Functions.Worker.Grpc.Messages.StartStream.set_WorkerId(String value) in D:\a\_work\1\s\src\DotNetWorker.Grpc\obj\Release\net8.0\FunctionRpc.cs:line 2055
    at Microsoft.Azure.Functions.Worker.Grpc.GrpcWorkerClientFactory.GrpcWorkerClient.SendStartStreamMessageAsync(IClientStreamWriter`1 requestStream) in D:\a\_work\1\s\src\DotNetWorker.Grpc\GrpcWorkerClientFactory.cs:line 74
    at Microsoft.Azure.Functions.Worker.Grpc.GrpcWorkerClientFactory.GrpcWorkerClient.StartAsync(CancellationToken token) in D:\a\_work\1\s\src\DotNetWorker.Grpc\GrpcWorkerClientFactory.cs:line 66
    at Microsoft.Azure.Functions.Worker.WorkerHostedService.StartAsync(CancellationToken cancellationToken) in D:\a\_work\1\s\src\DotNetWorker.Core\WorkerHostedService.cs:line 25
    at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>b__15_1(IHostedService service, CancellationToken token)
    at Microsoft.Extensions.Hosting.Internal.Host.ForeachService[T](IEnumerable`1 services, CancellationToken token, Boolean concurrent, Boolean abortOnFirstException, List`1 exceptions, Func`3 operation)
    at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>g__LogAndRethrow|15_3(<>c__DisplayClass15_0&)
    at Microsoft.Extensions.Hosting.Internal.Host.StartAsync(CancellationToken cancellationToken)
    at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.RunAsync(IHost host, CancellationToken token)
    at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)

2025-01-21T13:58:51    at <redacted> 88

.NET Version info

.NET SDK:
Version: 9.0.102
Commit: cb83cd4923
Workload version: 9.0.100-manifests.d67a1f3e
MSBuild version: 17.12.18+ed8c6aec5

Runtime Environment:
OS Name: Mac OS X
OS Version: 14.3
OS Platform: Darwin
RID: osx-arm64
Base Path: /usr/local/share/dotnet/sdk/9.0.102/

.NET workloads installed:
[aspire]
Installation Source: SDK 9.0.100
Manifest Version: 8.2.2/8.0.100
Manifest Path: /usr/local/share/dotnet/sdk-manifests/8.0.100/microsoft.net.sdk.aspire/8.2.2/WorkloadManifest.json
Install Type: FileBased

Configured to use loose manifests when installing new manifests.

Host:
Version: 9.0.1
Architecture: arm64
Commit: c8acea2262

.NET SDKs installed:
6.0.423 [/usr/local/share/dotnet/sdk]
7.0.401 [/usr/local/share/dotnet/sdk]
8.0.100 [/usr/local/share/dotnet/sdk]
8.0.201 [/usr/local/share/dotnet/sdk]
8.0.203 [/usr/local/share/dotnet/sdk]
9.0.102 [/usr/local/share/dotnet/sdk]

.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.31 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 7.0.11 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.0 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.2 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 8.0.3 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 9.0.1 [/usr/local/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.31 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 7.0.11 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.0 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.2 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 8.0.3 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]
Microsoft.NETCore.App 9.0.1 [/usr/local/share/dotnet/shared/Microsoft.NETCore.App]

Other architectures found:
None

Environment variables:
Not set

global.json file:
Not found

Learn more:
https://aka.ms/dotnet/info

Download .NET:
https://aka.ms/dotnet/download

Anything else?

Aspire project: Uses .NET 9

<ItemGroup>
	<PackageReference Include="Aspire.Hosting.AppHost" Version="9.0.0" />
	<PackageReference Include="Aspire.Hosting.Azure" Version="9.0.0" />
	<PackageReference Include="Aspire.Hosting.Azure.ServiceBus" Version="9.0.0" />
	<PackageReference Include="Aspire.Hosting.Azure.Storage" Version="9.0.0" />
	<PackageReference Include="Aspire.Hosting.NodeJs" Version="9.0.0" />
	<PackageReference Include="Aspire.Hosting.SqlServer" Version="9.0.0" />
	<PackageReference Include="Aspire.Hosting.Azure.Functions" Version="9.0.0-preview.5.24551.3" />
</ItemGroup>

Function project (some transient deps missing from here): Uses .NET 8

<ItemGroup>
	<PackageReference Include="Azure.Storage.Blobs" Version="12.19.1" />
	<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.ServiceBus" Version="5.18.0" />
	<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="8.0.1" />
	<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
	<PackageReference Include="Serilog.Sinks.ApplicationInsights" Version="4.0.0" />
	<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="2.0.0" />
	<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.3.0" />
	<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0" />
	<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
	<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
</ItemGroup>
@joperezr joperezr added untriaged New issue has not been triaged area-integrations Issues pertaining to Aspire Integrations packages labels Jan 21, 2025
@joperezr
Copy link
Member

Thanks for the report! @captainsafia any clues on what might be going on here?

@captainsafia
Copy link
Member

Yes, unfortunately, this is a current constraint of the Aspire + Azure Functions integration. The feature relies on behavior that is only available in the .NET 9 SDK.

It's totally OK to have the Functions project and the Aspire app host target different runtimes but the SDK that's used must be a .NET 9 SDK.

@davidfowl davidfowl added azure Issues associated specifically with scenarios tied to using Azure azure-functions Issues related to the Azure Functions integration labels Jan 22, 2025
@shinkathe
Copy link
Author

shinkathe commented Jan 23, 2025

I think I managed to misunderstand the documentation, that the apphost would require .NET 9 SDK and I found it very difficult to make myself believe, that through Aspire, a .NET 8 azure function can be made to rely on .NET 9 SDK features. Logically maybe, that didn't sound possible, maybe because in my head ".NET would never do that". But somehow aspire is capable of making changes to the projects it runs, is probably more correct way to think about it 🤔

Thanks for clearing that up, I understand now what is going on.

The real life problem this causes us looks like this, if you're curious:

We have a large project, over multiple repositories, where azure functions have been dropped here and there and we need global.json SDK specification to make our IDE environments understand, that it should not suggest .NET 9 features before we have migrated to it. It has caused the very real problem, of people using IDE suggested syntax things from a newer SDK just to find out in CI that it will not build.

So, now we are also trying to add aspire to this project, and try to make all the various functions run in various contexts and this global json obviously causes the above problem.

My question is, should the global.json have this effect on Aspire? (Note, that the global.json does not target the apphost, only the function) Or are we using the global.json incorrectly in the first place 🤔

@davidfowl davidfowl removed the untriaged New issue has not been triaged label Jan 25, 2025
@davidfowl davidfowl added this to the Backlog milestone Jan 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-integrations Issues pertaining to Aspire Integrations packages azure Issues associated specifically with scenarios tied to using Azure azure-functions Issues related to the Azure Functions integration
Projects
None yet
Development

No branches or pull requests

4 participants