How to trigger .NET Lambdas with S3 Events


When a file lands in S3, sometimes you want that to automatically trigger backend processing: image resizing, virus scanning, or sending a notification. AWS makes this possible using S3 event notifications to trigger Lambda functions. In this post, we’ll walk through wiring an S3 upload event to a .NET Lambda function.
Prerequisites
AWS CLI (configured with credentials)
Amazon.Lambda.Tools CLI (
dotnet tool install -g Amazon.Lambda.Tools
)An existing or new S3 bucket
Step 1: Create the Lambda Project
Start with the empty Lambda template:
dotnet new lambda.EmptyFunction --name S3TriggeredLambda
cd S3TriggeredLambda
Step 2: Define the Handler for S3 Events
Update Function.cs
to accept an S3Event
and log the key of the uploaded file:
using Amazon.Lambda.S3Events;
using Amazon.S3;
using Amazon.S3.Util;
using Amazon.Lambda.Core;
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
public class Function
{
private readonly IAmazonS3 _s3Client;
public Function() : this(new AmazonS3Client()) { }
public Function(IAmazonS3 s3Client)
{
_s3Client = s3Client;
}
public async Task FunctionHandler(S3Event evnt, ILambdaContext context)
{
foreach (var record in evnt.Records)
{
var bucket = record.S3.Bucket.Name;
var key = record.S3.Object.Key;
context.Logger.LogLine($"File uploaded to S3: {bucket}/{key}");
// Optional: read content
var response = await _s3Client.GetObjectAsync(bucket, key);
using var reader = new StreamReader(response.ResponseStream);
var content = await reader.ReadToEndAsync();
context.Logger.LogLine($"First 100 characters: {content[..Math.Min(100, content.Length)]}");
}
}
}
Step 3: Configure Lambda Deployment
Create aws-lambda-tools-defaults.json
:
{
"profile": "default",
"region": "us-east-1",
"configuration": "Release",
"framework": "net6.0",
"function-runtime": "dotnet6",
"function-handler": "S3TriggeredLambda::S3TriggeredLambda.Function::FunctionHandler",
"function-memory-size": 256,
"function-timeout": 30,
"function-name": "S3TriggeredLambda",
"function-role": "arn:aws:iam::123456789012:role/your-lambda-role"
}
Step 4: Deploy the Function
dotnet lambda deploy-function
Take note of the function name or ARN printed after deployment.
Step 5: Configure S3 to Trigger the Lambda
Use the AWS CLI or Console to attach the Lambda as a notification target for your S3 bucket.
Option A: Using AWS Console
Go to your S3 bucket
Choose Properties > Event notifications
Create a new event
Event type: PUT
Destination: Lambda function
Select your Lambda
Option B: Using AWS CLI
aws s3api put-bucket-notification-configuration --bucket your-bucket-name --notification-configuration '{
"LambdaFunctionConfigurations": [
{
"LambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:S3TriggeredLambda",
"Events": ["s3:ObjectCreated:*"]
}
]
}'
Make sure your Lambda function has permission to be invoked by S3:
aws lambda add-permission \
--function-name S3TriggeredLambda \
--principal s3.amazonaws.com \
--statement-id s3invoke \
--action "lambda:InvokeFunction" \
--source-arn arn:aws:s3:::your-bucket-name
Step 6: Test the Integration
Upload a file to your S3 bucket:
aws s3 cp sample.txt s3://your-bucket-name/
Then check the Lambda logs:
aws logs describe-log-groups
aws logs get-log-events --log-group-name /aws/lambda/S3TriggeredLambda --log-stream-name <latest-stream-name>
You should see log lines indicating that your Lambda processed the S3 object.
Cleanup
To avoid charges, delete the Lambda function and remove the S3 notification:
aws lambda delete-function --function-name S3TriggeredLambda
Summary
You’ve now connected S3 with a .NET Lambda to react to file uploads in real time. This pattern is ideal for file processing pipelines, ingestion workflows, or triggering downstream services without managing infrastructure.
References
Subscribe to my newsletter
Read articles from Renato Ramos Nascimento directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Renato Ramos Nascimento
Renato Ramos Nascimento
With over 14 years in software development, I specialize in backend systems using .NET, Python, and Java. I bring full lifecycle expertise, including requirements analysis, client/server and data layer development, automated testing (unit, integration, end-to-end), and CI/CD implementations using Docker, GitLab Pipelines, GitHub Actions, Terraform, and AWS CodeStar.