Wenn Sie beginnen, Infrastruktur als Code zu erstellen. Sie werden in die Situation kommen, dass Sie einen Stack in separate Stacks aufteilen wollen. Oder Sie haben eine Ressource im falschen Stack implementiert. Das ist alles Teil des Entwicklungslebenszyklus. Sie probieren etwas aus, manches gelingt, manches wird scheitern. Aber eingesetzte Produktionsressourcen lassen sich nur schwer wiederherstellen. Sie haben entweder einen komplexen Datenmigrationspfad oder Sie können sich die Ausfallzeit nicht leisten.
Wenn Sie akzeptieren, dass sich einige Ressourcen in unerwarteten Stapeln befinden. Die Komplexität Ihrer Infrastruktur wird zunehmen. Und Komplexität wird in Zukunft zu Zwischenfällen führen.
In diesem Blogbeitrag erkläre ich Ihnen, wie Sie eine eingesetzte Ressource von einem CDK-Stack zu einem anderen verschieben können.
Einführung
Zunächst einmal ist es wichtig zu wissen, dass CDK CloudFormation erzeugt. CloudFormation bietet Funktionen, um bestehende Ressourcen unter seine Kontrolle zu bringen. Das bedeutet, dass Sie eine bereits bereitgestellte Ressource in einen CloudFormation Stack importieren können. Was hat das nun mit CDK zu tun?
Nehmen wir an, Sie haben einen CDK-Stack erstellt, der eine DynamoDB-Tabelle erstellt hat. Diese Tabelle enthält Informationen oder wird gerade verwendet. In diesen Fällen können Sie die Ressource nicht löschen und neu erstellen. Das würde zu Datenverlust oder Ausfallzeiten führen. In diesem Szenario könnten wir also die Ressource von einem Stack zu einem anderen migrieren.
Voraussetzungen
Sie müssen die folgenden Befehlszeilen-Tools verwenden.
Vergewissern Sie sich, dass Sie über gültige Zugangsdaten für das richtige Konto verfügen.
Schritt 1 - Entfernen Sie die Ressource aus dem vorhandenen Stapel
Laden Sie die vorhandene CloudFormation-Vorlage herunter:
aws cloudformation get-template
--output json
--stack-name <my-cloudformation-stack-name> | jq -r '.TemplateBody' > original-template.yml
cp original-template.yml modified-template.yml
In der Vorlage modified-template.yml müssen Sie die Ressource ausfindig machen, die Sie in Ihren "neuen" Stapel verschieben möchten. Sobald Sie sie gefunden haben, müssen Sie der Ressource die folgende DeletionPolicy: Retain hinzufügen.
Resources:
MyTable794EDED1:
Type: AWS::DynamoDB::Table
Properties:
KeySchema:
- AttributeName: id
KeyType: HASH
AttributeDefinitions:
- AttributeName: id
AttributeType: S
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
TableName: Games
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
Dadurch bleibt die Ressource erhalten, wenn Sie sie aus dem Stack löschen. Jetzt werden wir den CloudFormation Stack aktualisieren:
aws cloudformation update-stack
--stack-name <my-cloudformation-stack-name>
--template-body file://modified-template.yml
cp modified-template.yml final-template.yml
Der nächste Schritt hängt ein wenig von Ihrer Situation ab. In manchen Fällen können Sie den gesamten Stapel entfernen, weil es keine anderen Ressourcen im Stapel gibt. Oder weil sie nicht mehr benötigt werden. Aber in anderen Fällen müssen Sie eine Ressource auslagern. (Eine DynamoDB-Tabelle in diesem Beispiel)
Wenn Sie die anderen Ressourcen nicht mehr benötigen, können Sie den gesamten Stapel löschen. Wenn Sie den Rest der Ressourcen erhalten möchten. Dazu müssen Sie die Ressource aus der Vorlage entfernen, die Sie verschieben möchten. Wir entfernen also MyTable794EDED1 aus der Datei final-template.yml.
Führen Sie den Befehl update-stack erneut aus. Wir werden CloudFormation anweisen, die Ressource zu entfernen. Aber da wir die Richtlinie Retain festgelegt haben. Die Ressource wird nur aus dem Stack entfernt.
aws cloudformation update-stack
--stack-name <my-cloudformation-stack-name>
--template-body file://final-template.yml
Schritt 2 - Importieren Sie die Ressource
Wenn Sie Ressourcen verschieben, verschieben Sie sie entweder in einen neuen oder in einen bestehenden Stapel. Wenn Sie mit einem bestehenden Stapel arbeiten, benötigen Sie zunächst die bestehende Vorlage.
Laden Sie den vorhandenen Stack herunter
Laden Sie die vorhandene CloudFormation-Vorlage herunter:
aws cloudformation get-template
--output json
--stack-name <my-other-cloudformation-stack-name> | jq -r '.TemplateBody' > template.yml
Importieren Sie die vorhandene Ressource
Wenn Sie die Ressource auf einen neuen Stapel verschieben möchten. Sie müssen eine neue template.yml Datei erstellen. Wenn Sie die Ressource in einen bestehenden Stapel verschieben möchten, haben Sie die bestehende Vorlage bereits fertig.
Um die Ressource zu importieren, benötigen wir die Ressourcendefinition. Diese können Sie aus der Datei modified-template.yml aus Schritt 1 kopieren. Ich kann dies empfehlen, weil die CloudFormation-Definition mit der bereitgestellten Ressource übereinstimmen sollte. Der zweite Punkt ist, dass sie die DeletionPolicy: Retain Definition haben muss. Unser Beispiel wird also so aussehen:
Resources:
MyTable794EDED1:
Type: AWS::DynamoDB::Table
Properties:
KeySchema:
- AttributeName: id
KeyType: HASH
AttributeDefinitions:
- AttributeName: id
AttributeType: S
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
TableName: Games
UpdateReplacePolicy: Retain
DeletionPolicy: Retain
Als nächstes müssen wir eine Datei erstellen, nennen wir sie import.json. In dieser Datei werden wir für jede Ressource, die wir importieren, Folgendes definieren:
- AWS Ressourcentyp, der Typ der Ressource selbst.
- LogicalResourceId, der Bezeichner in der Vorlage. In diesem Beispiel wäre das
Games. - ResourceIdentifier, der Bezeichner der vorhandenen Ressource.
Wie Sie sehen können, enthält diese Datei die Beziehung zwischen dem Stack und dem, was bereits bereitgestellt wurde. Die Datei sieht wie folgt aus:
[
{
"ResourceType":"AWS::DynamoDB::Table",
"LogicalResourceId":"MyTable794EDED1",
"ResourceIdentifier": {
"TableName":"Games"
}
}
]
Als nächstes müssen Sie den Stack bereitstellen. Dies können Sie mit den folgenden Befehlen tun:
aws cloudformation create-change-set
--stack-name <my-other-cloudformation-stack-name>
--change-set-name ImportChangeSet
--change-set-type IMPORT
--template-body file://template.yml
--resources-to-import file://import.json
aws cloudformation wait change-set-create-complete --change-set-name ImportChangeSet --stack-name <my-other-cloudformation-stack-name>
aws cloudformation execute-change-set --change-set-name ImportChangeSet --stack-name <my-other-cloudformation-stack-name>
Schritt 3 - Neuverteilung mit CDK
Zu diesem Zeitpunkt ist die DynamoDB-Tabelle Teil des neuen Stacks. Aber wenn Sie den CDK-Stack neu bereitstellen, wird die DynamoDB-Ressourcendefinition nicht gerendert. Daher müssen wir die Definition zum CDK-Stack hinzufügen. Für dieses Beispiel habe ich das folgende CDK-Snippet verwendet. Aber wenn Sie von einem CDK-Stack zu einem anderen wechseln, können Sie den entsprechenden Code einfach verschieben.
dynamodb.Table(self, "MyTable",
table_name="GamesTable",
partition_key=dynamodb.Attribute(name="id", type=dynamodb.AttributeType.STRING),
billing_mode=dynamodb.BillingMode.PROVISIONED
)
Theoretisch sollte dies dieselbe Vorlage wiedergeben, die Sie beim Importieren verwendet haben. Aber wenn es Änderungen gibt, wird CloudFormation diese als Aktualisierungen aufzeichnen. Es versucht, die Ressource in den neuen Zustand zu versetzen. Nachdem Sie mit CDK bereitgestellt haben, ist alles wie gewohnt.
Fazit
Indem Sie die Komplexität Ihrer Infrastruktur reduzieren. Sie reduzieren das Risiko von Ausfällen und Zwischenfällen. Diese Reduzierung kann durch die Verlagerung von Ressourcen auf logischere Stacks erreicht werden. Der Prozess selbst beinhaltet manuelle Schritte. Aber wenn Ihre Ressourcen Daten enthalten oder sich keine Ausfallzeiten leisten können. Dies könnte Ihre einzige Lösung sein.
Verfasst von

Joris Conijn
Joris is the AWS Practise CTO of the Xebia Cloud service line and has been working with the AWS cloud since 2009 and focussing on building event-driven architectures. While working with the cloud from (almost) the start, he has seen most of the services being launched. Joris strongly believes in automation and infrastructure as code and is open to learning new things and experimenting with them because that is the way to learn and grow.
Unsere Ideen
Weitere Blogs
Contact




