Skip to content

Repository files navigation

@designofadecade/cdk-constructs

License: MIT

A comprehensive collection of opinionated AWS CDK constructs for rapid infrastructure deployment. This library provides high-level abstractions that simplify common AWS infrastructure patterns while following best practices.

πŸ“¦ Installation

Install the package from npm:

npm install @designofadecade/cdk-constructs

Peer Dependencies

This package requires the following peer dependencies:

npm install aws-cdk-lib constructs

πŸš€ Quick Start

import { Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Vpc, S3Bucket, CloudFront } from '@designofadecade/cdk-constructs';

export class MyStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    // Create a VPC with best practice defaults
    const vpc = new Vpc(this, 'MyVpc', {
      maxAzs: 3,
      natGateways: 1,
    });

    // Create an S3 bucket with versioning enabled
    const bucket = new S3Bucket(this, 'MyBucket', {
      versioned: true,
    });

    // Create a CloudFront distribution
    const distribution = new CloudFront(this, 'MyDistribution', {
      defaultBehavior: {
        origin: bucket.bucket,
      },
    });
  }
}

οΏ½ Documentation

Comprehensive documentation for all constructs is available in the docs/ directory:

Each document includes:

  • Detailed usage examples
  • Best practices and recommendations
  • Cost optimization tips
  • Common pitfalls to avoid
  • Related constructs

οΏ½πŸ“š Available Constructs

Infrastructure

  • Vpc - Virtual Private Cloud with configurable subnets and VPC endpoints
  • BastionHost - EC2 bastion host for secure SSH access
  • Server - EC2 instance with customizable configuration

Storage

  • S3Bucket - S3 bucket with encryption, versioning, and lifecycle policies
  • DynamoTable - DynamoDB table with global secondary indexes

Content Delivery

  • CloudFront - CDN distribution with custom domains and security headers

Compute

  • Function - Lambda function with simplified configuration
  • HttpApi - API Gateway HTTP API with Lambda integrations

Database

  • RdsDatabase - Aurora databases with provisioned and serverless v2 instances

Authentication & Authorization

  • Cognito - User pools with OAuth, MFA, and custom domains
  • GitHubAccess - GitHub Actions OIDC roles for secure CI/CD deployments

Messaging & Events

  • Sqs - SQS queues with dead letter queue support
  • EventBridge - EventBridge rules with scheduled tasks
  • Ses - Simple Email Service configuration

Secrets Management

  • Secrets - Secrets Manager with automatic rotation support

πŸ“– Construct Documentation

Vpc

Creates a VPC with public, private, and isolated subnets across multiple availability zones.

const vpc = new Vpc(this, 'MyVpc', {
  maxAzs: 3,
  natGateways: 1,
  endpoints: ['s3', 'dynamodb', 'secretsmanager'],
});

Key Features:

  • Configurable number of availability zones
  • Optional NAT gateways for private subnet internet access
  • VPC endpoints for AWS services (S3, DynamoDB, Secrets Manager, etc.)
  • Flow logs enabled by default

S3Bucket

Creates an S3 bucket with security best practices enabled.

const bucket = new S3Bucket(this, 'MyBucket', {
  versioned: true,
  lifecycleRules: [{
    enabled: true,
    transitions: [{
      storageClass: StorageClass.INTELLIGENT_TIERING,
      transitionAfter: Duration.days(30),
    }],
  }],
});

Key Features:

  • Encryption at rest with AWS managed keys
  • Block public access by default
  • Optional versioning
  • Lifecycle rules support
  • CORS configuration

CloudFront

Creates a CloudFront distribution with custom domains and security headers.

const distribution = new CloudFront(this, 'MyDistribution', {
  domainNames: ['example.com', 'www.example.com'],
  certificate: myCertificate,
  defaultBehavior: {
    origin: bucket.bucket,
    viewerProtocolPolicy: ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
  },
  responseHeadersPolicy: {
    securityHeaders: {
      strictTransportSecurity: {
        accessControlMaxAge: Duration.days(365),
        includeSubdomains: true,
      },
    },
  },
});

Key Features:

  • Custom domain support with ACM certificates
  • Security headers (HSTS, CSP, X-Frame-Options, etc.)
  • Origin access identity for S3 buckets
  • Custom behaviors and caching policies
  • Lambda@Edge function association

Function

Creates a Lambda function with simplified configuration.

const fn = new Function(this, 'MyFunction', {
  handler: 'index.handler',
  runtime: Runtime.NODEJS_20_X,
  code: Code.fromAsset('lambda'),
  environment: {
    TABLE_NAME: table.tableName,
  },
  timeout: Duration.seconds(30),
});

Key Features:

  • TypeScript and Node.js support
  • Environment variables
  • VPC integration
  • Function URLs
  • Layer support

HttpApi

Creates an API Gateway HTTP API with Lambda integrations.

const api = new HttpApi(this, 'MyApi', {
  corsConfiguration: {
    allowOrigins: ['https://example.com'],
    allowMethods: [CorsHttpMethod.GET, CorsHttpMethod.POST],
  },
});

// Add routes
api.addFunctionIntegration({
  path: '/users',
  method: 'GET',
  function: getUsersFunction,
});

// Add JWT authorizer
api.createJwtAuthorizer({
  identitySource: ['$request.header.Authorization'],
  issuerUrl: 'https://cognito-idp.us-east-1.amazonaws.com/us-east-1_xxxxx',
  audience: ['client-id'],
});

Key Features:

  • CORS configuration
  • JWT authorization with Cognito
  • Lambda function integrations
  • Custom domains
  • Request/response transformations

Cognito

Creates a Cognito User Pool with advanced features.

const cognito = new Cognito(this, 'MyUserPool', {
  selfSignUpEnabled: true,
  mfa: {
    mfaRequired: true,
    enableSms: false,
    enableTotp: true,
  },
  standardAttributes: {
    email: { required: true, mutable: false },
    phoneNumber: { required: false, mutable: true },
  },
  customDomain: {
    domainPrefix: 'auth-myapp',
  },
  callbackUrls: ['https://myapp.com/callback'],
  logoutUrls: ['https://myapp.com/logout'],
});

Key Features:

  • OAuth 2.0 flows (authorization code, implicit)
  • Multi-factor authentication (SMS, TOTP)
  • Custom domains
  • Email/SMS verification
  • Lambda triggers (pre-authentication, custom message, etc.)
  • User pool clients with branding

GitHubAccess

Creates IAM roles with OIDC federation for secure GitHub Actions deployments.

const githubRole = new GitHubAccess(this, 'GitHubActionsRole', {
  name: 'github-actions-role',
  description: 'GitHub Actions deployment role for production',
  stack: {
    id: 'my-app',
    tags: [{ key: 'Environment', value: 'production' }],
  },
  githubOidc: {
    providerArn: 'arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com',
    repository: 'my-org/my-repo',
    allowedBranch: 'main',
    environmentName: 'production',
  },
  s3Access: [{
    bucket: myBucket,
    prefixes: ['dashboard/*', 'public/*'],
  }],
  cloudFrontAccess: [{
    distribution: myDistribution,
  }],
  lambdaAccess: [{
    functionPrefix: 'my-app-*',
    region: this.region,
    accountId: this.account,
  }],
});

Key Features:

  • GitHub OIDC provider integration (no long-lived credentials)
  • Granular S3, CloudFront, and Lambda permissions
  • Branch and environment restrictions
  • Support for tag-based deployments
  • CloudFormation output with role ARN

DynamoTable

Creates a DynamoDB table with best practices.

const table = new DynamoTable(this, 'MyTable', {
  partitionKey: { name: 'userId', type: AttributeType.STRING },
  sortKey: { name: 'timestamp', type: AttributeType.NUMBER },
  billingMode: BillingMode.PAY_PER_REQUEST,
  globalSecondaryIndexes: [{
    indexName: 'EmailIndex',
    partitionKey: { name: 'email', type: AttributeType.STRING },
    projectionType: ProjectionType.ALL,
  }],
  pointInTimeRecovery: true,
});

Key Features:

  • On-demand or provisioned billing
  • Global secondary indexes
  • Point-in-time recovery
  • Encryption at rest
  • Time-to-live (TTL) support

RdsDatabase

Creates an Aurora database cluster with support for both provisioned and serverless v2 instances.

Serverless v2 Example:

import { DatabaseClusterEngine, AuroraMysqlEngineVersion } from 'aws-cdk-lib/aws-rds';

const database = new RdsDatabase(this, 'MyDatabase', {
  name: 'my-database',
  vpc: vpc.vpc,
  databaseName: 'appdata',
  serverlessV2MinCapacity: 0.5,
  serverlessV2MaxCapacity: 4,
  readers: 1,
  engine: DatabaseClusterEngine.auroraMysql({
    version: AuroraMysqlEngineVersion.VER_3_12_0,
  }),
  backupRetentionDays: 7,
  stack: { id: 'my-app', tags: [] },
});

Provisioned Instance Example:

const database = new RdsDatabase(this, 'MyDatabase', {
  name: 'my-database',
  vpc: vpc.vpc,
  databaseName: 'appdata',
  instanceClass: RdsDatabase.InstanceClass.MEMORY5_GRAVITON,
  instanceSize: RdsDatabase.InstanceSize.LARGE,
  readers: 2,
  backupRetentionDays: 14,
  stack: { id: 'my-app', tags: [] },
});

Key Features:

  • Aurora PostgreSQL or MySQL support (default: PostgreSQL 17.6)
  • Provisioned or serverless v2 instances
  • Multi-AZ deployment with read replicas
  • Automated backups with configurable retention
  • Encryption at rest enabled
  • Deployed in private isolated subnets
  • Security group configuration
  • Secrets Manager integration for credentials
  • Restore from snapshot support

Sqs

Creates SQS queues with DLQ support.

const queue = new Sqs(this, 'MyQueue', {
  visibilityTimeout: Duration.seconds(300),
  retentionPeriod: Duration.days(14),
  deadLetterQueue: {
    maxReceiveCount: 3,
  },
  encryption: QueueEncryption.KMS_MANAGED,
});

Key Features:

  • Dead letter queue configuration
  • Encryption with KMS
  • FIFO queue support
  • Visibility timeout configuration
  • Message retention policies

EventBridge

Creates EventBridge rules for scheduled tasks.

const eventBridge = new EventBridge(this, 'MyScheduler', {
  tasks: [{
    name: 'DailyBackup',
    schedule: Schedule.cron({ hour: '2', minute: '0' }),
    target: backupFunction,
  }],
});

Key Features:

  • CloudWatch Events integration
  • Cron and rate expressions
  • Lambda function targets
  • Custom event patterns

Ses

Configures SES for sending emails.

const ses = new Ses(this, 'MyEmailService', {
  fromEmail: 'noreply@example.com',
  replyToEmail: 'support@example.com',
  configurationSetName: 'MyConfigSet',
});

Key Features:

  • Email identity verification
  • Configuration sets
  • Bounce and complaint handling
  • Sending quotas

BastionHost

Creates a bastion host for secure access to private resources.

const bastion = new BastionHost(this, 'MyBastion', {
  vpc,
  instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.MICRO),
  allowedCidr: '203.0.113.0/24',
});

Key Features:

  • Systems Manager Session Manager support
  • Security group with SSH access
  • CloudWatch logging
  • Elastic IP

Server

Creates an EC2 server with customizable configuration.

const server = new Server(this, 'MyServer', {
  vpc,
  instanceType: InstanceType.of(InstanceClass.T3, InstanceSize.MEDIUM),
  machineImage: MachineImage.latestAmazonLinux2(),
  volumes: [{
    deviceName: '/dev/sda1',
    volumeSize: 30,
    volumeType: EbsDeviceVolumeType.GP3,
  }],
  userData: UserData.forLinux(),
});

Key Features:

  • Custom AMI support
  • EBS volumes configuration
  • User data scripts
  • IAM role attachment
  • VPC placement

Secrets

Manages secrets in AWS Secrets Manager.

const secret = new Secrets(this, 'MySecret', {
  secretName: 'my-app/database',
  generateSecretString: {
    secretStringTemplate: JSON.stringify({ username: 'admin' }),
    generateStringKey: 'password',
    excludePunctuation: true,
  },
});

Key Features:

  • Automatic secret generation
  • Rotation configuration
  • KMS encryption
  • Cross-account access

🎯 Best Practices

Security

  1. Always use encryption at rest and in transit

    const bucket = new S3Bucket(this, 'Bucket', {
      encryption: BucketEncryption.KMS_MANAGED,
    });
  2. Enable MFA for sensitive operations

    const cognito = new Cognito(this, 'UserPool', {
      mfa: { mfaRequired: true, enableTotp: true },
    });
  3. Use least privilege IAM policies

    myFunction.addToRolePolicy(new PolicyStatement({
      actions: ['dynamodb:GetItem'],
      resources: [table.tableArn],
    }));
  4. Enable logging and monitoring

    const vpc = new Vpc(this, 'Vpc', {
      flowLogs: true, // Enabled by default
    });

Cost Optimization

  1. Use appropriate instance types

    • Start with smaller instances (t3.micro, t3.small)
    • Monitor and scale based on metrics
  2. Enable S3 lifecycle policies

    const bucket = new S3Bucket(this, 'Bucket', {
      lifecycleRules: [{
        transitions: [{
          storageClass: StorageClass.INTELLIGENT_TIERING,
          transitionAfter: Duration.days(30),
        }],
      }],
    });
  3. Use on-demand billing for DynamoDB when appropriate

    const table = new DynamoTable(this, 'Table', {
      billingMode: BillingMode.PAY_PER_REQUEST,
    });

High Availability

  1. Deploy across multiple AZs

    const vpc = new Vpc(this, 'Vpc', { maxAzs: 3 });
    const rds = new RdsDatabase(this, 'Db', { multiAz: true });
  2. Configure auto-scaling

    table.autoScaleReadCapacity({
      minCapacity: 1,
      maxCapacity: 100,
    });
  3. Use CloudFront for global distribution

    const distribution = new CloudFront(this, 'CDN', {
      defaultBehavior: { origin: bucket.bucket },
    });

Performance

  1. Enable caching where appropriate

    const distribution = new CloudFront(this, 'CDN', {
      defaultBehavior: {
        cachePolicy: CachePolicy.CACHING_OPTIMIZED,
      },
    });
  2. Use VPC endpoints to reduce latency

    const vpc = new Vpc(this, 'Vpc', {
      endpoints: ['s3', 'dynamodb', 'secretsmanager'],
    });
  3. Configure Lambda memory and timeout appropriately

    const fn = new Function(this, 'Fn', {
      memorySize: 1024, // More memory = more CPU
      timeout: Duration.seconds(30),
    });

🚒 Deployment

Prerequisites

  • Node.js 20+ installed
  • AWS CLI configured with appropriate credentials
  • AWS CDK CLI installed: npm install -g aws-cdk

Deployment Steps

  1. Initialize your CDK app

    mkdir my-infrastructure
    cd my-infrastructure
    cdk init app --language typescript
  2. Install the package

    npm install @designofadecade/cdk-constructs
  3. Create your stack

    // lib/my-stack.ts
    import { Stack, StackProps } from 'aws-cdk-lib';
    import { Construct } from 'constructs';
    import { Vpc, S3Bucket } from '@designofadecade/cdk-constructs';
    
    export class MyStack extends Stack {
      constructor(scope: Construct, id: string, props?: StackProps) {
        super(scope, id, props);
        
        const vpc = new Vpc(this, 'Vpc');
        const bucket = new S3Bucket(this, 'Bucket');
      }
    }
  4. Bootstrap your AWS environment (first time only)

    cdk bootstrap aws://ACCOUNT-NUMBER/REGION
  5. Deploy your stack

    # Preview changes
    cdk diff
    
    # Deploy
    cdk deploy
    
    # Deploy all stacks
    cdk deploy --all

Multi-Environment Deployment

// bin/app.ts
import { App } from 'aws-cdk-lib';
import { MyStack } from '../lib/my-stack';

const app = new App();

// Development environment
new MyStack(app, 'MyStack-Dev', {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: 'us-east-1',
  },
  tags: {
    Environment: 'Development',
  },
});

// Production environment
new MyStack(app, 'MyStack-Prod', {
  env: {
    account: process.env.PROD_ACCOUNT,
    region: 'us-west-2',
  },
  tags: {
    Environment: 'Production',
  },
});

CI/CD Integration

GitHub Actions

# .github/workflows/deploy.yml
name: Deploy Infrastructure

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
          
      - name: Install dependencies
        run: npm ci
        
      - name: Run tests
        run: npm test
        
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: us-east-1
          
      - name: CDK Diff
        run: npx cdk diff
        
      - name: CDK Deploy
        if: github.ref == 'refs/heads/main'
        run: npx cdk deploy --require-approval never

πŸ”§ Development & Maintenance

Setting Up Development Environment

  1. Clone the repository

    git clone https://github.com/designofadecade/cdk-constructs.git
    cd cdk-constructs
  2. Install dependencies

    npm install
  3. Run tests

    npm test
  4. Watch mode for development

    npm run test:watch
    npm run watch  # TypeScript compilation

Testing

This library uses Vitest for unit testing. All constructs have comprehensive test coverage.

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with UI
npm run test:ui

# Generate coverage report
npm run test:coverage

Building

# Build TypeScript to JavaScript
npm run build

# Watch for changes
npm run watch

Publishing to GitHub Packages

Automatic Publishing (Recommended)

GitHub Actions automatically publishes the package when you push a version tag:

  1. Update version and create tag

    npm version minor  # or patch/major
  2. Push changes and tags

    git push origin main --tags
  3. GitHub Actions automatically:

    • Runs tests
    • Builds the package
    • Publishes to GitHub Packages

No manual authentication needed! The workflow triggers on any v* tag push.

Manual Publishing (Alternative)

If you prefer to publish manually:

  1. Update version

    npm version minor  # or patch/major
  2. Authenticate with GitHub

    npm login --registry=https://npm.pkg.github.com
    # Username: your-github-username
    # Password: your-github-token (with write:packages permission)
  3. Build, test, and publish

    npm run build
    npm test
    npm publish
  4. Push to GitHub

    git push origin main --tags

The package is configured to publish only to GitHub Packages via the publishConfig in package.json.

Versioning Strategy

This project follows Semantic Versioning:

  • MAJOR version (x.0.0): Breaking changes
  • MINOR version (0.x.0): New features, backwards compatible
  • PATCH version (0.0.x): Bug fixes, backwards compatible
# Bump patch version (0.2.2 -> 0.2.3)
npm version patch

# Bump minor version (0.2.2 -> 0.3.0)
npm version minor

# Bump major version (0.2.2 -> 1.0.0)
npm version major

Maintenance Checklist

Regular Tasks

  • Update dependencies monthly

    npm outdated
    npm update
  • Review and merge dependabot PRs

  • Monitor GitHub issues and discussions

  • Update documentation for new features

  • Run security audits

    npm audit
    npm audit fix

Before Each Release

  • Run full test suite: npm test
  • Generate and review coverage: npm run test:coverage
  • Update CHANGELOG.md
  • Update version in package.json
  • Update README.md if needed
  • Create GitHub release with release notes
  • Tag the release: git tag v0.3.0
  • Push tags: git push --tags

Quarterly Review

  • Review AWS CDK compatibility
  • Update peer dependencies
  • Review and update security best practices
  • Audit construct defaults
  • Review performance benchmarks
  • Update examples and documentation

Contributing

We welcome contributions! Please follow these guidelines:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/my-feature
  3. Make your changes
  4. Add tests for new functionality
  5. Run tests: npm test
  6. Commit your changes: git commit -am 'Add new feature'
  7. Push to the branch: git push origin feature/my-feature
  8. Submit a pull request

Code Style

  • Follow TypeScript best practices
  • Use meaningful variable and function names
  • Add JSDoc comments for public APIs
  • Keep functions small and focused
  • Write tests for all new features

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

🀝 Support

πŸ—ΊοΈ Roadmap

  • Additional AWS services (AppSync, Step Functions, etc.)
  • Enhanced monitoring and alerting constructs
  • Multi-region deployment patterns
  • Cost optimization utilities
  • Infrastructure testing helpers
  • Migration guides from other CDK libraries

πŸ“Š Changelog

See CHANGELOG.md for a detailed history of changes.

πŸ™ Acknowledgments

Built with ❀️ using AWS CDK


Made by Design of a Decade | Website | GitHub

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages