Dynamic AWS CDK Development Engine
Enterprise-ready skill that automates aWS cloud development with CDK best practices and serverless patterns. Built for Claude Code with best practices and real-world patterns.
AWS CDK Development
An infrastructure-as-code skill for defining, deploying, and managing AWS cloud infrastructure using the AWS Cloud Development Kit with TypeScript, including best practices for constructs, stacks, and CI/CD.
When to Use
Choose AWS CDK when:
- Defining AWS infrastructure using TypeScript/Python instead of YAML/JSON templates
- Building reusable infrastructure components as CDK constructs
- Deploying complex multi-stack AWS architectures with dependencies
- Implementing infrastructure CI/CD pipelines with automated testing
Consider alternatives when:
- Managing multi-cloud infrastructure — use Terraform or Pulumi
- Simple serverless deployments — use SST or AWS SAM
- One-time infrastructure setup — use the AWS Console or CLI
Quick Start
# Install and initialize CDK npm install -g aws-cdk cdk init app --language typescript # Deploy cdk synth # Generate CloudFormation cdk diff # Preview changes cdk deploy # Deploy to AWS
import * as cdk from 'aws-cdk-lib'; import * as lambda from 'aws-cdk-lib/aws-lambda'; import * as apigateway from 'aws-cdk-lib/aws-apigateway'; import * as dynamodb from 'aws-cdk-lib/aws-dynamodb'; import { Construct } from 'constructs'; export class ApiStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // DynamoDB table const table = new dynamodb.Table(this, 'ItemsTable', { partitionKey: { name: 'PK', type: dynamodb.AttributeType.STRING }, sortKey: { name: 'SK', type: dynamodb.AttributeType.STRING }, billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, removalPolicy: cdk.RemovalPolicy.RETAIN, pointInTimeRecovery: true }); table.addGlobalSecondaryIndex({ indexName: 'GSI1', partitionKey: { name: 'GSI1PK', type: dynamodb.AttributeType.STRING }, sortKey: { name: 'GSI1SK', type: dynamodb.AttributeType.STRING } }); // Lambda function const handler = new lambda.Function(this, 'ApiHandler', { runtime: lambda.Runtime.NODEJS_20_X, handler: 'index.handler', code: lambda.Code.fromAsset('lambda'), environment: { TABLE_NAME: table.tableName, NODE_ENV: 'production' }, memorySize: 256, timeout: cdk.Duration.seconds(30), tracing: lambda.Tracing.ACTIVE }); table.grantReadWriteData(handler); // API Gateway const api = new apigateway.RestApi(this, 'ItemsApi', { restApiName: 'Items Service', deployOptions: { stageName: 'prod', throttlingRateLimit: 100, throttlingBurstLimit: 200 }, defaultCorsPreflightOptions: { allowOrigins: apigateway.Cors.ALL_ORIGINS, allowMethods: apigateway.Cors.ALL_METHODS } }); const items = api.root.addResource('items'); items.addMethod('GET', new apigateway.LambdaIntegration(handler)); items.addMethod('POST', new apigateway.LambdaIntegration(handler)); const item = items.addResource('{id}'); item.addMethod('GET', new apigateway.LambdaIntegration(handler)); item.addMethod('PUT', new apigateway.LambdaIntegration(handler)); item.addMethod('DELETE', new apigateway.LambdaIntegration(handler)); // Outputs new cdk.CfnOutput(this, 'ApiUrl', { value: api.url }); new cdk.CfnOutput(this, 'TableName', { value: table.tableName }); } }
Core Concepts
CDK Architecture
| Concept | Description | Scope |
|---|---|---|
| App | Root container for all stacks | Account-level |
| Stack | Unit of deployment (CloudFormation stack) | Region-level |
| Construct | Reusable infrastructure component | Stack-level |
| L1 (Cfn) | Direct CloudFormation resources | Low-level |
| L2 | Opinionated AWS constructs | Mid-level |
| L3 (Patterns) | Multi-resource patterns | High-level |
| Aspect | Cross-cutting concerns (tagging, compliance) | App-level |
Reusable Construct Pattern
interface MicroserviceProps { serviceName: string; tableName: string; memorySize?: number; environment?: Record<string, string>; } class Microservice extends Construct { public readonly function: lambda.Function; public readonly table: dynamodb.Table; public readonly api: apigateway.RestApi; constructor(scope: Construct, id: string, props: MicroserviceProps) { super(scope, id); this.table = new dynamodb.Table(this, 'Table', { tableName: props.tableName, partitionKey: { name: 'id', type: dynamodb.AttributeType.STRING }, billingMode: dynamodb.BillingMode.PAY_PER_REQUEST }); this.function = new lambda.Function(this, 'Handler', { runtime: lambda.Runtime.NODEJS_20_X, handler: 'index.handler', code: lambda.Code.fromAsset(`services/${props.serviceName}`), memorySize: props.memorySize || 256, environment: { TABLE_NAME: this.table.tableName, ...props.environment } }); this.table.grantReadWriteData(this.function); this.api = new apigateway.RestApi(this, 'Api', { restApiName: `${props.serviceName}-api` }); } }
Configuration
| Option | Description | Default |
|---|---|---|
account | AWS account ID | From environment |
region | AWS region | From environment |
stage | Deployment stage: dev, staging, prod | "dev" |
removal_policy | Resource deletion behavior | RETAIN (prod) |
encryption | Enable encryption at rest | true |
monitoring | Enable CloudWatch alarms | true |
tagging | Default resource tags | {} |
stack_prefix | Prefix for all stack names | "" |
Best Practices
- Create reusable L3 constructs for common patterns in your organization (API + Lambda + DynamoDB) so teams get consistent, well-configured infrastructure without repeating boilerplate across stacks
- Use
cdk diffbefore every deploy to review infrastructure changes before they are applied — CDK changes can have surprising effects like replacing databases or changing security group rules - Set
removalPolicy: RETAINon stateful resources (databases, S3 buckets) in production to prevent accidental data loss when stacks are updated or deleted - Use CDK Aspects for cross-cutting concerns like tagging all resources, enforcing encryption, or ensuring logging is enabled — Aspects apply rules across the entire construct tree without modifying individual constructs
- Write CDK tests using the assertions library to verify your constructs produce the expected CloudFormation output, catching configuration errors before deployment
Common Issues
Circular dependency between stacks: Two stacks that reference each other's resources create a circular dependency that CDK cannot resolve. Break the cycle by passing resource ARNs as stack parameters, using SSM Parameter Store for cross-stack references, or consolidating related resources into a single stack.
CloudFormation resource limits: A single stack can contain at most 500 resources. Monitor resource count with cdk synth output, split large applications into multiple stacks with clearly defined boundaries, and use nested stacks for logical grouping.
Drift between CDK and actual AWS state: Manual changes in the AWS Console create drift that CDK does not detect. Use cdk diff to identify drift, import manually-created resources with cdk import, and establish a policy that all infrastructure changes go through CDK to prevent future drift.
Reviews
No reviews yet. Be the first to review this template!
Similar Templates
Full-Stack Code Reviewer
Comprehensive code review skill that checks for security vulnerabilities, performance issues, accessibility, and best practices across frontend and backend code.
Test Suite Generator
Generates comprehensive test suites with unit tests, integration tests, and edge cases. Supports Jest, Vitest, Pytest, and Go testing.
Pro Architecture Workspace
Battle-tested skill for architectural, decision, making, framework. Includes structured workflows, validation checks, and reusable patterns for development.