Skip to main content

AWS CDK Guide

Define AWS infrastructure using real programming languages — TypeScript, Python, Java, C#, or Go. AWS CDK synthesizes your code into CloudFormation and deploys it with a single command.

✓ TypeScript / Python / Java / C# / Go ✓ L1 / L2 / L3 Constructs ✓ CDK Pipelines CI/CD ✓ cdk diff safety checks

What is AWS CDK?

AWS Cloud Development Kit (CDK) is an open-source infrastructure-as-code framework that lets you define cloud resources using general-purpose programming languages instead of YAML or JSON. Released by AWS in 2019 and now at v2, CDK compiles your code into CloudFormation templates during a synthesis step, then uses CloudFormation's battle-tested engine to provision and update resources. This means you get all the safety guarantees of CloudFormation (drift detection, rollbacks, change sets) plus the developer ergonomics of modern languages: type safety, IDE auto-complete, loops, conditionals, unit tests, and package management via npm or pip.

The core abstraction in CDK is the Construct — a reusable cloud component that can represent a single resource (like an S3 bucket) or a complex pattern (like a load-balanced ECS service with autoscaling, logging, and IAM). Constructs are organized into Stacks, which map 1:1 to CloudFormation stacks. Stacks live inside an App, the root of every CDK project.

Key Features

Getting Started: Your First CDK App

Install the CDK CLI and scaffold a new TypeScript project:

npm install -g aws-cdk
cdk init app --language typescript
npm install

Define a stack with an S3 bucket and Lambda function:

// lib/my-app-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as s3n from 'aws-cdk-lib/aws-s3-notifications';
import { Construct } from 'constructs';

export class MyAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // L2 construct — S3 bucket with secure defaults
    const bucket = new s3.Bucket(this, 'DataBucket', {
      bucketName: `my-app-data-${this.account}`,
      versioned: true,
      encryption: s3.BucketEncryption.S3_MANAGED,
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
      removalPolicy: cdk.RemovalPolicy.RETAIN,
    });

    // L2 construct — Lambda function with bundled code
    const processor = new lambda.Function(this, 'Processor', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromAsset('lambda'),
      environment: {
        BUCKET_NAME: bucket.bucketName,
      },
      timeout: cdk.Duration.seconds(30),
      memorySize: 512,
    });

    // Grant Lambda read/write access to the bucket (manages IAM automatically)
    bucket.grantReadWrite(processor);

    // Trigger Lambda on S3 object uploads
    bucket.addEventNotification(
      s3.EventType.OBJECT_CREATED,
      new s3n.LambdaDestination(processor)
    );

    // Output the bucket name
    new cdk.CfnOutput(this, 'BucketName', { value: bucket.bucketName });
  }
}

Synthesize and deploy:

cdk bootstrap aws://ACCOUNT_ID/us-east-1   # one-time setup
cdk synth                                   # generate CloudFormation template
cdk diff                                    # preview changes
cdk deploy                                  # deploy to AWS

Using L3 Pattern Constructs

import * as ecs_patterns from 'aws-cdk-lib/aws-ecs-patterns';
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

// One L3 construct provisions: VPC, ECS cluster, Fargate service,
// Application Load Balancer, target group, IAM roles, CloudWatch logs
const loadBalancedService = new ecs_patterns.ApplicationLoadBalancedFargateService(
  this, 'ApiService', {
    cluster: new ecs.Cluster(this, 'Cluster', { vpc }),
    cpu: 512,
    memoryLimitMiB: 1024,
    desiredCount: 2,
    taskImageOptions: {
      image: ecs.ContainerImage.fromRegistry('nginx:latest'),
      containerPort: 80,
    },
    publicLoadBalancer: true,
  }
);

// Add autoscaling
const scaling = loadBalancedService.service.autoScaleTaskCount({ maxCapacity: 10 });
scaling.scaleOnCpuUtilization('CpuScaling', { targetUtilizationPercent: 70 });

CDK vs Alternatives

Feature AWS CDK Terraform CloudFormation Pulumi SAM
Language TS / Python / Java / C# / Go HCL YAML / JSON TS / Python / Go / .NET YAML
Cloud support AWS only Multi-cloud AWS only Multi-cloud AWS only (serverless)
State management CloudFormation State file (S3/TFC) CloudFormation Pulumi Service / S3 CloudFormation
Type safety Excellent (TypeScript) Good (HCL validation) Poor (YAML) Excellent Poor (YAML)
Learning curve Medium Low-Medium High (verbose) Medium Low
CI/CD integration CDK Pipelines Terraform Cloud / Actions CodePipeline Pulumi Deployments SAM Pipelines

Use Cases

Pros and Cons

Pros

  • ✓ Full programming language expressiveness
  • ✓ IDE auto-complete and type checking catch errors early
  • ✓ Reusable constructs reduce boilerplate significantly
  • ✓ CloudFormation handles state, rollbacks, drift detection
  • ✓ Large and growing construct ecosystem (Construct Hub)
  • ✓ Unit-testable infrastructure code

Cons

  • ✗ AWS-only (no Azure or GCP support)
  • ✗ CloudFormation limits apply (500 resources per stack)
  • ✗ Synthesis can be slow for very large apps
  • ✗ Breaking changes between major CDK versions
  • ✗ Harder to read for ops teams unfamiliar with programming
  • ✗ CloudFormation deployment can be slower than Terraform

Frequently Asked Questions

What is AWS CDK and how does it differ from CloudFormation?▼

AWS CDK (Cloud Development Kit) is an open-source framework that lets you define cloud infrastructure using familiar programming languages like TypeScript, Python, Java, C#, and Go. Under the hood, CDK synthesizes your code into CloudFormation templates. The key difference is developer experience: instead of writing hundreds of lines of YAML, you write type-safe, object-oriented code with IDE auto-completion, loops, conditionals, and abstractions. CDK Constructs are reusable building blocks that encapsulate best practices, making CDK far more productive than raw CloudFormation.

What are L1, L2, and L3 constructs in AWS CDK?▼

CDK organizes constructs into three levels. L1 (CloudFormation Resources, prefixed with Cfn) are auto-generated direct mappings to CloudFormation resources — they expose every property but require you to configure everything. L2 constructs are handcrafted abstractions with sensible defaults, type-safe properties, and helper methods (e.g., s3.Bucket, lambda.Function). L3 constructs (also called Patterns) are higher-level solutions that compose multiple L2 constructs, like aws-ecs-patterns.ApplicationLoadBalancedFargateService, which wires up ECS, ALB, IAM, and more automatically.

How do I deploy a CDK app to AWS?▼

First run cdk bootstrap to provision the CDK Toolkit stack in your account (one-time per account/region). Then run cdk synth to generate the CloudFormation template and review it. Run cdk diff to see exactly what changes will be made versus what is currently deployed. Finally run cdk deploy to provision or update resources. You can deploy specific stacks with cdk deploy MyStack or all stacks with cdk deploy --all. For CI/CD, use CDK Pipelines which automates synthesis, testing, and multi-stage deployment.

What is cdk diff and why is it important?▼

cdk diff compares your synthesized template against the currently deployed CloudFormation stack and shows a detailed diff of added, modified, and removed resources. This is critical for safety — it lets you review exactly what will change before deploying, similar to terraform plan. Pay special attention to replacements (shown in red): some resource changes (like renaming a DynamoDB table) require destroying and recreating the resource, which means data loss. Always run cdk diff before cdk deploy in production.

How does CDK handle secrets and sensitive configuration?▼

CDK itself does not store secrets. The recommended pattern is to use AWS Secrets Manager or AWS Systems Manager Parameter Store to store secrets, then reference them in your CDK code using SecretValue.secretsManager() or ssm.StringParameter.valueForStringParameter(). This keeps secrets out of your source code and CDK templates. For environment-specific configuration, use CDK context values (cdk.json or --context flags) for non-sensitive data, and never hardcode credentials in stacks.

What is CDK Pipelines and when should I use it?▼

CDK Pipelines is a high-level construct library for building continuous delivery pipelines using AWS CodePipeline. It automates the entire release process: source checkout, CDK synthesis, unit tests, deployment to multiple stages (dev/staging/prod), and integration tests between stages. You should use CDK Pipelines when you want self-mutating pipelines (the pipeline updates itself when you push changes to its definition), multi-account deployments, or a GitOps-style workflow where merging to main automatically triggers deployments.

Share this tool: X / Twitter LinkedIn
✓ 60,000+ developers use DevPlaybook ★★★★★ 4.8 / 5 on Gumroad ✓ MIT licensed · Instant download ✓ No login required

Related Products

on Gumroad

You Might Also Need

More Free Tools

Enjoying this tool? Get more like it.

Weekly developer tool guides, productivity playbooks & AI tricks. Free. No spam.

DevPlaybook Pro 7 days free

Unlock AI-Powered Dev Tools

  • ⚡ AI Code Review, Doc Generator & SQL Builder
  • ⚡ All premium templates & early access
  • ⚡ Member discounts on Gumroad products
Start Free Trial →

$9/mo after trial · Cancel anytime

Want the full toolkit?

Get DevPlaybook Pro

Every template, guide, boilerplate, and automation script in one bundle. 13 premium products — grab them all at once and save big.

$79
$241 separately Save $162 (67% off)
Get DevPlaybook Pro — $79 →

MIT licensed · Instant download · No subscription

See what's included → Browse all deals →