AWS CDK
The AWS Cloud Development Kit (CDK) lets you define infrastructure in a general-purpose programming language — TypeScript, Python, Java, C#, or Go. You write classes and functions; CDK synthesizes a CloudFormation template; CloudFormation creates the resources.
It addresses CloudFormation's real pain point: long YAML with macros and intrinsic functions is hard to read, test, and reuse. CDK does not replace CloudFormation — it is a higher layer that compiles down to it.
Constructs
A construct is a class representing one or more resources, in three levels of abstraction. L1 (Cfn*) maps directly to CloudFormation resource types — you set every property. L2 wraps L1 with safe defaults and helper methods (s3.Bucket blocks public access and adds grantRead). L3 patterns compose whole architectures (ApplicationLoadBalancedFargateService wires up the service, ALB, target groups, and roles).
Start at L2; drop to L1 when L2 lacks a property; use L3 for full patterns that match your architecture.
The Workflow
A CDK project follows a fixed shape: cdk init to create it, cdk synth to turn code into a template, cdk diff to show changes against the deployed stack (the CDK equivalent of a change set), and cdk deploy to apply. Tests are first-class — you assert the synthesized template has the resources and properties you expect.
Before deploying from a new account or Region, run cdk bootstrap once to create the supporting assets bucket, ECR repo, and roles CDK needs.
AWS CDK — infrastructure in a real programming language with abstractions and tests, for teams comfortable writing code.
CloudFormation — plain YAML/JSON, more accessible to ops engineers who prefer declarative templates and exact control.
Terraform / Pulumi — multi-cloud infrastructure across AWS and other providers.
- Reaching for L1 constructs by default instead of starting at L2 and gaining safe defaults and helper methods.
- Running
cdk deployin production withoutcdk difffirst, the same risk as skipping a change set. - Building one monolithic stack with hundreds of resources that is hard to update safely.
- Not pinning the CDK library version, producing surprise diffs as constructs evolve.
- Writing no unit tests for stacks, so a refactor silently changes the synthesized template.
- Choosing CDK for multi-cloud infrastructure, where Terraform or Pulumi fit better.
- Start at L2 constructs; use L1 only for properties L2 does not expose.
- Write unit tests asserting the synthesized template's resources and properties.
- Run
cdk diffbeforecdk deployin production. - Keep one stack per logical deployment unit.
- Pin the CDK library version to avoid surprise diffs.
- Use CDK Pipelines for CI/CD and publish shared constructs as packages.
Knowledge Check
What does the CDK do with the code you write?
- Synthesizes a CloudFormation template that CloudFormation then deploys
- Provisions resources directly via the AWS API, bypassing CloudFormation
- Generates Terraform HCL
- Runs the code as a Lambda function in production
Which construct level should you start with for new work?
- L2 — opinionated wrappers with safe defaults and helper methods
- L1 — raw CloudFormation mappings where you set every property by hand
- L3 — full architectural patterns, reached for on every new stack
- There is only one construct level, so the choice never comes up
What is the CDK equivalent of a CloudFormation change set?
- cdk diff — it shows what would be created, changed, or replaced against the deployed stack
- cdk synth — it diffs your synthesized code against the running stack and prints the deltas
- cdk bootstrap — it previews each resource change before the deploy proceeds
- cdk init — it reports the pending changes queued against a deployed stack
When is CDK the wrong choice?
- For multi-cloud setups — CDK is AWS-focused; use Terraform or Pulumi
- For teams comfortable writing TypeScript or Python who want loops and types
- When you want unit-tested infrastructure with template assertions
- When you want reusable construct libraries shared across teams
You got correct