
Infrastructure as Code mit AWS CDK
Nicolai Lang
AWS Serverless expert. Advises and supports teams in building scalable cloud architectures.
Ein API Gateway, ein paar Lambdas, DynamoDB, S3. Natürlich IAM, CloudWatch Logs, ein paar Alarme. Überschaubar, auch ohne Infrastructure as Code. Das ist schnell zusammengeklickt und läuft.
Nur bleibt es nicht lange dabei. Nächstes Feature, nächste Lambda, neue Routen im API Gateway. Dann wird eine SQS-Queue gebraucht, eine EventBridge-Rule kommt dazu. Die Infrastruktur wächst stetig - und jedes Mal müssen in der Console manuell Ressourcen erstellt oder verändert werden. Wäre es nicht besser, das automatisieren und versionieren zu können? Irgendwo zu sehen, wie die aktuelle Infrastruktur aussehen soll?
Was sich mit Infrastructure as Code ändert
Genau dafür gibt es Infrastructure as Code (IaC). Infrastruktur nicht mehr in der Console zusammenklicken, sondern im Code definieren - versioniert in Git, die Möglichkeit von Pull Requests und Reviews und vor allem reproduzierbar.
Testen in einem Sandbox-Account? Nur ein weiterer Deploy. Staging soll anders konfiguriert sein als Produktion? Ein Parameter. Jemand hat etwas an der Infrastruktur geändert und keiner weiß was? Git Blame. Ein Deployment geht schief? Rollback auf den letzten Stand, der funktioniert hat. Alles, was in der Console intransparent und fehleranfällig ist, wird nachvollziehbar und automatisierbar.
Das klingt erstmal nach Aufwand und Lernkurve. Und mit klassischen Tools wie CloudFormation oder Terraform fühlt es sich auch sperrig an. Das C von IaC ist kein wirklicher Code, sondern YAML - komplexe Konfigurationsdateien für eine Handvoll Ressourcen, eine eigene Syntax und ständig die Dokumentation nebenher offen, weil man Property-Namen und erlaubte Werte nachschlagen muss.
Reproduzierbar ist die Infrastruktur damit zwar - aber die eigentlichen Probleme verschieben sich nur. Bei wachsenden Projekten werden die Templates schnell unübersichtlich, und mit der Unübersichtlichkeit steigt die Fehleranfälligkeit wieder. Dazu kommt fehlende Wiederverwendbarkeit: ein CloudFormation-Template für ein bewährtes Setup in einem anderen Projekt nutzen? Copy-Paste, anpassen, hoffen, dass nichts vergessen wurde. Echte Modularisierung sieht anders aus.
AWS CDK: Infrastruktur als echter Code - und als Teil des Software-Projekts
AWS CDK ist ein Open-Source-Framework, mit dem du AWS-Infrastruktur in einer echten Programmiersprache definierst. Kein YAML, kein JSON, kein HCL. Stattdessen schreibst du Code, der sich anfühlt wie ein normales Software-Projekt: mit Variablen, Funktionen, Typen. Deine IDE gibt dir Autocompletion und zeigt dir Fehler, bevor du deployst. Die Dokumentation, die bei CloudFormation ständig nebenher offen ist, wird mit CDK weitgehend überflüssig. Autovervollständigung und Typisierung lassen die API auf natürliche Weise erschließen.
CDK unterstützt TypeScript, Python, Java und Go. In diesem Artikel - und in der Praxis - verwenden wir TypeScript: Es ist die am besten unterstützte Sprache im CDK-Ökosystem, CDK selbst ist darin geschrieben, und die meisten Beispiele und Patterns in der Community setzen darauf.
Unter der Haube generiert CDK daraus CloudFormation-Templates und deployt sie. Du bekommst also die volle Stabilität und das Rollback-Verhalten von CloudFormation - ohne dessen Templates von Hand schreiben zu müssen.
Wie das aussieht? Nehmen wir das Beispiel vom Anfang - eine API mit Lambda und DynamoDB:
const table = new dynamodb.Table(this, "Items", {
partitionKey: { name: "id", type: dynamodb.AttributeType.STRING },
});
const fn = new lambda.Function(this, "Handler", {
runtime: lambda.Runtime.NODEJS_24_X,
handler: "index.handler",
code: lambda.Code.fromAsset("lambda"),
});
table.grantReadWriteData(fn);
new apigw.LambdaRestApi(this, "Api", { handler: fn });
Das ist die gesamte Infrastruktur. Tabelle, Funktion, API - und mit grantReadWriteData die
IAM-Berechtigungen dazwischen. Keine Rollen von Hand definieren, keine Policy-Dokumente
zusammenbauen. CDK generiert vieles automatisch im Hintergrund für dich.
Infrastruktur und Applikation wachsen zusammen
Was sich damit grundlegend ändert, ist die Art, wie ein Team mit seiner Infrastruktur umgeht. Pull Requests, Code Reviews, Tests, CI/CD - alles, was in der Softwareentwicklung Standard ist, funktioniert jetzt auch für Infrastruktur. Weil es ein ganz normales TypeScript-Projekt ist.
Der eigentliche Gewinn liegt aber noch tiefer. In der klassischen Welt existieren Infrastruktur und Applikation als getrennte Bausteine. Jemand legt eine DynamoDB-Tabelle an, jemand anders schreibt den Lambda-Handler, und dazwischen liegt ein Table-Name als String in einer Environment-Variable - den hoffentlich beide gleich benannt haben. Wenn sich etwas ändert, merkt man den Bruch erst zur Laufzeit.
In CDK ist das gelöst. Die Tabelle, die Lambda-Funktion und die Berechtigungen dazwischen leben im selben Projekt. Du kannst z.B. ganz einfach ein gemeinsames Interface für deine Environment-Variablen definieren und es sowohl im Stack als auch im Handler nutzen:
// shared/env.ts - wird von Stack und Handler importiert
export interface AppEnv {
TABLE_NAME: string;
BUCKET_NAME: string;
}
// Im CDK-Stack
const environment: AppEnv = {
TABLE_NAME: table.tableName,
BUCKET_NAME: bucket.bucketName,
};
const fn = new lambda.Function(this, "Handler", {
runtime: lambda.Runtime.NODEJS_24_X,
handler: "index.handler",
code: lambda.Code.fromAsset("lambda"),
environment,
});
// Im Lambda-Handler
const { TABLE_NAME, BUCKET_NAME } = process.env as unknown as AppEnv;
Wenn sich ein Table-Name ändert, ändert er sich an einer Stelle. Wenn dein Frontend ein
S3-Bucket-Deployment braucht, ist das Teil desselben Stacks. cdk diff zeigt dir vor dem Deployment
exakt, was sich ändern wird. cdk deploy rollt alles zusammen aus.
Und was am Anfang das Problem war - eine zweite Umgebung, die exakt gleich sein soll - ist damit kein Thema mehr. Aber auch kleine Unterschiede werden einfach über Parameter gelöst, im Code, ohne zusätzliche Syntax oder Einschränkungen. Niedrigere Throttles in Staging oder das Weglassen von Alarmen in der Developer-Sandbox sind einfach eine Bedingung im Code. Es bleibt derselbe Code, nur unterschiedlich konfiguriert, deployt in beliebig viele Accounts - ohne copy & paste und Kontrollverlust.
Wie fängt man an
Und die Lernkurve, die am Anfang noch im Weg stand? CDK ist TypeScript (oder Python, Java, Go) - also eine Sprache, die dein Team vermutlich schon kennt. Der offizielle CDK-Workshop von AWS führt in unter zwei Stunden durch die wichtigsten Konzepte. Die API-Dokumentation ist solide, die Community aktiv. Das reicht, um die ersten Stacks produktiv zu deployen.
Wer den Einstieg noch weiter beschleunigen will: AI-gestützte Coding-Agenten wie Claude Code oder Copilot können heute sauber strukturierten CDK-Code generieren - Constructs, Tests, Best Practices inklusive. Du beschreibst, was du brauchst, der Agent schreibt den Stack, du reviewst und deployst. Kein Muss, aber ein Beschleuniger.
CDK gibt dir dabei viel Freiheit und Flexibilität - wie du deine Stacks und Constructs schneidest, was du in eigene Bibliotheken auslagerst, wo du die Grenze zwischen Infrastruktur und Applikation ziehst. Es lohnt sich, früh ein paar gute Muster zu etablieren, die dann mitwachsen. Wie das konkret aussehen kann, schauen wir uns in einem eigenen Artikel an.
Und wenn du dich austauschen möchtest, wie ein CDK-Setup für dein Team konkret aussehen könnte - nimm gerne Kontakt mit uns auf 😉
