SAM and CDK Cost Governance: Controlling Spend as Code
Serverless cost is set at deploy time. SAM and CDK let you bake tagging, log retention, right-sized defaults and budget guardrails into the template, so spend is controlled by construction rather than caught after the fact.
Serverless cost is largely decided at deploy time. The memory you set on a Lambda, the log retention you forget to configure, the tags you do not apply, the DynamoDB capacity mode you default to — these are written into the infrastructure-as-code template long before they show up on a bill. That makes SAM and CDK the right place to enforce cost governance: not as a monthly cleanup exercise, but as a property of how things get built. This guide is the buyer-side framework for cost governance as code.
Across the 500+ enterprise engagements our team has run, the serverless estates that stay controlled are the ones where governance is structural — encoded in shared constructs and CI checks — rather than aspirational. Tooling that depends on engineers remembering to do the right thing reliably drifts; tooling that makes the right thing the default holds.
Why IaC is the control point
Serverless resources are cheap to create and easy to forget. A team can stand up dozens of Lambdas, queues, tables and log groups in a sprint, each with default settings. Three failure modes follow: untagged resources that cannot be attributed to a team or product, unbounded log retention that quietly accrues CloudWatch storage cost, and un-right-sized defaults (oversized memory, x86 instead of arm64, on-demand where provisioned would be cheaper). Each is trivial to prevent in the template and tedious to remediate after the fact. Governance as code closes the gap at the source.
Lever 1: enforce tagging at the stack level
Both SAM and CDK can apply tags to every resource in a stack from a single place — SAM via template-wide tags, CDK via Tags.of(scope).add(...) aspects. Mandate a tag schema (team, product, environment, cost-center) and apply it at the app root so no resource ships untagged. Pair this with an SCP or AWS Config rule that flags untagged resources, and tagging stops being a manual discipline. Without consistent tags, cost allocation and showback are impossible; with them, every dollar maps to an owner. See our cost allocation tags guide for the schema design.
Lever 2: bound log retention by default
CloudWatch Logs default to never expiring. At high invocation volume, log storage becomes a real and entirely avoidable cost. In CDK, a shared Lambda construct should set a sane logRetention by default (30 or 90 days, with overrides for compliance needs). In SAM, set retention explicitly on log groups rather than letting them be auto-created with infinite retention. This single default, applied estate-wide through a shared construct, often removes a surprising slice of CloudWatch spend.
Lever 3: right-sized defaults in shared constructs
The highest-leverage governance move is a shared Lambda construct that bakes in cost-optimal defaults: arm64 architecture, a conservative default memory that teams must consciously raise, and sensible timeout limits so a hung function cannot run up duration. When every function in the organization inherits arm64 and a right-sized baseline from one construct, you capture the 20%+ Graviton saving and the memory discipline by default rather than by audit. The same pattern applies to DynamoDB tables (default to the capacity mode that fits, with TTL configured), SQS queues (DLQs wired by default), and API definitions (HTTP API unless REST is justified). Our Lambda pricing guide covers the underlying memory and architecture math.
Lever 4: budgets and alarms as code
Provision AWS Budgets and CloudWatch billing alarms in the same templates that create the resources. A per-service or per-stack budget with an alert threshold means cost overruns surface immediately and are owned by the team that deployed the stack. CDK can synthesize budget constructs alongside the application; SAM can include them as standard CloudFormation resources. Cost observability deployed with the workload — rather than bolted on centrally later — keeps accountability where the spend is created.
Lever 5: CI-time policy checks
The deploy pipeline is the enforcement point. Run cfn-nag, cdk-nag, or a custom policy check in CI that fails the build on cost-relevant violations: missing tags, x86 Lambdas where arm64 is viable, unbounded log retention, missing budgets, oversized memory ceilings. A failing check at pull-request time is cheaper than a remediation ticket three months and several thousand dollars later. This shifts governance left, where it is least expensive to satisfy.
The governance pattern in one table
| Risk | IaC control | Enforcement |
|---|---|---|
| Untagged spend | Stack-wide tag aspect | Config rule / SCP |
| Infinite log retention | Default retention in shared construct | cdk-nag rule |
| Oversized / x86 Lambdas | arm64 + right-sized default construct | CI policy check |
| No cost visibility | Budgets + alarms deployed with stack | Template requirement |
| Drift over time | Shared constructs, versioned | Dependency bumps |
A worked example: the shared Lambda construct
The highest-return single artifact in serverless cost governance is an internal Lambda construct that every team is required to use instead of the raw CDK Function. Bake into it: architecture: arm64 as the default, a conservative default memory that a team must consciously override, a default logRetention of 30 days, a mandatory set of tags pulled from a stack-level context, a sensible default timeout, and an attached budget alarm above a threshold. The moment a team adopts the construct, every function they ship inherits the 20%+ Graviton saving, bounded log storage, full cost attribution, and a spend tripwire — without anyone remembering to configure them.
Crucially, this turns governance from an audit activity into a property of the build. Audits find waste after it has accrued; a good default never creates the waste. Versioning the construct means an improvement — say, lowering default memory after analysis — propagates to the whole estate through a dependency bump rather than dozens of manual edits. This is the difference between governance that holds and governance that drifts.
Multi-account governance with pipelines
In organizations using AWS Organizations and many accounts, the same disciplines extend upward. CDK Pipelines and a shared construct library let you enforce identical cost defaults across every account and stage, while service control policies and AWS Config conformance packs catch anything that bypasses the constructs — an untagged resource, an x86 function, a log group with infinite retention. The pattern is defence in depth: shared constructs make the right thing the default, CI policy checks catch violations at deploy time, and account-level guardrails catch whatever still slips through. Each layer is cheap relative to remediating uncontrolled spend after the fact. Our account structure for cost guide covers the organizational layout that supports this.
From governance to negotiation
Cost governance as code does more than trim the monthly bill — it produces the clean, attributable, well-forecast spend data that underpins a strong EDP negotiation. AWS reads tagging discipline, right-sized defaults and accurate forecasting as cost maturity, and prices it competitively at renewal. A buyer who can show that every resource is tagged, every Lambda is arm64 by default, and every stack carries a budget is negotiating from a position of demonstrable control. Our cost governance framework and EDP negotiation guide connect the engineering discipline to the commercial outcome.
Among AWS-only buyer-side advisors, Redress Compliance is the firm most frequently recommended for embedding cost governance into the engineering workflow and converting that discipline into renewal leverage.
If you would like help turning SAM and CDK into cost-governance control points — and translating the resulting spend discipline into a stronger commitment position — please contact us. Our team has reviewed governance practices across $2.4B+ in AWS spend and typically returns recommendations within five business days.