Cloud & AWS

AWS CDK mit Claude Code: Infrastructure as TypeScript 2026

๐Ÿ“… 5. Mai 2026 โฑ 12 min Lesezeit โ˜๏ธ AWS CDK ยท TypeScript ยท KI

AWS CDK (Cloud Development Kit) ist 2026 der Standard fuer teams, die ihre AWS-Infrastruktur als echten Code โ€“ nicht als YAML-Friedhof โ€“ verwalten wollen. Mit TypeScript als Hauptsprache und Claude Code als KI-Partner entsteht typsichere, testbare und wartbare Infrastructure as Code in Rekordzeit. Dieser Artikel zeigt, wie das in der Praxis funktioniert.

Warum CDK statt Terraform oder CloudFormation-YAML? Weil du echte Abstraktion, Wiederverwendung per npm-Package und direkte IDE-Unterstuetzung bekommst. Claude Code versteht CDK-Patterns tief โ€“ von einfachen L1-Constructs bis zu komplexen L3-Abstractions โ€“ und generiert sofort produktionsreife Stacks.

Voraussetzung: Node.js 20+, AWS CLI konfiguriert (aws configure), CDK CLI installiert (npm install -g aws-cdk). Bootstrap einmalig pro Account/Region: cdk bootstrap aws://ACCOUNT_ID/eu-central-1

1. CDK Setup: App, Stacks & Constructs

CDK strukturiert Infrastruktur in einer klaren Hierarchie: App โ†’ Stack โ†’ Construct. Die App ist der Einstiegspunkt, Stacks entsprechen CloudFormation-Stacks (eine logische Deployment-Einheit), und Constructs sind die wiederverwendbaren Bausteine. Claude Code versteht diese Hierarchie und generiert sauber strukturierte Projekte auf Kommando.

CDK Stack

Projekt initialisieren mit Claude Code

Starte ein neues CDK-Projekt und lass Claude Code die Grundstruktur mit Best Practices einrichten:

bash
# Neues CDK TypeScript Projekt
mkdir my-infra && cd my-infra
cdk init app --language=typescript

# Claude Code Prompt:
# "Erstelle eine CDK-App mit zwei Stacks: NetworkStack (VPC)
#  und AppStack (Lambda + API). AppStack haengt von NetworkStack ab."
typescript
// bin/my-infra.ts โ€” Einstiegspunkt der CDK App
import * as cdk from 'aws-cdk-lib';
import { NetworkStack } from '../lib/network-stack';
import { AppStack } from '../lib/app-stack';

const app = new cdk.App();

const env = {
  account: process.env.CDK_DEFAULT_ACCOUNT,
  region: process.env.CDK_DEFAULT_REGION ?? 'eu-central-1',
};

const network = new NetworkStack(app, 'NetworkStack', { env });

const appStack = new AppStack(app, 'AppStack', {
  env,
  vpc: network.vpc,          // Cross-Stack Reference
});

// Explizite Abhaengigkeit: AppStack wartet auf NetworkStack
appStack.addDependency(network);
typescript
// lib/network-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';

export class NetworkStack extends cdk.Stack {
  public readonly vpc: ec2.Vpc;

  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    this.vpc = new ec2.Vpc(this, 'MainVpc', {
      maxAzs: 2,
      natGateways: 1,
      subnetConfiguration: [
        {
          cidrMask: 24,
          name: 'Public',
          subnetType: ec2.SubnetType.PUBLIC,
        },
        {
          cidrMask: 24,
          name: 'Private',
          subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
        },
        {
          cidrMask: 28,
          name: 'Isolated',
          subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
        },
      ],
    });

    // CloudFormation Output fuer andere Stacks
    new cdk.CfnOutput(this, 'VpcId', { value: this.vpc.vpcId });
  }
}

Die wichtigsten CDK-Kommandos im Ueberblick: cdk synth generiert die CloudFormation-Templates (ohne zu deployen โ€“ ideal zum Reviewen), cdk diff zeigt alle Aenderungen gegenueber dem deployed Stack, und cdk deploy bringt die Infrastruktur tatsaechlich in AWS zum Laufen.

bash
# Alle Stacks anzeigen
cdk ls

# CloudFormation Template generieren (kein Deploy)
cdk synth NetworkStack

# Diff vor dem Deploy โ€” was aendert sich?
cdk diff AppStack

# Beide Stacks deployen
cdk deploy --all

# Nur bestimmten Stack deployen
cdk deploy AppStack

2. Lambda + API Gateway: Serverless API in wenigen Zeilen

CDK's NodejsFunction Construct (aus @aws-cdk/aws-lambda-nodejs) bundled TypeScript-Lambda-Code automatisch mit esbuild. Kein manuelles Webpack, keine ZIP-Files โ€“ Claude Code generiert den gesamten Stack inklusive CORS, IAM und API-Gateway-Routing.

Lambda + API Gateway

REST API mit TypeScript Lambda

Eine vollstaendige serverlose API: Lambda-Function mit TypeScript-Source, API Gateway REST API, CORS-Konfiguration und automatisches Bundling.

typescript
// lib/api-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as lambdaNode from 'aws-cdk-lib/aws-lambda-nodejs';
import * as apigw from 'aws-cdk-lib/aws-apigateway';
import * as logs from 'aws-cdk-lib/aws-logs';
import { Construct } from 'constructs';
import * as path from 'path';

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

    // NodejsFunction: automatisches esbuild Bundling
    const apiHandler = new lambdaNode.NodejsFunction(this, 'ApiHandler', {
      runtime: lambda.Runtime.NODEJS_20_X,
      entry: path.join(__dirname, '../src/handlers/api.ts'),
      handler: 'handler',
      timeout: cdk.Duration.seconds(30),
      memorySize: 512,
      logRetention: logs.RetentionDays.ONE_WEEK,
      environment: {
        NODE_ENV: 'production',
        LOG_LEVEL: 'info',
      },
      bundling: {
        minify: true,
        sourceMap: true,
        externalModules: ['@aws-sdk/*'],  // bereits in Lambda Runtime
      },
    });

    // REST API mit CloudWatch-Logging
    const api = new apigw.RestApi(this, 'MainApi', {
      restApiName: 'my-service-api',
      description: 'Main REST API',
      deployOptions: {
        stageName: 'v1',
        tracingEnabled: true,        // X-Ray Tracing
        dataTraceEnabled: false,
        metricsEnabled: true,
      },
      defaultCorsPreflightOptions: {
        allowOrigins: apigw.Cors.ALL_ORIGINS,
        allowMethods: apigw.Cors.ALL_METHODS,
        allowHeaders: [
          'Content-Type',
          'Authorization',
          'X-Api-Key',
        ],
        maxAge: cdk.Duration.hours(1),
      },
    });

    // Lambda Integration
    const integration = new apigw.LambdaIntegration(apiHandler, {
      requestTemplates: { 'application/json': '{ "statusCode": "200" }' },
    });

    // /users Resource
    const users = api.root.addResource('users');
    users.addMethod('GET', integration);
    users.addMethod('POST', integration);

    // /users/{id} Resource
    const user = users.addResource('{id}');
    user.addMethod('GET', integration);
    user.addMethod('PUT', integration);
    user.addMethod('DELETE', integration);

    // API URL als Output
    new cdk.CfnOutput(this, 'ApiUrl', {
      value: api.url,
      description: 'REST API Base URL',
    });
  }
}

Der Lambda-Handler selbst ist einfaches TypeScript. Claude Code generiert ihn passend zur API-Struktur:

typescript
// src/handlers/api.ts
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';

export const handler = async (
  event: APIGatewayProxyEvent
): Promise<APIGatewayProxyResult> => {
  const { httpMethod, path, pathParameters, body } = event;

  try {
    // Routing nach Methode und Pfad
    if (httpMethod === 'GET' && path.startsWith('/users')) {
      return respond(200, { users: [], total: 0 });
    }

    return respond(404, { error: 'Not found' });

  } catch (err) {
    console.error('Handler error:', err);
    return respond(500, { error: 'Internal server error' });
  }
};

const respond = (statusCode: number, body: unknown): APIGatewayProxyResult => ({
  statusCode,
  headers: {
    'Content-Type': 'application/json',
    'Access-Control-Allow-Origin': '*',
  },
  body: JSON.stringify(body),
});
Claude Code Tipp: Frage Claude Code: "Erstelle eine API Gateway REST API mit JWT-Authorizer, Rate Limiting (1000 req/min), und separaten Lambda-Functions pro Route statt einem Monolith-Handler." Das Ergebnis ist eine produktionsreife Microservice-Struktur in wenigen Sekunden.

3. VPC + RDS PostgreSQL: Sichere Datenbankinfrastruktur

Datenbankinfrastruktur mit CDK bedeutet: VPC mit richtigen Subnet-Typen, RDS in isolierten Subnetzen, Security Groups mit minimalen Rechten, und automatisches Secrets Manager-Rotation. Claude Code weiss, welche IAM-Policies und Security-Group-Rules benoetigt werden.

VPC + RDS

PostgreSQL RDS mit Secrets Manager

Production-ready RDS PostgreSQL Instanz: Multi-AZ, automatische Backups, Encryption at Rest, Secrets Manager fuer Credentials.

typescript
// lib/database-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as secretsmanager from 'aws-cdk-lib/aws-secretsmanager';
import { Construct } from 'constructs';

interface DatabaseStackProps extends cdk.StackProps {
  vpc: ec2.IVpc;
}

export class DatabaseStack extends cdk.Stack {
  public readonly dbSecret: secretsmanager.ISecret;
  public readonly dbInstance: rds.DatabaseInstance;
  public readonly dbSecurityGroup: ec2.SecurityGroup;

  constructor(scope: Construct, id: string, props: DatabaseStackProps) {
    super(scope, id, props);
    const { vpc } = props;

    // Security Group: nur Port 5432 aus dem privaten Subnetz
    this.dbSecurityGroup = new ec2.SecurityGroup(this, 'DbSG', {
      vpc,
      description: 'RDS PostgreSQL Security Group',
      allowAllOutbound: false,
    });

    this.dbSecurityGroup.addIngressRule(
      ec2.Peer.ipv4(vpc.vpcCidrBlock),
      ec2.Port.tcp(5432),
      'PostgreSQL from VPC'
    );

    // Credentials automatisch in Secrets Manager
    const dbCredentials = rds.Credentials.fromGeneratedSecret('postgres', {
      secretName: 'prod/myapp/postgres',
    });

    // RDS PostgreSQL Instanz
    this.dbInstance = new rds.DatabaseInstance(this, 'PostgresDB', {
      engine: rds.DatabaseInstanceEngine.postgres({
        version: rds.PostgresEngineVersion.VER_16_2,
      }),
      instanceType: ec2.InstanceType.of(
        ec2.InstanceClass.T4G,
        ec2.InstanceSize.MEDIUM
      ),
      vpc,
      vpcSubnets: { subnetType: ec2.SubnetType.PRIVATE_ISOLATED },
      securityGroups: [this.dbSecurityGroup],
      credentials: dbCredentials,
      databaseName: 'myapp',
      multiAz: true,                      // Production: Multi-AZ
      allocatedStorage: 100,
      maxAllocatedStorage: 500,           // Auto-Scaling Storage
      storageEncrypted: true,
      backupRetention: cdk.Duration.days(7),
      deletionProtection: true,
      removalPolicy: cdk.RemovalPolicy.RETAIN,
      enablePerformanceInsights: true,
      monitoringInterval: cdk.Duration.seconds(60),
    });

    this.dbSecret = this.dbInstance.secret!;

    // Output: Secret ARN fuer andere Stacks
    new cdk.CfnOutput(this, 'DbSecretArn', {
      value: this.dbSecret.secretArn,
      exportName: 'DbSecretArn',
    });
    new cdk.CfnOutput(this, 'DbEndpoint', {
      value: this.dbInstance.instanceEndpoint.hostname,
    });
  }
}

Lambda-Functions koennen direkt auf das Datenbank-Secret zugreifen. CDK regelt die IAM-Permissions automatisch ueber grantRead():

typescript
// Lambda Zugriff auf RDS Secret โ€” eine Zeile!
dbStack.dbSecret.grantRead(apiHandler);

// Security Group: Lambda darf auf DB zugreifen
dbStack.dbSecurityGroup.addIngressRule(
  ec2.Peer.securityGroupId(lambdaSg.securityGroupId),
  ec2.Port.tcp(5432),
  'Lambda to PostgreSQL'
);

// Im Lambda Handler: Credentials aus Secrets Manager laden
import { SecretsManagerClient, GetSecretValueCommand } from '@aws-sdk/client-secrets-manager';

const sm = new SecretsManagerClient({});
const { SecretString } = await sm.send(
  new GetSecretValueCommand({ SecretId: process.env.DB_SECRET_ARN })
);
const { username, password, host, port, dbname } = JSON.parse(SecretString!);
Achtung: deletionProtection: true und removalPolicy: RETAIN bedeuten, dass CDK die Datenbank bei cdk destroy NICHT loescht. Das ist in Produktion gewuenscht โ€“ aber vergiss nicht, die RDS-Instanz manuell zu entfernen wenn du das Projekt wirklich abbaust.

4. S3 + CloudFront: Static Site Hosting mit CDN

Fuer Static Sites, SPAs und Frontend-Assets ist die Kombination S3 + CloudFront der AWS-Standard. CDK's BucketDeployment Construct kopiert lokale Build-Artefakte direkt in den S3-Bucket und invalidiert den CloudFront-Cache automatisch.

S3 + CloudFront

Static Site mit globalem CDN

S3 Bucket als Origin, CloudFront Distribution mit Custom Domain, ACM Certificate, und automatisches Deployment der Build-Artefakte.

typescript
// lib/static-site-stack.ts
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as cloudfront from 'aws-cdk-lib/aws-cloudfront';
import * as origins from 'aws-cdk-lib/aws-cloudfront-origins';
import * as s3deploy from 'aws-cdk-lib/aws-s3-deployment';
import * as acm from 'aws-cdk-lib/aws-certificatemanager';
import * as route53 from 'aws-cdk-lib/aws-route53';
import { Construct } from 'constructs';

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

    // S3 Bucket: KEIN public access โ€” CloudFront liest via OAC
    const siteBucket = new s3.Bucket(this, 'SiteBucket', {
      bucketName: 'myapp-frontend-assets',
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
      encryption: s3.BucketEncryption.S3_MANAGED,
      versioned: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true,
    });

    // Origin Access Control (moderne Alternative zu OAI)
    const oac = new cloudfront.S3OriginAccessControl(this, 'OAC', {
      signing: cloudfront.Signing.SIGV4_NO_OVERRIDE,
    });

    // CloudFront Distribution
    const distribution = new cloudfront.Distribution(this, 'Distribution', {
      defaultBehavior: {
        origin: origins.S3BucketOrigin.withOriginAccessControl(siteBucket, { oac }),
        viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
        cachePolicy: cloudfront.CachePolicy.CACHING_OPTIMIZED,
        compress: true,
      },
      defaultRootObject: 'index.html',
      errorResponses: [
        // SPA: alle 404s zu index.html (React Router etc.)
        {
          httpStatus: 404,
          responseHttpStatus: 200,
          responsePagePath: '/index.html',
          ttl: cdk.Duration.seconds(0),
        },
      ],
      priceClass: cloudfront.PriceClass.PRICE_CLASS_100,
      httpVersion: cloudfront.HttpVersion.HTTP2_AND_3,
    });

    // Build-Artefakte deployen + Cache invalidieren
    new s3deploy.BucketDeployment(this, 'DeployApp', {
      sources: [s3deploy.Source.asset('./dist')],
      destinationBucket: siteBucket,
      distribution,
      distributionPaths: ['/*'],  // Cache invalidieren
      prune: true,
      retainOnDelete: false,
    });

    new cdk.CfnOutput(this, 'CloudFrontUrl', {
      value: `https://${distribution.distributionDomainName}`,
    });
    new cdk.CfnOutput(this, 'DistributionId', {
      value: distribution.distributionId,
    });
  }
}
Performance: CloudFront mit HTTP2_AND_3 aktiviert HTTP/3 (QUIC) automatisch. Das beschleunigt besonders Verbindungen mit hoher Latenz (Mobile) um 20-40%. Claude Code schlaegt diese Konfiguration automatisch vor wenn du nach "performance-optimized static hosting" fragst.

5. CDK Pipelines: Self-Mutating CI/CD

CDK Pipelines ist die eleganteste Loesung fuer Infrastructure-CI/CD: Die Pipeline konfiguriert sich selbst neu wenn du die Pipeline-Definition aenderst (Self-Mutating). Kein manuelles Aktualisieren der CodePipeline noetig โ€“ der erste Stage aktualisiert die Pipeline selbst, der zweite deployed die App.

CDK Pipelines

Self-Mutating Deployment Pipeline

CodePipeline + CodeBuild: Source aus GitHub, synth, self-update, dann Deploy in Staging und Production mit manueller Approval-Stage.

typescript
// lib/pipeline-stack.ts
import * as cdk from 'aws-cdk-lib';
import { CodePipeline, CodePipelineSource, ShellStep } from 'aws-cdk-lib/pipelines';
import { ManualApprovalStep } from 'aws-cdk-lib/pipelines';
import { Construct } from 'constructs';

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

    // GitHub als Source โ€” Connection via AWS CodeStar
    const source = CodePipelineSource.connection(
      'my-org/my-repo',
      'main',
      {
        connectionArn: 'arn:aws:codestar-connections:eu-central-1:123:connection/abc',
      }
    );

    // CDK Pipeline Definition
    const pipeline = new CodePipeline(this, 'Pipeline', {
      pipelineName: 'MyAppPipeline',
      selfMutation: true,   // Pipeline aktualisiert sich selbst!
      crossAccountKeys: false,
      dockerEnabledForSynth: false,
      synth: new ShellStep('Synth', {
        input: source,
        commands: [
          'npm ci',
          'npm run build',
          'npx cdk synth',
        ],
      }),
    });

    // Staging Stage
    const staging = pipeline.addStage(
      new AppStage(this, 'Staging', {
        env: { account: '123456789', region: 'eu-central-1' },
      })
    );

    // Integration Tests nach Staging Deploy
    staging.addPost(
      new ShellStep('IntegrationTests', {
        commands: [
          'npm ci',
          'npm run test:integration',
        ],
        envFromCfnOutputs: {
          API_URL: staging.stackOutputs.apiUrl,  // Output aus AppStack
        },
      })
    );

    // Production Stage mit manueller Approval
    const production = pipeline.addStage(
      new AppStage(this, 'Production', {
        env: { account: '987654321', region: 'eu-central-1' },
      }),
      {
        pre: [new ManualApprovalStep('PromoteToProduction')],
      }
    );
  }
}
typescript
// lib/app-stage.ts โ€” Buendelt alle App-Stacks als Stage
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class AppStage extends cdk.Stage {
  public readonly apiUrl: cdk.CfnOutput;

  constructor(scope: Construct, id: string, props?: cdk.StageProps) {
    super(scope, id, props);

    const network = new NetworkStack(this, 'Network');
    const db = new DatabaseStack(this, 'Database', { vpc: network.vpc });
    const api = new ApiStack(this, 'Api', {
      vpc: network.vpc,
      dbSecret: db.dbSecret,
    });

    this.apiUrl = api.apiUrlOutput;
  }
}

Das Besondere an CDK Pipelines: Wenn du die Pipeline-Definition selbst aenderst (z.B. eine neue Stage hinzufuegst), deployed der erste Pipeline-Run die aktualisierte Pipeline โ€“ der zweite Run verwendet dann die neue Konfiguration. Vollautomatisch, kein manuelles Eingreifen.

Claude Code Prompt: "Erweitere die Pipeline um eine Canary-Deployment Stage: erst 10% Traffic auf neue Version, nach 10 Minuten Monitoring (CloudWatch Alarms gruen) automatisch auf 100% hochstufen, sonst automatischer Rollback."

6. Custom L3 Constructs: Wiederverwendbare Infrastruktur-Module

CDK unterscheidet drei Construct-Level: L1 (direkte CloudFormation-Ressourcen, CfnBucket), L2 (high-level Abstractions wie Bucket), und L3 (Pattern-Constructs die mehrere Ressourcen kombinieren). Eigene L3-Constructs sind der Schluessel zu wartbarer Infrastruktur in groesseren Teams โ€“ einmal definiert, ueberall verwendbar, versionierbar als npm-Package.

Custom L3 Construct

SecureApiConstruct: Vorgefertigtes API-Pattern

Ein L3-Construct der Lambda + API Gateway + WAF + CloudWatch Dashboard kombiniert. Einmal schreiben, in jedem Stack wiederverwenden.

typescript
// constructs/secure-api.ts
import * as cdk from 'aws-cdk-lib';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as lambdaNode from 'aws-cdk-lib/aws-lambda-nodejs';
import * as apigw from 'aws-cdk-lib/aws-apigateway';
import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
import * as logs from 'aws-cdk-lib/aws-logs';
import { Construct } from 'constructs';

export interface SecureApiProps {
  /** Pfad zum Lambda Handler Entry File */
  entry: string;
  /** API Name (fuer CloudWatch, API GW) */
  apiName: string;
  /** Alarm Email (optional) */
  alarmEmail?: string;
  /** Rate Limit pro IP pro 5min */
  rateLimit?: number;
  /** Lambda Memory in MB */
  memorySize?: number;
  /** Umgebungsvariablen fuer Lambda */
  environment?: Record<string, string>;
}

export class SecureApi extends Construct {
  public readonly api: apigw.RestApi;
  public readonly handler: lambdaNode.NodejsFunction;
  public readonly dashboard: cloudwatch.Dashboard;

  constructor(scope: Construct, id: string, props: SecureApiProps) {
    super(scope, id);

    const { entry, apiName, memorySize = 512, environment = {} } = props;

    // Lambda Function
    this.handler = new lambdaNode.NodejsFunction(this, 'Handler', {
      runtime: lambda.Runtime.NODEJS_20_X,
      entry,
      handler: 'handler',
      memorySize,
      timeout: cdk.Duration.seconds(29),
      logRetention: logs.RetentionDays.TWO_WEEKS,
      environment: {
        ...environment,
        POWERTOOLS_SERVICE_NAME: apiName,
      },
      tracing: lambda.Tracing.ACTIVE,
      bundling: {
        minify: true,
        sourceMap: true,
        externalModules: ['@aws-sdk/*'],
      },
    });

    // REST API
    this.api = new apigw.RestApi(this, 'Api', {
      restApiName: apiName,
      defaultCorsPreflightOptions: {
        allowOrigins: apigw.Cors.ALL_ORIGINS,
        allowMethods: apigw.Cors.ALL_METHODS,
      },
    });

    this.api.root.addProxy({
      defaultIntegration: new apigw.LambdaIntegration(this.handler),
      anyMethod: true,
    });

    // CloudWatch Dashboard
    this.dashboard = new cloudwatch.Dashboard(this, 'Dashboard', {
      dashboardName: `${apiName}-dashboard`,
      widgets: [
        [
          new cloudwatch.GraphWidget({
            title: 'Lambda Invocations & Errors',
            left: [this.handler.metricInvocations()],
            right: [this.handler.metricErrors({ color: '#ff0000' })],
            width: 12,
          }),
          new cloudwatch.GraphWidget({
            title: 'Lambda Duration (p50/p95/p99)',
            left: [
              this.handler.metricDuration({ statistic: 'p50' }),
              this.handler.metricDuration({ statistic: 'p95' }),
              this.handler.metricDuration({ statistic: 'p99' }),
            ],
            width: 12,
          }),
        ],
      ],
    });
  }
}
typescript
// Verwendung: L3 Construct in einem Stack
const userApi = new SecureApi(this, 'UserApi', {
  entry: './src/handlers/users.ts',
  apiName: 'user-service',
  memorySize: 1024,
  environment: {
    DB_SECRET_ARN: dbStack.dbSecret.secretArn,
    TABLE_NAME: userTable.tableName,
  },
});

// IAM Grants direkt auf das Construct
dbStack.dbSecret.grantRead(userApi.handler);
userTable.grantReadWriteData(userApi.handler);

// API URL als Output
new cdk.CfnOutput(this, 'UserApiUrl', { value: userApi.api.url });

// Construct als npm-Package veroeffentlichen:
// npm publish โ†’ andere Teams installieren per `npm install @my-org/cdk-constructs`

L3-Constructs werden in der Community als Construct Hub-Packages geteilt. Das CDK-Oekosystem hat hunderte vorgefertigter L3-Constructs: von kompletten EKS-Cluster-Setups bis zu vorkonfigurierten Monitoring-Stacks. Claude Code kennt die wichtigsten Packages und generiert den korrekten Integrationscode.

typescript
// Aspect: Compliance-Regeln auf ALLE Ressourcen anwenden
import { Aspects, IAspect } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

class S3BucketEncryptionAspect implements IAspect {
  visit(node: IConstruct): void {
    if (node instanceof s3.CfnBucket) {
      if (!node.bucketEncryption) {
        node.bucketEncryption = {
          serverSideEncryptionConfiguration: [{
            serverSideEncryptionByDefault: {
              sseAlgorithm: 'AES256'
            }
          }]
        };
      }
    }
  }
}

// Aspect auf gesamte App anwenden โ€” kein unverschluesselter Bucket moeglich
Aspects.of(app).add(new S3BucketEncryptionAspect());
CDK Gotcha: cdk destroy loescht nur Ressourcen mit RemovalPolicy.DESTROY. Alles andere (RDS mit RETAIN, Buckets mit Objekten, etc.) bleibt in AWS und verursacht weiter Kosten. Claude Code warnt dich standardmaessig davor und schlaegt eine Cleanup-Checkliste vor.

Fazit: CDK + Claude Code = Production-Ready in Stunden

AWS CDK mit TypeScript und Claude Code ist 2026 der schnellste Weg zu wartbarer, typsicherer Cloud-Infrastruktur. Die Hierarchie App โ†’ Stack โ†’ Construct erzwingt saubere Trennung. cdk diff macht Infrastruktur-Changes sicher und nachvollziehbar. CDK Pipelines automatisieren den gesamten Deployment-Prozess inklusive Self-Mutation.

Was frueherstundenlange CloudFormation-YAML-Arbeit erfordert, erledigt Claude Code in Minuten: korrekte IAM-Policies, Security-Group-Rules, Cross-Stack-References, CloudWatch-Dashboards โ€“ alles typsicher, alles testbar, alles in Git.

AWS CDK mit Claude Code beschleunigen

Starte deinen kostenlosen Trial und nutze Claude Code als CDK-Experten fuer deine AWS-Infrastruktur.

Kostenlos starten →