AWS CDK Guide

Created: March 23, 2025

What is AWS CDK

  • AWS Cloud Development Kit - a framework for defining cloud resources using programming languages
  • Supports TypeScript, JavaScript, Python, Java, C#, Go and other programming languages
  • Learning resources: AWS Black Belt Online Seminar, workshops, and more
Define your infrastructure
as code using your favorite
programming language!

Benefits

  • Type safety helps detect errors at compile time
  • Code reuse standardizes best practices and improves quality
  • Improved productivity: IDE completion, conditions, loops, etc.
  • Infrastructure and app integration: unified repository management
  • Scaling and governance: easy deployment across multiple environments/regions
Build the same environment
with less code than
CloudFormation!

CDK Components

  • App: Top-level construct that defines stack dependencies
  • Stack: Corresponds to one CloudFormation stack
  • Construct: Creates resource definitions in the stack
  • Construct levels:
    • L1: 1:1 mapping with CloudFormation resources (Cfn prefix)
    • L2: Higher level of abstraction (reduces boilerplate code)
    • L3: Patterns, implementations combining multiple resources
L2 Constructs are recommended!
They auto-generate resources
and reduce code volume

CDK Commands

  • cdk init: Set up necessary files
  • cdk bootstrap: Create resources needed for CDK
  • cdk deploy: Deploy resources to AWS environment
  • cdk diff: Check differences between code and deployed environment
  • cdk synth: Generate CloudFormation template
  • cdk destroy: Delete stacks
  • cdk list / cdk ls: Display list of stacks in the app

Development Methods

  • Required knowledge: AWS resources basics, CloudFormation experience, programming experience
  • Required environment: AWS CLI v2, Node.js, text editor (IDE recommended)
  • Directory structure: separate into stacks, resources, utils, parameters
  • Stack division: manage with a single stack when possible (cross-stack references are complex)
  • Construct ID naming conventions: PascalCase, simple names recommended
Be careful with stack division!
Resource dependencies can
cause deadlocks!

Testing Methods

  • Snapshot Test: Check differences from previously generated templates
  • Unit Test: Resource-level testing using Jest
  • Test example:
test("create the vpc", () => {
  // GIVEN
  const app = new App();
  const stack = new VPCStack(app, "testing-vpc", {});
  // WHEN
  const template = Template.fromStack(stack);
  // THEN
  template.resourceCountIs("AWS::EC2::VPC", 1);
  template.hasResourceProperties("AWS::EC2::VPC", {
    CidrBlock: "10.0.0.0/16",
  });
});

Practical Tips

  • Common tagging: Tags.of(app).add('Key', 'Value')
  • Dynamic parameters: Specify with -c key=value, retrieve with app.node.tryGetContext('key')
  • Production environment protection: Warning messages, terminationProtection: true
  • Region specification: Manage with defaultEnv variable
  • Profile naming: Match environment identifiers with profile names to prevent mistakes
Pre-define commands in
package.json for convenience!
npm run cdk:deploy:all

cdk-nag

  • cdk-nag: Static analysis tool for security and compliance enforcement
  • Rules Pack: Numerous rule sets including AWS Solutions, HIPAA, NIST, PCI
  • Implementation example:
// Add to App definition
import { AwsSolutionsChecks } from "cdk-nag";
const app = new cdk.App();
cdk.Aspects.of(app).add(new AwsSolutionsChecks());
  • Error suppression: Exclude specific rules with NagSuppressions
  • Custom rules: Add your own rules by extending NagPack
Use cdk-nag to
automatically check
security best practices!

CDK v2 Features

  • Single package: Libraries integrated into aws-cdk-lib
  • Difference from v1:
// CDK v1
npm install @aws-cdk/aws-lambda
npm install @aws-cdk/aws-s3
// ...other packages

// CDK v2
npm install aws-cdk-lib
  • Separation trend: Since February 2025, AWS CDK CLI and CDK construct library are being separated
  • CLI starts from version 2.1000.0 with the new version system
Pay attention to latest trends!
Dependency management in
package.json might change!