AWS CDK (Cloud Development Kit)
The AWS Cloud Development Kit (CDK) lets you define your cloud infrastructure using a real programming language — TypeScript, Python, Java, Go, or C# — instead of hand-writing YAML. You write code that describes resources, run a command, and the CDK turns it into a CloudFormation template that AWS then deploys. This matters because you get loops, variables, functions, and your editor’s autocomplete to build infrastructure, while still riding on top of CloudFormation, Amazon’s battle-tested provisioning engine. Infrastructure as Code (IaC) means describing your servers and networks in files you commit to Git, rather than clicking buttons in a console.
What the CDK actually is
The CDK is not a separate provisioning system. When you run cdk synth, your program executes and produces a plain CloudFormation template (JSON). When you run cdk deploy, the CDK hands that template to CloudFormation, which creates a stack — a named collection of resources managed as one unit. So everything you already know about CloudFormation (stacks, drift, rollback, service limits) applies unchanged.
The building blocks of CDK code are constructs. A construct is a reusable object that represents one or more AWS resources. They come in three levels:
| Level | Name | What it is | Example |
|---|---|---|---|
| L1 | CFN resources | A direct 1-to-1 mapping to a CloudFormation resource, prefixed Cfn | CfnBucket |
| L2 | Curated constructs | A higher-level class with sensible defaults and helper methods | s3.Bucket |
| L3 | Patterns | An opinionated bundle of many resources for a whole use case | ApplicationLoadBalancedFargateService |
L2 and L3 constructs are where the CDK saves you the most typing — and where the biggest surprises hide, because one line of your code can generate dozens of resources.
When to use the CDK (and when not to)
When to use it: your team writes application code already and prefers a real language over YAML, you want to package and share reusable infrastructure patterns across projects, or you have logic-heavy infrastructure (e.g. “create one queue per microservice in this list”). The CDK itself is free; you pay only for the resources it creates.
When NOT to use it: you need to manage non-AWS clouds (use Terraform), your team is more comfortable with declarative YAML and your stacks are simple (use raw CloudFormation), or you need every reviewer to read the exact resources at a glance — CDK code hides the generated detail until you synthesize it.
Getting started
You install the CDK Toolkit (the command-line tool) with npm, the Node.js package manager. You need Node.js installed even for Python or Java projects, because the toolkit itself runs on Node.
npm install -g aws-cdk
cdk --version
Output:
2.149.0 (build 9e0b8b9)
Create a new TypeScript project and bootstrap your account. Bootstrapping sets up a small support stack (an S3 bucket and IAM roles) the CDK uses to upload templates and assets — you do it once per account/Region.
mkdir my-app && cd my-app
cdk init app --language typescript
cdk bootstrap aws://123456789012/us-east-1
Output:
✅ Environment aws://123456789012/us-east-1 bootstrapped.
A minimal stack
Here is a CDK stack in TypeScript that creates an S3 bucket (object storage). Notice the L2 Bucket construct: a few options expand into a fully configured, encrypted, versioned bucket.
import { Stack, StackProps, RemovalPolicy } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
export class MyAppStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
new s3.Bucket(this, 'AppAssets', {
bucketName: 'devcraftly-app-assets-2026',
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
removalPolicy: RemovalPolicy.RETAIN,
});
}
}
See what it generates, then deploy
This is the most important habit with the CDK: always inspect before you deploy. cdk diff compares your code against what is currently deployed and lists every change — including resources you never typed but a construct created for you.
cdk diff
Output:
Stack MyAppStack
Resources
[+] AWS::S3::Bucket AppAssets AppAssets1A2B3C4D
[+] AWS::S3::BucketPolicy AppAssets/Policy AppAssetsPolicy0E1F2A3B
Number of stacks with differences: 1
cdk deploy
Output:
✅ MyAppStack
ARN: arn:aws:cloudformation:us-east-1:123456789012:stack/MyAppStack/0a1b2c3d
You can also do everything in the AWS Management Console, since the CDK just produces CloudFormation:
- Run
cdk synth > template.yamllocally to generate the template. - Open the AWS Console and go to CloudFormation.
- Click Create stack then With new resources (standard).
- Choose Upload a template file, select your
template.yaml, and click Next. - Name the stack, accept the IAM capability checkbox if prompted, and click Submit.
The CDK is CloudFormation underneath. An L3 pattern like
ApplicationLoadBalancedFargateServicecan quietly create a VPC, subnets, NAT gateways, a load balancer, and an ECS cluster — 30-plus resources from one line. Two NAT gateways alone cost roughly 65 USD per month before any traffic. Always runcdk diffand read the resource list so a one-line code change does not balloon your bill.
Because it is CloudFormation, the same replacement gotchas apply. Changing an immutable property (like a bucket name or an RDS database identifier) makes CloudFormation delete and recreate the resource. With
removalPolicy: RemovalPolicy.RETAINand stateful resources, double-checkcdk difffor[-]/[+]pairs that signal data loss.
Best practices
- Run
cdk diffbefore everycdk deployand actually read the generated resources — never deploy blind. - Prefer L2 constructs over L1 for sensible defaults, but drop to L1 (
Cfn*) when you need fine control the L2 does not expose. - Pin your CDK library version in
package.jsonand keep the toolkit and library versions aligned to avoid synth errors. - Keep stateful resources (databases, buckets with data) in separate stacks from disposable compute, so you can redeploy compute without risking data.
- Use
removalPolicy: RETAINon anything holding data so an accidentalcdk destroycannot wipe it. - Treat the synthesized template as the source of truth in code review for high-risk changes, since the CDK code hides the real resource graph.
- Tag stacks and use
cdk deploy --require-approval broadeningso security-group or IAM widening changes pause for confirmation.