AWS Infrastructure as Code in 2026: CDK vs Terraform vs Pulumi vs Serverless vs SAM
There are five serious ways to define AWS infrastructure as code in 2026 — AWS CDK, Terraform, Pulumi, the Serverless Framework, and AWS SAM — all sitting on top of one substrate, CloudFormation. They look interchangeable from a distance and feel very different in daily use. This is the grounded comparison: what each one is, how it handles the things that bite you later, and how to pick.
What “infrastructure as code” means on AWS
Infrastructure as code (IaC) means your cloud resources — networks, databases, functions, permissions — are defined in version-controlled files instead of clicked together in a console. You get repeatable environments, code review on infrastructure changes, and a diff to read before anything deploys. On AWS specifically, every IaC tool answers the same two questions, and the answers are what actually separate them:
- How do you describe a resource? A declarative document (YAML/HCL) or a real programming language (TypeScript, Python, Go).
- How does the tool know what already exists? Either AWS tracks it for you as a CloudFormation stack, or the tool keeps its own state file that you store and lock.
That second question is the cleanest way to split the field. CloudFormation, CDK, SAM, and the Serverless Framework all ultimately produce a CloudFormation stack — AWS holds the state, deploys are transactional, and you can open the stack in the console to see exactly what exists. Terraform and Pulumi instead talk to the AWS API directly through their own engine and keep their own state. Neither approach is wrong; they fail in different ways, which is the whole point of choosing deliberately.
CloudFormation: the substrate everything else sits on
AWS CloudFormation is the native engine. You write a YAML or JSON template listing resources and their properties; AWS provisions them as a stack, tracks their state, and rolls the whole thing back if a deploy fails. It’s free — you pay only for the resources it creates — AWS-only, and the foundation the next three tools compile down to.
Almost nobody writes raw CloudFormation by hand anymore, and for good reason: it’s punishingly verbose, there are no loops or real abstractions, and a modest serverless app becomes hundreds of lines of YAML. You should still understand it, because when CDK or SAM misbehaves, the CloudFormation stack and its event log are where you debug. Think of it as assembly language: you rarely write it directly, but it’s what everything else emits.
AWS CDK: infrastructure as real, typed code
The AWS Cloud Development Kit lets you define infrastructure in TypeScript, Python, Java, C#, or Go, then synthesizes it to CloudFormation. A Cognito user pool is an object; passing its ARN into a Lambda’s environment is an ordinary property reference the compiler checks. Its higher-level “L2” constructs bake in sane defaults, so you write a fraction of the YAML a raw template needs. Because the output is a CloudFormation stack, there’s no state file you own — AWS holds it — and deploys are transactional.
CDK is AWS-only by design, and it’s a first-party AWS project, so new services tend to land with CDK support as a matter of course. The trade-off is a layer of indirection: occasionally you debug the generated template rather than your source. For a team that’s all-in on AWS and writing TypeScript anyway, it’s the most natural fit — and increasingly the one a coding agent operates best, since typed cross-stack references catch mistakes before any deploy runs. It’s the foundation the cdkbase template is built on.
Terraform: the multi-cloud standard
Terraform uses HCL, a declarative configuration language, and ships the broadest provider ecosystem of any tool here — AWS, Cloudflare, Datadog, GitHub, and thousands more in one dependency graph. It keeps its own state file (typically in S3 with a DynamoDB lock, or a managed backend), and its plan/apply workflow with first-class drift detection is a genuine strength: you see a precise diff before anything changes.
Two governance footnotes matter for a multi-year commitment. HashiCorp relicensed Terraform under the Business Source License in 2023 — prompting the community to fork it as OpenTofu under the Linux Foundation — and HashiCorp has since been acquired by IBM. Terraform is still heavily maintained, but “Terraform or OpenTofu?” is now a real question. For a single-cloud AWS serverless app, Terraform’s multi-cloud breadth is power you’re paying for in extra boilerplate and a state backend to babysit, without using it.
Pulumi: Terraform’s model, real languages
Pulumi is, roughly, “Terraform with real programming languages.” You write TypeScript, Python, Go, C#, or Java; it talks to provider APIs directly and keeps its own state — either self-managed in S3 or a local file (free), or in Pulumi Cloud (free for individuals, paid for teams). The CLI and SDKs are Apache-2.0 open source. It’s genuinely multi-cloud, so it lands between CDK (real code, AWS-only, CloudFormation-backed) and Terraform (declarative, multi-cloud, own state).
If you want CDK’s real-language ergonomics and Terraform’s multi-cloud reach, Pulumi is the tool that does both. The cost is the same as Terraform’s: there’s no CloudFormation stack to open in the console — what got deployed lives in Pulumi’s own state, not as an AWS-native record — and a smaller community than either CDK or Terraform.
Serverless Framework: Lambda-first, plugin-rich
The Serverless Framework is built around Lambda-centric applications. You describe functions, events, and resources in a serverless.yml, and on AWS it compiles down to CloudFormation. Its large plugin ecosystem and event-source shorthands make standing up an API-plus-functions app fast, and it supports multiple providers (though it’s most at home on AWS).
One thing to know before you adopt it: Serverless Framework v4 (May 2024) introduced commercial licensing — the CLI is free for individuals and organizations under $2M in annual revenue, and requires a paid subscription above that, on an honor system (as of this writing). It shines for Lambda-heavy apps; it’s a worse fit when your infrastructure is broad rather than function-centric, since it’s not a general-purpose IaC tool.
AWS SAM: the native serverless shorthand
The Serverless Application Model (SAM) is AWS’s own answer to “CloudFormation is too verbose for serverless.” It’s a CloudFormation extension: a few special resource types (AWS::Serverless::Function, Api, SimpleTable) expand into full CloudFormation at deploy time. Because it is CloudFormation, you get the same transactional deploys and console-visible stacks, plus a CLI whose sam local can emulate Lambda and API Gateway on your laptop. It’s free and AWS-native.
SAM is the lightest AWS-native option if you like YAML and your workload is genuinely serverless. Its limits are the flip side of that focus: it’s YAML (no real-language logic, loops, or strong typing), and it’s aimed at serverless resources rather than general-purpose infrastructure. When you outgrow “a handful of functions and tables,” teams usually graduate to CDK.
The comparison at a glance
| Tool | How you write it | Clouds | State | Best for |
|---|---|---|---|---|
| CloudFormation | YAML / JSON | AWS only | AWS-managed stack | The substrate; rarely written by hand |
| AWS CDK | TS, Python, Java, C#, Go | AWS only | AWS-managed stack (synthesized) | Typed, full AWS apps; AI-agent workflows |
| Terraform | HCL | Multi-cloud | Own state file | Multi-cloud; widest provider ecosystem |
| Pulumi | TS, Python, Go, C#, Java | Multi-cloud | Own state (self- or cloud-managed) | Multi-cloud with real languages |
| Serverless Fmwk | YAML + plugins | AWS-first, multi-provider | CloudFormation (on AWS) | Lambda-centric apps (paid > $2M rev) |
| AWS SAM | YAML | AWS only | AWS-managed stack (transform) | Lightweight, native serverless apps |
Popular head-to-head comparisons
Most people arrive here already weighing two specific tools. These are the in-depth head-to-heads we’ve published so far — we add a dedicated comparison for a pairing once there’s real demand for it:
How to choose
- All-in on AWS, want real-language types across your whole stack: CDK. The most natural fit if you’re writing TypeScript and building more than just Lambdas.
- Multi-cloud, or you need the broadest provider ecosystem and explicit plans: Terraform (or OpenTofu).
- Multi-cloud, but you’d rather write real code than HCL: Pulumi.
- A purely serverless app and you like YAML, AWS-native, zero added cost: SAM — or the Serverless Framework if you want its plugin ecosystem and are under the $2M revenue line.
- Optimizing for full-stack serverless developer experience: SST is worth a look — see CDK vs Terraform vs SST and SST vs Terraform.
When each is the wrong choice
A feature matrix tells you what each tool can do; the more useful question is when it’s the wrong call:
- CDK — wrong if you’re multi-cloud, or your team wants legible declarative diffs and dislikes the synth-to-CloudFormation indirection.
- Terraform — overkill for a single-cloud AWS serverless app: you take on a state backend and HCL boilerplate to buy multi-cloud reach you aren’t using, plus the licensing/governance question.
- Pulumi — wrong if you specifically want AWS-native, console-visible stacks; like Terraform, it’s API-driven with its own state, and its community is smaller.
- Serverless Framework — wrong for infrastructure that isn’t Lambda-centric, or if the v4 commercial license is a non-starter.
- SAM — wrong once you outgrow pure serverless and want real-language logic, loops, and typing across a broader stack.
The bottom line
For a single-cloud AWS serverless SaaS — especially one you’re building in TypeScript alongside an AI agent — the field narrows fast. SAM is the featherweight native option for pure-serverless workloads; Terraform and Pulumi earn their keep the moment you go multi-cloud; the Serverless Framework fits Lambda-first apps under its revenue line. CDK is the sweet spot when you want real, typed code, AWS-managed state with no backend to babysit, and a first-party tool that keeps pace with AWS. That’s why cdkbase defines its entire stack in CDK. If you’ve already narrowed it down, the CDK vs Terraform vs SST head-to-head goes deeper on the three that matter most for serverless.
Skip the wiring and start from a working stack
cdkbase is a fork-ready AWS serverless template that ships everything in this article — CDK infrastructure, Cognito auth, Aurora DSQL, a Hono API, Stripe billing, and web/SPA/mobile frontends — already wired together and built for Claude Code. See pricing or read the getting-started guide.