Blog

Verwaltung komplexer Infrastrukturen mit AWS CDK und Go

Konstantinos Bessas

Konstantinos Bessas

Aktualisiert Oktober 15, 2025
5 Minuten

In einem früheren Artikel haben wir uns mit dem Thema"Verwaltung von K8S-Infrastruktur und -Anwendungen auf AWS" beschäftigt. Dort haben wir anhand des AWS Cloud Development Kit (CDK) und der Sprache Python gesehen, wie wir eine komplette Lösung rund um Kubernetes (K8s) auf AWS verwalten können, d.h. die Bereitstellung der gesamten Infrastruktur sowie der Arbeitslasten aus einer einzigen Codebasis mit einer einzigen Programmiersprache, nämlich Python. Wie am Ende dieses Artikels versprochen, wollte ich dasselbe Projekt in anderen Programmiersprachen, die von der CDK-Framework-Familie unterstützt werden, vorlegen. Jetzt ist es an der Zeit, die gleiche Lösung mit Golang zu reproduzieren.

In diesem Artikel werden wir nicht auf die Infrastruktur von K8 und die Anwendungen eingehen. All diese Informationen finden Sie in dem oben erwähnten Originalartikel. Bei dem Versuch, einen Code in Go zu schreiben, der ein ähnliches Ergebnis liefert wie mein ursprüngliches Projekt in Python, bin ich über einige Herausforderungen gestolpert. Ich möchte diese Reise mit Ihnen teilen und hoffentlich allen helfen, die an einem Einstieg in das AWS CDK in Kombination mit der Sprache Go interessiert sind.

Projektstruktur

Im Internet finden Sie mehrere Beispiele für die Erstellung von Infrastructure as Code (IaC) mit dem AWS CDK und Go. Alle diese Beispiele konzentrieren sich auf eine Single-Stack-Lösung, bei der nur eine sehr begrenzte Menge an Ressourcen eingesetzt wird. Diese Beispiele können sehr hilfreich sein, wenn Sie herausfinden wollen, wie Sie mit dem AWS CDK und der Sprache Go beginnen können. Für mich ist es sehr wichtig, die Lösung entsprechend zu strukturieren, wenn ich mit der Arbeit an einem IaC-Projekt beginne, das potenziell eine große Anzahl von Ressourcen umfassen würde. AWS unterstützt seit einigen Jahren das Konzept der Nested Stacks. Ich glaube, dass es für jedes produktionsreife Projekt von nicht trivialer Komplexität auf AWS von größter Bedeutung ist, die Vorteile von Nested Stacks zu nutzen.

Als ich mich nach Best Practices für die Strukturierung eines AWS CDK-Projekts in Go umsah, konnte ich zu meiner Überraschung keine anderen Informationen als Beispiele für eine einzelne Datei und einen einzelnen Stack finden. Ich möchte Ihnen hier meine Meinung dazu mitteilen, wie ich ein komplexes IaC-Projekt strukturieren würde.

Ordnerstruktur

Mit dem Gedanken im Hinterkopf, dass ich viele verschachtelte Stacks und verschiedene Konfigurationen pro Einsatzumgebung verwenden würde (ich habe einen separaten Artikel darüber geschrieben, den Sie hier finden), wäre dies eine Vorlage dafür, wie die Ordnerstruktur aussehen sollte:

├── charts/
 │   ├── cdk8s-chart-1.go
 │   ├── cdk8s-chart-2.go
├── config/
 │   ├── development.yaml
 │   ├── test.yaml
 │   ├── acceptance.yaml
 │   ├── production.yaml
├── helper/
 │   ├── helper-functions-1.go
 │   ├── helper-functions-2.go
├── stacks/
 │   ├── nested-stack-1.go
 │   ├── nested-stack-2.go
 │   ├── nested-stack-3.go
├── cdk.context.json
├── cdk.json
├── parent-stack-main.go
└──

Pakete gehen

Go ist für seine Einfachheit und Benutzerfreundlichkeit bekannt, und eine der grundlegenden Möglichkeiten, dies zu erreichen, ist sein Paketsystem. Pakete spielen eine zentrale Rolle bei der Strukturierung und Organisation von Go-Code und machen ihn modular, wiederverwendbar und wartbar. Sie bieten einen Mechanismus für die Kapselung des Codes, die Zusammenarbeit und die Wiederverwendbarkeit des Codes, die für jede Programmiersprache entscheidend sind.

Der Hauptzweck von Go-Paketen besteht darin, logische und in sich geschlossene Codeeinheiten zu erstellen, die importiert und in anderen Teilen der Anwendung verwendet werden können. Diese Pakete dienen als Container für verwandte Funktionen, Typen, Variablen und andere Komponenten, die zusammen ein bestimmtes Problem lösen oder eine bestimmte Funktionalität bieten.

Mit der oben genannten Ordnerstruktur im Hinterkopf könnte die Anwendung in 4 Pakete aufgeteilt werden:

  • Haupt
  • Karten
  • Helfer
  • stapelt

Es könnten auch mehr Pakete verwendet werden, zum Beispiel, wenn jemand die verschachtelten Stapel weiter trennen möchte. Die oben genannten 4 Pakete sind das empfohlene Minimum.

Übergabe von Werten zwischen Stapeln

Die meisten der von der CDK-Framework-Familie unterstützten Sprachen verwenden Konzepte der objektorientierten Programmierung (OOP). Obwohl es sich nicht bei allen um reine OOP-Sprachen handelt, gelten die Konzepte der objektorientierten Softwareentwicklung: Sie können (verschachtelte) Stacks in Klassen aufteilen und Sie können Ressourcen und Werte freilegen, indem Sie sie in Ihrer Anwendung öffentlich zugänglich machen.

Go ist keine OOP-Sprache. Wie könnten Sie dann Ressourcen zwischen Stapeln teilen?

Sie können sie als Rückgabewerte der Stack-Funktionen verfügbar machen.

Nehmen wir an, Sie möchten einen NetworkingStack erstellen, der den VPC erstellt und mit allen anderen Nested Stacks teilt. Wie können Sie dies in Go erreichen?

Lassen Sie uns eine Datei networking-stack.go im Ordner stacks/ erstellen. Der Inhalt der Datei sollte wie folgt aussehen:

package stacks

import (
    "github.com/aws/aws-cdk-go/awscdk/v2"
    "github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
    "github.com/aws/constructs-go/constructs/v10"
    // https://docs.aws.amazon.com/sdk-for-go/api/aws/
    "github.com/aws/aws-sdk-go-v2/aws"
)

type NetworkingNestedStackProps struct {
    awscdk.NestedStackProps
}

func NetworkingStack(scope constructs.Construct, id string, props *NetworkingNestedStackProps) (awscdk.NestedStack, awsec2.IVpc) {
    var nsprops awscdk.NestedStackProps
    if props != nil {
        nsprops = props.NestedStackProps
    }
    stack := awscdk.NewNestedStack(scope, &id, &nsprops)

    vpc := awsec2.NewVpc(stack, aws.String("sample-vpc"), 
        &awsec2.VpcProps{
            IpAddresses: awsec2.IpAddresses_Cidr(aws.String("10.0.0.0/16"),
            SubnetConfiguration: &[]*awsec2.SubnetConfiguration{
                {
                    CidrMask: aws.Float64(28),
                    SubnetType: awsec2.SubnetType_PUBLIC,
                    Name: aws.String("public"),
                },
                {
                    CidrMask: aws.Float64(28),
                    SubnetType: awsec2.SubnetType_PRIVATE_WITH_EGRESS,
                    Name: aws.String("private"),
                },
            },
        },
    )

    return stack, vpc
}


Wie Sie sehen können, definiert die NetworkingStack zwei Rückgabewerte. Einer ist vom Typ und der andere vom Typ . Unten schließlich werden beide Werte mit der Anweisung return stack, vpc zurückgegeben.

In der Funktion main() können wir dann einen neuen Stapel instanziieren, dem wir den Wert von Vpc übergeben wollen. Das können wir wie folgt tun:

package main

import (
    "parent-stack-main/stacks"
         ...
)

func main() {
    defer jsii.Close()

    app := awscdk.NewApp(nil)

         stack := NewParentStack(app, "NewParentStack", &NewParentStackProps{...})

    _, nsvpc := stacks.NetworkingStack(stack, "NetworkingStack", nil)
    stacks.MyNewNestedStack(stack, "MyNewNestedStack", &stacks.MyNewNestedStackProps{
        Vpc: nsvpc,
    })

    app.Synth(nil)
}

Fazit

Sie finden die gesamte Codebasis, die die in"Verwalten von K8S-Infrastruktur und -Anwendungen auf AWS" beschriebene Lösung repliziert, in Go umgeschrieben auf GitHub. Durch den Vergleich der Python- und der Go-Implementierung können Sie weitere Unterschiede und Lösungen erkennen, wie Sie dieselbe Funktionalität in diesen unterschiedlichen Hochsprachen implementieren können. Ich hoffe, Sie finden diese Informationen nützlich, um sich in der Welt von AWS CDK mit Go zurechtzufinden.

Hauptbild von svstudioart auf Freepik

Verfasst von

Konstantinos Bessas

Contact

Let’s discuss how we can support your journey.