CDK is a framework for defining cloud infrastructure in familiar programming languages, and it doesn’t actually "migrate" CloudFormation templates; it lets you re-implement them.
Let’s see how this works with an example. Imagine you have a simple CloudFormation template that creates an S3 bucket.
Resources:
MyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-unique-bucket-name-12345
Tags:
- Key: Environment
Value: Production
Here’s how you’d define the exact same S3 bucket using the AWS CDK in TypeScript:
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import { Construct } from 'constructs';
export class MyS3Stack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
new s3.Bucket(this, 'MyS3Bucket', {
bucketName: 'my-unique-bucket-name-12345',
removalPolicy: cdk.RemovalPolicy.RETAIN, // Default is RETAIN for buckets
autoDeleteObjects: false, // Default is false
versioned: false, // Default is false
encryption: s3.BucketEncryption.S3_MANAGED, // Default is S3_MANAGED
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, // Default is BLOCK_ALL
tags: {
Environment: 'Production',
},
});
}
}
When you run cdk synth, the CDK CLI synthesizes this TypeScript code into a CloudFormation template. The output will look something like this:
Resources:
MyS3Bucket8B962869:
Type: AWS::S3::Bucket
Properties:
BucketName: my-unique-bucket-name-12345
Tags:
- Key: Environment
Value: Production
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: AES256
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
DeletionPolicy: Retain
Notice how the CDK automatically adds sensible defaults for BucketEncryption, PublicAccessBlockConfiguration, and DeletionPolicy (which corresponds to removalPolicy in CDK). This is a key difference: CloudFormation defines what you want, and the CDK defines what you want and then uses sensible defaults to fill in the rest, often making your definitions more concise.
The core problem the CDK solves is the verbosity and imperative nature of CloudFormation. CloudFormation templates are JSON or YAML documents that describe resources and their relationships. While powerful, they can become very large and difficult to manage, especially for complex applications. The CDK allows you to define infrastructure using familiar programming paradigms like classes, loops, conditionals, and functions. This leads to more readable, maintainable, and reusable infrastructure code.
Internally, the CDK uses a concept called "Constructs." A Construct is a logical component that represents a cloud resource or a collection of resources. When you instantiate a CDK construct (like new s3.Bucket(...)), you’re creating an object that knows how to generate the underlying CloudFormation resources. The CDK framework then traverses this "construct tree" during synthesis to produce the final CloudFormation template.
You control the CDK through the programming language you choose (TypeScript, Python, Java, C#, Go) and the specific AWS service libraries you import. For instance, to define an EC2 instance, you’d import aws-ec2 and use classes like Instance. The cdk.Stack is the fundamental unit of deployment, representing a CloudFormation stack. You can group related stacks into cdk.App for managing multiple deployments.
One of the most powerful aspects of the CDK, and something often overlooked, is its ability to compose and abstract infrastructure. You can create your own custom constructs that encapsulate common patterns of resources. For instance, you might create a DatabaseCluster construct that bundles an RDS instance, a security group, and a parameter group. This allows you to treat complex infrastructure setups as single, reusable components. When you use this DatabaseCluster construct multiple times in your application, you’re not repeating dozens of lines of CloudFormation; you’re simply instantiating your custom construct. This abstraction is where the real power of the CDK lies for managing infrastructure at scale.
The next step after defining your infrastructure with CDK constructs is deploying it.