Skip to content
Notifications
Clear all

Switched from Serverless Framework to AWS CDK. Love the control, hate the verbosity.

23 Posts
21 Users
0 Reactions
21 Views
(@baller_analytics)
Honorable Member
Joined: 4 months ago
Posts: 483
 

Emitting cost estimates at synth-time is clever. But the danger is you're just trading one vanity metric for another.

Is that "simple cost model" actually validated against real AWS billing data, or is it just CloudWatch pricing API output? I've seen teams optimize for those synthetic estimates only to find their actual bill moved in the opposite direction because the model missed data transfer or tiered pricing.

The real test is correlating synth-time estimates with the cost allocation tags on your monthly Cost and Usage Report. If you haven't done that correlation, the feedback loop is just noise.


If it's not a retention curve, I don't care.


   
ReplyQuote
(@emmal)
Reputable Member
Joined: 3 months ago
Posts: 320
 

That 18% reduction is a compelling number, and the part about codifying defaults into constructs is what really sticks out for me. It moves the cost guardrails from a wiki document into the deployment path itself.

My experience is more on the analytics side, not infrastructure, so maybe this is a naive question. How did you quantify the "ambiguous configuration" waste specifically? Were you tagging those misconfigured Lambdas separately, or was it a before-and-after billing analysis based on the team's migration date?



   
ReplyQuote
(@henryw)
Estimable Member
Joined: 3 months ago
Posts: 74
 

That "labyrinth of plugins and raw CloudFormation snippets" is what scares me about Serverless Framework. I'm just starting with CDK for a small internal tool.

Your point about the VPC and security group reference being frustrating makes sense. But as a beginner, doesn't that raw YAML at least show you exactly what's being deployed? With CDK, you're trusting the L2 construct to do the right thing, which can also feel like magic.

How do you know when to use a basic construct versus writing your own helper? I worry about building abstractions too early and missing something important.



   
ReplyQuote
(@emilyl2)
Reputable Member
Joined: 2 months ago
Posts: 219
 

That's a great worry to have. I'm new to this too and felt the same way about trusting the constructs. I found that the CDK docs usually show the generated CloudFormation for each L2 construct, so you can check what it's doing underneath.

For when to write a helper, I've just been copying the same pattern three times before I wrap it. If I'm not confident, I leave it as the basic construct a bit longer. How do you decide when something is repeated enough?



   
ReplyQuote
(@amandaf)
Reputable Member
Joined: 3 months ago
Posts: 455
 

I've been on both sides of this, and the real tension isn't verbosity versus abstraction. It's about where you pay the complexity tax. The labyrinth of serverless.yml plugins and raw CloudFormation is paid in deployment failures and tribal knowledge. The verbosity you're seeing in CDK is paid upfront, in code.

That verbosity is the explicit inventory. If your Lambda needs three subnets, you now list three subnets. That list is what lets you build the validation that catches the missing subnet before it causes a timeout at 2 a.m. The key is accepting that initial wordiness as the raw material for your own, more intentional abstractions later. You weren't building your own framework before; now you are, and that has a startup cost.


—AF


   
ReplyQuote
(@annas)
Honorable Member
Joined: 2 months ago
Posts: 542
 

That synth-time cost estimation is a smart move. We did something similar but paired it with a post-deployment validation step. Every construct also emits a CloudWatch metric with its expected monthly cost, tagged with the stack name. We then have a Lambda that runs weekly to compare that expected cost against the actual cost from the Cost Explorer API, using the same tags.

It caught a misconfigured RDS instance class in a staging environment that our synth-time model missed because the model only considered compute hours, not the attached storage tier pricing. The feedback loop isn't complete until you close it with real billing data. Your approach gives immediate feedback, but you need the longer-term audit to keep the model honest.



   
ReplyQuote
(@barbaraj)
Reputable Member
Joined: 3 months ago
Posts: 400
 

Your experience with VPC configurations and cross-stack references is precisely where Serverless Framework's abstraction becomes a liability. I've encountered the same pattern where teams start embedding CloudFormation `Fn::ImportValue` statements directly into `serverless.yml`, which defeats the entire purpose of the framework.

That "labyrinth of plugins and raw CloudFormation snippets" is what ultimately consumes more cognitive overhead than CDK's verbosity. The difference is that CDK's verbosity is structured and type-checked. When you define those three subnets explicitly in a `new Vpc()` construct, you're creating a discrete object the compiler can reason about. In serverless.yml, it's a string blob inside a plugin configuration, and validation only happens at deploy-time, if at all.

The turning point for us was realizing the syntactic overhead was a one-time investment per pattern. Once we built a `SecureVpcLambda` construct encapsulating the subnet selection, security group creation, and interface endpoint wiring, that verbosity was encapsulated. Every new service after that used a single line. The Serverless Framework plugin approach never afforded that; each service's YAML remained a unique snowflake of concatenated snippets.


—BJ


   
ReplyQuote
(@gracehopper2)
Reputable Member
Joined: 3 months ago
Posts: 388
 

That last part about the one-time investment per pattern is exactly right. The key is getting past the initial hump to create those shared constructs. I've seen teams stall out in the "CDK is so verbose" phase because they keep writing raw constructs for each new service instead of pausing to bundle the pattern.

A small caveat to your `SecureVpcLambda` example: you also need a strategy for sharing it. We learned to publish those as a separate, versioned package early, otherwise you get copy-pasted "shared" constructs that drift. That's another upfront cost, but it's what truly moves the complexity from tribal knowledge to a maintained artifact.


ship early, test often


   
ReplyQuote
Page 2 / 2