CloudFormation YAML is verbose and lacks logic. The AWS Cloud Development Kit (CDK) allows you to define cloud resources using imperative languages. In this guide, we build a complete serverless stack (Lambda + API Gateway + DynamoDB) using TypeScript.
The Construct Tree
CDK components are called “Constructs”. Level 1 (L1) constructs are 1:1 mappings to CloudFormation. Level 2 (L2) constructs offer high-level abstractions with sensible defaults.
import * as cdk from '@aws-cdk/core';
import * as lambda from '@aws-cdk/aws-lambda';
import * as apigateway from '@aws-cdk/aws-apigateway';
import * as dynamodb from '@aws-cdk/aws-dynamodb';
export class ServerlessStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// L2 Construct: DynamoDB Table
const table = new dynamodb.Table(this, 'ItemsTable', {
partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, // On-Demand
removalPolicy: cdk.RemovalPolicy.DESTROY // For dev only
});
// L2 Construct: Lambda
const handler = new lambda.Function(this, 'ItemHandler', {
runtime: lambda.Runtime.NODEJS_12_X,
code: lambda.Code.fromAsset('lambdas'),
handler: 'items.handler',
environment: {
TABLE_NAME: table.tableName
}
});
// Auto-grant permissions (IAM)
table.grantReadWriteData(handler);
// L2 Construct: API Gateway
const api = new apigateway.RestApi(this, 'ItemsApi');
api.root.addMethod('GET', new apigateway.LambdaIntegration(handler));
}
}
Synthesis and Deployment
CDK compiles your code into a CloudFormation template.
# Generate YAML
cdk synth
# Deploy to AWS
cdk deploy
Testing Infrastructure
Since it’s code, you can write unit tests using `@aws-cdk/assert`.
test('DynamoDB Table Created', () => {
const app = new cdk.App();
const stack = new ServerlessStack(app, 'MyTestStack');
expectCDK(stack).to(haveResource('AWS::DynamoDB::Table', {
BillingMode: 'PAY_PER_REQUEST'
}));
});
Key Takeaways
- CDK is **not** Terraform; it generates CloudFormation which AWS executes.
- Use **grant** methods (e.g., `grantReadWriteData`) to handle complex IAM policies automatically.
- Unit test your infrastructure configuration to catch compliance issues early.
Discover more from C4: Container, Code, Cloud & Context
Subscribe to get the latest posts sent to your email.