AWS CDK vs CloudFormation: Which One Should You Use?

Definition

AWS CloudFormation is AWS's native declarative IaC service. You describe resources in a JSON or YAML template; CloudFormation reconciles them into a stack. AWS Cloud Development Kit (CDK) is an open-source framework that lets you define infrastructure in TypeScript, Python, Java, Go, or .NET, then synthesizes a CloudFormation template and submits it to CloudFormation for deployment. The crucial point: CDK is not a replacement for CloudFormation — it's a higher-level author-time experience that runs on top of CloudFormation. Every CDK deployment is a CloudFormation deployment under the hood. The question isn't whether to use CloudFormation, but whether to write templates directly or generate them from code.

How It Works

CloudFormation (raw YAML/JSON)

You author a template file with Resources, Parameters, Outputs, etc., and submit it with the Console, CLI, SDK, or pipeline:

Resources:
  MyBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'my-bucket-${AWS::AccountId}'
      VersioningConfiguration:
        Status: Enabled

CloudFormation parses the template, builds a dependency graph, and creates/updates/deletes resources with automatic rollback on failure.

CDK

You write code that constructs objects from the AWS Construct Library:

const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: `my-bucket-${cdk.Aws.ACCOUNT_ID}`,
  versioned: true,
});

Run cdk synth and the CDK walks the tree of constructs and emits a CloudFormation template (the Cloud Assembly). Run cdk deploy and the CDK uploads assets to the bootstrap S3 bucket/ECR repo and calls CloudFormation with the synthesized template. The same rollback, Change Sets, drift detection, and StackSets all apply.

Key Features and Limits

Authoring ergonomics

  • CloudFormation is declarative text — clean for simple stacks, verbose for complex ones. No real loops or conditionals (outside of Conditions / Fn::If). Intrinsic functions like !Ref, !GetAtt, !Sub are idiomatic but require memorization.
  • CDK is code: loops, functions, types, refactors, IDE autocomplete, and unit tests. You can factor a VPC + ECS service into a function and call it with different parameters per environment, something that requires nested stacks or macros in raw CloudFormation.

Constructs vs resources

  • CloudFormation resources are 1:1 with AWS API objects.
  • CDK adds L2 constructs (opinionated wrappers with defaults and helper methods like bucket.grantRead(lambdaFn)) and L3 patterns (ApplicationLoadBalancedFargateService produces VPC + ALB + ECS + security groups from a few lines). A few lines of CDK often expand into hundreds of lines of CloudFormation.

Type safety and IDE support

  • CloudFormation: limited linting (cfn-lint, cfn-nag). No autocomplete for property names. Typos surface at deploy time.
  • CDK: full IDE autocomplete, compile-time type checking (TypeScript / Java / Go / .NET), Python type hints, schema validation at synth time.

Bootstrap overhead

  • CloudFormation requires nothing — submit template, get stack.
  • CDK requires cdk bootstrap once per account + Region, which creates a CDKToolkit stack (S3 asset bucket, ECR repo, IAM roles). A one-time step, but necessary for every new account or Region.

Governance

  • CloudFormation templates are plain text. Review tools, AWS Config rules on AWS::CloudFormation::Stack, and CloudFormation Hooks can enforce policy.
  • CDK synthesizes templates — governance still happens on the generated CFN, but you can also enforce rules at synth time using Aspects (walk the construct tree and block disallowed configurations) and cdk-nag (AWS-authored rule packs for Well-Architected / HIPAA / NIST compliance).

Deployment model

  • Both ultimately invoke CloudFormation, so rollback, Change Sets, drift detection, and stack limits (500 resources, 1 MB template) are identical. CDK mitigates the template-size limit via nested stacks by default when a stack grows.

Skill requirements

  • CloudFormation: YAML/JSON, AWS API knowledge, intrinsic functions.
  • CDK: a real programming language, npm/PyPI/Maven workflow, package version management, plus CloudFormation mental model for debugging synthesized output.

Common Use Cases

  1. Large organization standardizing via CloudFormation templates — ops teams distribute YAML templates via Service Catalog; developers consume them without touching code.
  2. Developer teams preferring a programming language — JavaScript/TypeScript shops pick CDK for type safety and refactoring.
  3. Reusable platform constructs — internal platform teams publish L3 constructs (CompanyFargateService, CompanyWebApp) encoding compliance defaults.
  4. Serverless applications — CDK (aws-lambda, aws-apigatewayv2) often wins; SAM (a CloudFormation macro) is a lighter alternative.
  5. Brand-new AWS features on day one — raw CloudFormation or CDK L1 (CfnXxx) constructs, since L2 wrappers sometimes lag.
  6. Compliance-heavy environments — CloudFormation + Service Catalog gives strong guardrails; CDK + cdk-nag + Aspects is the code-native equivalent.

Pricing Model

CDK is free; CloudFormation is free for AWS::* resources. Both charge only for the underlying AWS resources they deploy. CDK adds a small ongoing cost for the bootstrap S3 bucket and ECR repo (typically a few dollars per account/Region per month, dominated by asset storage). Neither tool has per-deploy or per-stack service fees.

Pros and Cons

CDK pros

  • Real programming language: loops, types, IDE autocomplete, refactoring.
  • L2/L3 constructs drastically reduce boilerplate.
  • Grant-style IAM (table.grantReadWriteData(fn)) generates least-privilege automatically.
  • Unit-testable with @aws-cdk/assertions.
  • Inherits CloudFormation's reliability.

CDK cons

  • Bootstrap step per account/Region.
  • Synthesized CloudFormation is verbose and sometimes surprising; debugging requires reading generated output.
  • Package version management (npm/PyPI) adds supply-chain surface.
  • Team must be comfortable writing code, not just config.

CloudFormation pros

  • Zero tooling — just a template.
  • Declarative, reviewable, diff-friendly.
  • No synth step; the template is the source of truth.
  • Strong governance pattern with Service Catalog and Hooks.

CloudFormation cons

  • Verbose for complex stacks.
  • Limited loop/condition support.
  • Harder to unit-test and refactor.
  • Cross-stack references (Export/ImportValue) can become tangled at scale.

Comparison with Alternatives

| | CDK | CloudFormation | Terraform | SAM | | --- | --- | --- | --- | --- | | Language | TS/Py/Java/Go/.NET | YAML/JSON | HCL | YAML (CFN macro) | | Paradigm | Imperative | Declarative | Declarative | Declarative | | Engine | CloudFormation | CloudFormation | Terraform | CloudFormation | | Best for | Developer-heavy teams, reuse | Pure declarative, governance | Multi-cloud | Serverless apps | | Day-one AWS features | L1 (fast) | Native (fastest) | Some lag | Native (fast) | | Unit tests | Yes (assertions lib) | Limited (cfn-lint, cfn-nag) | Yes (terratest) | Limited |

Exam Relevance

  • Developer Associate (DVA-C02) — understand that CDK synthesizes CloudFormation; know L1/L2/L3, cdk bootstrap, and when SAM vs CDK fits.
  • DevOps Professional (DOP-C02) — heavy coverage: CDK Pipelines (self-mutating pipelines), CloudFormation vs CDK trade-offs, Service Catalog, StackSets, multi-account deploys.
  • Solutions Architect Professional (SAP-C02) — strategic trade-offs: governance, developer productivity, Well-Architected compliance (cdk-nag).
  • SysOps Administrator (SOA-C02) — drift detection, rollback behavior (identical for both, since CDK uses CloudFormation), stack operational concerns.

Exam trap: remembering that CDK is not a separate deployment engine — it produces a CloudFormation template, so rollback, Change Sets, and drift detection behave exactly as they do for raw CloudFormation.

Frequently Asked Questions

Q: If CDK just generates CloudFormation, why not always use CDK?

A: For many modern teams the answer is "use CDK by default," but raw CloudFormation still wins in three situations. Governance-first organizations distribute approved YAML templates via Service Catalog — developers instantiate stacks without authoring code, which simplifies audit. Small, simple stacks (one SQS queue, two IAM roles) are more concise in 30 lines of YAML than a TypeScript project with package.json, tsconfig, and bootstrap. Day-one AWS feature adoption sometimes beats CDK L2 construct updates — raw CFN or CDK L1 bridges the gap. Everything else — reusable patterns, growing applications, multi-stack composition — generally favors CDK.

Q: What does cdk bootstrap do, and do I have to run it?

A: cdk bootstrap deploys a one-time CloudFormation stack called CDKToolkit into each AWS account + Region. It creates an S3 bucket (for uploaded Lambda bundles, Docker images via ECR, and nested templates too large to inline), an ECR repository, a KMS key, and IAM roles that CloudFormation assumes during deploys. You must bootstrap any account/Region pair before cdk deploy there. For cross-account deploys, bootstrap with --trust <ci-account-id> so the CI account can assume the deploy role. Raw CloudFormation has no equivalent step — you simply submit templates.

Q: Can I migrate an existing CloudFormation stack to CDK (or vice versa)?

A: Yes, in both directions. CFN → CDK: import the existing template as a stack via cdk.include.CfnInclude, which lets you keep the template verbatim and gradually refactor it into L2 constructs. CDK → CFN: simply check in the synthesized template from cdk synth, and deploy it directly with CloudFormation. There's no lock-in because the deployment engine is the same. For brand-new resources you often see hybrid shops: existing CFN/SAM templates continue to deploy as-is, while new microservices adopt CDK.


This article reflects AWS features and pricing as of 2026. AWS services evolve rapidly — always verify against the official AWS CDK documentation and CloudFormation documentation before making production decisions.

Published: 4/17/2026 / Updated: 4/17/2026

This article is for informational purposes only. AWS services, pricing, and features change frequently — always verify details against the official AWS documentation before making production decisions.

More in DevOps