Hallisloak
Hallisloak

Reputation: 33

Cannot get Minimal API .NET 8 AOT lambda to work

I'm kind of new to AWS, but trying out the lambdas for minimal api aot for .NET 8. Using the ".NET 8(C#/F#/Powershell)" runtime, with the x86_64 architecture. Built the lambda with the "dotnet lambda packckage" cli tool, and uploaded the .ZIP file via the lambda dashboard.

The dashboard show green check after upload, but the lambda gets an init error when trying to test it trough the dashboard with a basic test.

Error reads like this:

INIT_REPORT Init Duration: 20.68 ms Phase: init Status: error   Error Type: Runtime.ExitError
Error: .NET binaries for Lambda function are not correctly installed in the /var/task directory of the image when the image was built. The /var/task directory is missing the required .deps.json file.
Error: .NET binaries for Lambda function are not correctly installed in the /var/task directory of the image when the image was built. The /var/task directory is missing the required .deps.json file.
INIT_REPORT Init Duration: 21.40 ms Phase: invoke   Status: error   Error Type: Runtime.ExitError
START RequestId: <redacted UUID> Version: $LATEST
RequestId: <redacted UUID> Error: Runtime exited with error: exit status 105

These are the relevant files i used. "BasicRules" is just the name of the .NET project and the lambda.

Program.cs

using Amazon.Lambda.Serialization.SystemTextJson;
using BasicRules;
using Microsoft.Extensions.Options;

var builder = WebApplication.CreateSlimBuilder(args);

builder.Services.ConfigureHttpJsonOptions(options =>
{
    options.SerializerOptions.TypeInfoResolver = CustomSerializationContext.Default;
});

builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi, options =>
{
    options.Serializer = new SourceGeneratorLambdaJsonSerializer<CustomSerializationContext>();
});

var app = builder.Build();

app.MapGet("/", () => "Welcome to running AOT compiled ASP.NET Core Minimal API on AWS Lambda");

app.MapGet("/_health", () => "We are healthy");

app.MapGet("/test", () => "Test endpoint");

app.Run();

BasicRules.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
        <AWSProjectType>Lambda</AWSProjectType>
        <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
        <PublishReadyToRun>true</PublishReadyToRun>
        <PublishAot>true</PublishAot>
        <OutputType>exe</OutputType>
        <StripSymbols>true</StripSymbols>
    </PropertyGroup>
    
    <ItemGroup>
        <PackageReference Include="Amazon.Lambda.AspNetCoreServer.Hosting" Version="1.7.0" />
        <PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.4.1" />
        <PackageReference Include="AWS.Lambda.Powertools.Logging" Version="1.5.0" />
        <PackageReference Include="AWS.Lambda.Powertools.Metrics" Version="1.6.0" />
        <PackageReference Include="AWS.Lambda.Powertools.Tracing" Version="1.4.0" />
        <PackageReference Include="Amazon.Lambda.APIGatewayEvents" Version="2.7.0" />
<!--        <PackageReference Include="Amazon.Lambda.Core" Version="2.2.0" />-->
<!--        <PackageReference Include="Amazon.Lambda.Annotations" Version="1.2.0" />-->
<!--        <PackageReference Include="Amazon.Lambda.RuntimeSupport" Version="1.10.0" />-->
<!--        <PackageReference Include="AWSXRayRecorder.Core" Version="2.14.0" />-->
<!--        <PackageReference Include="AWSXRayRecorder.Handlers.AwsSdk" Version="2.12.0" />-->
    </ItemGroup>

    <ItemGroup>
        <TrimmerRootAssembly Include="Amazon.Lambda.AspNetCoreServer.Hosting"/>
        <TrimmerRootAssembly Include="BasicRules" />
        <TrimmerRootAssembly Include="AWS.Lambda.Powertools.Logging" />
        <TrimmerRootAssembly Include="AWS.Lambda.Powertools.Tracing" />
        <TrimmerRootAssembly Include="AWS.Lambda.Powertools.Metrics" />
        <TrimmerRootAssembly Include="Amazon.Lambda.APIGatewayEvents" />
<!--        <TrimmerRootAssembly Include="Amazon.Lambda.RuntimeSupport"/>-->
<!--        <TrimmerRootAssembly Include="AWSSDK.Core" />-->
<!--        <TrimmerRootAssembly Include="AWSXRayRecorder.Core" />-->
<!--        <TrimmerRootAssembly Include="AWSXRayRecorder.Handlers.AwsSdk" />-->
    </ItemGroup>
    
</Project>

The commented out lines here are just different packages i tried to add erlier from different examples i found.

aws-lambda-tools-defaults.json

{
  "function-memory-size" : 1024,
  "configuration": "Release",
  "function-runtime" : "dotnet8",
  "function-architecture": "x86_64"
}

CustomSerializerContext.cs

using System.Text.Json.Serialization;
using Amazon.Lambda.APIGatewayEvents;

namespace BasicRules;

[JsonSerializable(typeof(APIGatewayProxyRequest))]
[JsonSerializable(typeof(APIGatewayProxyResponse))]
[JsonSerializable(typeof(Dictionary<string, object>))]
public partial class CustomSerializationContext : JsonSerializerContext
{
}

Upvotes: 2

Views: 1034

Answers (1)

Guru Stron
Guru Stron

Reputation: 143098

Native AOT compilation results in a self-contained native executable binary:

Publishing your app as Native AOT produces an app that's self-contained and that has been ahead-of-time (AOT) compiled to native code.

It does not need .NET runtime. To correctly use AOT compiled .NET app in AWS you should look into using OS-only runtimes for AWS Lambda, not the .NET one. See the .NET functions with native AOT compilation documentation.

Upvotes: 1

Related Questions