D

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.

SkillCommunitydevopsv1.0.0MIT
0 views0 copies

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

ConceptDescriptionScope
AppRoot container for all stacksAccount-level
StackUnit of deployment (CloudFormation stack)Region-level
ConstructReusable infrastructure componentStack-level
L1 (Cfn)Direct CloudFormation resourcesLow-level
L2Opinionated AWS constructsMid-level
L3 (Patterns)Multi-resource patternsHigh-level
AspectCross-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

OptionDescriptionDefault
accountAWS account IDFrom environment
regionAWS regionFrom environment
stageDeployment stage: dev, staging, prod"dev"
removal_policyResource deletion behaviorRETAIN (prod)
encryptionEnable encryption at resttrue
monitoringEnable CloudWatch alarmstrue
taggingDefault resource tags{}
stack_prefixPrefix for all stack names""

Best Practices

  1. 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
  2. Use cdk diff before every deploy to review infrastructure changes before they are applied — CDK changes can have surprising effects like replacing databases or changing security group rules
  3. Set removalPolicy: RETAIN on stateful resources (databases, S3 buckets) in production to prevent accidental data loss when stacks are updated or deleted
  4. 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
  5. 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.

Community

Reviews

Write a review

No reviews yet. Be the first to review this template!

Similar Templates