Skip to content

Why .NET Devs Should Stop Writing Lambda YAML Forever

Published:

Infrastructure Shouldn’t Be This Hard

Building out a serverless .NET application on AWS can feel like pushing a piano upstairs. Each step – creating Lambda functions, setting up API Gateway, defining DynamoDB tables, gluing it all together with IAM – can leave even experienced engineers tired. And don’t get me started on uploading zipped project files and hacking together permissions using YAML or console clicks. That isn’t just tedious, it’s a asking for errors and inconsistency.

I’ve felt the sting of “isn’t there a better way?” far too often. There’s a reason we moved from hand-crafting EC2 instances to infrastructure-as-code: serverless should be even easier, right?

Time for a reality check: it doesn’t have to be this painful. It’s 2026 after all, should we really be writing YAML anymore?

A Better Way: CDK for .NET Developers

AWS’s CDK – Cloud Development Kit – is a quiet revolution for anyone serious about system architecture. Forget scribbling YAML or clicking through AWS’s console. With CDK, you define all your infrastructure and wiring in a familiar programming language. For .NET devs? Say hello to C#. Write actual code, leverage your IDE, and get the power of compile-time checks and IntelliSense. Deploying your infrastructure starts to feel like writing your app.

Here’s how that looks in practice:

// Install the CDK CLI first
npm install -g aws-cdk

// Scaffold a new CDK project in C#:
cdk init app --language=csharp

You get a Program.cs (entry point), and a stack class – essentially your blueprint for AWS resources. Everything lives in code, so you can refactor, reuse, and share custom constructs.

Want an SQS queue? Spin up an SNS topic? Just instantiate the relevant class:

var queue = new Amazon.CDK.AWS.SQS.Queue(this, "MyQueue", new QueueProps());
var topic = new Amazon.CDK.AWS.SNS.Topic(this, "MyTopic", new TopicProps());

Everything’s named intuitively. Your editor’s autocomplete all but eliminates time spent hunting documentation.

Compiling .NET Lambda: No More Zip Files

Let’s tackle .NET Lambdas. Traditionally, you’re stuck compiling your app, zipping the output, uploading it manually (or with some awkward CLI script), and then crossing your fingers for a successful deployment. CDK brings sanity back: add Amazon.CDK.AWS.Lambda.NET, and you can point the resource at your project directory. That’s it.

var myFunction = new DotnetFunction(this, "ItemsApiFunction", new DotnetFunctionProps {
    ProjectDir = "../src/ItemsApi",
    // Specify handler, runtime, memory as needed
});

When CDK deploys, it handles compilation, packaging, and uploads automatically. No more manual zip files, no brittle scripts, and no wasted time.

Even better: the Lambda Annotations framework (for .NET) generates helpful serverless.template files so you can easily grab handler strings. It’s not just about ease–it’s about eliminating those subtle, recurring errors that make serverless adoption a headache.

Permissions: Grant, Don’t Guess

IAM is a perennial pain point. Previously, you’d hack together policies, pray you had the right actions, and hope it all worked. CDK lets you grant specific permissions directly in code:

table.GrantReadWrite(myFunction); // DynamoDB table permission
myFunction.GrantInvoke(apiGateway); // Lambda invocation permission
queue.GrantSendMessages(myFunction); // SQS publish permission

This declarative approach is not just concise—it’s robust. The abstraction more closely matches how architects think about relationships between components. No more YAML incantations or black-box IAM troubleshooting.

Wiring Up the API

API Gateway integrations are a notorious rabbit hole: create endpoints, wire up integrations, assign permissions, and then (finally) add routes. With CDK, you stay inside the world of C#, and, crucially, you can refactor and abstract repeated patterns.

For example, to define an HTTP API with Lambda integrations:

var api = new HttpApi(this, "ItemsApi", new HttpApiProps());
var integration = new LambdaProxyIntegration({ Handler = myFunction });
api.AddRoutes(new AddRoutesProps {
    Path = "/items",
    Method = HttpMethod.POST,
    Integration = integration
});

You define API stages, integrations, and set permissions, all as code. It’s all composable, testable, and accessible to your whole team.

Custom Constructs: Codify Best Practices

This is where things get interesting. Infrastructure code is finally just code–so you can leverage inheritance, composition, and abstraction. Imagine custom constructs that centralize repeated patterns: dead-letter queue wiring, API-Lambda integration scaffolding, security hardening. You can create custom classes and libraries, push them to your internal registry, and empower your team to reuse solid foundations.

Say you had to make ten APIs with similar configuration. Previously, you’d copy-paste YAML, risk error, and throw consistency out the window. With CDK:

public class ApiDotnetFunction : DotnetFunction {

public ApiDotnetFunction(ApiProps props) : base(props) {
    // Wiring up integration, routes, permissions centralised here
}

}

Now, deploy a new Lambda with API integration by instantiating a single construct. It’s as DRY (and as powerful) as any application code. Need loops and conditionals? Use them. Need custom logic for config? Go wild. Best practice becomes encapsulated, not bolted-on.

// Lambda Function - CDK builds and packages automatically
var getAllItemsFunction = new ApiDotnetFunction(this, "ItemsFunction", new ApiDotnetFunctionProps()
{
    ProjectDir = "../src/ItemsApi",
    Handler = "ItemsApi::ItemsApi.Functions_GetAllItems_Generated::GetAllItems",
    Runtime = Runtime.DOTNET_10,
    MemorySize = 512,
    Timeout = Duration.Seconds(30),
    Environment = new Dictionary<string, string>
    {
        { "TABLE_NAME", table.TableName }
    },
    Api = api,
    RouteKey = "GET /items",
    Region = this.Region,
    Account = this.Account
});

Nothing Else to Learn

The heart of modern serverless engineering is about minimizing friction. CDK for .NET lets you write both your application and infrastructure code in C#. No switch to YAML, Terraform syntax, or ever more brittle scripting. You can leverage your existing skill set, move fast, and make fewer mistakes–all while unlocking the expressive power of typed languages.

Practical Takeaway

Serverless was supposed to abstract away the pain. Yet until recently, for .NET devs, deploying meaningful apps felt half-baked. The AWS CDK transforms that landscape. By merging infrastructure and application logic into code, you get the harmony you always wanted: deep reuse, expressive abstractions, and a consistent deployment model.

Try out CDK in your next project. Refactor construct patterns. Push your infra classes to your internal registry. Treat infra code as engineering, not bureaucracy. Move your teams up the stairs and keep the music playing.

Curious for hands-on visuals? Check out the video version of this blog post.