Terraform vs Pulumi vs AWS CDK for Small Teams

This article contains affiliate links. We may earn a commission if you purchase through them, at no extra cost to you.

You’ve got a team of 3–8 engineers, your infrastructure is getting messy, and someone finally said the words: “we need to formalize our IaC.” Now you’re staring down three real options — Terraform, Pulumi, and AWS CDK — and every comparison article you find either reads like it was written by a vendor or stops at “it depends.”

I’ve used all three in production. Here’s the honest breakdown for Terraform vs Pulumi vs AWS CDK for small teams, with a clear recommendation at the end.

⚡ TL;DR Quick Verdict

  • Terraform: Best default choice. Huge ecosystem, multi-cloud, battle-tested. The BSL license change is annoying but not a dealbreaker for most small teams.
  • Pulumi: Best if your team already writes TypeScript/Python and hates HCL. Real programming languages, real loops, real abstractions. Genuinely excellent.
  • AWS CDK: Best if you’re AWS-only and want to stay in that world. Great L2/L3 constructs, but you’re locked in hard.

My pick for most small teams: Pulumi or Terraform, depending on your language preferences.

Why Small Teams Have Different IaC Needs

Big companies can afford dedicated platform engineers who spend six months becoming Terraform experts. Small teams can’t. You need something that:

  • A new hire can get productive with in a week
  • Doesn’t require a full-time person to maintain the state backend
  • Has enough community resources that StackOverflow (or your AI assistant) can answer most questions
  • Won’t lock you into decisions you’ll regret in two years

That last point is increasingly relevant since HashiCorp switched Terraform to the Business Source License (BSL) in 2023. It’s not open source anymore. For most small teams using Terraform directly, this doesn’t change anything today — but it’s a legitimate reason to evaluate alternatives before you’re deep in HCL debt.

Terraform: The Incumbent You Know

What it actually is

Terraform uses HCL (HashiCorp Configuration Language) — a declarative DSL that describes your desired infrastructure state. You write .tf files, run terraform plan, review the diff, and apply. It’s been the default IaC choice since roughly 2017, and the provider ecosystem is enormous: 3,000+ providers covering everything from AWS to Cloudflare to GitHub to PagerDuty.

The real experience using it

Terraform shines when your infrastructure is relatively stable and you’re mostly doing CRUD on cloud resources. Setting up a VPC, some EC2 instances, an RDS cluster, a load balancer — this is Terraform at its best. The HCL is readable, the plan output is clear, and the community has solved almost every problem you’ll encounter.

Where it falls apart: anything that requires actual logic. Want to create a variable number of resources based on a list? You’re writing for_each loops that feel like solving a puzzle. Want to share reusable infrastructure patterns across projects? Modules help, but they’re verbose and the dependency management is clunky. I’ve seen small teams spend an entire sprint untangling a circular dependency in a Terraform module tree.

The state management story is also a real operational burden. You need a remote backend (S3 + DynamoDB for AWS, or Terraform Cloud), you need to handle state locking, and you need a process for when state gets corrupted (and it will, eventually). For a team that’s just formalizing their infra, this is non-trivial overhead.

The BSL situation

Terraform 1.6+ is BSL-licensed. The practical restriction: you can’t use Terraform to build a product that competes with HashiCorp’s offerings. For a small team building their own SaaS? You’re fine. But if you’re building an internal developer platform or a managed infra service, read the license carefully. OpenTofu (the open-source fork) is a viable alternative if the license is a blocker.

Terraform pros and cons

  • ✅ Largest provider ecosystem by far
  • ✅ Most Stack Overflow answers, tutorials, and community resources
  • ✅ Multi-cloud without fighting the tool
  • ✅ Readable plans that non-engineers can review
  • ❌ HCL is a dead-end language — you can’t import libraries or write real logic
  • ❌ State management is operational overhead
  • ❌ BSL license is a legitimate concern for some use cases
  • ❌ Module ecosystem quality is wildly inconsistent

Pulumi: The One That Actually Lets You Code

What it actually is

Pulumi lets you write infrastructure in TypeScript, Python, Go, C#, Java, or YAML. Not a DSL that looks like a programming language — actual TypeScript that runs in Node.js, with real imports, real functions, real classes. You describe infrastructure as code objects, and Pulumi figures out the diff and applies it.

Pulumi is genuinely open source (Apache 2.0) and has been aggressively building features and community since the Terraform BSL change gave them a huge tailwind. The timing is good for them, and the product quality shows it.

The real experience using it

The first time you write Pulumi code after months of HCL, it feels like taking off a weighted vest. Need to create one S3 bucket per environment from a list? That’s a for loop. Need to conditionally create a resource based on a config flag? That’s an if statement. Need to share a pattern across five microservices? That’s a function or a class.

Here’s a concrete example. In Terraform, creating 5 similar Lambda functions with slight variations involves either copy-pasting blocks or wrestling with for_each and complex variable maps. In Pulumi TypeScript:

const services = ["auth", "billing", "notifications", "search", "webhooks"];

const lambdas = services.map(name => new aws.lambda.Function(`${name}-handler`, {
  runtime: aws.lambda.Runtime.NodeJS18dX,
  role: lambdaRole.arn,
  handler: "index.handler",
  code: new pulumi.asset.AssetArchive({
    ".": new pulumi.asset.FileArchive(`./dist/${name}`),
  }),
  environment: {
    variables: { SERVICE_NAME: name, STAGE: stack },
  },
}));

Clean. Readable. No HCL gymnastics.

The Pulumi Cloud backend handles state for you (there’s a generous free tier), or you can self-host state in S3/Azure Blob/GCS. The CLI experience is similar to Terraform — pulumi preview, pulumi up, pulumi destroy. The diff output is just as readable.

The downside: you need to understand async/await in TypeScript because Pulumi outputs are Output<T> types, not plain values. This trips up developers who are new to the model. It’s learnable, but expect a few hours of confusion the first time you try to pass a resource’s ARN into another resource’s config.

Pulumi pros and cons

  • ✅ Real programming languages — loops, conditionals, functions, imports
  • ✅ Apache 2.0 license — genuinely open source
  • ✅ Multi-cloud with the same provider coverage as Terraform (they auto-generate from Terraform providers)
  • ✅ Pulumi Cloud free tier handles state management for you
  • ✅ Excellent TypeScript/Python support with real type safety and IDE autocomplete
  • ❌ The Output<T> async model has a learning curve
  • ❌ Smaller community than Terraform (fewer StackOverflow answers, fewer blog posts)
  • ❌ If something breaks in the Pulumi runtime itself, debugging is harder

If your team is primarily TypeScript or Python developers, Pulumi is worth serious consideration. The developer experience is genuinely better for teams that write code for a living. If you’re also evaluating where to host, Pulumi works great with any major cloud provider.

Get the dev tool stack guide

A weekly breakdown of the tools worth your time — and the ones that aren’t. Join 500+ developers.



No spam. Unsubscribe anytime.

AWS CDK: The AWS-Native Option

What it actually is

AWS CDK (Cloud Development Kit) lets you define AWS infrastructure in TypeScript, Python, Java, Go, or C#. It compiles down to CloudFormation under the hood. The key differentiator is the construct library — AWS ships pre-built, opinionated L2 and L3 constructs that encapsulate best practices. A single new ApplicationLoadBalancedFargateService() creates a Fargate service, load balancer, target group, security groups, and IAM roles with sensible defaults.

The real experience using it

CDK’s high-level constructs are genuinely impressive. For common AWS patterns, you can get a production-quality setup with far less code than Terraform or Pulumi. The AWS team has put real thought into the L2/L3 constructs — they encode years of AWS best practices into single method calls.

But the CloudFormation dependency is a real limitation. Every CDK deployment synthesizes to a CloudFormation template and deploys through CloudFormation. That means:

  • CloudFormation’s 500-resource limit per stack applies
  • CloudFormation’s notoriously slow deployment times apply (a full ECS service update can take 10+ minutes)
  • CloudFormation drift detection is your state management, which is less flexible than Terraform/Pulumi state
  • You’re 100% AWS. No Azure, no GCP, no Cloudflare, no Datadog.

For a small team that’s AWS-only and plans to stay that way, CDK is a legitimate choice. For anyone who uses even a single non-AWS service in their infrastructure, it’s a non-starter as your primary IaC tool.

AWS CDK pros and cons

  • ✅ Best-in-class L2/L3 constructs for common AWS patterns
  • ✅ Real programming languages with full type safety
  • ✅ Apache 2.0 license
  • ✅ Deep AWS integration — new services get CDK support faster than Terraform/Pulumi
  • ❌ CloudFormation under the hood — slow, resource limits, less flexible
  • ❌ AWS-only, full stop
  • ❌ CloudFormation errors can be cryptic and hard to debug
  • ❌ Bootstrapping requirements add friction to new AWS accounts

Head-to-Head Comparison

Criteria Terraform Pulumi AWS CDK
Language HCL (DSL) TS, Python, Go, C# TS, Python, Go, Java
Multi-cloud ✅ Excellent ✅ Excellent ❌ AWS only
License BSL (not OSS) Apache 2.0 ✅ Apache 2.0 ✅
State management DIY or Terraform Cloud Pulumi Cloud (free tier) CloudFormation
Learning curve Medium (HCL is new) Medium (Output<T> model) Low-Medium (if AWS-familiar)
Provider ecosystem ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐ (AWS only)
Community/resources ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐⭐
Deployment speed Fast Fast Slow (CloudFormation)
Free tier OSS CLI free; Cloud $20+/mo Free up to 200k resources/mo Free (CloudFormation costs)

Pricing Breakdown

Terraform

The open-source CLI is free. Terraform Cloud (for remote state, team collaboration, and policy enforcement) starts at $20/user/month for the Plus plan. For a 4-person team, that’s $80/month just for state management and CI/CD integration. The free tier of Terraform Cloud supports 1 user and 500 managed resources — workable for solo projects, not for a team. OpenTofu (the BSL-free fork) is free and compatible with most Terraform providers.

Pulumi

Pulumi Cloud’s free tier is genuinely usable: up to 200,000 resource-updates per month, unlimited stacks, and team collaboration features for up to 10 members. The Team tier is $50/month flat (not per-user) for more advanced features. For most small teams, the free tier is enough to start, and $50/month is reasonable if you need audit logs and SAML SSO. You can also self-host state in S3 for free if you prefer.

AWS CDK

CDK itself is free. You pay for CloudFormation API calls (about $0.0009 per handler operation, with 1,000 free per month) and whatever AWS resources you create. For most small teams, CloudFormation costs are negligible — the real cost is the time you spend waiting for CloudFormation deployments to complete.

Use Case Recommendations

Use Terraform if:

  • You’re multi-cloud or use a lot of non-AWS/GCP/Azure services (Cloudflare, Datadog, GitHub, etc.)
  • You need the largest possible community for hiring and onboarding
  • Your infrastructure is relatively static and doesn’t need complex logic
  • You’re comfortable with the BSL license for your use case
  • Consider OpenTofu if the license is a concern — it’s a drop-in replacement

Use Pulumi if:

  • Your team writes TypeScript or Python daily and HCL feels like a tax
  • You need real programming constructs — loops, conditionals, shared libraries
  • You want multi-cloud with a genuinely open-source tool
  • You’re starting fresh and want the best developer experience available today
  • You’re migrating away from Terraform post-BSL and want to minimize friction

Use AWS CDK if:

  • You are 100% AWS and plan to stay that way
  • You want the highest-level abstractions for common AWS patterns
  • Your team is already deep in the AWS ecosystem and CloudFormation isn’t new to you
  • Deployment speed is not a critical concern

The Migration Question

If you’re currently on Terraform and considering a move: don’t migrate everything at once. The most pragmatic path I’ve seen work for small teams is:

  1. Keep existing Terraform for stable, rarely-changed infrastructure (VPCs, base networking, IAM)
  2. Start new projects in Pulumi or CDK
  3. Migrate opportunistically when you’re already touching a module

Pulumi has a tf2pulumi converter that handles maybe 70% of the mechanical work. The remaining 30% is where you actually think about your infrastructure, which is usually a good thing.

If you’re also thinking about where to run your infrastructure, check out our Best Cloud Hosting for Side Projects guide and our DigitalOcean vs Hetzner vs Vultr comparison — both of which cover providers that work well with all three IaC tools. Speaking of which, if you’re deploying to DigitalOcean, all three tools have solid providers for it, and their $200 free credit for new accounts makes it easy to experiment.

And if you’re using AI assistants to help write your infrastructure code (and you should be), check out our breakdown of Claude vs ChatGPT for developers — Claude in particular is excellent at generating and debugging Pulumi TypeScript.

Final Recommendation

Here’s my honest take after using all three in real teams:

If I’m starting a new small team from scratch in 2026, I’m choosing Pulumi with TypeScript. The developer experience is genuinely better, the license is clean, the free tier handles state management without operational overhead, and the ability to write real code instead of HCL pays dividends every time your infrastructure has any complexity at all. The community is smaller than Terraform’s, but it’s growing fast and the documentation is solid.

If my team has existing Terraform and no burning reason to migrate, I’m staying on Terraform (or moving to OpenTofu if the BSL is a concern). The ecosystem and community are still unmatched, and the switching cost isn’t worth it if things are working.

AWS CDK is a distant third for most small teams — the CloudFormation dependency is a genuine productivity tax, and the AWS-only constraint is a real limitation as soon as you add a single non-AWS service to your stack.

Whatever you pick, the most important thing is picking something and committing. Informal infra that lives in someone’s head or a pile of bash scripts is the real enemy. Any of these three tools, used consistently, will serve a small team well.

Get the dev tool stack guide

A weekly breakdown of the tools worth your time — and the ones that aren’t. Join 500+ developers.



No spam. Unsubscribe anytime.

Leave a Comment

Stay sharp.

A weekly breakdown of the tools worth your time — and the ones that aren't.

Join 500+ developers. No spam ever.