CloudFormation is the AWS-native service that creates resources from a template as a stack, tracks what it created, and rolls back if something fails. The AWS Cloud Development Kit (CDK) lets you write the same infrastructure in a programming language such as TypeScript or Python, then generates CloudFormation templates for you. CDK version 2, which is a single package called aws-cdk-lib, has been the current line since December 2021.
From code to resources
flowchart TB
CODE[CDK app in TypeScript] -->|cdk synth| TPL[CloudFormation template JSON]
YAML[Handwritten template YAML] --> TPL
TPL -->|cdk diff or change set| REVIEW{Review changes}
REVIEW -->|approve| STACK
subgraph STACK[CloudFormation stack]
R1[Resources] --> ST[Stack state and events]
end
STACK -->|create update delete| AWS[(AWS services)]
STACK -->|failure| RB[Automatic rollback]
BOOT[CDKToolkit bootstrap stack<br/>S3 bucket, ECR, IAM roles] -.-> STACK
STACK --> DRIFT[Drift detection<br/>finds manual console changes]
CloudFormation by hand
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
Env: { Type: String, AllowedValues: [dev, prod] }
Resources:
Assets:
Type: AWS::S3::Bucket
DeletionPolicy: Retain
UpdateReplacePolicy: Retain
Properties:
BucketName: !Sub "acme-assets-${Env}-${AWS::AccountId}"
VersioningConfiguration: { Status: Enabled }
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault: { SSEAlgorithm: AES256 }
Outputs:
BucketArn: { Value: !GetAtt Assets.Arn }
aws cloudformation validate-template --template-body file://assets.yaml
aws cloudformation deploy --template-file assets.yaml --stack-name assets-dev \
--parameter-overrides Env=dev --no-execute-changeset # create a change set only
aws cloudformation describe-change-set --stack-name assets-dev --change-set-name <name-from-output>
aws cloudformation deploy --template-file assets.yaml --stack-name assets-dev --parameter-overrides Env=dev
aws cloudformation describe-stack-events --stack-name assets-dev --max-items 10
aws cloudformation detect-stack-drift --stack-name assets-dev
A change set shows what will be added, modified or replaced before anything happens. Replacement of a stateful resource (database, bucket) usually means data loss, so DeletionPolicy: Retain (or Snapshot for databases) and UpdateReplacePolicy are your safety net.
The same thing with CDK
node --version # use an active LTS version, 16 at the moment
npm install -g aws-cdk
mkdir assets && cd assets
cdk init app --language typescript
cdk bootstrap aws://111122223333/ap-south-1 # once per account and region
lib/assets-stack.ts:
import { Stack, StackProps, RemovalPolicy, CfnOutput } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
export class AssetsStack extends Stack {
constructor(scope: Construct, id: string, props?: StackProps) {
super(scope, id, props);
const bucket = new s3.Bucket(this, 'Assets', {
versioned: true,
encryption: s3.BucketEncryption.S3_MANAGED,
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
enforceSSL: true,
removalPolicy: RemovalPolicy.RETAIN,
});
new CfnOutput(this, 'BucketArn', { value: bucket.bucketArn });
}
}
npm run build
cdk synth # print the template
cdk diff # what would change, including IAM statement changes
cdk deploy
cdk destroy # respects the retain policy
CDK constructs come in three levels: L1 (CfnBucket, a direct template mapping), L2 (s3.Bucket, sensible defaults and helper methods like bucket.grantRead(fn)) and L3 (patterns that wire several services). L2 helpers generate least-privilege IAM policies for you, a big reason teams like CDK.
Choosing between tools
| Question | CloudFormation | CDK | Terraform |
|---|---|---|---|
| Only AWS | Good | Good | Good |
| Several clouds or SaaS | No | No | Yes |
| Loops, conditions, reuse | Awkward | Natural (a real language) | Good (HCL) |
| State to manage yourself | No (service tracks it) | No | Yes (remote state) |
| New AWS features | Often first | Follows CloudFormation | Provider release lag |
Operations
- Stack policies and termination protection (
aws cloudformation update-termination-protection --enable-termination-protection) for production stacks. - Roll back safely: failed updates roll back automatically; a stack stuck in
UPDATE_ROLLBACK_FAILEDcan be continued withcontinue-update-rollback, skipping the stuck resource only when you understand why. - Split stacks by lifecycle (network, data, application). Avoid one giant stack: the limit is 500 resources per stack, and big stacks deploy slowly.
- Cross-stack references with exports create tight coupling; pass values through parameters or SSM parameters where you can.
- Deploy from CI with a role limited to CloudFormation and what the stack manages; commit
cdk.context.jsonand the lock file, and pin the CDK version inpackage.json. - Run
cfn-lint(templates) and unit-test CDK with theassertionsmodule in the pull request. - Never edit CloudFormation-managed resources in the console; run drift detection regularly and fix drift in code.