What you'll learn
- CDK has three levels of constructs. L1 (
CfnBucket) mirrors CloudFormation one to one; L2 (Bucket) adds sensible defaults and helper methods; L3 are patterns. - Stateful resources default to RETAIN: deleting the stack leaves the bucket behind. For a disposable dev stack choose
DESTROY. autoDeleteObjectsneedsremovalPolicy: DESTROY. CDK refuses the combination otherwise: it would empty a bucket that CloudFormation then keeps.
Section 01
L1, L2 and L3
L1 constructs are generated from the CloudFormation specification and are named Cfn…. You set every property yourself and get no defaults. L2 constructs are hand-written, one per service concept: s3.Bucket, dynamodb.Table, lambda.Function. They choose safe defaults, validate your input and give you methods like grantRead. L3 constructs, also called patterns, assemble several resources for a use case.
Start with L2. Drop to L1 only when a property you need isn't exposed yet (an escape hatch, which you'll meet in Quest 12).
| Level | Example | You get |
|---|---|---|
| L1 | s3.CfnBucket | Exactly the CloudFormation resource, nothing added |
| L2 | s3.Bucket | Defaults, validation, grant and metric methods |
| L3 | ApplicationLoadBalancedFargateService | Several resources wired together for one purpose |
Section 02
Create the bucket
Props are plain data: strings, booleans and enum values. Python spells them in snake_case; TypeScript in camelCase. They mean the same thing.
versionedkeeps old versions, so an overwritten card can be restored.blockPublicAccess: new buckets already block public access at the account default, but saying it in code makes the intent reviewable.enforceSSLadds a bucket policy that denies any request not made over TLS.
import * as cdk from "aws-cdk-lib";
import * as s3 from "aws-cdk-lib/aws-s3";
const bucket = new s3.Bucket(this, "CardsBucket", {
versioned: true,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
enforceSSL: true,
removalPolicy: cdk.RemovalPolicy.DESTROY, // dev only
autoDeleteObjects: true, // needs DESTROY
});Section 03
What synth really produces
A few props produce more than one resource. The bucket itself carries DeletionPolicy: Delete because you chose DESTROY; enforceSSL adds an AWS::S3::BucketPolicy; and autoDeleteObjects adds a custom resource, Custom::S3AutoDeleteObjects, backed by a small Lambda function that empties the bucket when the stack is deleted. Run the exercise below and open the output to see all of them.
"CardsBucket685ECB20": {
"Type": "AWS::S3::Bucket",
"Properties": { "VersioningConfiguration": { "Status": "Enabled" }, … },
"UpdateReplacePolicy": "Delete",
"DeletionPolicy": "Delete"
}Try it · What synth produces
Toggle bucket props and see the resources CloudFormation would receive.
new s3.Bucket(this, "CardsBucket", {
versioned: true,
});Resources (1)
- AWS::S3::BucketCardsBucket685ECB20DeletionPolicy: Retain (the default)
Section 04
Removal policies
The removal policy answers: “when this resource is removed from the stack, or the stack is deleted, what happens?” RETAIN keeps it (the default for buckets and tables), also when CloudFormation replaces it, DESTROY deletes it, SNAPSHOT takes a final snapshot where the service supports it, and RETAIN_ON_UPDATE_OR_DELETE keeps it on update or delete, but still removes a resource whose creation failed and rolled back.
The exercise starter fails on purpose: it sets autoDeleteObjects without DESTROY. The error text is the real one CDK throws. Fix the combination and finish the bucket.
Practice
Your turn
Configure the card bucket for the dev stack. It should keep every version of a card, refuse public access and plain-HTTP requests, and — because this is a throwaway dev stack — be deleted together with its objects. The starter already fails: read the error.
versioned, blockPublicAccess: BLOCK_ALL, enforceSSL, and removalPolicy: DESTROY with autoDeleteObjects.The simulator runs the constructs this course teaches, plus simple loops and helper methods. Other CDK code may not be recognised.
Check
Check your understanding
Quick Quiz · one question, as many tries as you need.
s3.Bucket (an L2 construct) versus s3.CfnBucket (L1) is true?Choose one answer.