AWS CDK — Cloud Development Kit¶
From apprenticeship coursework and AWS docs.
Ultra-Short Summary¶
CDK lets you define AWS infrastructure using real programming languages (Python, TypeScript, Java) instead of JSON/YAML. You write code, CDK synthesises it into a CloudFormation template, and CloudFormation deploys it. The benefit: type safety, loops, conditionals, reusable components — things YAML can't do.
CDK vs CloudFormation vs Terraform¶
CloudFormation:
-> AWS-native IaC, JSON or YAML templates
-> Verbose, no loops or conditionals
-> Everything is possible but tedious for complex infrastructure
Terraform:
-> HCL (HashiCorp Config Language), multi-cloud
-> More expressive than raw CF, state stored separately
-> Large ecosystem, standard in many orgs
CDK:
-> Write in Python, TypeScript, Java, C#, Go
-> Compiles to CloudFormation
-> Best of both: real code + native AWS integration
-> You still get CloudFormation's rollback and state management
CDK is not a replacement for CloudFormation — it's a higher-level abstraction on top of it.
Core Concepts¶
App -> top-level CDK program
Stack -> unit of deployment (one CloudFormation stack)
Construct -> a reusable component (can be a single resource or many)
Hierarchy:
App
+-- Stack (dev)
| +-- Construct: VPC
| +-- Construct: ECS Cluster
| +-- Construct: Task Definition
| +-- Construct: Fargate Service
+-- Stack (prod)
+-- same constructs, different config
Constructs — Three Levels¶
| Level | Name | Description | Example |
|---|---|---|---|
| L1 | Cfn (CloudFormation) | Direct 1:1 mapping to CF resource | CfnBucket |
| L2 | Default | Higher-level with sensible defaults | s3.Bucket |
| L3 | Patterns | Complete solution patterns | ecs_patterns.ApplicationLoadBalancedFargateService |
Start with L2 (default), drop to L1 only if you need a CF property that L2 doesn't expose.
Setup and CLI¶
# Install CDK CLI
npm install -g aws-cdk
# Bootstrap your AWS account (one-time per region)
cdk bootstrap aws://ACCOUNT_ID/REGION
# Create a new project
mkdir my-app && cd my-app
cdk init app --language python
# Core workflow
cdk synth # synthesise CloudFormation template (see what will deploy)
cdk diff # show what will change vs what's deployed
cdk deploy # deploy to AWS
cdk destroy # tear down all resources in the stack
cdk bootstrap creates an S3 bucket and IAM roles CDK needs to deploy assets.
Python CDK Example¶
from aws_cdk import (
Stack,
aws_s3 as s3,
aws_lambda as lambda_,
aws_s3_notifications as s3n,
Duration,
)
from constructs import Construct
class ProcessingStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs):
super().__init__(scope, construct_id, **kwargs)
# S3 bucket with versioning and encryption (L2 sensible defaults)
bucket = s3.Bucket(
self, "UploadBucket",
versioned=True,
encryption=s3.BucketEncryption.S3_MANAGED,
removal_policy=RemovalPolicy.DESTROY, # for dev/test only
)
# Lambda function
processor = lambda_.Function(
self, "Processor",
runtime=lambda_.Runtime.PYTHON_3_12,
handler="index.handler",
code=lambda_.Code.from_asset("lambda"),
timeout=Duration.seconds(30),
)
# Grant Lambda read access to bucket (CDK manages the IAM policy)
bucket.grant_read(processor)
# Trigger Lambda when objects are uploaded
bucket.add_event_notification(
s3.EventType.OBJECT_CREATED,
s3n.LambdaDestination(processor),
)
Key things to notice:
- CDK generates IAM policies automatically (grant_read, grant_write)
- Resources have logical IDs (UploadBucket, Processor) — CDK generates unique physical names
- RemovalPolicy.DESTROY — CDK will delete the bucket on cdk destroy (dangerous in prod)
CDK Workflow¶
Write CDK code (Python/TypeScript)
|
v
cdk synth -> CloudFormation template (JSON)
|
v
cdk deploy -> CloudFormation executes the template
|
v
AWS resources created/updated
If anything fails:
CloudFormation rolls back all changes automatically
Useful CDK Patterns¶
Environment-specific stacks¶
app = cdk.App()
ProcessingStack(app, "Dev",
env=cdk.Environment(account="123456789", region="ap-southeast-2"),
stage="dev",
)
ProcessingStack(app, "Prod",
env=cdk.Environment(account="987654321", region="ap-southeast-2"),
stage="prod",
)
CDK Context and Parameters¶
# Pass values at deploy time
cdk deploy --context instance_type=t3.large
# Read in code
instance_type = self.node.try_get_context("instance_type") or "t3.small"
Aspect for tagging all resources¶
CDK Constructs Library¶
The constructs library has patterns for common architectures:
from aws_cdk import aws_ecs_patterns as ecs_patterns
# One construct deploys: ECS Cluster + Fargate Service + ALB + Target Group + Security Groups
ecs_patterns.ApplicationLoadBalancedFargateService(
self, "Service",
cluster=cluster,
cpu=512,
memory_limit_mib=1024,
task_image_options=ecs_patterns.ApplicationLoadBalancedTaskImageOptions(
image=ecs.ContainerImage.from_registry("nginx"),
),
public_load_balancer=True,
)
Mental Model¶
CloudFormation YAML = writing assembly language
CDK = writing Python that generates the assembly language
The compiler (CDK) knows AWS best practices:
-> L2 constructs add encryption by default
-> grant_read() creates the minimal necessary IAM policy
-> Constructs wire resources together correctly
You think in architecture, CDK thinks in CloudFormation.
cdk diff = git diff for infrastructure -- see changes before deploying
cdk synth = dry run -- inspect what will be deployed without touching AWS
SAA / SAP Patterns¶
| Scenario | Answer |
|---|---|
| Reuse infrastructure across multiple apps | CDK Construct (package and import) |
| Manage multiple environments from one codebase | CDK Stacks with env parameters |
| Add tags to every resource across the app | cdk.Tags.of(app).add(...) |
| Full-stack app deployment (ALB + ECS + RDS) | CDK Patterns (L3 constructs) |
| Preview changes before deploying | cdk diff |
| Roll back a bad deployment | CloudFormation handles rollback automatically |
Self-Quiz¶
- What does
cdk synthproduce and why should you run it before deploying? - What's the difference between L1, L2, and L3 CDK constructs?
- Why do you need to run
cdk bootstrapand what does it create? - How does
bucket.grant_read(processor)work — what does CDK generate? - You want different resources in dev vs prod. How do you structure this in CDK?
- CDK deploy fails halfway through. What happens to the resources already created?
- What's the relationship between CDK and CloudFormation?
- When would you reach for L1 (Cfn) constructs instead of L2?