

Dies ist der AWS CDK v2-Entwicklerhandbuch. Das ältere CDK v1 wurde am 1. Juni 2022 gewartet und der Support wurde am 1. Juni 2023 eingestellt.

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Lernen Sie die Kernkonzepte von AWS CDK kennen
<a name="core-concepts"></a>

Lernen Sie die Kernkonzepte hinter dem AWS Cloud Development Kit (AWS CDK) kennen.

## AWS CDK und IaC
<a name="concepts-iac"></a>

Das AWS CDK ist ein Open-Source-Framework, mit dem Sie Ihre AWS Infrastruktur mithilfe von Code verwalten können. Dieser Ansatz wird *Infrastructure as Code (IaC)* genannt. Indem Sie Ihre Infrastruktur als Code verwalten und bereitstellen, behandeln Sie Ihre Infrastruktur genauso wie Entwickler Code behandeln. Dies bietet viele Vorteile, z. B. Versionskontrolle und Skalierbarkeit. Weitere Informationen zu IaC finden Sie unter [Was ist Infrastruktur als Code](https://aws.amazon.com/what-is/iac/)? 

## AWS CDK und AWS CloudFormation
<a name="concepts-cfn"></a>

Das AWS CDK ist eng mit integriert. AWS CloudFormation AWS CloudFormation ist ein vollständig verwalteter Service, mit dem Sie Ihre Infrastruktur verwalten und bereitstellen können. AWS Mit AWS CloudFormation definieren Sie Ihre Infrastruktur in Vorlagen und stellen diese bereit AWS CloudFormation. Der AWS CloudFormation Service stellt dann Ihre Infrastruktur gemäß der in Ihren Vorlagen definierten Konfiguration bereit.

 AWS CloudFormation Vorlagen sind *deklarativ*, d. h. sie deklarieren den gewünschten Zustand oder das gewünschte Ergebnis Ihrer Infrastruktur. *Mithilfe von JSON oder YAML deklarieren Sie Ihre AWS Infrastruktur, indem Sie AWS *Ressourcen und Eigenschaften* definieren.* Ressourcen stellen die vielen Dienste dar, die aktiviert sind, AWS und Eigenschaften stehen für Ihre gewünschte Konfiguration dieser Dienste. Wenn Sie Ihre Vorlage auf bereitstellen AWS CloudFormation, werden Ihre Ressourcen und ihre konfigurierten Eigenschaften wie in Ihrer Vorlage beschrieben bereitgestellt.

Mit dem AWS CDK können Sie Ihre Infrastruktur mithilfe von *Allzweck-Programmiersprachen zwingend* verwalten. Anstatt nur einen gewünschten Zustand deklarativ zu definieren, können Sie die Logik oder Reihenfolge definieren, die erforderlich ist, um den gewünschten Zustand zu erreichen. Sie können beispielsweise `if` Anweisungen oder bedingte Schleifen verwenden, die bestimmen, wie ein gewünschter Endzustand für Ihre Infrastruktur erreicht werden kann.

Die mit dem AWS CDK erstellte Infrastruktur wird schließlich übersetzt oder in AWS CloudFormation Vorlagen *zusammengefasst* und mithilfe des AWS CloudFormation Dienstes bereitgestellt. Das AWS CDK bietet zwar einen anderen Ansatz für die Erstellung Ihrer Infrastruktur, Sie profitieren aber dennoch von den Vorteilen AWS CloudFormation, wie z. B. umfassender Unterstützung bei der AWS Ressourcenkonfiguration und robusten Bereitstellungsprozessen.

Weitere Informationen dazu finden Sie AWS CloudFormation unter [Was ist AWS CloudFormation?](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) im * AWS CloudFormation Benutzerhandbuch*.

## AWS CDK und Abstraktionen
<a name="concepts-abstractions"></a>

Mit AWS CloudFormation müssen Sie jedes Detail der Konfiguration Ihrer Ressourcen definieren. Dies bietet den Vorteil, dass Sie die vollständige Kontrolle über Ihre Infrastruktur haben. Dies erfordert jedoch, dass Sie sich mit robusten Vorlagen vertraut machen, diese verstehen und erstellen, die Details zur Ressourcenkonfiguration und Beziehungen zwischen Ressourcen enthalten, z. B. Berechtigungen und ereignisgesteuerte Interaktionen.

Mit dem AWS CDK können Sie die gleiche Kontrolle über Ihre Ressourcenkonfigurationen haben. Das AWS CDK bietet jedoch auch leistungsstarke Abstraktionen, die den Infrastrukturentwicklungsprozess beschleunigen und vereinfachen können. Zum Beispiel enthält das AWS CDK Konstrukte, die sinnvolle Standardkonfigurationen bereitstellen, und Hilfsmethoden, die Standardcode für Sie generieren. Das AWS CDK bietet auch Tools wie das AWS CDK Command Line Interface (AWS CDK CLI), die Infrastrukturverwaltungsaktionen für Sie ausführen.

## Erfahren Sie mehr über die Kernkonzepte von CDK AWS
<a name="concepts-learn"></a><a name="concepts-learn-interact"></a>

 **Interaktion mit dem CDK AWS **   
Bei der Verwendung mit dem AWS CDK interagieren Sie hauptsächlich mit der AWS Construct Library und der AWS CDK-CLI.<a name="concepts-learn-develop"></a>

 **Entwickeln mit dem CDK AWS **   
Das AWS CDK kann in jeder [unterstützten Programmiersprache](languages.md) geschrieben werden. [Sie beginnen mit einem [CDK-Projekt](projects.md), das eine Struktur von Ordnern und Dateien, einschließlich Assets, enthält.](assets.md) Innerhalb des Projekts erstellen Sie eine [CDK-Anwendung](apps.md). Innerhalb der App definieren Sie einen [Stack](stacks.md), der direkt einen CloudFormation Stack darstellt. Innerhalb des Stacks definieren Sie Ihre AWS Ressourcen und Eigenschaften mithilfe von [Konstrukten.](constructs.md)<a name="concepts-learn-deploy"></a>

 **Bereitstellung mit dem CDK AWS **   
[Sie stellen CDK-Apps in einer AWS Umgebung bereit.](environments.md) Vor der Bereitstellung müssen Sie ein einmaliges [Bootstrapping](bootstrapping.md) durchführen, um Ihre Umgebung vorzubereiten.<a name="concepts-learn-more"></a>

 **Weitere Informationen**   
Weitere Informationen zu den Kernkonzepten von AWS CDK finden Sie in den Themen in diesem Abschnitt.

# Unterstützte Programmiersprachen für das AWS CDK
<a name="languages"></a>

Das AWS Cloud Development Kit (AWS CDK) bietet erstklassige Unterstützung für die folgenden Allzweck-Programmiersprachen:
+ TypeScript
+ JavaScript
+ Python
+ Java
+ C\$1
+  Go 

Sonstige JVM and .NET CLR Sprachen können auch theoretisch verwendet werden, aber wir bieten derzeit keinen offiziellen Support an.

Das AWS CDK wurde in einer Sprache entwickelt, TypeScript. Um die anderen Sprachen zu unterstützen, verwendet das AWS CDK ein Tool namens [JSII](https://github.com/aws/jsii), um Sprachbindungen zu generieren.

Wir versuchen, die üblichen Konventionen jeder Sprache anzubieten, um die Entwicklung mit dem AWS CDK so natürlich und intuitiv wie möglich zu gestalten. Zum Beispiel verteilen wir AWS Construct Library-Module über das Standard-Repository Ihrer bevorzugten Sprache, und Sie installieren sie mit dem Standard-Paketmanager der Sprache. Methoden und Eigenschaften werden ebenfalls nach den von Ihrer Sprache empfohlenen Benennungsmustern benannt.

Im Folgenden finden Sie einige Codebeispiele:

**Example**  

```
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
  bucketName: 'amzn-s3-demo-bucket',
  versioned: true,
  websiteRedirect: {hostName: 'aws.amazon.com'}});
```

```
const bucket = new s3.Bucket(this, 'amzn-s3-demo-bucket', {
  bucketName: 'amzn-s3-demo-bucket',
  versioned: true,
  websiteRedirect: {hostName: 'aws.amazon.com'}});
```

```
bucket = s3.Bucket("amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket", versioned=True,
            website_redirect=s3.RedirectTarget(host_name="aws.amazon.com"))
```

```
Bucket bucket = Bucket.Builder.create(self, "amzn-s3-demo-bucket")
                      .bucketName("amzn-s3-demo-bucket")
                      .versioned(true)
                      .websiteRedirect(new RedirectTarget.Builder()
                          .hostName("aws.amazon.com").build())
                      .build();
```

```
var bucket = new Bucket(this, "amzn-s3-demo-bucket", new BucketProps {
                      BucketName = "amzn-s3-demo-bucket",
                      Versioned  = true,
                      WebsiteRedirect = new RedirectTarget {
                              HostName = "aws.amazon.com"
                      }});
```

```
bucket := awss3.NewBucket(scope, jsii.String("amzn-s3-demo-bucket"), &awss3.BucketProps {
	BucketName: jsii.String("amzn-s3-demo-bucket"),
	Versioned: jsii.Bool(true),
	WebsiteRedirect: &awss3.RedirectTarget {
		HostName: jsii.String("aws.amazon.com"),
	},
})
```

**Anmerkung**  
Diese Codefragmente dienen nur der Veranschaulichung. Sie sind unvollständig und werden nicht so ausgeführt, wie sie sind.

Die AWS Construct-Bibliothek wird mit den Standard-Paketverwaltungstools jeder Sprache verteilt, darunter NPM, PyPi, Maven, und NuGet. Wir bieten auch eine Version der [AWS CDK-API-Referenz](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html) für jede Sprache an.

Um Ihnen zu helfen, das AWS CDK in Ihrer bevorzugten Sprache zu verwenden, enthält dieser Leitfaden die folgenden Themen für unterstützte Sprachen:
+  [Arbeiten mit dem AWS CDK in TypeScript](work-with-cdk-typescript.md) 
+  [Arbeiten mit dem AWS CDK in JavaScript](work-with-cdk-javascript.md) 
+  [Arbeiten mit dem AWS CDK in Python](work-with-cdk-python.md) 
+  [Arbeiten mit dem AWS CDK in Java](work-with-cdk-java.md) 
+  [Arbeiten mit dem AWS CDK in C\$1](work-with-cdk-csharp.md) 
+  [Arbeiten mit dem AWS CDK in Go](work-with-cdk-go.md) 

TypeScript war die erste Sprache, die vom AWS CDK unterstützt wurde, und ein Großteil des AWS CDK-Beispielcodes ist in dieser Sprache geschrieben. TypeScript Dieses Handbuch enthält ein Thema, das speziell zeigt, wie TypeScript AWS CDK-Code für die Verwendung mit den anderen unterstützten Sprachen angepasst werden kann. Weitere Informationen finden Sie unter [AWS CDK TypeScript mit anderen Sprachen vergleichen](work-with.md#work-with-cdk-compare).

# Die AWS CDK-Bibliotheken
<a name="libraries"></a>

Erfahren Sie mehr über die Kernbibliotheken, die Sie mit dem AWS Cloud Development Kit (AWS CDK) verwenden werden.

## Die AWS CDK-Bibliothek
<a name="libraries-cdk"></a>

Die AWS CDK-Bibliothek, auch bekannt als, ist die Hauptbibliothek`aws-cdk-lib`, die Sie zur Entwicklung von Anwendungen mit dem AWS CDK verwenden werden. Sie wird entwickelt und verwaltet von. AWS Diese Bibliothek enthält Basisklassen wie [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html)und [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html). Sie enthält auch die Bibliotheken, die Sie verwenden werden, um Ihre Infrastruktur mithilfe von Konstrukten zu definieren.

## Die AWS Construct-Bibliothek
<a name="libraries-construct"></a>

Die AWS Construct Library ist Teil der AWS CDK-Bibliothek. Sie enthält eine Sammlung von [Konstrukten](constructs.md), die von entwickelt und verwaltet werden. AWS Es ist für jeden AWS Dienst in verschiedene Module unterteilt. Jedes Modul enthält Konstrukte, mit denen Sie Ihre AWS Ressourcen und Eigenschaften definieren können.

## Die Constructs-Bibliothek
<a name="libraries-constructs"></a>

Die Constructs-Bibliothek, allgemein als „Constructs“ bezeichnet`constructs`, ist eine Bibliothek zum Definieren und Zusammenstellen von Cloud-Infrastrukturkomponenten. Sie enthält die [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html)Kernklasse, die den Konstruktbaustein darstellt. Diese Klasse ist die grundlegende Basisklasse aller Konstrukte aus der AWS Construct Library. *Die Constructs-Bibliothek ist eine separate Allzweckbibliothek, die von anderen konstruktbasierten Tools wie *CDK für Terraform und CDK* für Kubernetes verwendet wird.*

## AWS Die CDK-API-Referenz
<a name="libraries-reference"></a>

Die [AWS CDK-API-Referenz enthält die offizielle Referenzdokumentation](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-construct-library.html) für die AWS CDK-Bibliothek, einschließlich der AWS Construct Library und der Constructs-Bibliothek. Für jede unterstützte Programmiersprache wird eine Version der API-Referenz bereitgestellt.
+ Die Dokumentation zu AWS CDK Library (`aws-cdk-lib`) finden Sie im [aws-cdk-lib Modul](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html).
+ Die Dokumentation für Konstrukte in der AWS Construct Library ist nach AWS Diensten im folgenden Format organisiert:. `aws-cdk-lib.<service>` Die Konstruktionsdokumentation für Amazon Simple Storage Service (Amazon S3) finden Sie beispielsweise im Modul [aws-cdk-lib.aws\$1s3](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3-readme.html).
+ [Die Dokumentation zur Constructs-Bibliothek (Constructs) finden Sie unter Constructs-Modul.](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs-readme.html)

### Tragen Sie zur CDK-API-Referenz bei AWS
<a name="libraries-reference-contribute"></a>

Das AWS CDK ist Open Source und wir freuen uns über Ihren Beitrag. Beiträge der Community wirken sich positiv auf das CDK aus und verbessern es. AWS Anweisungen, wie Sie speziell zur AWS CDK-API-Referenzdokumentation beitragen können, finden Sie in der [Dokumentation](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md#documentation) im aws-cdk * GitHub Repository. *

## Weitere Informationen
<a name="libraries-learn"></a>

Anweisungen zum Importieren und Verwenden der CDK-Bibliothek finden Sie unter [Arbeiten mit der CDK-Bibliothek](work-with.md).

# AWS CDK-Projekte
<a name="projects"></a>

Ein AWS Cloud Development Kit (AWS CDK) -Projekt stellt die Dateien und Ordner dar, die Ihren CDK-Code enthalten. Der Inhalt hängt von Ihrer Programmiersprache ab.

Sie können Ihr AWS CDK-Projekt manuell oder mit dem Befehl AWS CDK Command Line Interface (AWS CDK CLI) erstellen. `cdk init` In diesem Thema werden wir uns mit der Projektstruktur und den Namenskonventionen von Dateien und Ordnern befassen, die mit der AWS CDK-CLI erstellt wurden. Sie können Ihre CDK-Projekte an Ihre Bedürfnisse anpassen und organisieren.

**Anmerkung**  
Die von der AWS CDK-CLI erstellte Projektstruktur kann im Laufe der Zeit von Version zu Version variieren.

## Universelle Dateien und Ordner
<a name="projects-universal"></a><a name="projects-universal-git"></a>

 `.git`   
Wenn Sie `git` installiert haben, initialisiert die AWS CDK-CLI automatisch eine Git Repository für Ihr Projekt. Das `.git` Verzeichnis enthält Informationen über das Repository.<a name="projects-universal-gitignore"></a>

 `.gitignore`   
Textdatei, die verwendet wird von Git um Dateien und Ordner anzugeben, die ignoriert werden sollen.<a name="projects-universal-readme"></a>

 `README.md`   
Textdatei, die Ihnen grundlegende Anleitungen und wichtige Informationen für die Verwaltung Ihres AWS CDK-Projekts bietet. Ändern Sie diese Datei nach Bedarf, um wichtige Informationen zu Ihrem CDK-Projekt zu dokumentieren.<a name="projects-universal-cdk"></a>

 `cdk.json`   
Konfigurationsdatei für das AWS CDK. Diese Datei enthält Anweisungen für die AWS CDK-CLI zur Ausführung Ihrer App.

## Sprachspezifische Dateien und Ordner
<a name="projects-specific"></a>

Die folgenden Dateien und Ordner sind für jede unterstützte Programmiersprache einzigartig.

**Example**  
Im Folgenden finden Sie ein Beispielprojekt, das im `my-cdk-ts-project` Verzeichnis mit dem folgenden `cdk init --language typescript` Befehl erstellt wurde:  

```
my-cdk-ts-project
├── .git
├── .gitignore
├── .npmignore
├── README.md
├── bin
│   └── my-cdk-ts-project.ts
├── cdk.json
├── jest.config.js
├── lib
│   └── my-cdk-ts-project-stack.ts
├── node_modules
├── package-lock.json
├── package.json
├── test
│   └── my-cdk-ts-project.test.ts
└── tsconfig.json
```  
 `.npmignore`   
Datei, die angibt, welche Dateien und Ordner ignoriert werden sollen, wenn ein Paket in der `npm` Registrierung veröffentlicht wird. Diese Datei ähnelt Paketen`.gitignore`, ist aber spezifisch für `npm` Pakete.  
 `bin/my-cdk-ts-project.ts`   
Die *Anwendungsdatei* definiert Ihre CDK-App. CDK-Projekte können eine oder mehrere Anwendungsdateien enthalten. Anwendungsdateien werden in dem `bin` Ordner gespeichert.  
Im Folgenden finden Sie ein Beispiel für eine grundlegende Anwendungsdatei, die eine CDK-App definiert:  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyCdkTsProjectStack } from '../lib/my-cdk-ts-project-stack';

const app = new cdk.App();
new MyCdkTsProjectStack(app, 'MyCdkTsProjectStack');
```  
 `jest.config.js`   
Konfigurationsdatei für Jest. *Jest* ist ein beliebtes JavaScript Test-Framework.  
 `lib/my-cdk-ts-project-stack.ts`   
Die *Stack-Datei* definiert Ihren CDK-Stack. Innerhalb Ihres Stacks definieren Sie AWS Ressourcen und Eigenschaften mithilfe von Konstrukten.  
Im Folgenden finden Sie ein Beispiel für eine grundlegende Stack-Datei, die einen CDK-Stack definiert:  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

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

  // code that defines your resources and properties go here
 }
}
```  
 `node_modules`   
Gemeinsamer Ordner in Node.js Projekte, die Abhängigkeiten für Ihr Projekt enthalten.  
 `package-lock.json`   
Metadatendatei, die mit der `package.json` Datei zusammenarbeitet, um Versionen von Abhängigkeiten zu verwalten.  
 `package.json`   
Metadatendatei, die häufig verwendet wird in Node.js projekte. Diese Datei enthält Informationen über Ihr CDK-Projekt wie den Projektnamen, Skriptdefinitionen, Abhängigkeiten und andere Importinformationen auf Projektebene.  
 `test/my-cdk-ts-project.test.ts`   
Ein Testordner wird erstellt, um Tests für Ihr CDK-Projekt zu organisieren. Eine Beispieltestdatei wird ebenfalls erstellt.  
Sie können Tests einschreiben TypeScript und verwenden Jest um Ihren TypeScript Code zu kompilieren, bevor Sie Tests ausführen.  
 `tsconfig.json`   
In TypeScript Projekten verwendete Konfigurationsdatei, die Compileroptionen und Projekteinstellungen spezifiziert.
Das Folgende ist ein Beispielprojekt, das im `my-cdk-js-project` Verzeichnis mit dem `cdk init --language javascript` Befehl erstellt wurde:  

```
my-cdk-js-project
├── .git
├── .gitignore
├── .npmignore
├── README.md
├── bin
│   └── my-cdk-js-project.js
├── cdk.json
├── jest.config.js
├── lib
│   └── my-cdk-js-project-stack.js
├── node_modules
├── package-lock.json
├── package.json
└── test
    └── my-cdk-js-project.test.js
```  
 `.npmignore`   
Datei, die angibt, welche Dateien und Ordner ignoriert werden sollen, wenn ein Paket in der `npm` Registrierung veröffentlicht wird. Diese Datei ähnelt Paketen`.gitignore`, ist aber spezifisch für `npm` Pakete.  
 `bin/my-cdk-js-project.js`   
Die *Anwendungsdatei* definiert Ihre CDK-App. CDK-Projekte können eine oder mehrere Anwendungsdateien enthalten. Anwendungsdateien werden in dem `bin` Ordner gespeichert.  
Im Folgenden finden Sie ein Beispiel für eine grundlegende Anwendungsdatei, die eine CDK-App definiert:  

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { MyCdkJsProjectStack } = require('../lib/my-cdk-js-project-stack');

const app = new cdk.App();
new MyCdkJsProjectStack(app, 'MyCdkJsProjectStack');
```  
 `jest.config.js`   
Konfigurationsdatei für Jest. *Jest* ist ein beliebtes JavaScript Test-Framework.  
 `lib/my-cdk-js-project-stack.js`   
Die *Stack-Datei* definiert Ihren CDK-Stack. Innerhalb Ihres Stacks definieren Sie AWS Ressourcen und Eigenschaften mithilfe von Konstrukten.  
Im Folgenden finden Sie ein Beispiel für eine grundlegende Stack-Datei, die einen CDK-Stack definiert:  

```
const { Stack, Duration } = require('aws-cdk-lib');

class MyCdkJsProjectStack extends Stack {
 constructor(scope, id, props) {
  super(scope, id, props);

  // code that defines your resources and properties go here
 }
}

module.exports = { MyCdkJsProjectStack }
```  
 `node_modules`   
Gemeinsamer Ordner in Node.js Projekte, die Abhängigkeiten für Ihr Projekt enthalten.  
 `package-lock.json`   
Metadatendatei, die mit der `package.json` Datei zusammenarbeitet, um Versionen von Abhängigkeiten zu verwalten.  
 `package.json`   
Metadatendatei, die häufig verwendet wird in Node.js projekte. Diese Datei enthält Informationen über Ihr CDK-Projekt wie den Projektnamen, Skriptdefinitionen, Abhängigkeiten und andere Importinformationen auf Projektebene.  
 `test/my-cdk-js-project.test.js`   
Ein Testordner wird erstellt, um Tests für Ihr CDK-Projekt zu organisieren. Eine Beispieltestdatei wird ebenfalls erstellt.  
Sie können Tests einschreiben JavaScript und verwenden Jest um Ihren JavaScript Code zu kompilieren, bevor Sie Tests ausführen.
Das Folgende ist ein Beispielprojekt, das im `my-cdk-py-project` Verzeichnis mit dem `cdk init --language python` Befehl erstellt wurde:  

```
my-cdk-py-project
├── .git
├── .gitignore
├── .venv
├── README.md
├── app.py
├── cdk.json
├── my_cdk_py_project
│   ├── __init__.py
│   └── my_cdk_py_project_stack.py
├── requirements-dev.txt
├── requirements.txt
├── source.bat
└── tests
    ├── __init__.py
    └── unit
```  
 `.venv`   
Die CDK-CLI erstellt automatisch eine virtuelle Umgebung für Ihr Projekt. Das `.venv` Verzeichnis bezieht sich auf diese virtuelle Umgebung.  
 `app.py`   
Die *Anwendungsdatei* definiert Ihre CDK-App. CDK-Projekte können eine oder mehrere Anwendungsdateien enthalten.  
Im Folgenden finden Sie ein Beispiel für eine grundlegende Anwendungsdatei, die eine CDK-App definiert:  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from my_cdk_py_project.my_cdk_py_project_stack import MyCdkPyProjectStack

app = cdk.App()
MyCdkPyProjectStack(app, "MyCdkPyProjectStack")

app.synth()
```  
 `my_cdk_py_project`   
Verzeichnis, das Ihre *Stack-Dateien* enthält. Die CDK-CLI erstellt hier Folgendes:  
+ \$1\$1init\$1\$1.py — Eine leere Python-Paketdefinitionsdatei.
+  `my_cdk_py_project`— Datei, die Ihren CDK-Stack definiert. Anschließend definieren Sie AWS Ressourcen und Eigenschaften innerhalb des Stacks mithilfe von Konstrukten.
Im Folgenden finden Sie ein Beispiel für eine Stack-Datei:  

```
from aws_cdk import Stack

from constructs import Construct

class MyCdkPyProjectStack(Stack):
 def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
  super().__init__(scope, construct_id, **kwargs)

  # code that defines your resources and properties go here
```  
 `requirements-dev.txt`   
Datei`requirements.txt`, die ähnlich ist, aber zur Verwaltung von Abhängigkeiten speziell für Entwicklungszwecke und nicht für Produktionszwecke verwendet wird.  
 `requirements.txt`   
Allgemeine Datei, die in Python-Projekten verwendet wird, um Projektabhängigkeiten zu spezifizieren und zu verwalten.  
 `source.bat`   
Batch-Datei für Windows das wird verwendet, um die virtuelle Python-Umgebung einzurichten.  
 `tests`   
Verzeichnis, das Tests für Ihr CDK-Projekt enthält.  
Das Folgende ist ein Beispiel für einen Komponententest:  

```
import aws_cdk as core
import aws_cdk.assertions as assertions

from my_cdk_py_project.my_cdk_py_project_stack import MyCdkPyProjectStack

def test_sqs_queue_created():
 app = core.App()
 stack = MyCdkPyProjectStack(app, "my-cdk-py-project")
 template = assertions.Template.from_stack(stack)

 template.has_resource_properties("AWS::SQS::Queue", {
  "VisibilityTimeout": 300
 })
```
Das Folgende ist ein Beispielprojekt, das im `my-cdk-java-project` Verzeichnis mit dem `cdk init --language java` Befehl erstellt wurde:  

```
my-cdk-java-project
├── .git
├── .gitignore
├── README.md
├── cdk.json
├── pom.xml
└── src
    ├── main
    └── test
```  
 `pom.xml`   
Datei, die Konfigurationsinformationen und Metadaten zu Ihrem CDK-Projekt enthält. Diese Datei ist Teil von Maven.  
 `src/main`   
Verzeichnis, das Ihre *Anwendungs* - und *Stack-Dateien* enthält.  
Im Folgenden finden Sie ein Beispiel für eine Anwendungsdatei:  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class MyCdkJavaProjectApp {
 public static void main(final String[] args) {
  App app = new App();

  new MyCdkJavaProjectStack(app, "MyCdkJavaProjectStack", StackProps.builder()
   .build());

  app.synth();
 }
}
```
Im Folgenden finden Sie ein Beispiel für eine Stack-Datei:  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class MyCdkJavaProjectStack extends Stack {
 public MyCdkJavaProjectStack(final Construct scope, final String id) {
  this(scope, id, null);
 }

 public MyCdkJavaProjectStack(final Construct scope, final String id, final StackProps props) {
  super(scope, id, props);

  // code that defines your resources and properties go here
 }
}
```  
 `src/test`   
Verzeichnis, das Ihre Testdateien enthält. Im Folgenden wird ein Beispiel gezeigt:  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.assertions.Template;
import java.io.IOException;

import java.util.HashMap;

import org.junit.jupiter.api.Test;

public class MyCdkJavaProjectTest {

 @Test
 public void testStack() throws IOException {
  App app = new App();
  MyCdkJavaProjectStack stack = new MyCdkJavaProjectStack(app, "test");

  Template template = Template.fromStack(stack);

  template.hasResourceProperties("AWS::SQS::Queue", new HashMap<String, Number>() {{
   put("VisibilityTimeout", 300);
  }});
 }
}
```
Das Folgende ist ein Beispielprojekt, das in dem `my-cdk-csharp-project` Verzeichnis mit dem `cdk init --language csharp` Befehl erstellt wurde:  

```
my-cdk-csharp-project
├── .git
├── .gitignore
├── README.md
├── cdk.json
└── src
    ├── MyCdkCsharpProject
    └── MyCdkCsharpProject.sln
```  
 `src/MyCdkCsharpProject`   
Verzeichnis, das Ihre *Anwendungs* - und *Stack-Dateien* enthält.  
Im Folgenden finden Sie ein Beispiel für eine Anwendungsdatei:  

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace MyCdkCsharpProject
{
 sealed class Program
 {
  public static void Main(string[] args)
  {
   var app = new App();
   new MyCdkCsharpProjectStack(app, "MyCdkCsharpProjectStack", new StackProps{});
   app.Synth();
  }
 }
}
```
Im Folgenden finden Sie ein Beispiel für eine Stack-Datei:  

```
using Amazon.CDK;
using Constructs;

namespace MyCdkCsharpProject
{
 public class MyCdkCsharpProjectStack : Stack
 {
  internal MyCdkCsharpProjectStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
  {
   // code that defines your resources and properties go here
  }
 }
}
```
Dieses Verzeichnis enthält auch Folgendes:  
  
+  `GlobalSuppressions.cs`— Datei, die verwendet wird, um bestimmte Compiler-Warnungen oder -Fehler in Ihrem Projekt zu unterdrücken.
+  `.csproj`— XML-basierte Datei, die zur Definition von Projekteinstellungen, Abhängigkeiten und Build-Konfigurationen verwendet wird. ---  
 `src/MyCdkCsharpProject.sln`   
 Microsoft Visual Studio Solution File wird verwendet, um verwandte Projekte zu organisieren und zu verwalten.
Im Folgenden finden Sie ein Beispielprojekt, das im `my-cdk-go-project` Verzeichnis mit dem `cdk init --language go` Befehl erstellt wurde:  

```
my-cdk-go-project
├── .git
├── .gitignore
├── README.md
├── cdk.json
├── go.mod
├── my-cdk-go-project.go
└── my-cdk-go-project_test.go
```  
 `go.mod`   
Datei, die Modulinformationen enthält und zur Verwaltung von Abhängigkeiten und Versionierung für Ihr Go Projekt.  
 `my-cdk-go-project.go`   
Datei, die Ihre CDK-Anwendung und Stacks definiert.  
Im Folgenden wird ein Beispiel gezeigt:  

```
package main
import (
 "github.com/aws/aws-cdk-go/awscdk/v2"
 "github.com/aws/constructs-go/constructs/v10"
 "github.com/aws/jsii-runtime-go"
)

type MyCdkGoProjectStackProps struct {
 awscdk.StackProps
}

func NewMyCdkGoProjectStack(scope constructs.Construct, id string, props *MyCdkGoProjectStackProps) awscdk.Stack {
 var sprops awscdk.StackProps
 if props != nil {
  sprops = props.StackProps
 }
 stack := awscdk.NewStack(scope, &id, &sprops)
 // The code that defines your resources and properties go here

  return stack
}

func main() {
 defer jsii.Close()
 app := awscdk.NewApp(nil)
 NewMyCdkGoProjectStack(app, "MyCdkGoProjectStack", &MyCdkGoProjectStackProps{
  awscdk.StackProps{
   Env: env(),
  },
 })
 app.Synth(nil)
}

func env() *awscdk.Environment {

 return nil
}
```  
 `my-cdk-go-project_test.go`   
Datei, die einen Beispieltest definiert.  
Im Folgenden wird ein Beispiel gezeigt:  

```
package main

import (
 "testing"

 "github.com/aws/aws-cdk-go/awscdk/v2"
 "github.com/aws/aws-cdk-go/awscdk/v2/assertions"
 "github.com/aws/jsii-runtime-go"
)

func TestMyCdkGoProjectStack(t *testing.T) {

 // GIVEN
 app := awscdk.NewApp(nil)

 // WHEN
 stack := NewMyCdkGoProjectStack(app, "MyStack", nil)

 // THEN
 template := assertions.Template_FromStack(stack, nil)
 template.HasResourceProperties(jsii.String("AWS::SQS::Queue"), map[string]interface{}{
  "VisibilityTimeout": 300,
 })
}
```

# AWS CDK-Apps
<a name="apps"></a>

[Die AWS Cloud Development Kit (AWS CDK) -Anwendung oder *-App* ist eine Sammlung von einem oder mehreren CDK-Stacks.](stacks.md) Stacks sind eine Sammlung von einem oder mehreren [Konstrukten](constructs.md), die Ressourcen und Eigenschaften definieren. AWS Daher wird die Gesamtgruppierung Ihrer Stapel und Konstrukte als Ihre CDK-App bezeichnet.

## Wie erstelle ich eine CDK-App
<a name="apps-define"></a>

Sie erstellen eine App, indem Sie eine App-Instanz in der Anwendungsdatei Ihres [Projekts](projects.md) definieren. Dazu importieren und verwenden Sie das [App-Konstrukt](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html) aus der AWS Construct-Bibliothek. Das `App` Konstrukt benötigt keine Initialisierungsargumente. Es ist das einzige Konstrukt, das als Wurzel verwendet werden kann.

Die ` [Stack](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html) ` Klassen ` [App](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html) ` und aus der AWS Construct-Bibliothek sind einzigartige Konstrukte. Im Vergleich zu anderen Konstrukten konfigurieren sie AWS Ressourcen nicht eigenständig. Stattdessen werden sie verwendet, um Kontext für Ihre anderen Konstrukte bereitzustellen. Alle Konstrukte, die AWS Ressourcen darstellen, müssen direkt oder indirekt im Rahmen eines `Stack` Konstrukts definiert werden. `Stack`Konstrukte werden innerhalb des Gültigkeitsbereichs eines `App` Konstrukts definiert.

Apps werden dann synthetisiert, um AWS CloudFormation Vorlagen für Ihre Stacks zu erstellen. Im Folgenden wird ein Beispiel gezeigt:

**Example**  

```
const app = new App();
new MyFirstStack(app, 'hello-cdk');
app.synth();
```

```
const app = new App();
new MyFirstStack(app, 'hello-cdk');
app.synth();
```

```
app = App()
MyFirstStack(app, "hello-cdk")
app.synth()
```

```
App app = new App();
new MyFirstStack(app, "hello-cdk");
app.synth();
```

```
var app = new App();
new MyFirstStack(app, "hello-cdk");
app.Synth();
```

```
app := awscdk.NewApp(nil)

MyFirstStack(app, "MyFirstStack", &MyFirstStackProps{
  awscdk.StackProps{
    Env: env(),
  },
})

app.Synth(nil)
```

Stacks innerhalb einer einzigen App können problemlos auf die Ressourcen und Eigenschaften der jeweils anderen App verweisen. Das AWS CDK leitet Abhängigkeiten zwischen Stacks ab, sodass sie in der richtigen Reihenfolge bereitgestellt werden können. Sie können einen oder alle Stacks innerhalb einer App mit einem einzigen Befehl bereitstellen. `cdk deploy`

## Der Konstruktbaum
<a name="apps-tree"></a>

Konstrukte werden innerhalb anderer Konstrukte mit dem `scope` Argument definiert, das an jedes Konstrukt übergeben wird, wobei die `App` Klasse die Wurzel ist. *Auf diese Weise definiert eine AWS CDK-App eine Hierarchie von Konstrukten, die als Konstruktbaum bezeichnet wird.*

Die Wurzel dieses Baums ist Ihre App, die eine Instanz der `App` Klasse ist. Innerhalb der App instanziieren Sie einen oder mehrere Stapel. Innerhalb von Stacks instanziieren Sie Konstrukte, die wiederum Ressourcen oder andere Konstrukte instanziieren können, und so weiter im Baum.

Konstrukte werden *immer* explizit im Rahmen eines anderen Konstrukts definiert, wodurch Beziehungen zwischen Konstrukten hergestellt werden. Fast immer sollten Sie `this` (in Python`self`) als Gültigkeitsbereich übergeben, was darauf hinweist, dass das neue Konstrukt ein untergeordnetes Objekt des aktuellen Konstrukts ist. Das beabsichtigte Muster besteht darin, dass Sie Ihr Konstrukt ableiten und dann die Konstrukte instanziieren [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html), die es in seinem Konstruktor verwendet.

[Die explizite Übergabe des Gültigkeitsbereichs ermöglicht es jedem Konstrukt, sich selbst zum Baum hinzuzufügen, wobei dieses Verhalten vollständig in der Basisklasse enthalten ist. `Construct`](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) Es funktioniert in jeder vom AWS CDK unterstützten Sprache auf die gleiche Weise und erfordert keine zusätzliche Anpassung.

**Wichtig**  
Technisch gesehen ist es möglich, einen anderen Gültigkeitsbereich als `this` bei der Instanziierung eines Konstrukts zu übergeben. Sie können Konstrukte an einer beliebigen Stelle im Baum oder sogar in einem anderen Stapel in derselben App hinzufügen. Sie könnten beispielsweise eine Funktion im Mixin-Stil schreiben, die einem als Argument übergebenen Bereich Konstrukte hinzufügt. Die praktische Schwierigkeit dabei besteht darin, dass Sie nicht ohne Weiteres sicherstellen können, dass die Konstrukte, die IDs Sie für Ihre Konstrukte auswählen, innerhalb des Gültigkeitsbereichs einer anderen Person einzigartig sind. Diese Vorgehensweise macht es auch schwieriger, Ihren Code zu verstehen, zu verwalten und wiederzuverwenden. Daher empfehlen wir, die allgemeine Struktur des Konstruktbaums zu verwenden.

Das AWS CDK verwendet alle Konstrukte im Pfad IDs von der Wurzel des Baums bis zu jedem untergeordneten Konstrukt, um das für IDs erforderliche eindeutige Objekt zu generieren. AWS CloudFormation Dieser Ansatz bedeutet, dass das Konstrukt IDs nur innerhalb seines Gültigkeitsbereichs einzigartig sein muss und nicht wie bei nativem System innerhalb des gesamten Stacks. AWS CloudFormation Wenn Sie ein Konstrukt jedoch in einen anderen Bereich verschieben, ändert sich die generierte eindeutige Stack-ID und es AWS CloudFormation wird nicht als dieselbe Ressource betrachtet.

Der Konstruktbaum ist getrennt von den Konstrukten, die Sie in Ihrem CDK-Code definieren. AWS Er ist jedoch über das `node` Attribut jedes Konstrukts zugänglich, das ein Verweis auf den Knoten ist, der dieses Konstrukt im Baum darstellt. Jeder Knoten ist eine [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Node.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Node.html)Instanz, deren Attribute den Zugriff auf die Wurzel des Baums und auf die übergeordneten Bereiche und untergeordneten Bereiche des Knotens ermöglichen.

1.  `node.children`— Die direkten untergeordneten Elemente des Konstrukts.

1.  `node.id`— Der Bezeichner des Konstrukts innerhalb seines Gültigkeitsbereichs.

1.  `node.path`— Der vollständige Pfad des Konstrukts einschließlich IDs aller seiner Eltern.

1.  `node.root`— Die Wurzel des Konstruktbaums (die App).

1.  `node.scope`— Der Bereich (übergeordnetes Objekt) des Konstrukts oder undefiniert, wenn es sich bei dem Knoten um die Wurzel handelt.

1.  `node.scopes`— Alle übergeordneten Elemente des Konstrukts, bis zur Wurzel.

1.  `node.uniqueId`— Die eindeutige alphanumerische Kennung für dieses Konstrukt innerhalb des Baums (standardmäßig generiert aus `node.path` und ein Hash).

Der Konstruktbaum definiert eine implizite Reihenfolge, in der Konstrukte in der endgültigen Vorlage zu Ressourcen synthetisiert werden. AWS CloudFormation Dabei muss eine Ressource vor einer anderen erstellt werden, AWS CloudFormation oder die AWS Construct-Bibliothek leitet im Allgemeinen auf die Abhängigkeit ab. Sie stellen dann sicher, dass die Ressourcen in der richtigen Reihenfolge erstellt werden.

Sie können auch eine explizite Abhängigkeit zwischen zwei Knoten hinzufügen, indem Sie `node.addDependency()` Weitere Informationen finden Sie unter [Abhängigkeiten](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib-readme.html#dependencies) in der * AWS CDK-API-Referenz.*

Das AWS CDK bietet eine einfache Möglichkeit, jeden Knoten im Konstruktbaum zu besuchen und an jedem Knoten eine Operation auszuführen. Weitere Informationen finden Sie unter [Aspekte und AWS CDK](aspects.md).

# Einführung in AWS CDK-Stacks
<a name="stacks"></a>

Ein AWS CDK-Stack ist die kleinste einzelne Bereitstellungseinheit. Er stellt eine Sammlung von AWS Ressourcen dar, die Sie mithilfe von CDK-Konstrukten definieren. Wenn Sie CDK-Apps bereitstellen, werden die Ressourcen innerhalb eines CDK-Stacks zusammen als Stapel bereitgestellt. AWS CloudFormation *Weitere Informationen zu AWS CloudFormation Stacks finden Sie im Benutzerhandbuch unter [AWS Ressourcen als eine Einheit mit AWS CloudFormation Stacks verwalten](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html). AWS CloudFormation *

Sie definieren einen Stapel, indem Sie das Konstrukt erweitern oder von ihm erben. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html) Das folgende Beispiel ist ein gängiges Muster für die Definition eines CDK-Stacks in einer separaten Datei, einer sogenannten *Stack-Datei*. Hier erweitern oder erben wir die `Stack` Klasse und definieren einen Konstruktor, der`scope`, `id` und akzeptiert. `props` Dann rufen wir den `Stack` Basisklassenkonstruktor auf, indem wir `super` mit den empfangenen`scope`,, und: `id` `props`

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

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

    // Define your constructs here

  }
}
```

```
const { Stack } = require('aws-cdk-lib');

class MyCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define your constructs here

  }
}

module.exports = { MyCdkStack }
```

```
from aws_cdk import (
  Stack,
)
from constructs import Construct

class MyCdkStack(Stack):

  def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
    super().__init__(scope, construct_id, **kwargs)

    # Define your constructs here
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class MyCdkStack extends Stack {
  public MyCdkStack(final Construct scope, final String id) {
    this(scope, id, null);
  }

  public MyCdkStack(final Construct scope, final String id, final StackProps props) {
    super(scope, id, props);

    // Define your constructs here
  }
}
```

```
using Amazon.CDK;
using Constructs;

namespace MyCdk
{
  public class MyCdkStack : Stack
  {
    internal MyCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
    {
      // Define your constructs here
    }
  }
}
```

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// The code that defines your stack goes here

	return stack
}

func main() {
	defer jsii.Close()

	app := awscdk.NewApp(nil)

	NewCdkDemoAppStack(app, "CdkDemoAppStack", &CdkDemoAppStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	app.Synth(nil)
}

//...
```

Das vorherige Beispiel hat nur einen Stack definiert. Um den Stack zu erstellen, muss er im Kontext Ihrer CDK-App instanziiert werden. *Ein gängiges Muster besteht darin, Ihre CDK-App zu definieren und Ihren Stack in einer separaten Datei zu initialisieren, die als Anwendungsdatei bezeichnet wird.*

Im Folgenden finden Sie ein Beispiel, das einen CDK-Stack mit dem Namen erstellt. `MyCdkStack` Hier wird die CDK-App erstellt und `MyCdkStack` im Kontext der App instanziiert:

**Example**  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyCdkStack } from '../lib/my-cdk-stack';

const app = new cdk.App();
new MyCdkStack(app, 'MyCdkStack', {
});
```

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { MyCdkStack } = require('../lib/my-cdk-stack');

const app = new cdk.App();
new MyCdkStack(app, 'MyCdkStack', {
});
```
Befindet sich in: `app.py`  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from my_cdk.my_cdk_stack import MyCdkStack


app = cdk.App()
MyCdkStack(app, "MyCdkStack",)

app.synth()
```

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class MyCdkApp {
  public static void main(final String[] args) {
    App app = new App();

    new MyCdkStack(app, "MyCdkStack", StackProps.builder()
      .build());

    app.synth();
  }
}
```

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace MyCdk
{
  sealed class Program
  {
    public static void Main(string[] args)
    {
      var app = new App();
      new MyCdkStack(app, "MyCdkStack", new StackProps
      {});
      app.Synth();
    }
  }
}
```

```
package main

import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/constructs-go/constructs/v10"
  "github.com/aws/jsii-runtime-go"
)

// ...

func main() {
  defer jsii.Close()

  app := awscdk.NewApp(nil)

  NewMyCdkStack(app, "MyCdkStack", &MyCdkStackProps{
    awscdk.StackProps{
      Env: env(),
    },
  })

  app.Synth(nil)
}

// ...
```

Im folgenden Beispiel wird eine CDK-App erstellt, die zwei Stacks enthält:

**Example**  

```
const app = new App();

new MyFirstStack(app, 'stack1');
new MySecondStack(app, 'stack2');

app.synth();
```

```
const app = new App();

new MyFirstStack(app, 'stack1');
new MySecondStack(app, 'stack2');

app.synth();
```

```
app = App()

MyFirstStack(app, 'stack1')
MySecondStack(app, 'stack2')

app.synth()
```

```
App app = new App();

new MyFirstStack(app, "stack1");
new MySecondStack(app, "stack2");

app.synth();
```

```
var app = new App();

new MyFirstStack(app, "stack1");
new MySecondStack(app, "stack2");

app.Synth();
```

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type MyFirstStackProps struct {
	awscdk.StackProps
}

func NewMyFirstStack(scope constructs.Construct, id string, props *MyFirstStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	myFirstStack := awscdk.NewStack(scope, &id, &sprops)

	// The code that defines your stack goes here

	return myFirstStack
}

type MySecondStackProps struct {
	awscdk.StackProps
}

func NewMySecondStack(scope constructs.Construct, id string, props *MySecondStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	mySecondStack := awscdk.NewStack(scope, &id, &sprops)

	// The code that defines your stack goes here

	return mySecondStack
}

func main() {
	defer jsii.Close()

	app := awscdk.NewApp(nil)

	NewMyFirstStack(app, "MyFirstStack", &MyFirstStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	NewMySecondStack(app, "MySecondStack", &MySecondStackProps{
		awscdk.StackProps{
			Env: env(),
		},
	})

	app.Synth(nil)
}

// ...
```

## Über die Stack-API
<a name="stack-api"></a>

Das [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html)Objekt bietet eine umfangreiche API, einschließlich der folgenden:
+  `Stack.of(construct)`— Eine statische Methode, die den **Stack** zurückgibt, in dem ein Konstrukt definiert ist. Dies ist nützlich, wenn Sie innerhalb eines wiederverwendbaren Konstrukts mit einem Stapel interagieren müssen. Der Aufruf schlägt fehl, wenn ein Stack im Gültigkeitsbereich nicht gefunden werden kann.
+  `stack.stackName`(Python:`stack_name`) — Gibt den physischen Namen des Stacks zurück. Wie bereits erwähnt, haben alle AWS CDK-Stacks einen physikalischen Namen, den der AWS CDK während der Synthese auflösen kann.
+  `stack.region`und `stack.account` — Gibt die AWS Region bzw. das Konto zurück, in dem dieser Stack bereitgestellt werden soll. Diese Eigenschaften geben einen der folgenden Werte zurück:
  + Das Konto oder die Region, das bei der Definition des Stacks explizit angegeben wurde
  + Ein string-codiertes Token, das in die AWS CloudFormation Pseudo-Parameter für Account und Region aufgelöst wird, um anzuzeigen, dass dieser Stack umgebungsunabhängig ist

    [Informationen darüber, wie Umgebungen für Stacks bestimmt werden, finden Sie unter Umgebungen für das CDK. AWS](environments.md)
+  `stack.addDependency(stack)`(Python:`stack.add_dependency(stack)`) — Kann verwendet werden, um die Reihenfolge der Abhängigkeiten zwischen zwei Stacks explizit zu definieren. Diese Reihenfolge wird vom `cdk deploy` Befehl respektiert, wenn mehrere Stacks gleichzeitig bereitgestellt werden.
+  `stack.tags`— Gibt eine zurück [TagManager](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.TagManager.html), mit der Sie Tags auf Stackebene hinzufügen oder entfernen können. Dieser Tag-Manager markiert alle Ressourcen innerhalb des Stacks und markiert auch den Stack selbst, wenn er durch diesen erstellt wird. AWS CloudFormation
+  `stack.partition`, `stack.urlSuffix` (Python:`url_suffix`), `stack.stackId` (Python:`stack_id`) und `stack.notificationArn` (Python:`notification_arn`) — Gibt Tokens zurück, die in die jeweiligen AWS CloudFormation Pseudo-Parameter aufgelöst werden, wie `{ "Ref": "AWS::Partition" }` z. B. Diese Token sind dem spezifischen Stack-Objekt zugeordnet, sodass das AWS CDK-Framework stapelübergreifende Referenzen identifizieren kann.
+  `stack.availabilityZones`(Python:`availability_zones`) — Gibt den Satz von Availability Zones zurück, die in der Umgebung verfügbar sind, in der dieser Stack bereitgestellt wird. Bei umgebungsunabhängigen Stacks wird dadurch immer ein Array mit zwei Availability Zones zurückgegeben. Bei umgebungsspezifischen Stacks fragt das AWS CDK die Umgebung ab und gibt genau die Availability Zones zurück, die in der von Ihnen angegebenen Region verfügbar sind.
+  `stack.parseArn(arn)`und `stack.formatArn(comps)` (Python:`parse_arn`,`format_arn`) — Kann verwendet werden, um mit Amazon Resource Names (ARNs) zu arbeiten.
+  `stack.toJsonString(obj)`(Python:`to_json_string`) — Kann verwendet werden, um ein beliebiges Objekt als JSON-String zu formatieren, der in eine AWS CloudFormation Vorlage eingebettet werden kann. Das Objekt kann Token, Attribute und Verweise enthalten, die nur während der Bereitstellung aufgelöst werden.
+  `stack.templateOptions`(Python:`template_options`) — Wird verwendet, um AWS CloudFormation Vorlagenoptionen wie Transformation, Beschreibung und Metadaten für Ihren Stack anzugeben.

## Arbeiten mit -Stacks
<a name="stacks-work"></a>

Stacks werden als AWS CloudFormation Stapel in einer AWS [Umgebung](environments.md) bereitgestellt. Die Umgebung deckt ein bestimmtes AWS Konto und eine bestimmte AWS Region ab.

Wenn Sie den `cdk synth` Befehl für eine App mit mehreren Stacks ausführen, enthält die Cloud-Assembly eine separate Vorlage für jede Stack-Instanz. Selbst wenn es sich bei den beiden Stacks um Instanzen derselben Klasse handelt, gibt das AWS CDK sie als zwei einzelne Vorlagen aus.

Sie können jede Vorlage synthetisieren, indem Sie den Stacknamen im Befehl angeben. `cdk synth` Das folgende Beispiel synthetisiert die Vorlage für: `stack1`

```
$ cdk synth <stack1>
```

[Dieser Ansatz unterscheidet sich konzeptionell von der üblichen Verwendung von AWS CloudFormation Vorlagen, bei der eine Vorlage mehrfach bereitgestellt und über Parameter parametrisiert werden kann.AWS CloudFormation ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) AWS CloudFormation Parameter können zwar im AWS CDK definiert werden, es wird jedoch generell davon abgeraten, da AWS CloudFormation Parameter erst während der Bereitstellung aufgelöst werden. Das bedeutet, dass Sie ihren Wert nicht in Ihrem Code bestimmen können.

Um beispielsweise eine Ressource auf der Grundlage eines Parameterwerts bedingt in Ihre App aufzunehmen, müssen Sie eine [AWS CloudFormation Bedingung](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html) einrichten und die Ressource damit kennzeichnen. Das AWS CDK verfolgt einen Ansatz, bei dem konkrete Vorlagen zum Zeitpunkt der Synthese aufgelöst werden. Daher können Sie mithilfe einer `if` Anweisung den Wert überprüfen, um festzustellen, ob eine Ressource definiert oder ein bestimmtes Verhalten angewendet werden sollte.

**Anmerkung**  
Das AWS CDK bietet während der Synthesezeit so viel Auflösung wie möglich, um eine idiomatische und natürliche Verwendung Ihrer Programmiersprache zu ermöglichen.

Wie jedes andere Konstrukt können Stapel zu Gruppen zusammengesetzt werden. Der folgende Code zeigt ein Beispiel für einen Service, der aus drei Stacks besteht: einer Steuerungsebene, einer Datenebene und Überwachungsstapeln. Das Dienstkonstrukt ist zweimal definiert: einmal für die Betaumgebung und einmal für die Produktionsumgebung.

**Example**  

```
import { App, Stack } from 'aws-cdk-lib';
import { Construct } from 'constructs';

interface EnvProps {
  prod: boolean;
}

// imagine these stacks declare a bunch of related resources
class ControlPlane extends Stack {}
class DataPlane extends Stack {}
class Monitoring extends Stack {}

class MyService extends Construct {

  constructor(scope: Construct, id: string, props?: EnvProps) {

    super(scope, id);

    // we might use the prod argument to change how the service is configured
    new ControlPlane(this, "cp");
    new DataPlane(this, "data");
    new Monitoring(this, "mon");  }
}

const app = new App();
new MyService(app, "beta");
new MyService(app, "prod", { prod: true });

app.synth();
```

```
const { App, Stack } = require('aws-cdk-lib');
const { Construct } = require('constructs');

// imagine these stacks declare a bunch of related resources
class ControlPlane extends Stack {}
class DataPlane extends Stack {}
class Monitoring extends Stack {}

class MyService extends Construct {

  constructor(scope, id, props) {

    super(scope, id);

    // we might use the prod argument to change how the service is configured
    new ControlPlane(this, "cp");
    new DataPlane(this, "data");
    new Monitoring(this, "mon");
  }
}

const app = new App();
new MyService(app, "beta");
new MyService(app, "prod", { prod: true });

app.synth();
```

```
from aws_cdk import App, Stack
from constructs import Construct

# imagine these stacks declare a bunch of related resources
class ControlPlane(Stack): pass
class DataPlane(Stack): pass
class Monitoring(Stack): pass

class MyService(Construct):

  def __init__(self, scope: Construct, id: str, *, prod=False):

    super().__init__(scope, id)

    # we might use the prod argument to change how the service is configured
    ControlPlane(self, "cp")
    DataPlane(self, "data")
    Monitoring(self, "mon")

app = App();
MyService(app, "beta")
MyService(app, "prod", prod=True)

app.synth()
```

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Stack;
import software.constructs.Construct;

public class MyApp {

    // imagine these stacks declare a bunch of related resources
    static class ControlPlane extends Stack {
        ControlPlane(Construct scope, String id) {
            super(scope, id);
        }
    }

    static class DataPlane extends Stack {
        DataPlane(Construct scope, String id) {
            super(scope, id);
        }
    }

    static class Monitoring extends Stack {
        Monitoring(Construct scope, String id) {
            super(scope, id);
        }
    }

    static class MyService extends Construct {
        MyService(Construct scope, String id) {
            this(scope, id, false);
        }

        MyService(Construct scope, String id, boolean prod) {
            super(scope, id);

            // we might use the prod argument to change how the service is configured
            new ControlPlane(this, "cp");
            new DataPlane(this, "data");
            new Monitoring(this, "mon");
        }
    }

    public static void main(final String argv[]) {
        App app = new App();

        new MyService(app, "beta");
        new MyService(app, "prod", true);

        app.synth();
    }
}
```

```
using Amazon.CDK;
using Constructs;

// imagine these stacks declare a bunch of related resources
public class ControlPlane : Stack {
    public ControlPlane(Construct scope, string id=null) : base(scope, id) { }
}

public class DataPlane : Stack {
    public DataPlane(Construct scope, string id=null) : base(scope, id) { }
}

public class Monitoring : Stack
{
    public Monitoring(Construct scope, string id=null) : base(scope, id) { }
}

public class MyService : Construct
{
    public MyService(Construct scope, string id, Boolean prod=false) : base(scope, id)
    {
        // we might use the prod argument to change how the service is configured
        new ControlPlane(this, "cp");
        new DataPlane(this, "data");
        new Monitoring(this, "mon");
    }
}

class Program
{
    static void Main(string[] args)
    {

        var app = new App();
        new MyService(app, "beta");
        new MyService(app, "prod", prod: true);
        app.Synth();
    }
}
```

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type ControlPlaneStackProps struct {
	awscdk.StackProps
}

func NewControlPlaneStack(scope constructs.Construct, id string, props *ControlPlaneStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	ControlPlaneStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	// The code that defines your stack goes here

	return ControlPlaneStack
}

type DataPlaneStackProps struct {
	awscdk.StackProps
}

func NewDataPlaneStack(scope constructs.Construct, id string, props *DataPlaneStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	DataPlaneStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	// The code that defines your stack goes here

	return DataPlaneStack
}

type MonitoringStackProps struct {
	awscdk.StackProps
}

func NewMonitoringStack(scope constructs.Construct, id string, props *MonitoringStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	MonitoringStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	// The code that defines your stack goes here

	return MonitoringStack
}

type MyServiceStackProps struct {
	awscdk.StackProps
	Prod bool
}

func NewMyServiceStack(scope constructs.Construct, id string, props *MyServiceStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	MyServiceStack := awscdk.NewStack(scope, jsii.String(id), &sprops)

	NewControlPlaneStack(MyServiceStack, "cp", &ControlPlaneStackProps{
		StackProps: sprops,
	})
	NewDataPlaneStack(MyServiceStack, "data", &DataPlaneStackProps{
		StackProps: sprops,
	})
	NewMonitoringStack(MyServiceStack, "mon", &MonitoringStackProps{
		StackProps: sprops,
	})

	return MyServiceStack
}

func main() {
	defer jsii.Close()

	app := awscdk.NewApp(nil)

	betaProps := MyServiceStackProps{
		StackProps: awscdk.StackProps{
			Env: env(),
		},
		Prod: false,
	}

	NewMyServiceStack(app, "beta", &betaProps)

	prodProps := MyServiceStackProps{
		StackProps: awscdk.StackProps{
			Env: env(),
		},
		Prod: true,
	}

	NewMyServiceStack(app, "prod", &prodProps)

	app.Synth(nil)
}

// ...
```
Diese AWS CDK-App besteht letztendlich aus sechs Stacks, drei für jede Umgebung:  

```
$ cdk ls

betacpDA8372D3
betadataE23DB2BA
betamon632BD457
prodcp187264CE
proddataF7378CE5
prodmon631A1083
```

Die physischen Namen der AWS CloudFormation Stacks werden automatisch vom AWS CDK auf der Grundlage des Konstruktpfads des Stacks im Baum bestimmt. Standardmäßig wird der Name eines Stacks von der Konstrukt-ID des `Stack` Objekts abgeleitet. Sie können jedoch einen expliziten Namen angeben, indem Sie die `stackName` Requisite (in Python,`stack_name`) wie folgt verwenden.

**Example**  

```
new MyStack(this, 'not:a:stack:name', { stackName: 'this-is-stack-name' });
```

```
new MyStack(this, 'not:a:stack:name', { stackName: 'this-is-stack-name' });
```

```
MyStack(self, "not:a:stack:name", stack_name="this-is-stack-name")
```

```
new MyStack(this, "not:a:stack:name", StackProps.builder()
    .StackName("this-is-stack-name").build());
```

```
new MyStack(this, "not:a:stack:name", new StackProps
{
    StackName = "this-is-stack-name"
});
```

### Arbeiten mit verschachtelten Stacks
<a name="stack-nesting"></a>

Ein *verschachtelter Stapel* ist ein CDK-Stapel, den Sie in einem anderen Stapel, dem sogenannten übergeordneten Stapel, erstellen. Sie erstellen verschachtelte Stapel mithilfe des Konstrukts. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.NestedStack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.NestedStack.html)

Durch die Verwendung verschachtelter Stacks können Sie Ressourcen auf mehrere Stapel verteilen. Verschachtelte Stapel bieten auch eine Möglichkeit, das Limit von 500 Ressourcen für Stapel zu umgehen. AWS CloudFormation Ein verschachtelter Stapel zählt nur als eine Ressource in dem Stapel, der ihn enthält. Er kann jedoch bis zu 500 Ressourcen enthalten, einschließlich zusätzlicher verschachtelter Stacks.

Der Gültigkeitsbereich eines verschachtelten Stacks muss ein `Stack` Oder-Konstrukt sein. `NestedStack` Der verschachtelte Stapel muss innerhalb seines übergeordneten Stacks nicht lexikalisch deklariert werden. Bei der Instanziierung des verschachtelten Stacks muss nur der übergeordnete Stapel als ersten Parameter (`scope`) übergeben werden. Abgesehen von dieser Einschränkung funktioniert die Definition von Konstrukten in einem verschachtelten Stack genauso wie in einem normalen Stack.

Zum Zeitpunkt der Synthese wird der verschachtelte Stack zu einer eigenen AWS CloudFormation Vorlage synthetisiert, die bei der Bereitstellung in den AWS CDK-Staging-Bucket hochgeladen wird. Verschachtelte Stacks sind an ihren übergeordneten Stapel gebunden und werden nicht als unabhängige Bereitstellungsartefakte behandelt. Sie sind nicht in der Liste aufgeführt und können auch nicht von `cdk list` bereitgestellt werden. `cdk deploy`

[Verweise zwischen übergeordneten Stacks und verschachtelten Stacks werden automatisch in Stack-Parameter und Ausgaben in den generierten AWS CloudFormation Vorlagen übersetzt, wie bei jeder stapelübergreifenden Referenz.](resources.md#resource-stack)

**Warnung**  
Änderungen der Sicherheitslage werden vor der Bereitstellung für verschachtelte Stacks nicht angezeigt. Diese Informationen werden nur für Stacks der obersten Ebene angezeigt.

# Einführung in die AWS CDK-Phasen
<a name="stages"></a>

Eine AWS Cloud Development Kit (AWS CDK) *-Phase* stellt eine Gruppe von einem oder mehreren CDK-Stacks dar, die für die gemeinsame Bereitstellung konfiguriert sind. Verwenden Sie Phasen, um dieselbe Gruppierung von Stacks in mehreren Umgebungen bereitzustellen, z. B. in der Entwicklungs-, Test- und Produktionsumgebung.

Um eine CDK-Phase zu konfigurieren, importieren und verwenden Sie das Konstrukt. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stage.html)

Im Folgenden finden Sie ein einfaches Beispiel, das eine CDK-Phase mit dem Namen definiert. `MyAppStage` Wir fügen unserer Phase zwei CDK-Stacks mit dem Namen `AppStack` und `DatabaseStack` hinzu. In diesem Beispiel `AppStack` enthält es Anwendungsressourcen und `DatabaseStack` Datenbankressourcen. Anschließend erstellen wir zwei Instanzen von `MyAppStage` für Entwicklungs- und Produktionsumgebungen:

**Example**  
In `cdk-demo-app/lib/app-stack.ts`:  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

// Define the app stack
export class AppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    // The code that defines your application goes here
  }
}
```
In `cdk-demo-app/lib/database-stack.ts`:  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

// Define the database stack
export class DatabaseStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    // The code that defines your database goes here
  }
}
```
In `cdk-demo-app/lib/my-stage.ts`:  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import { Stage } from 'aws-cdk-lib';
import { AppStack } from './app-stack';
import { DatabaseStack } from './database-stack';

// Define the stage
export class MyAppStage extends Stage {
  constructor(scope: Construct, id: string, props?: cdk.StageProps) {
    super(scope, id, props);

    // Add both stacks to the stage
    new AppStack(this, 'AppStack');
    new DatabaseStack(this, 'DatabaseStack');
  }
}
```
In `cdk-demo-app/bin/cdk-demo-app.ts`:  

```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { MyAppStage } from '../lib/my-stage';

// Create a CDK app
const app = new cdk.App();

// Create the development stage
new MyAppStage(app, 'Dev', {
  env: {
    account: '123456789012',
    region: 'us-east-1'
  }
});

// Create the production stage
new MyAppStage(app, 'Prod', {
  env: {
    account: '098765432109',
    region: 'us-east-1'
  }
});
```
In `cdk-demo-app/lib/app-stack.js`:  

```
const { Stack } = require('aws-cdk-lib');

class AppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // The code that defines your application goes here
  }
}

module.exports = { AppStack }
```
In `cdk-demo-app/lib/database-stack.js`:  

```
const { Stack } = require('aws-cdk-lib');

class DatabaseStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // The code that defines your database goes here
  }
}

module.exports = { DatabaseStack }
```
In `cdk-demo-app/lib/my-stage.js`:  

```
const { Stage } = require('aws-cdk-lib');
const { AppStack } = require('./app-stack');
const { DatabaseStack } = require('./database-stack');

// Define the stage
class MyAppStage extends Stage {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Add both stacks to the stage
    new AppStack(this, 'AppStack');
    new DatabaseStack(this, 'DatabaseStack');
  }
}

module.exports = { MyAppStage };
```
In `cdk-demo-app/bin/cdk-demo-app.js`:  

```
#!/usr/bin/env node

const cdk = require('aws-cdk-lib');
const { MyAppStage } = require('../lib/my-stage');

// Create the CDK app
const app = new cdk.App();

// Create the development stage
new MyAppStage(app, 'Dev', {
  env: {
    account: '123456789012',
    region: 'us-east-1',
  },
});

// Create the production stage
new MyAppStage(app, 'Prod', {
  env: {
    account: '098765432109',
    region: 'us-east-1',
  },
});
```
In `cdk-demo-app/cdk_demo_app/app_stack.py`:  

```
from aws_cdk import Stack
from constructs import Construct

# Define the app stack
class AppStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your application goes here
```
In `cdk-demo-app/cdk_demo_app/database_stack.py`:  

```
from aws_cdk import Stack
from constructs import Construct

# Define the database stack
class DatabaseStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # The code that defines your database goes here
```
In `cdk-demo-app/cdk_demo_app/my_stage.py`:  

```
from aws_cdk import Stage
from constructs import Construct
from .app_stack import AppStack
from .database_stack import DatabaseStack

# Define the stage
class MyAppStage(Stage):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # Add both stacks to the stage
        AppStack(self, "AppStack")
        DatabaseStack(self, "DatabaseStack")
```
In `cdk-demo-app/app.py`:  

```
#!/usr/bin/env python3
import os

import aws_cdk as cdk

from cdk_demo_app.my_stage import MyAppStage

#  Create a CDK app
app = cdk.App()

# Create the development stage
MyAppStage(app, 'Dev',
           env=cdk.Environment(account='123456789012', region='us-east-1'),
           )

# Create the production stage
MyAppStage(app, 'Prod',
           env=cdk.Environment(account='098765432109', region='us-east-1'),
           )

app.synth()
```
In `cdk-demo-app/src/main/java/com/myorg/AppStack.java`:  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class AppStack extends Stack {
    public AppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public AppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // The code that defines your application goes here
    }
}
```
In `cdk-demo-app/src/main/java/com/myorg/DatabaseStack.java`:  

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;

public class DatabaseStack extends Stack {
    public DatabaseStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public DatabaseStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // The code that defines your database goes here
    }
}
```
In `cdk-demo-app/src/main/java/com/myorg/MyAppStage.java`:  

```
package com.myorg;

import software.amazon.awscdk.Stage;
import software.amazon.awscdk.StageProps;
import software.constructs.Construct;

// Define the stage
public class MyAppStage extends Stage {
    public MyAppStage(final Construct scope, final String id, final software.amazon.awscdk.Environment env) {
        super(scope, id, StageProps.builder().env(env).build());

        // Add both stacks to the stage
        new AppStack(this, "AppStack");
        new DatabaseStack(this, "DatabaseStack");
    }
}
```
In `cdk-demo-app/src/main/java/com/myorg/CdkDemoAppApp.java`:  

```
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Environment;
import software.amazon.awscdk.StackProps;

import java.util.Arrays;

public class CdkDemoAppApp {
    public static void main(final String[] args) {

        // Create a CDK app
        App app = new App();

        // Create the development stage
        new MyAppStage(app, "Dev", Environment.builder()
                .account("123456789012")
                .region("us-east-1")
                .build());

        // Create the production stage
        new MyAppStage(app, "Prod", Environment.builder()
        .account("098765432109")
        .region("us-east-1")
        .build());

        app.synth();
    }
}
```
In `cdk-demo-app/src/CdkDemoApp/AppStack.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkDemoApp
{
    public class AppStack : Stack
    {
        internal AppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your application goes here
        }
    }
}
```
In `cdk-demo-app/src/CdkDemoApp/DatabaseStack.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkDemoApp
{
    public class DatabaseStack : Stack
    {
        internal DatabaseStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // The code that defines your database goes here
        }
    }
}
```
In `cdk-demo-app/src/CdkDemoApp/MyAppStage.cs`:  

```
using Amazon.CDK;
using Constructs;

namespace CdkDemoApp
{
    // Define the stage
    public class MyAppStage : Stage
    {
        internal MyAppStage(Construct scope, string id, Environment env) : base(scope, id, new StageProps { Env = env })
        {
            // Add both stacks to the stage
            new AppStack(this, "AppStack");
            new DatabaseStack(this, "DatabaseStack");
        }
    }
}
```
In `cdk-demo-app/src/CdkDemoApp/program.cs`:  

```
using Amazon.CDK;
using System;
using System.Collections.Generic;
using System.Linq;

namespace CdkDemoApp
{
    sealed class Program
    {
        public static void Main(string[] args)
        {
            // Create a CDK app
            var app = new App();

            // Create the development stage
            new MyAppStage(app, "Dev", new Amazon.CDK.Environment
            {
                Account = "123456789012",
                Region = "us-east-1"
            });

            // Create the production stage
            new MyAppStage(app, "Prod", new Amazon.CDK.Environment
            {
                Account = "098765432109",
                Region = "us-east-1"
            });

            app.Synth();
        }
    }
}
```
In `cdk-demo-app/cdk-demo-app.go`:  

```
package main

import (
	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

// Define the app stack
type AppStackProps struct {
	awscdk.StackProps
}

func NewAppStack(scope constructs.Construct, id string, props *AppStackProps) awscdk.Stack {
	stack := awscdk.NewStack(scope, &id, &props.StackProps)

	// The code that defines your application goes here

	return stack
}

// Define the database stack
type DatabaseStackProps struct {
	awscdk.StackProps
}

func NewDatabaseStack(scope constructs.Construct, id string, props *DatabaseStackProps) awscdk.Stack {
	stack := awscdk.NewStack(scope, &id, &props.StackProps)

	// The code that defines your database goes here

	return stack
}

// Define the stage
type MyAppStageProps struct {
	awscdk.StageProps
}

func NewMyAppStage(scope constructs.Construct, id string, props *MyAppStageProps) awscdk.Stage {
	stage := awscdk.NewStage(scope, &id, &props.StageProps)

	// Add both stacks to the stage
	NewAppStack(stage, "AppStack", &AppStackProps{
		StackProps: awscdk.StackProps{
			Env: props.Env,
		},
	})

	NewDatabaseStack(stage, "DatabaseStack", &DatabaseStackProps{
		StackProps: awscdk.StackProps{
			Env: props.Env,
		},
	})

	return stage
}

func main() {
	defer jsii.Close()

	// Create a CDK app
	app := awscdk.NewApp(nil)

	// Create the development stage
	NewMyAppStage(app, "Dev", &MyAppStageProps{
		StageProps: awscdk.StageProps{
			Env: &awscdk.Environment{
				Account: jsii.String("123456789012"),
				Region:  jsii.String("us-east-1"),
			},
		},
	})

	// Create the production stage
	NewMyAppStage(app, "Prod", &MyAppStageProps{
		StageProps: awscdk.StageProps{
			Env: &awscdk.Environment{
				Account: jsii.String("098765432109"),
				Region:  jsii.String("us-east-1"),
			},
		},
	})

	app.Synth(nil)
}

func env() *awscdk.Environment {
	return nil
}
```

Bei der Ausführung `cdk synth` werden zwei Cloud-Assemblys in erstellt`cdk.out`. Diese beiden Cloud-Assemblys enthalten die synthetisierte AWS CloudFormation Vorlage und die Assets für jede Phase. Das Folgende ist ein Auszug aus unserem Projektverzeichnis:

**Example**  

```
cdk-demo-app
├── bin
│   └── cdk-demo-app.ts
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
└── lib
    ├── app-stack.ts
    ├── database-stack.ts
    └── my-stage.ts
```

```
cdk-demo-app
├── bin
│   └── cdk-demo-app.js
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
└── lib
    ├── app-stack.js
    ├── database-stack.js
    └── my-stage.js
```

```
cdk-demo-app
├── app.py
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── cdk.out
│   ├── manifest.json
│   └── tree.json
└── cdk_demo_app
    ├── __init__.py
    ├── app_stack.py
    ├── database_stack.py
    └── my_stage.py
```

```
cdk-demo-app
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── cdk.out
│   ├── manifest.json
│   └── tree.json
└── src
    └── main
        └── java
            └── com
                └── myorg
                    ├── AppStack.java
                    ├── CdkDemoAppApp.java
                    ├── DatabaseStack.java
                    └── MyAppStage.java
```

```
cdk-demo-app
├── cdk.out
│   ├── assembly-Dev
│   │   ├── DevAppStack<unique-hash>.assets.json
│   │   ├── DevAppStack<unique-hash>.template.json
│   │   ├── DevDatabaseStack<unique-hash>.assets.json
│   │   ├── DevDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── assembly-Prod
│   │   ├── ProdAppStack<unique-hash>.assets.json
│   │   ├── ProdAppStack<unique-hash>.template.json
│   │   ├── ProdDatabaseStack<unique-hash>.assets.json
│   │   ├── ProdDatabaseStack<unique-hash>.template.json
│   │   ├── cdk.out
│   │   └── manifest.json
│   ├── cdk.out
│   ├── manifest.json
│   └── tree.json
└── src
    └── CdkDemoApp
        ├── AppStack.cs
        ├── DatabaseStack.cs
        ├── MyAppStage.cs
        └── Program.cs
```

```
cdk-demo-app
├── cdk-demo-app.go
└── cdk.out
    ├── assembly-Dev
    │   ├── DevAppStack<unique-hash>.assets.json
    │   ├── DevAppStack<unique-hash>.template.json
    │   ├── DevDatabaseStack<unique-hash>.assets.json
    │   ├── DevDatabaseStack<unique-hash>.template.json
    │   ├── cdk.out
    │   └── manifest.json
    ├── assembly-Prod
    │   ├── ProdAppStack<unique-hash>.assets.json
    │   ├── ProdAppStack<unique-hash>.template.json
    │   ├── ProdDatabaseStack<unique-hash>.assets.json
    │   ├── ProdDatabaseStack<unique-hash>.template.json
    │   ├── cdk.out
    │   └── manifest.json
    ├── cdk.out
    ├── manifest.json
    └── tree.json
```
Wenn wir unsere Stapel mit auflisten`cdk list`, sehen wir insgesamt vier Stapel:  

```
$ cdk list
Dev/AppStack (Dev-AppStack)
Dev/DatabaseStack (Dev-DatabaseStack)
Prod/AppStack (Prod-AppStack)
Prod/DatabaseStack (Prod-DatabaseStack)
```
Um eine bestimmte Phase bereitzustellen, führen wir die Stacks aus `cdk deploy` und stellen sie bereit. Im Folgenden finden Sie ein Beispiel, das den `/*` Platzhalter verwendet, um beide Stacks in unserer Phase bereitzustellen: `Dev`  

```
$ cdk deploy <"Dev/*">

✨  Synthesis time: 3.18s

Dev/AppStack (Dev-AppStack)
Dev/AppStack (Dev-AppStack): deploying... [1/2]

 ✅  Dev/AppStack (Dev-AppStack)

✨  Deployment time: 1.11s

Stack ARN:
...

✨  Total time: 4.29s

Dev/DatabaseStack (Dev-DatabaseStack)
Dev/DatabaseStack (Dev-DatabaseStack): deploying... [2/2]

 ✅  Dev/DatabaseStack (Dev-DatabaseStack)

✨  Deployment time: 1.09s

Stack ARN:
...

✨  Total time: 4.27s
```

# AWS CDK-Konstrukte
<a name="constructs"></a>

Konstrukte sind die grundlegenden Bausteine von AWS Cloud Development Kit (AWS CDK) -Anwendungen. Ein Konstrukt ist eine Komponente innerhalb Ihrer Anwendung, die eine oder mehrere AWS CloudFormation Ressourcen und deren Konfiguration darstellt. Sie erstellen Ihre Anwendung Stück für Stück, indem Sie Konstrukte importieren und konfigurieren.

## Importieren und verwenden Sie Konstrukte
<a name="constructs-import"></a>

[Konstrukte sind Klassen, die Sie aus der Construct Library in Ihre CDK-Anwendungen importieren.AWS](libraries.md#libraries-construct) Sie können auch Ihre eigenen Konstrukte erstellen und verteilen oder Konstrukte verwenden, die von Drittanbietern erstellt wurden.

Konstrukte sind Teil des Construct Programming Model (CPM). Sie können mit anderen Tools wie CDK for Terraform (CDKtf), CDK for Kubernetes (CDK8s) und verwendet werden. Projen

Zahlreiche Drittanbieter haben auch Konstrukte veröffentlicht, die mit dem CDK kompatibel sind. AWS Besuchen Sie [Construct Hub](https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&offset=0), um das AWS CDK Construct-Partner-Ökosystem zu erkunden.

## Konstruieren Sie Ebenen
<a name="constructs-lib-levels"></a>

Konstrukte aus der AWS Construct Library sind in drei Stufen unterteilt. Jede Ebene bietet eine zunehmende Abstraktionsebene. Je höher die Abstraktion, desto einfacher ist die Konfiguration und erfordert weniger Fachwissen. Je niedriger die Abstraktion, desto mehr Anpassungen sind verfügbar und erfordern mehr Fachwissen.<a name="constructs-lib-levels-one"></a>

 **Konstrukte der Stufe 1 (L1)**   
L1-Konstrukte, auch *CFN-Ressourcen* genannt, sind das Konstrukt der untersten Ebene und bieten keine Abstraktion. Jedes L1-Konstrukt ist direkt einer einzelnen Ressource zugeordnet. AWS CloudFormation Bei L1-Konstrukten importieren Sie ein Konstrukt, das eine bestimmte Ressource darstellt. AWS CloudFormation Anschließend definieren Sie die Eigenschaften der Ressource in Ihrer Konstruktinstanz.  
L1-Konstrukte eignen sich hervorragend, wenn Sie mit der Definition Ihrer AWS Ressourceneigenschaften vertraut sind AWS CloudFormation und vollständige Kontrolle darüber benötigen.  
In der AWS Construct-Bibliothek werden L1-Konstrukte beginnend mit benannt`Cfn`, gefolgt von einem Bezeichner für die AWS CloudFormation Ressource, für die sie stehen. Das [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.CfnBucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.CfnBucket.html)Konstrukt ist beispielsweise ein L1-Konstrukt, das eine Ressource darstellt. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) AWS CloudFormation   
[L1-Konstrukte werden anhand der Ressourcenspezifikation generiert.AWS CloudFormation ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-resource-specification.html) Wenn eine Ressource in existiert AWS CloudFormation, ist sie im AWS CDK als L1-Konstrukt verfügbar. Es kann bis zu einer Woche dauern, bis neue Ressourcen oder Eigenschaften in der AWS Construct-Bibliothek verfügbar sind. Weitere Informationen finden Sie in der [Referenz zu AWS Ressourcen- und Eigenschaftstypen](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) im * AWS CloudFormation Benutzerhandbuch*.<a name="constructs-lib-levels-two"></a>

 **Konstrukte der Ebene 2 (L2)**   
L2-Konstrukte, auch als *kuratierte* Konstrukte bekannt, wurden vom CDK-Team sorgfältig entwickelt und sind in der Regel der am häufigsten verwendete Konstrukttyp. L2-Konstrukte werden, ähnlich wie L1-Konstrukte, direkt einzelnen Ressourcen zugeordnet. AWS CloudFormation Im Vergleich zu L1-Konstrukten bieten L2-Konstrukte über eine intuitive absichtsbasierte API eine Abstraktion auf höherer Ebene. L2-Konstrukte beinhalten sinnvolle Standardkonfigurationen für Eigenschaften, bewährte Sicherheitsrichtlinien und generieren einen Großteil des Standardcodes und der Glue-Logik für Sie.  
L2-Konstrukte bieten auch Hilfsmethoden für die meisten Ressourcen, mit denen Eigenschaften, Berechtigungen, ereignisbasierte Interaktionen zwischen Ressourcen und mehr einfacher und schneller definiert werden können. Viele dieser Funktionen sind auch als unabhängige Bausteine, sogenannte [Mixins](mixins.md), verfügbar, die mit dieser Methode sowohl auf L1- als auch auf L2-Konstrukte angewendet werden können. `.with()`  
Die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html)Klasse ist ein Beispiel für ein L2-Konstrukt für eine Bucket-Ressource von Amazon Simple Storage Service (Amazon S3).  
Die AWS Construct-Bibliothek enthält L2-Konstrukte, die als stabil und produktionsbereit gekennzeichnet sind. L2-Konstrukte, die sich in der Entwicklung befinden, werden als experimentell eingestuft und in einem separaten Modul angeboten.<a name="constructs-lib-levels-three"></a>

 **Konstrukte der Stufe 3 (L3)**   
L3-Konstrukte, auch *Muster genannt, stellen die höchste Abstraktionsebene* dar. Jedes L3-Konstrukt kann eine Sammlung von Ressourcen enthalten, die so konfiguriert sind, dass sie zusammenarbeiten, um eine bestimmte Aufgabe oder einen bestimmten Dienst innerhalb Ihrer Anwendung auszuführen. L3-Konstrukte werden verwendet, um ganze AWS Architekturen für bestimmte Anwendungsfälle in Ihrer Anwendung zu erstellen.  
Um komplette Systementwürfe oder wesentliche Teile eines größeren Systems bereitzustellen, bieten L3-Konstrukte individuelle Standardkonfigurationen für Eigenschaften. Sie basieren auf einem bestimmten Ansatz zur Lösung eines Problems und zur Bereitstellung einer Lösung. Mit L3-Konstrukten können Sie schnell und mit dem geringsten Aufwand an Eingabe und Code mehrere Ressourcen erstellen und konfigurieren.  
Die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs_patterns.ApplicationLoadBalancedFargateService.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs_patterns.ApplicationLoadBalancedFargateService.html)Klasse ist ein Beispiel für ein L3-Konstrukt, das einen AWS Fargate-Service darstellt, der auf einem Amazon Elastic Container Service (Amazon ECS) -Cluster ausgeführt wird und von einem Application Load Balancer unterstützt wird.  
Ähnlich wie L2-Konstrukte sind L3-Konstrukte, die für den produktiven Einsatz bereit sind, in der Construct-Bibliothek enthalten. AWS Diejenigen, die sich in der Entwicklung befinden, werden in separaten Modulen angeboten.

## Konstrukte definieren
<a name="constructs-define"></a>

### Composition
<a name="constructs-composition"></a>

 Die *Komposition* ist das Schlüsselmuster für die Definition von Abstraktionen auf höherer Ebene durch Konstrukte. Ein Konstrukt auf hoher Ebene kann aus einer beliebigen Anzahl von Konstrukten niedrigerer Ebenen zusammengesetzt werden. Von unten nach oben betrachtet, verwenden Sie Konstrukte, um die einzelnen AWS Ressourcen zu organisieren, die Sie bereitstellen möchten. Sie verwenden die für Ihren Zweck geeigneten Abstraktionen mit so vielen Ebenen, wie Sie benötigen.

Bei der Komposition definieren Sie wiederverwendbare Komponenten und teilen sie wie jeden anderen Code. Ein Team kann beispielsweise ein Konstrukt definieren, das die Best Practices des Unternehmens für eine Amazon DynamoDB-Tabelle implementiert, einschließlich Backup, globaler Replikation, automatischer Skalierung und Überwachung. Das Team kann das Konstrukt intern mit anderen Teams oder öffentlich teilen.

Teams können Konstrukte wie jedes andere Bibliothekspaket verwenden. Wenn die Bibliothek aktualisiert wird, erhalten Entwickler Zugriff auf die Verbesserungen und Bugfixes der neuen Version, ähnlich wie bei jeder anderen Codebibliothek.

### Initialisierung
<a name="constructs-init"></a>

Konstrukte werden in Klassen implementiert, die die [https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html)-Basisklasse erweitern. Sie definieren ein Konstrukt, indem Sie die Klasse instanziieren. Alle Konstrukte benötigen drei Parameter, wenn sie initialisiert werden:
+  **Gültigkeitsbereich** — Das übergeordnete Objekt oder der Eigentümer des Konstrukts. Dies kann entweder ein Stapel oder ein anderes Konstrukt sein. Der Geltungsbereich bestimmt die Position des [Konstrukts im Konstruktbaum](apps.md#apps-tree). Normalerweise sollten Sie `this` (`self`in Python), was das aktuelle Objekt darstellt, für den Bereich übergeben.
+  **id** — Ein [Bezeichner](identifiers.md), der innerhalb des Gültigkeitsbereichs eindeutig sein muss. Der Bezeichner dient als Namespace für alles, was innerhalb des Konstrukts definiert ist. Er wird verwendet, um eindeutige Bezeichner wie [Ressourcennamen](resources.md#resources-physical-names) und AWS CloudFormation logische Bezeichner zu generieren. IDs

  Identifikatoren müssen nur innerhalb eines Bereichs eindeutig sein. Auf diese Weise können Sie Konstrukte instanziieren und wiederverwenden, ohne sich Gedanken über die darin enthaltenen Konstrukte und Bezeichner machen zu müssen. Außerdem können Sie Konstrukte zu Abstraktionen auf höherer Ebene zusammensetzen. Darüber hinaus ermöglichen Gültigkeitsbereiche, auf Gruppen von Konstrukten gleichzeitig zu verweisen. Beispiele hierfür sind das [Markieren](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tag.html) oder die Angabe, wo die Konstrukte eingesetzt werden sollen.
+  **props** — Je nach Sprache eine Reihe von Eigenschaften oder Schlüsselwortargumenten, die die ursprüngliche Konfiguration des Konstrukts definieren. Konstrukte auf höherer Ebene bieten mehr Standardwerte, und wenn alle Prop-Elemente optional sind, können Sie den Parameter props komplett weglassen.

### Konfiguration
<a name="constructs-config"></a>

Die meisten Konstrukte akzeptieren `props` als drittes Argument (oder in Python Schlüsselwortargumente) eine name/value Sammlung, die die Konfiguration des Konstrukts definiert. Das folgende Beispiel definiert einen Bucket mit aktivierter AWS Key Management Service (AWS KMS) -Verschlüsselung und statischem Website-Hosting. Da es nicht explizit einen Verschlüsselungsschlüssel spezifiziert, definiert das `Bucket` Konstrukt einen neuen `kms.Key` und ordnet ihn dem Bucket zu.

**Example**  

```
new s3.Bucket(this, 'MyEncryptedBucket', {
  encryption: s3.BucketEncryption.KMS,
  websiteIndexDocument: 'index.html'
});
```

```
new s3.Bucket(this, 'MyEncryptedBucket', {
  encryption: s3.BucketEncryption.KMS,
  websiteIndexDocument: 'index.html'
});
```

```
s3.Bucket(self, "MyEncryptedBucket", encryption=s3.BucketEncryption.KMS,
    website_index_document="index.html")
```

```
Bucket.Builder.create(this, "MyEncryptedBucket")
        .encryption(BucketEncryption.KMS_MANAGED)
        .websiteIndexDocument("index.html").build();
```

```
new Bucket(this, "MyEncryptedBucket", new BucketProps
{
    Encryption = BucketEncryption.KMS_MANAGED,
    WebsiteIndexDocument = "index.html"
});
```

```
	awss3.NewBucket(stack, jsii.String("MyEncryptedBucket"), &awss3.BucketProps{
		Encryption: awss3.BucketEncryption_KMS,
		WebsiteIndexDocument: jsii.String("index.html"),
	})
```

### Interaktion mit Konstrukten
<a name="constructs-interact"></a>

Konstrukte sind Klassen, die die Basisklasse [Construct](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) erweitern. Nachdem Sie ein Konstrukt instanziiert haben, stellt das Konstruktobjekt eine Reihe von Methoden und Eigenschaften zur Verfügung, mit denen Sie mit dem Konstrukt interagieren und es als Referenz an andere Teile des Systems weitergeben können.

Das AWS CDK-Framework schränkt die Verwendung von Konstrukten nicht ein. APIs Autoren können jede beliebige API definieren. Die AWS Konstrukte, die in der AWS Construct-Bibliothek enthalten sind`s3.Bucket`, folgen jedoch Richtlinien und gängigen Mustern. Dadurch wird ein einheitliches Benutzererlebnis für alle AWS Ressourcen gewährleistet.

Die meisten AWS Konstrukte verfügen über eine Reihe von [Erteilungsmethoden](permissions.md#permissions-grants), mit denen Sie einem Prinzipal AWS Identity and Access Management (IAM) -Berechtigungen für dieses Konstrukt gewähren können. Im folgenden Beispiel wird der IAM-Gruppe die `data-science` Berechtigung erteilt, aus dem Amazon S3 S3-Bucket `raw-data` zu lesen.

**Example**  

```
const rawData = new s3.Bucket(this, 'raw-data');
const dataScience = new iam.Group(this, 'data-science');
rawData.grants.read(dataScience);
```

```
const rawData = new s3.Bucket(this, 'raw-data');
const dataScience = new iam.Group(this, 'data-science');
rawData.grants.read(dataScience);
```

```
raw_data = s3.Bucket(self, 'raw-data')
data_science = iam.Group(self, 'data-science')
raw_data.grants.read(data_science)
```

```
Bucket rawData = new Bucket(this, "raw-data");
Group dataScience = new Group(this, "data-science");
rawData.getGrants().read(dataScience);
```

```
var rawData = new Bucket(this, "raw-data");
var dataScience = new Group(this, "data-science");
rawData.Grants.Read(dataScience);
```

```
	rawData := awss3.NewBucket(stack, jsii.String("raw-data"), nil)
	dataScience := awsiam.NewGroup(stack, jsii.String("data-science"), nil)
	rawData.Grants().Read(dataScience, nil)
```

Ein anderes gängiges Muster besteht darin, dass AWS Konstrukte eines der Ressourcenattribute anhand von Daten festlegen, die an anderer Stelle bereitgestellt wurden. Zu den Attributen können Amazon Resource Names (ARNs), Namen oder gehören URLs.

Der folgende Code definiert eine AWS Lambda-Funktion und ordnet sie über die URL der Warteschlange in einer Umgebungsvariablen einer Amazon Simple Queue Service (Amazon SQS) -Warteschlange zu.

**Example**  

```
const jobsQueue = new sqs.Queue(this, 'jobs');
const createJobLambda = new lambda.Function(this, 'create-job', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./create-job-lambda-code'),
  environment: {
    QUEUE_URL: jobsQueue.queueUrl
  }
});
```

```
const jobsQueue = new sqs.Queue(this, 'jobs');
const createJobLambda = new lambda.Function(this, 'create-job', {
  runtime: lambda.Runtime.NODEJS_18_X,
  handler: 'index.handler',
  code: lambda.Code.fromAsset('./create-job-lambda-code'),
  environment: {
    QUEUE_URL: jobsQueue.queueUrl
  }
});
```

```
jobs_queue = sqs.Queue(self, "jobs")
create_job_lambda = lambda_.Function(self, "create-job",
    runtime=lambda_.Runtime.NODEJS_18_X,
    handler="index.handler",
    code=lambda_.Code.from_asset("./create-job-lambda-code"),
    environment=dict(
        QUEUE_URL=jobs_queue.queue_url
    )
)
```

```
final Queue jobsQueue = new Queue(this, "jobs");
Function createJobLambda = Function.Builder.create(this, "create-job")
                .handler("index.handler")
                .code(Code.fromAsset("./create-job-lambda-code"))
                .environment(java.util.Map.of(   // Map.of is Java 9 or later
                    "QUEUE_URL", jobsQueue.getQueueUrl()))
                .build();
```

```
var jobsQueue = new Queue(this, "jobs");
var createJobLambda = new Function(this, "create-job", new FunctionProps
{
    Runtime = Runtime.NODEJS_18_X,
    Handler = "index.handler",
    Code = Code.FromAsset(@".\create-job-lambda-code"),
    Environment = new Dictionary<string, string>
    {
        ["QUEUE_URL"] = jobsQueue.QueueUrl
    }
});
```

```
	createJobLambda := awslambda.NewFunction(stack, jsii.String("create-job"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_18_X(),
		Handler: jsii.String("index.handler"),
		Code:    awslambda.Code_FromAsset(jsii.String(".\\create-job-lambda-code"), nil),
		Environment: &map[string]*string{
			"QUEUE_URL": jsii.String(*jobsQueue.QueueUrl()),
		},
	})
```

Informationen zu den gängigsten API-Mustern in der AWS Construct-Bibliothek finden Sie unter [Ressourcen und CDK](resources.md). AWS 

### Fügen Sie Funktionen mit Mixins hinzu
<a name="constructs-mixins"></a>

Mixins sind zusammensetzbare Funktionen, die Sie mit dieser Methode auf jedes Konstrukt anwenden können. `.with()` Mit Mixins können Sie L1- und L2-Konstrukten Funktionen hinzufügen, ohne ein anderes Konstrukt verwenden oder Low-Level-Code schreiben zu müssen.

Sie können beispielsweise die Versionierung aktivieren und den öffentlichen Zugriff auf einen Amazon S3 S3-Bucket blockieren — unabhängig davon, ob es sich um einen L1 `CfnBucket` - oder L2-Bucket handelt: `Bucket`

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Apply mixins to an L1 construct
new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Apply mixins to an L2 construct
new s3.Bucket(this, 'MyL2Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })
  .with(new s3.mixins.BucketAutoDeleteObjects());
```

```
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Apply mixins to an L1 construct
new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Apply mixins to an L2 construct
new s3.Bucket(this, 'MyL2Bucket', { removalPolicy: cdk.RemovalPolicy.DESTROY })
  .with(new s3.mixins.BucketAutoDeleteObjects());
```

```
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# Apply mixins to an L1 construct
s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())

# Apply mixins to an L2 construct
s3.Bucket(self, "MyL2Bucket", removal_policy=cdk.RemovalPolicy.DESTROY) \
    .with_(s3.mixins.BucketAutoDeleteObjects())
```

```
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

// Apply mixins to an L1 construct
CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());

// Apply mixins to an L2 construct
Bucket l2Bucket = Bucket.Builder.create(this, "MyL2Bucket")
        .removalPolicy(RemovalPolicy.DESTROY)
        .build();
l2Bucket.with(new BucketAutoDeleteObjects());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Apply mixins to an L1 construct
var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());

// Apply mixins to an L2 construct
var l2Bucket = new Bucket(this, "MyL2Bucket", new BucketProps
{
    RemovalPolicy = RemovalPolicy.DESTROY
});
l2Bucket.With(new BucketAutoDeleteObjects());
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())

l2Bucket := awss3.NewBucket(stack, jsii.String("MyL2Bucket"), &awss3.BucketProps{
    RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
l2Bucket.With(awss3.NewBucketAutoDeleteObjects())
```

Mixins sind über den `mixins` Namespace jedes Servicemoduls verfügbar (z. B.). `s3.mixins` Jedes Mixin zielt auf einen bestimmten Ressourcentyp ab und ist nach dieser Ressource benannt. Wenn Sie ein Mixin auf ein L2-Konstrukt anwenden, gilt es automatisch für die zugrunde liegende L1-Ressource.

[Weitere Informationen zu Mixins finden Sie unter Mixins.](mixins.md)

### Das App- und Stack-Konstrukt
<a name="constructs-apps-stacks"></a>

Die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html)Klassen [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.App.html)und aus der AWS Construct-Bibliothek sind einzigartige Konstrukte. Im Vergleich zu anderen Konstrukten konfigurieren sie AWS Ressourcen nicht eigenständig. Stattdessen werden sie verwendet, um Kontext für Ihre anderen Konstrukte bereitzustellen. Alle Konstrukte, die AWS Ressourcen darstellen, müssen direkt oder indirekt im Rahmen eines `Stack` Konstrukts definiert werden. `Stack`Konstrukte werden innerhalb des Gültigkeitsbereichs eines `App` Konstrukts definiert.

Weitere Informationen zu CDK-Apps finden Sie unter [AWS CDK-Apps](apps.md). Weitere Informationen zu CDK-Stacks finden Sie unter [Einführung in](stacks.md) CDK-Stacks. AWS 

Das folgende Beispiel definiert eine App mit einem einzigen Stack. Innerhalb des Stacks wird ein L2-Konstrukt verwendet, um eine Amazon S3 S3-Bucket-Ressource zu konfigurieren.

**Example**  

```
import { App, Stack, StackProps } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

class HelloCdkStack extends Stack {
  constructor(scope: App, id: string, props?: StackProps) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true
    });
  }
}

const app = new App();
new HelloCdkStack(app, "HelloCdkStack");
```

```
const { App , Stack } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

class HelloCdkStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyFirstBucket', {
      versioned: true
    });
  }
}

const app = new App();
new HelloCdkStack(app, "HelloCdkStack");
```

```
from aws_cdk import App, Stack
import aws_cdk.aws_s3 as s3
from constructs import Construct

class HelloCdkStack(Stack):

    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        s3.Bucket(self, "MyFirstBucket", versioned=True)

app = App()
HelloCdkStack(app, "HelloCdkStack")
```
In der `HelloCdkStack.java` Datei definierter Stack:  

```
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.s3.*;

public class HelloCdkStack extends Stack {
    public HelloCdkStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public HelloCdkStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Bucket.Builder.create(this, "MyFirstBucket")
            .versioned(true).build();
    }
}
```
In der `HelloCdkApp.java` Datei definierte App:  

```
import software.amazon.awscdk.App;
import software.amazon.awscdk.StackProps;

public class HelloCdkApp {
    public static void main(final String[] args) {
        App app = new App();

        new HelloCdkStack(app, "HelloCdkStack", StackProps.builder()
                .build());

        app.synth();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

namespace HelloCdkApp
{
    internal static class Program
    {
        public static void Main(string[] args)
        {
            var app = new App();
            new HelloCdkStack(app, "HelloCdkStack");
            app.Synth();
        }
    }

    public class HelloCdkStack : Stack
    {
        public HelloCdkStack(Construct scope, string id, IStackProps props=null) : base(scope, id, props)
        {
            new Bucket(this, "MyFirstBucket", new BucketProps { Versioned = true });
        }
    }
}
```

```
func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{
		Versioned: jsii.Bool(true),
	})

	return stack
}
```

## Mit Konstrukten arbeiten
<a name="constructs-work"></a>

### Mit L1-Konstrukten arbeiten
<a name="constructs-l1-using"></a>

L1-Konstrukte sind direkt einzelnen Ressourcen zugeordnet. AWS CloudFormation Sie müssen die für die Ressource erforderliche Konfiguration angeben.

In diesem Beispiel erstellen wir ein `bucket` Objekt mit dem `CfnBucket` L1-Konstrukt:

**Example**  

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket"
});
```

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket"
});
```

```
bucket = s3.CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket")
```

```
CfnBucket bucket = new CfnBucket.Builder().bucketName("amzn-s3-demo-bucket").build();
```

```
var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps
{
    BucketName= "amzn-s3-demo-bucket"
});
```

```
	awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{
		BucketName: jsii.String("amzn-s3-demo-bucket"),
	})
```

Konstrukteigenschaften, bei denen es sich nicht um einfache Boolesche Werte, Zeichenketten, Zahlen oder Container handelt, werden in den unterstützten Sprachen unterschiedlich behandelt.

**Example**  

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket",
  corsConfiguration: {
    corsRules: [{
          allowedOrigins: ["*"],
          allowedMethods: ["GET"]
    }]
  }
});
```

```
const bucket = new s3.CfnBucket(this, "amzn-s3-demo-bucket", {
  bucketName: "amzn-s3-demo-bucket",
  corsConfiguration: {
    corsRules: [{
          allowedOrigins: ["*"],
          allowedMethods: ["GET"]
    }]
  }
});
```
In Python werden diese Eigenschaften durch Typen repräsentiert, die als innere Klassen des L1-Konstrukts definiert sind. Beispielsweise `CfnBucket` erfordert die optionale Eigenschaft `cors_configuration` von a einen Wrapper des Typs. `CfnBucket.CorsConfigurationProperty` Hier definieren wir für `cors_configuration` eine `CfnBucket` Instanz.  

```
bucket = CfnBucket(self, "amzn-s3-demo-bucket", bucket_name="amzn-s3-demo-bucket",
    cors_configuration=CfnBucket.CorsConfigurationProperty(
        cors_rules=[CfnBucket.CorsRuleProperty(
            allowed_origins=["*"],
            allowed_methods=["GET"]
        )]
    )
)
```
In Java werden diese Eigenschaften durch Typen repräsentiert, die als innere Klassen des L1-Konstrukts definiert sind. Zum Beispiel `CfnBucket` erfordert die optionale Eigenschaft `corsConfiguration` von a einen Wrapper vom Typ. `CfnBucket.CorsConfigurationProperty` Hier definieren wir für `corsConfiguration` eine `CfnBucket` Instanz.  

```
CfnBucket bucket = CfnBucket.Builder.create(this, "amzn-s3-demo-bucket")
                        .bucketName("amzn-s3-demo-bucket")
                        .corsConfiguration(new CfnBucket.CorsConfigurationProperty.Builder()
                            .corsRules(Arrays.asList(new CfnBucket.CorsRuleProperty.Builder()
                                .allowedOrigins(Arrays.asList("*"))
                                .allowedMethods(Arrays.asList("GET"))
                                .build()))
                            .build())
                        .build();
```
In C\$1 werden diese Eigenschaften durch Typen repräsentiert, die als innere Klassen des L1-Konstrukts definiert sind. Beispielsweise `CfnBucket` erfordert die optionale Eigenschaft `CorsConfiguration` von a einen Wrapper des Typs. `CfnBucket.CorsConfigurationProperty` Hier definieren wir für `CorsConfiguration` eine `CfnBucket` Instanz.  

```
var bucket = new CfnBucket(this, "amzn-s3-demo-bucket", new CfnBucketProps
{
    BucketName = "amzn-s3-demo-bucket",
    CorsConfiguration = new CfnBucket.CorsConfigurationProperty
    {
        CorsRules = new object[] {
            new CfnBucket.CorsRuleProperty
            {
                AllowedOrigins = new string[] { "*" },
                AllowedMethods = new string[] { "GET" },
            }
        }
    }
});
```
In Go werden diese Typen mit dem Namen des L1-Konstrukts, einem Unterstrich und dem Eigenschaftsnamen benannt. Beispielsweise `CfnBucket` erfordert die optionale Eigenschaft `CorsConfiguration` von a einen Wrapper des Typs. `CfnBucket_CorsConfigurationProperty` Hier definieren wir für `CorsConfiguration` eine `CfnBucket` Instanz.  

```
	awss3.NewCfnBucket(stack, jsii.String("amzn-s3-demo-bucket"), &awss3.CfnBucketProps{
		BucketName: jsii.String("amzn-s3-demo-bucket"),
		CorsConfiguration: &awss3.CfnBucket_CorsConfigurationProperty{
			CorsRules: []awss3.CorsRule{
				awss3.CorsRule{
					AllowedOrigins: jsii.Strings("*"),
					AllowedMethods: &[]awss3.HttpMethods{"GET"},
				},
			},
		},
	})
```

**Wichtig**  
Sie können L2-Eigenschaftstypen nicht mit L1-Konstrukten verwenden oder umgekehrt. Verwenden Sie bei der Arbeit mit L1-Konstrukten immer die Typen, die für das verwendete L1-Konstrukt definiert sind. Verwenden Sie keine Typen aus anderen L1-Konstrukten (einige haben möglicherweise denselben Namen, sind aber nicht vom gleichen Typ).  
Einige unserer sprachspezifischen API-Referenzen enthalten derzeit Fehler in den Pfaden zu L1-Eigenschaftstypen oder dokumentieren diese Klassen überhaupt nicht. Wir hoffen, das bald beheben zu können. Denken Sie in der Zwischenzeit daran, dass solche Typen immer innere Klassen des L1-Konstrukts sind, mit dem sie verwendet werden.

#### Referenzieren von Ressourcen aus anderen Konstrukten
<a name="constructs-resource-references"></a>

Bei der Konfiguration von Konstrukteigenschaften, die auf andere AWS-Ressourcen verweisen, stehen Ihnen zwei gleichwertige Optionen zur Verfügung:
+  **Zeichenkettenverweise**: Übergeben Sie explizite Zeichenkettenwerte wie ARNs Namen oder andere Ressourcen-Identifikatoren
+  **Objektverweise**: Übergeben Sie Konstruktionsobjekte direkt. Auf diese Weise müssen Sie nicht ermitteln, welchen Bezeichnertyp eine Eigenschaft erwartet — das CDK erledigt das für Sie.

##### Verwenden von Zeichenkettenreferenzen
<a name="_using_string_references"></a>

Sie können jederzeit explizite Zeichenkettenwerte wie ARNs Namen oder andere Ressourcenbezeichner übergeben. Dieser Ansatz funktioniert für alle Eigenschaften und ist für verschachtelte Eigenschaften innerhalb komplexer Objekte erforderlich.

Im folgenden Beispiel wird eine Lambda-Funktion mit einem L1-Konstrukt (`CfnFunction`) erstellt, wobei eine Rolle mithilfe eines L2-Konstrukts () definiert ist. `Role` Der ARN der Rolle wird an die `role` Eigenschaft übergeben:

**Example**  

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    ),
  ],
});

const myFunction = new lambda.CfnFunction(this, 'HelloWorldFunction', {
  runtime: 'nodejs24.x',
  role: role.roleArn, // Pass the ARN string explicitly
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});
```

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    )
  ]
});

const myFunction = new lambda.CfnFunction(this, "HelloWorldFunction", {
  runtime: 'nodejs24.x',
  role: role.roleArn, // Pass the ARN string explicitly
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});
```

```
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ]
)

my_function = _lambda.CfnFunction(self, "HelloWorldFunction",
    runtime="nodejs24.x",
    role=role.role_arn,  # Pass the ARN string explicitly
    handler="index.handler",
    code=_lambda.CfnFunction.CodeProperty(
        zip_file=
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        """
    )
)
```

```
Role role = Role.Builder.create(this, "MyRole")
    .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
    .managedPolicies(Arrays.asList(
        ManagedPolicy.fromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ))
    .build();

CfnFunction myFunction = CfnFunction.Builder.create(this, "HelloWorldFunction")
    .runtime("nodejs24.x")
    .role(role.getRoleArn())  // Pass the ARN string explicitly
    .handler("index.handler")
    .code(CfnFunction.CodeProperty.builder()
        .zipFile(
            "exports.handler = async function(event) {" +
            "  return {" +
            "    statusCode: 200," +
            "    body: JSON.stringify('Hello World!')," +
            "  };" +
            "};")
        .build())
    .build();
```

```
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com"),
    ManagedPolicies = new[]
    {
        ManagedPolicy.FromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    }
});

var myFunction = new CfnFunction(this, "HelloWorldFunction", new CfnFunctionProps
{
    Runtime = "nodejs24.x",
    Role = role.RoleArn,  // Pass the ARN string explicitly
    Handler = "index.handler",
    Code = new CfnFunction.CodeProperty
    {
        ZipFile = @"
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        "
    }
});
```

```
role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
	AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
	ManagedPolicies: &[]awsiam.IManagedPolicy{
		awsiam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("service-role/AWSLambdaBasicExecutionRole")),
	},
})

myFunction := awslambda.NewCfnFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.CfnFunctionProps{
	Runtime: jsii.String("nodejs24.x"),
	Role:    role.RoleArn(), // Pass the ARN string explicitly
	Handler: jsii.String("index.handler"),
	Code: &awslambda.CfnFunction_CodeProperty{
		ZipFile: jsii.String(`
		exports.handler = async function(event) {
		  return {
		    statusCode: 200,
		    body: JSON.stringify('Hello World!'),
		  };
		};
		`),
	},
})
```

##### Verwenden von Objektreferenzen
<a name="_using_object_references"></a>

Für ausgewählte Eigenschaften können Sie Konstruktobjekte direkt übergeben, anstatt ihre Attribute manuell zu extrahieren. Die Support für Objektreferenzen ist je nach Eigenschaft unterschiedlich und kann im Laufe der Zeit zunehmen, wenn neue Eigenschaften hinzugefügt werden.

Wenn Sie eine Objektreferenz im Konstrukt übergeben`props`, löst das CDK sie in den entsprechenden Zeichenkettenwert auf (z. B. einen ARN, einen Namen oder einen anderen Bezeichner). Wenn Sie später auf die entsprechende Eigenschaft in der Konstruktinstanz zugreifen, sehen Sie diesen aufgelösten Zeichenkettenwert, nicht die ursprüngliche Objektreferenz.

Objektverweise funktionieren nur für Eigenschaften von Konstrukten der obersten Ebene. Verschachtelte Eigenschaften innerhalb komplexer Objekte erfordern explizite Zeichenkettenwerte.

Das folgende Beispiel zeigt dieselbe Lambda-Funktion, verwendet jedoch das Rollenobjekt anstelle der ARN-Zeichenfolge der Rolle:

**Example**  

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    ),
  ],
});

const myFunction = new lambda.CfnFunction(this, 'HelloWorldFunction', {
  runtime: 'nodejs24.x',
  role: role, // CDK resolves to role ARN automatically
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});

// After creation, myFunction.role contains the resolved ARN string
```

```
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
  managedPolicies: [
    iam.ManagedPolicy.fromAwsManagedPolicyName(
      'service-role/AWSLambdaBasicExecutionRole'
    )
  ]
});

const myFunction = new lambda.CfnFunction(this, "HelloWorldFunction", {
  runtime: 'nodejs24.x',
  role: role, // CDK resolves to role ARN automatically
  handler: 'index.handler',
  code: {
    zipFile: `
    exports.handler = async function(event) {
      return {
        statusCode: 200,
        body: JSON.stringify('Hello World!'),
      };
    };
  `}
});

// After creation, myFunction.role contains the resolved ARN string
```

```
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ]
)

my_function = _lambda.CfnFunction(self, "HelloWorldFunction",
    runtime="nodejs24.x",
    role=role,  # CDK resolves to role ARN automatically
    handler="index.handler",
    code=_lambda.CfnFunction.CodeProperty(
        zip_file=
        """
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        """
    )
)

# After creation, my_function.role contains the resolved ARN string
```

```
Role role = Role.Builder.create(this, "MyRole")
    .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
    .managedPolicies(Arrays.asList(
        ManagedPolicy.fromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    ))
    .build();

CfnFunction myFunction = CfnFunction.Builder.create(this, "HelloWorldFunction")
    .runtime("nodejs24.x")
    .role(role)  // CDK resolves to role ARN automatically
    .handler("index.handler")
    .code(CfnFunction.CodeProperty.builder()
        .zipFile(
            "exports.handler = async function(event) {" +
            "  return {" +
            "    statusCode: 200," +
            "    body: JSON.stringify('Hello World!')," +
            "  };" +
            "};")
        .build())
    .build();

// After creation, myFunction.getRole() contains the resolved ARN string
```

```
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com"),
    ManagedPolicies = new[]
    {
        ManagedPolicy.FromAwsManagedPolicyName(
            "service-role/AWSLambdaBasicExecutionRole"
        )
    }
});

var myFunction = new CfnFunction(this, "HelloWorldFunction", new CfnFunctionProps
{
    Runtime = "nodejs24.x",
    Role = role,  // CDK resolves to role ARN automatically
    Handler = "index.handler",
    Code = new CfnFunction.CodeProperty
    {
        ZipFile = @"
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
        "
    }
});

// After creation, myFunction.Role contains the resolved ARN string
```

```
role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
	AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
	ManagedPolicies: &[]awsiam.IManagedPolicy{
		awsiam.ManagedPolicy_FromAwsManagedPolicyName(jsii.String("service-role/AWSLambdaBasicExecutionRole")),
	},
})

myFunction := awslambda.NewCfnFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.CfnFunctionProps{
	Runtime: jsii.String("nodejs24.x"),
	Role:    role, // CDK resolves to role ARN automatically
	Handler: jsii.String("index.handler"),
	Code: &awslambda.CfnFunction_CodeProperty{
		ZipFile: jsii.String(`
		exports.handler = async function(event) {
		  return {
		    statusCode: 200,
		    body: JSON.stringify('Hello World!'),
		  };
		};
		`),
	},
})

// After creation, *myFunction.Role() contains the resolved ARN string
```

### Mit L2-Konstrukten arbeiten
<a name="constructs-using"></a>

Im folgenden Beispiel definieren wir einen Amazon S3 S3-Bucket, indem wir ein Objekt aus dem [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html)L2-Konstrukt erstellen:

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';

// "this" is HelloCdkStack
new s3.Bucket(this, 'MyFirstBucket', {
  versioned: true
});
```

```
const s3 = require('aws-cdk-lib/aws-s3');

// "this" is HelloCdkStack
new s3.Bucket(this, 'MyFirstBucket', {
  versioned: true
});
```

```
import aws_cdk.aws_s3 as s3

# "self" is HelloCdkStack
s3.Bucket(self, "MyFirstBucket", versioned=True)
```

```
import software.amazon.awscdk.services.s3.*;

public class HelloCdkStack extends Stack {
    public HelloCdkStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public HelloCdkStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Bucket.Builder.create(this, "MyFirstBucket")
                .versioned(true).build();
    }
}
```

```
using Amazon.CDK.AWS.S3;

// "this" is HelloCdkStack
new Bucket(this, "MyFirstBucket", new BucketProps
{
    Versioned = true
});
```

```
import (
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/jsii-runtime-go"
)

// stack is HelloCdkStack
awss3.NewBucket(stack, jsii.String("MyFirstBucket"), &awss3.BucketProps{
		Versioned: jsii.Bool(true),
	})
```

 `MyFirstBucket`ist nicht der Name des Buckets, der AWS CloudFormation erstellt wird. Es ist eine logische Kennung, die dem neuen Konstrukt im Kontext Ihrer CDK-App zugewiesen wurde. Der Wert [PhysicalName](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Resource.html#physicalname) wird verwendet, um die Ressource zu benennen. AWS CloudFormation 

## Arbeiten mit Konstrukten von Drittanbietern
<a name="constructs-work-third"></a>

 [Construct Hub](https://constructs.dev/search?q=&cdk=aws-cdk&cdkver=2&sort=downloadsDesc&offset=0) ist eine Ressource, die Ihnen hilft AWS, weitere Konstrukte von Drittanbietern und der Open-Source-CDK-Community zu entdecken.

### Schreiben Sie Ihre eigenen Konstrukte
<a name="constructs-author"></a>

Sie können nicht nur bestehende Konstrukte verwenden, sondern auch Ihre eigenen Konstrukte schreiben und sie von jedem in seinen Apps verwenden lassen. Alle Konstrukte sind im CDK gleich. AWS Konstrukte aus der AWS Construct-Bibliothek werden genauso behandelt wie Konstrukte aus einer Drittanbieterbibliothek, die überNPM, Maven oder veröffentlicht wurden. PyPI Konstrukte, die im internen Paket-Repository Ihres Unternehmens veröffentlicht wurden, werden ebenfalls auf die gleiche Weise behandelt.

Um ein neues Konstrukt zu deklarieren, erstellen Sie im `constructs` Paket eine Klasse, die die [Construct-Basisklasse](https://docs.aws.amazon.com/cdk/api/v2/docs/constructs.Construct.html) erweitert, und folgen Sie dann dem Muster für Initialisierungsargumente.

Das folgende Beispiel zeigt, wie ein Konstrukt deklariert wird, das einen Amazon S3 S3-Bucket darstellt. Der S3-Bucket sendet jedes Mal, wenn jemand eine Datei in ihn hochlädt, eine Amazon Simple Notification Service (Amazon SNS) -Benachrichtigung.

**Example**  

```
export interface NotifyingBucketProps {
  prefix?: string;
}

export class NotifyingBucket extends Construct {
  constructor(scope: Construct, id: string, props: NotifyingBucketProps = {}) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    const topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic),
      { prefix: props.prefix });
  }
}
```

```
class NotifyingBucket extends Construct {
  constructor(scope, id, props = {}) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    const topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(topic),
      { prefix: props.prefix });
  }
}

module.exports = { NotifyingBucket }
```

```
class NotifyingBucket(Construct):

    def __init__(self, scope: Construct, id: str, *, prefix=None):
        super().__init__(scope, id)
        bucket = s3.Bucket(self, "bucket")
        topic = sns.Topic(self, "topic")
        bucket.add_object_created_notification(s3notify.SnsDestination(topic),
            s3.NotificationKeyFilter(prefix=prefix))
```

```
public class NotifyingBucket extends Construct {

    public NotifyingBucket(final Construct scope, final String id) {
        this(scope, id, null, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props) {
        this(scope, id, props, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final String prefix) {
        this(scope, id, null, prefix);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) {
        super(scope, id);

        Bucket bucket = new Bucket(this, "bucket");
        Topic topic = new Topic(this, "topic");
        if (prefix != null)
            bucket.addObjectCreatedNotification(new SnsDestination(topic),
                NotificationKeyFilter.builder().prefix(prefix).build());
     }
}
```

```
public class NotifyingBucketProps : BucketProps
{
    public string Prefix { get; set; }
}

public class NotifyingBucket : Construct
{
    public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id)
    {
        var bucket = new Bucket(this, "bucket");
        var topic = new Topic(this, "topic");
        bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter
        {
            Prefix = props?.Prefix
        });
    }
}
```

```
type NotifyingBucketProps struct {
	awss3.BucketProps
	Prefix *string
}

func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) awss3.Bucket {
	var bucket awss3.Bucket
	if props == nil {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil)
	} else {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps)
	}
	topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil)
	if props == nil {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic))
	} else {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{
			Prefix: props.Prefix,
		})
	}
	return bucket
}
```

**Anmerkung**  
Unser `NotifyingBucket` Konstrukt erbt nicht von, `Bucket` sondern von. `Construct` Wir verwenden Komposition, nicht Vererbung, um einen Amazon S3-Bucket und ein Amazon SNS SNS-Thema zu bündeln. Im Allgemeinen wird bei der Entwicklung von AWS CDK-Konstrukten die Zusammensetzung der Vererbung vorgezogen.

Der `NotifyingBucket` Konstruktor hat eine typische Konstruktsignatur:`scope`, und`id`. `props` Das letzte Argument,`props`, ist optional (erhält den Standardwert`{}`), da alle Requisiten optional sind. (Die `Construct` Basisklasse akzeptiert kein `props` Argument.) Sie könnten eine Instanz dieses Konstrukts in Ihrer App definieren`props`, ohne zum Beispiel:

**Example**  

```
new NotifyingBucket(this, 'MyNotifyingBucket');
```

```
new NotifyingBucket(this, 'MyNotifyingBucket');
```

```
NotifyingBucket(self, "MyNotifyingBucket")
```

```
new NotifyingBucket(this, "MyNotifyingBucket");
```

```
new NotifyingBucket(this, "MyNotifyingBucket");
```

```
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), nil)
```

Oder Sie könnten `props` (in Java einen zusätzlichen Parameter) verwenden, um das Pfadpräfix anzugeben, nach dem gefiltert werden soll, zum Beispiel:

**Example**  

```
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
```

```
new NotifyingBucket(this, 'MyNotifyingBucket', { prefix: 'images/' });
```

```
NotifyingBucket(self, "MyNotifyingBucket", prefix="images/")
```

```
new NotifyingBucket(this, "MyNotifyingBucket", "/images");
```

```
new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps
{
    Prefix = "/images"
});
```

```
NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{
	Prefix: jsii.String("images/"),
})
```

In der Regel möchten Sie auch einige Eigenschaften oder Methoden für Ihre Konstrukte verfügbar machen. Es ist nicht sehr nützlich, ein Thema hinter Ihrem Konstrukt zu verstecken, da Benutzer Ihres Konstrukts es nicht abonnieren können. Durch das Hinzufügen einer `topic` Eigenschaft können Verbraucher auf das innere Thema zugreifen, wie im folgenden Beispiel gezeigt wird:

**Example**  

```
export class NotifyingBucket extends Construct {
  public readonly topic: sns.Topic;

  constructor(scope: Construct, id: string, props: NotifyingBucketProps) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    this.topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix });
  }
}
```

```
class NotifyingBucket extends Construct {

  constructor(scope, id, props) {
    super(scope, id);
    const bucket = new s3.Bucket(this, 'bucket');
    this.topic = new sns.Topic(this, 'topic');
    bucket.addObjectCreatedNotification(new s3notify.SnsDestination(this.topic), { prefix: props.prefix });
  }
}

module.exports = { NotifyingBucket };
```

```
class NotifyingBucket(Construct):

    def __init__(self, scope: Construct, id: str, *, prefix=None, **kwargs):
        super().__init__(scope, id)
        bucket = s3.Bucket(self, "bucket")
        self.topic = sns.Topic(self, "topic")
        bucket.add_object_created_notification(s3notify.SnsDestination(self.topic),
            s3.NotificationKeyFilter(prefix=prefix))
```

```
public class NotifyingBucket extends Construct {

    public Topic topic = null;

    public NotifyingBucket(final Construct scope, final String id) {
        this(scope, id, null, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props) {
        this(scope, id, props, null);
    }

    public NotifyingBucket(final Construct scope, final String id, final String prefix) {
        this(scope, id, null, prefix);
    }

    public NotifyingBucket(final Construct scope, final String id, final BucketProps props, final String prefix) {
        super(scope, id);

        Bucket bucket = new Bucket(this, "bucket");
        topic = new Topic(this, "topic");
        if (prefix != null)
            bucket.addObjectCreatedNotification(new SnsDestination(topic),
                NotificationKeyFilter.builder().prefix(prefix).build());
     }
}
```

```
public class NotifyingBucket : Construct
{
    public readonly Topic topic;

    public NotifyingBucket(Construct scope, string id, NotifyingBucketProps props = null) : base(scope, id)
    {
        var bucket = new Bucket(this, "bucket");
        topic = new Topic(this, "topic");
        bucket.AddObjectCreatedNotification(new SnsDestination(topic), new NotificationKeyFilter
        {
            Prefix = props?.Prefix
        });
    }
}
```
Um dies in Go zu tun, benötigen wir ein wenig zusätzliche Klempnerarbeiten. Unsere ursprüngliche `NewNotifyingBucket` Funktion gab eine `awss3.Bucket` zurück. Wir müssen die Erweiterung `Bucket` um ein `topic` Mitglied erweitern, indem wir eine `NotifyingBucket` Struktur erstellen. Unsere Funktion gibt dann diesen Typ zurück.  

```
type NotifyingBucket struct {
	awss3.Bucket
	topic awssns.Topic
}

func NewNotifyingBucket(scope constructs.Construct, id *string, props *NotifyingBucketProps) NotifyingBucket {
	var bucket awss3.Bucket
	if props == nil {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), nil)
	} else {
		bucket = awss3.NewBucket(scope, jsii.String(*id+"Bucket"), &props.BucketProps)
	}
	topic := awssns.NewTopic(scope, jsii.String(*id+"Topic"), nil)
	if props == nil {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic))
	} else {
		bucket.AddObjectCreatedNotification(awss3notifications.NewSnsDestination(topic), &awss3.NotificationKeyFilter{
			Prefix: props.Prefix,
		})
	}
	var nbucket NotifyingBucket
	nbucket.Bucket = bucket
	nbucket.topic = topic
	return nbucket
}
```

Jetzt können Verbraucher das Thema abonnieren, zum Beispiel:

**Example**  

```
const queue = new sqs.Queue(this, 'NewImagesQueue');
const images = new NotifyingBucket(this, '/images');
images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
```

```
const queue = new sqs.Queue(this, 'NewImagesQueue');
const images = new NotifyingBucket(this, '/images');
images.topic.addSubscription(new sns_sub.SqsSubscription(queue));
```

```
queue = sqs.Queue(self, "NewImagesQueue")
images = NotifyingBucket(self, prefix="Images")
images.topic.add_subscription(sns_sub.SqsSubscription(queue))
```

```
NotifyingBucket images = new NotifyingBucket(this, "MyNotifyingBucket", "/images");
images.topic.addSubscription(new SqsSubscription(queue));
```

```
var queue = new Queue(this, "NewImagesQueue");
var images = new NotifyingBucket(this, "MyNotifyingBucket", new NotifyingBucketProps
{
    Prefix = "/images"
});
images.topic.AddSubscription(new SqsSubscription(queue));
```

```
	queue := awssqs.NewQueue(stack, jsii.String("NewImagesQueue"), nil)
	images := NewNotifyingBucket(stack, jsii.String("MyNotifyingBucket"), &NotifyingBucketProps{
		Prefix: jsii.String("/images"),
	})
	images.topic.AddSubscription(awssnssubscriptions.NewSqsSubscription(queue, nil))
```

## Weitere Informationen
<a name="constructs-learn"></a>

Das folgende Video bietet einen umfassenden Überblick über CDK-Konstrukte und erklärt, wie Sie sie in Ihren CDK-Apps verwenden können.

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/PzU-i0rJPGw?rel=0/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/PzU-i0rJPGw?rel=0)


# Mixins
<a name="mixins"></a>

Mixins sind wiederverwendbare Funktionen, die Sie mithilfe der `.with()` Methode auf Konstrukte anwenden. Sie fügen Funktionen sowohl zu L1- (CloudFormation-Ebene) als auch zu L2-Konstrukten (absichtsbasiert) hinzu, z. B. Versionierung, automatisches Löschen von Objekten oder Blockieren des öffentlichen Zugriffs. Jedes Mixin funktioniert auf einer einzigen Ressource. Verwenden Sie stattdessen [Facades](facades.md), um zwei Ressourcen zu verbinden.

Jedes Mixin zielt auf einen bestimmten Ressourcentyp ab und ist nach dieser Ressource benannt. `BucketVersioning`Zielt beispielsweise auf Amazon S3 S3-Buckets ab. Sie greifen über den `mixins` Namespace der einzelnen Servicemodule auf Mixins zu, z. `s3.mixins`

## Mixins anwenden
<a name="mixins-basic"></a>

Sie wenden Mixins mit der `.with()` Methode an, die für alle Konstrukte verfügbar ist. Sie können mehrere Mixins miteinander verketten:

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';

const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());
```

```
const s3 = require('aws-cdk-lib/aws-s3');

const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());
```

```
import aws_cdk.aws_s3 as s3

bucket = s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())
```

```
import software.amazon.awscdk.services.s3.*;

CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());
```

```
using Amazon.CDK.AWS.S3;

var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())
```

Jedes Mixin deklariert, welche Ressourcentypen es unterstützt. Wenn Sie ein Mixin auf ein Konstrukt anwenden, das es nicht unterstützt, wird es stillschweigend übersprungen. Das bedeutet, dass Sie Mixins sicher und breit anwenden können, ohne sich Gedanken über Typinkongruenzen machen zu müssen. [Wenn Sie sicherstellen müssen, dass ein Mixin angewendet wird, verwenden Sie oder. `requireAll()``requireAny()`](#mixins-advanced)

## Verwenden Sie Mixins mit L1- und L2-Konstrukten
<a name="mixins-l1-l2"></a>

Mixins funktionieren sowohl mit L1- als auch mit L2-Konstrukten. Wenn Sie ein Mixin auf ein L2-Konstrukt anwenden, gilt es auch für die dahinter stehende L1-Ressource.

Das folgende Beispiel zeigt, wie Mixins sowohl auf L1- als auch auf L2-Konstrukte angewendet werden:

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Using a mixin with an L1 construct
new s3.CfnBucket(this, 'L1Bucket')
  .with(new s3.mixins.BucketVersioning());

// Using a mixin with an L2 construct
new s3.Bucket(this, 'L2Bucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
}).with(new s3.mixins.BucketAutoDeleteObjects());
```

```
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Using a mixin with an L1 construct
new s3.CfnBucket(this, 'L1Bucket')
  .with(new s3.mixins.BucketVersioning());

// Using a mixin with an L2 construct
new s3.Bucket(this, 'L2Bucket', {
  removalPolicy: cdk.RemovalPolicy.DESTROY,
}).with(new s3.mixins.BucketAutoDeleteObjects());
```

```
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

# Using a mixin with an L1 construct
s3.CfnBucket(self, "L1Bucket") \
    .with_(s3.mixins.BucketVersioning())

# Using a mixin with an L2 construct
s3.Bucket(self, "L2Bucket",
    removal_policy=cdk.RemovalPolicy.DESTROY,
).with_(s3.mixins.BucketAutoDeleteObjects())
```

```
import software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;

// Using a mixin with an L1 construct
CfnBucket l1Bucket = new CfnBucket(this, "L1Bucket");
l1Bucket.with(new BucketVersioning());

// Using a mixin with an L2 construct
Bucket l2Bucket = Bucket.Builder.create(this, "L2Bucket")
        .removalPolicy(RemovalPolicy.DESTROY)
        .build();
l2Bucket.with(new BucketAutoDeleteObjects());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Using a mixin with an L1 construct
var l1Bucket = new CfnBucket(this, "L1Bucket");
l1Bucket.With(new BucketVersioning());

// Using a mixin with an L2 construct
var l2Bucket = new Bucket(this, "L2Bucket", new BucketProps
{
    RemovalPolicy = RemovalPolicy.DESTROY
});
l2Bucket.With(new BucketAutoDeleteObjects());
```

```
l1Bucket := awss3.NewCfnBucket(stack, jsii.String("L1Bucket"), nil)
l1Bucket.With(awss3.NewBucketVersioning())

l2Bucket := awss3.NewBucket(stack, jsii.String("L2Bucket"), &awss3.BucketProps{
    RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
})
l2Bucket.With(awss3.NewBucketAutoDeleteObjects())
```

## Mixins im Vergleich zu Konstrukteigenschaften
<a name="mixins-vs-props"></a>

Mixins und Konstrukteigenschaften arbeiten zusammen. L2-Konstrukteigenschaften richten eine Ressource ein, wenn Sie sie erstellen. Mixins können jederzeit angewendet werden.

Verwenden Sie L2-Konstrukteigenschaften, wenn  
Sie verwenden ein L2-Konstrukt und die benötigte Eigenschaft ist verfügbar. Dies ist der einfachste Ansatz.

Verwenden Sie Mixins, wenn  
+ Sie arbeiten mit einem L1-Konstrukt und benötigen L2-ähnliche Funktionen.
+ Sie möchten einem L2-Konstrukt ein Feature hinzufügen, das nicht als Eigenschaft verfügbar ist.
+ Sie möchten dasselbe Feature auf mehrere Konstrukte unterschiedlichen Typs anwenden.

Mixins ersetzen keine Konstrukteigenschaften. Sie können eine erforderliche Eigenschaft nicht optional machen oder Standardwerte ändern.

## Wenden Sie Mixins auf mehrere Konstrukte an
<a name="mixins-advanced"></a>

Die `Mixins.of()` API bietet mehr Kontrolle darüber, wie Mixins in einem bestimmten Bereich angewendet werden. Anstatt einzelne Konstrukte aufzurufen, können Sie ein Mixin `.with()` auf alle passenden Konstrukte in einem Stack oder Bereich gleichzeitig anwenden:

**Example**  

```
import { Mixins } from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

// Apply to all supported constructs in the stack
Mixins.of(stack).apply(new s3.mixins.BucketVersioning());
```

```
const { Mixins } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

// Apply to all supported constructs in the stack
Mixins.of(stack).apply(new s3.mixins.BucketVersioning());
```

```
from aws_cdk import Mixins
import aws_cdk.aws_s3 as s3

# Apply to all supported constructs in the stack
Mixins.of(stack).apply(s3.mixins.BucketVersioning())
```

```
import software.amazon.awscdk.Mixins;
import software.amazon.awscdk.services.s3.*;

// Apply to all supported constructs in the stack
Mixins.of(stack).apply(new BucketVersioning());
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

// Apply to all supported constructs in the stack
Mixins.Of(stack).Apply(new BucketVersioning());
```

```
awscdk.Mixins_Of(stack, nil).Apply(awss3.NewBucketVersioning())
```

Standardmäßig werden Konstrukte, die das Mixin nicht unterstützen, stillschweigend übersprungen. Wird verwendet, `requireAll()` um zu bestätigen, dass das Mixin auf jedes Konstrukt in der Auswahl angewendet wird, oder `requireAny()` um zu bestätigen, dass es auf mindestens eines angewendet wird. Dies ist nützlich, um zu erzwingen, dass Ressourcen eine erforderliche Konfiguration haben:

**Example**  

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack)
  .requireAll()
  .apply(new s3.mixins.BucketVersioning());
```

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack)
  .requireAll()
  .apply(new s3.mixins.BucketVersioning());
```

```
# Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack) \
    .require_all() \
    .apply(s3.mixins.BucketVersioning())
```

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.of(stack)
        .requireAll()
        .apply(new BucketVersioning());
```

```
// Throws an error if any construct in the scope doesn't support the mixin
Mixins.Of(stack)
    .RequireAll()
    .Apply(new BucketVersioning());
```

```
awscdk.Mixins_Of(stack, nil).RequireAll().Apply(awss3.NewBucketVersioning())
```

## Mixins und Aspekte
<a name="mixins-aspects"></a>

Mixins und [Aspects](aspects.md) sind verwandt, dienen aber unterschiedlichen Zwecken:
+  **Mixins** werden sofort angewendet, wenn Sie anrufen. `.with()` Sie wählen genau aus, auf welche Konstrukte sie angewendet werden sollen.
+  **Aspekte** gelten während der Synthese für alle Konstrukte in einem Bereich. Verwenden Sie sie für allgemeine Richtlinien und Kontrollen.

Verwenden Sie Mixins, um bestimmten Konstrukten ein Feature hinzuzufügen. Verwenden Sie Aspects, um Regeln durchzusetzen oder Änderungen auf Ihre gesamte Anwendung anzuwenden.

## Zugehörige Ressourcen
<a name="mixins-related"></a>
+  [Fassaden](facades.md) — Connect Ressourcen mit IAM-Prinzipalen und anderen Diensten.
+  [Aspekte](aspects.md) — Wenden Sie Änderungen an oder validieren Sie Konstrukte in Ihrer gesamten Anwendung.
+  [Konstrukte](constructs.md) — Erfahren Sie mehr über L1-, L2- und L3-Konstrukte.
+  [Gebäudemodule anpassen — Passen Sie Konstrukte mit Notschraffuren](cfn-layer.md) und unverarbeiteten Überschreibungen individuell an.

# Fassaden
<a name="facades"></a>

Fassaden sind Klassen, die eine Ressource mit anderen Teilen Ihrer Anwendung verbinden. Jede Fassade zielt auf einen Ressourcentyp ab. Die Klasse wird beispielsweise benannt, `BucketGrants` weil sie Zugriff auf Amazon S3 S3-Buckets gewährt. Fassaden funktionieren sowohl mit L1-Konstrukten (CloudFormation-Ebene) als auch mit L2-Konstrukten (absichtsbasiert).

Einige Fassaden sind für die meisten Ressourcen generiert und sofort einsatzbereit, z. B. für Kurse zu Metriken und reflections. Andere werden manuell für Ressourcen erstellt, die eine benutzerdefinierte Logik benötigen, wie z. B. Grants-Klassen.

## Gewährt Klassen
<a name="facades-grants"></a>

Die am häufigsten verwendeten Klassen für Fassaden sind Zuschüsse. Mit ihnen können Sie mit einfachen Methoden Zugriff auf AWS Ressourcen gewähren. Sie können es beispielsweise für Amazon S3 S3-Buckets und `BucketGrants` `TopicGrants` für Amazon SNS SNS-Themen verwenden.

L2-Konstrukte verfügen über eine `grants` Eigenschaft für den einfachen Zugriff. Sie können mithilfe der Factory-Methode auch eine Grants-Klasse aus einem L1-Konstrukt erstellen. Das folgende Beispiel zeigt beide Ansätze:

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
const l2Bucket = new s3.Bucket(this, 'L2Bucket');
l2Bucket.grants.read(myRole);

// Using grants on an L1 construct (via the factory method)
const l1Bucket = new s3.CfnBucket(this, 'L1Bucket');
s3.BucketGrants.fromBucket(l1Bucket).read(myRole);
```

```
const s3 = require('aws-cdk-lib/aws-s3');
const iam = require('aws-cdk-lib/aws-iam');

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
const l2Bucket = new s3.Bucket(this, 'L2Bucket');
l2Bucket.grants.read(myRole);

// Using grants on an L1 construct (via the factory method)
const l1Bucket = new s3.CfnBucket(this, 'L1Bucket');
s3.BucketGrants.fromBucket(l1Bucket).read(myRole);
```

```
import aws_cdk.aws_s3 as s3
import aws_cdk.aws_iam as iam

# my_role is an IAM role defined elsewhere in your app

# Using grants on an L2 construct (via the grants property)
l2_bucket = s3.Bucket(self, "L2Bucket")
l2_bucket.grants.read(my_role)

# Using grants on an L1 construct (via the factory method)
l1_bucket = s3.CfnBucket(self, "L1Bucket")
s3.BucketGrants.from_bucket(l1_bucket).read(my_role)
```

```
import software.amazon.awscdk.services.s3.*;
import software.amazon.awscdk.services.iam.*;

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
Bucket l2Bucket = new Bucket(this, "L2Bucket");
l2Bucket.getGrants().read(myRole);

// Using grants on an L1 construct (via the factory method)
CfnBucket l1Bucket = new CfnBucket(this, "L1Bucket");
BucketGrants.fromBucket(l1Bucket).read(myRole);
```

```
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.IAM;

// myRole is an IAM role defined elsewhere in your app

// Using grants on an L2 construct (via the grants property)
var l2Bucket = new Bucket(this, "L2Bucket");
l2Bucket.Grants.Read(myRole);

// Using grants on an L1 construct (via the factory method)
var l1Bucket = new CfnBucket(this, "L1Bucket");
BucketGrants.FromBucket(l1Bucket).Read(myRole);
```

```
import (
	"github.com/aws/jsii-runtime-go"
	awss3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
)

// myRole is an IAM role defined elsewhere in your app

l2Bucket := awss3.NewBucket(stack, jsii.String("L2Bucket"), nil)
l2Bucket.Grants().Read(myRole, nil)

l1Bucket := awss3.NewCfnBucket(stack, jsii.String("L1Bucket"), nil)
awss3.BucketGrants_FromBucket(l1Bucket).Read(myRole, nil)
```

Weitere Informationen zu Zuschüssen und Berechtigungen finden Sie unter [Zuschüsse](permissions.md#permissions-grants).

## Verwenden Sie Fassaden mit Mixins
<a name="facades-mixins-together"></a>

Sie können Fassaden mit [Mixins](mixins.md) kombinieren, um ein vollständiges L2-ähnliches Erlebnis mit L1-Konstrukten zu erhalten. Verwende Mixins, um die Ressource einzurichten, und Facades, um Zugriff zu gewähren:

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';

// Configure the resource with Mixins
const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Grant permissions using a Facade
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
s3.BucketGrants.fromBucket(bucket).read(role);
```

```
const s3 = require('aws-cdk-lib/aws-s3');
const iam = require('aws-cdk-lib/aws-iam');

// Configure the resource with Mixins
const bucket = new s3.CfnBucket(this, 'MyBucket')
  .with(new s3.mixins.BucketVersioning())
  .with(new s3.mixins.BucketBlockPublicAccess());

// Grant permissions using a Facade
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});
s3.BucketGrants.fromBucket(bucket).read(role);
```

```
import aws_cdk.aws_s3 as s3
import aws_cdk.aws_iam as iam

# Configure the resource with Mixins
bucket = s3.CfnBucket(self, "MyBucket") \
    .with_(s3.mixins.BucketVersioning()) \
    .with_(s3.mixins.BucketBlockPublicAccess())

# Grant permissions using a Facade
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
)
s3.BucketGrants.from_bucket(bucket).read(role)
```

```
import software.amazon.awscdk.services.s3.*;
import software.amazon.awscdk.services.iam.*;

// Configure the resource with Mixins
CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.with(new BucketVersioning());
bucket.with(new BucketBlockPublicAccess());

// Grant permissions using a Facade
Role role = Role.Builder.create(this, "MyRole")
        .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
        .build();
BucketGrants.fromBucket(bucket).read(role);
```

```
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.IAM;

// Configure the resource with Mixins
var bucket = new CfnBucket(this, "MyBucket");
bucket.With(new BucketVersioning());
bucket.With(new BucketBlockPublicAccess());

// Grant permissions using a Facade
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
});
BucketGrants.FromBucket(bucket).Read(role);
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.With(awss3.NewBucketVersioning())
bucket.With(awss3.NewBucketBlockPublicAccess())

role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
    AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
})
awss3.BucketGrants_FromBucket(bucket).Read(role, nil)
```

## Zugehörige Ressourcen
<a name="facades-related"></a>
+  [Mixins — Fügt](mixins.md) wiederverwendbare Funktionen zu L1- und L2-Konstrukten hinzu.
+  [Zuschüsse](permissions.md#permissions-grants) — Gewähren Sie Berechtigungen zwischen Ressourcen.
+  [Konstrukte](constructs.md) — Erfahren Sie mehr über L1-, L2- und L3-Konstrukte.

# Umgebungen für das AWS CDK
<a name="environments"></a>

Eine Umgebung besteht aus dem AWS Konto und der AWS Region, für die Sie einen AWS Cloud Development Kit (AWS CDK) -Stack bereitstellen.

 ** AWS account**   
Wenn Sie ein AWS Konto erstellen, erhalten Sie eine Konto-ID. Diese ID ist eine 12-stellige Zahl, z. B. **012345678901**, die Ihr Konto eindeutig identifiziert. *Weitere Informationen finden Sie im Referenzhandbuch zur [AWS Kontoverwaltung unter Kontokennungen anzeigen](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-identifiers.html). AWS *

 ** AWS Region**   
 AWS Regionen werden anhand einer Kombination aus geografischem Standort und einer Zahl benannt, die eine Availability Zone in der Region darstellt. Beispiel: ** us-east-1 **steht für eine Availability Zone in der Region USA Ost (Nord-Virginia). Weitere Informationen zu Regionen finden Sie unter AWS [Regionen und Availability Zones](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/). Eine Liste der Regionscodes finden Sie im * AWS Allgemeinen Referenzhandbuch* unter [Regionale Endpunkte](https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints).

Das AWS CDK kann Umgebungen anhand Ihrer Anmeldeinformationen und Konfigurationsdateien ermitteln. Diese Dateien können mit der AWS Befehlszeilenschnittstelle (AWS CLI) erstellt und verwaltet werden. Im Folgenden finden Sie ein grundlegendes Beispiel für diese Dateien:

 **Anmeldeinformationsdatei**   

```
[default]
aws_access_key_id=ASIAIOSFODNN7EXAMPLE
aws_secret_access_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aws_session_token = IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZVERYLONGSTRINGEXAMPLE

[user1]
aws_access_key_id=ASIAI44QH8DHBEXAMPLE
aws_secret_access_key=je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
aws_session_token = fcZib3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZ2luX2IQoJb3JpZVERYLONGSTRINGEXAMPLE
```

 **Konfigurationsdatei**   

```
[default]
region=us-west-2
output=json

[profile user1]
region=us-east-1
output=text
```

Sie können Umgebungsinformationen aus diesen Dateien in Ihrem CDK-Code über Umgebungsvariablen übergeben, die vom CDK bereitgestellt werden. Wenn Sie einen CDK-CLI-Befehl ausführen, z. B.`cdk deploy`, geben Sie das Profil aus Ihren Anmeldeinformationen und Konfigurationsdateien an, aus denen Umgebungsinformationen abgerufen werden sollen.

Im Folgenden finden Sie ein Beispiel für die Angabe dieser Umgebungsvariablen in Ihrem CDK-Code:

```
new MyDevStack(app, 'dev', {
  env: {
    account: process.env.CDK_DEFAULT_ACCOUNT,
    region: process.env.CDK_DEFAULT_REGION
}});
```

Im Folgenden finden Sie ein Beispiel für die Übergabe von mit dem `user1` Profil verknüpften Werten aus Ihren Anmeldeinformationen und Konfigurationsdateien an die CDK-CLI mithilfe der `--profile` Option. Werte aus diesen Dateien werden an Ihre Umgebungsvariablen übergeben:

```
$ cdk deploy <myStack> --profile <user1>
```

Anstatt Werte aus den Anmeldeinformationen und Konfigurationsdateien zu verwenden, können Sie Umgebungswerte auch fest in Ihrem CDK-Code codieren. Im Folgenden wird ein Beispiel gezeigt:

```
const envEU = { account: '238383838383', region: 'eu-west-1' };
const envUSA = { account: '837873873873', region: 'us-west-2' };

new MyFirstStack(app, 'first-stack-us', { env: envUSA });
new MyFirstStack(app, 'first-stack-eu', { env: envEU });
```

## Weitere Informationen
<a name="environments-learn"></a>

Informationen zu den ersten Schritten mit der Verwendung von Umgebungen mit dem AWS CDK finden [Sie unter Umgebungen für die Verwendung mit dem CDK konfigurieren](configure-env.md). AWS 

# AWS CDK-Bootstrapping
<a name="bootstrapping"></a>

 *Bootstrapping* ist der Prozess, bei dem Ihre AWS Umgebung für die Verwendung mit dem AWS Cloud Development Kit (AWS CDK) vorbereitet wird. Bevor Sie einen CDK-Stack in einer AWS Umgebung bereitstellen, muss die Umgebung zunächst gebootet werden.

## Was ist Bootstrapping?
<a name="bootstrapping-what"></a>

Bootstrapping bereitet Ihre AWS Umgebung vor, indem es bestimmte AWS Ressourcen in Ihrer Umgebung bereitstellt, die vom CDK verwendet werden. AWS *Diese Ressourcen werden allgemein als Ihre Bootstrap-Ressourcen bezeichnet.* Es handelt sich um folgende Werte:
+  **Amazon Simple Storage Service (Amazon S3) -Bucket** — Wird zum Speichern Ihrer CDK-Projektdateien wie AWS Lambda-Funktionscode und Assets verwendet.
+  **Amazon Elastic Container Registry (Amazon ECR) -Repository** — Wird hauptsächlich zum Speichern verwendet Docker Bilder.
+  ** AWS Identitäts- und Zugriffsmanagement-Rollen (IAM)** — Konfiguriert, um Berechtigungen zu gewähren, die das AWS CDK für die Durchführung von Bereitstellungen benötigt. [Weitere Informationen zu den beim Bootstrapping erstellten IAM-Rollen finden Sie unter Beim Bootstrapping erstellte IAM-Rollen.](bootstrapping-env.md#bootstrapping-env-roles)

## Wie funktioniert Bootstrapping?
<a name="bootstrapping-how"></a>

Ressourcen und ihre Konfiguration, die vom CDK verwendet werden, sind in einer Vorlage definiert. AWS CloudFormation Diese Vorlage wird vom CDK-Team erstellt und verwaltet. Die neueste Version dieser Vorlage finden Sie [https://github.com/aws/aws-cdk-cli/blob/main/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml](https://github.com/aws/aws-cdk-cli/blob/main/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml)in der * aws-cdk-cli GitHub Repository*.

Um eine Umgebung zu booten, verwenden Sie den Befehl AWS CDK Command Line Interface (AWS CDK CLI). `cdk bootstrap` *Die CDK-CLI ruft die Vorlage ab und stellt sie als Stack bereit, der AWS CloudFormation als Bootstrap-Stack bezeichnet wird.* Standardmäßig lautet der Stack-Name. `CDKToolkit` Durch die Bereitstellung dieser Vorlage CloudFormation werden die Ressourcen in Ihrer Umgebung bereitgestellt. Nach der Bereitstellung wird der Bootstrap-Stack in der AWS CloudFormation Konsole Ihrer Umgebung angezeigt.

Sie können das Bootstrapping auch anpassen, indem Sie die Vorlage ändern oder die CDK-CLI-Optionen mit dem Befehl verwenden. `cdk bootstrap`

 AWS Umgebungen sind unabhängig. Jede Umgebung, die Sie mit dem AWS CDK verwenden möchten, muss zuerst gebootet werden.

## Weitere Informationen
<a name="bootstrapping-learn"></a>

Anweisungen zum Bootstrapping Ihrer Umgebung finden Sie unter [Bootstrap your environment](bootstrapping-env.md) for use with the CDK. AWS 

# Ressourcen und das AWS CDK
<a name="resources"></a>

 *Ressourcen* sind das, was Sie für die Nutzung von AWS Diensten in Ihren Anwendungen konfigurieren. Ressourcen sind ein Feature von AWS CloudFormation. Indem Sie Ressourcen und ihre Eigenschaften in einer AWS CloudFormation Vorlage konfigurieren, können Sie diese bereitstellen, AWS CloudFormation um Ihre Ressourcen bereitzustellen. Mit dem AWS Cloud Development Kit (AWS CDK) können Sie Ressourcen mithilfe von Konstrukten konfigurieren. Anschließend stellen Sie Ihre CDK-App bereit. Dazu müssen Sie eine AWS CloudFormation Vorlage synthetisieren und diese bereitstellen, AWS CloudFormation um Ihre Ressourcen bereitzustellen.

## Konfiguration von Ressourcen mithilfe von Konstrukten
<a name="resources-configure"></a>

Wie in [AWS CDK Constructs](constructs.md) beschrieben, bietet das AWS CDK eine umfangreiche Klassenbibliothek mit Konstrukten, sogenannten *Konstrukten*, die alle Ressourcen repräsentieren. AWS 

Um eine Instanz einer Ressource mit dem entsprechenden Konstrukt zu erstellen, übergeben Sie den Gültigkeitsbereich als erstes Argument, die logische ID des Konstrukts und eine Reihe von Konfigurationseigenschaften (Requisiten). So erstellen Sie beispielsweise eine Amazon SQS SQS-Warteschlange mit AWS KMS-Verschlüsselung mithilfe des [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_sqs.Queue.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_sqs.Queue.html)Konstrukts aus der AWS Construct-Bibliothek.

**Example**  

```
import * as sqs from '@aws-cdk/aws-sqs';

new sqs.Queue(this, 'MyQueue', {
    encryption: sqs.QueueEncryption.KMS_MANAGED
});
```

```
const sqs = require('@aws-cdk/aws-sqs');

new sqs.Queue(this, 'MyQueue', {
    encryption: sqs.QueueEncryption.KMS_MANAGED
});
```

```
import aws_cdk.aws_sqs as sqs

sqs.Queue(self, "MyQueue", encryption=sqs.QueueEncryption.KMS_MANAGED)
```

```
import software.amazon.awscdk.services.sqs.*;

Queue.Builder.create(this, "MyQueue").encryption(
        QueueEncryption.KMS_MANAGED).build();
```

```
using Amazon.CDK.AWS.SQS;

new Queue(this, "MyQueue", new QueueProps
{
    Encryption = QueueEncryption.KMS_MANAGED
});
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
)

sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{
  Encryption: sqs.QueueEncryption_KMS_MANAGED,
})
```

Einige Konfigurationsrequisiten sind optional und haben in vielen Fällen Standardwerte. In einigen Fällen sind alle Requisiten optional, und das letzte Argument kann vollständig weggelassen werden.

### Ressourcenattribute
<a name="resources-attributes"></a>

Die meisten Ressourcen in der AWS Construct-Bibliothek stellen Attribute zur Verfügung, die bei der Bereitstellung von AWS CloudFormation aufgelöst werden. Attribute werden in Form von Eigenschaften für die Ressourcenklassen mit dem Typnamen als Präfix verfügbar gemacht. Das folgende Beispiel zeigt, wie die URL einer Amazon SQS SQS-Warteschlange mithilfe der Eigenschaft `queueUrl` (Python:`queue_url`) abgerufen wird.

**Example**  

```
import * as sqs from '@aws-cdk/aws-sqs';

const queue = new sqs.Queue(this, 'MyQueue');
const url = queue.queueUrl; // => A string representing a deploy-time value
```

```
const sqs = require('@aws-cdk/aws-sqs');

const queue = new sqs.Queue(this, 'MyQueue');
const url = queue.queueUrl; // => A string representing a deploy-time value
```

```
import aws_cdk.aws_sqs as sqs

queue = sqs.Queue(self, "MyQueue")
url = queue.queue_url # => A string representing a deploy-time value
```

```
Queue queue = new Queue(this, "MyQueue");
String url = queue.getQueueUrl();    // => A string representing a deploy-time value
```

```
var queue = new Queue(this, "MyQueue");
var url = queue.QueueUrl; // => A string representing a deploy-time value
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
)

queue := sqs.NewQueue(stack, jsii.String("MyQueue"), &sqs.QueueProps{})
url := queue.QueueUrl() // => A string representing a deploy-time value
```

Informationen darüber, wie [das AWS CDK Bereitstellungszeitattribute als Zeichenketten kodiert, finden Sie unter Tokens](tokens.md) und AWS CDK.

## Ressourcen referenzieren
<a name="resources-referencing"></a>

Bei der Konfiguration von Ressourcen müssen Sie häufig auf Eigenschaften einer anderen Ressource verweisen. Im Folgenden sind einige Beispiele aufgeführt:
+ Eine Amazon Elastic Container Service (Amazon ECS) -Ressource benötigt einen Verweis auf den Cluster, auf dem sie ausgeführt wird.
+ Für eine CloudFront Amazon-Distribution ist ein Verweis auf den Amazon Simple Storage Service (Amazon S3) -Bucket erforderlich, der den Quellcode enthält.

Sie können auf eine der folgenden Arten auf Ressourcen verweisen:
+ Indem Sie eine in Ihrer CDK-App definierte Ressource übergeben, entweder im selben Stack oder in einem anderen
+ Indem Sie ein Proxy-Objekt übergeben, das auf eine in Ihrem AWS Konto definierte Ressource verweist und aus einer eindeutigen Kennung der Ressource (z. B. einem ARN) erstellt wurde

Wenn die Eigenschaft eines Konstrukts ein Konstrukt für eine andere Ressource darstellt, entspricht ihr Typ dem Schnittstellentyp des Konstrukts. Das Amazon ECS-Konstrukt nimmt beispielsweise eine Eigenschaft `cluster` vom Typ an`ecs.ICluster`. Ein anderes Beispiel ist das CloudFront Verteilungskonstrukt, das eine Eigenschaft `sourceBucket` (Python:`source_bucket`) vom Typ annimmt`s3.IBucket`.

Sie können jedes Ressourcenobjekt des richtigen Typs, das in derselben AWS CDK-App definiert ist, direkt übergeben. Das folgende Beispiel definiert einen Amazon ECS-Cluster und verwendet ihn dann, um einen Amazon ECS-Service zu definieren.

**Example**  

```
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ });

const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
```

```
const cluster = new ecs.Cluster(this, 'Cluster', { /*...*/ });

const service = new ecs.Ec2Service(this, 'Service', { cluster: cluster });
```

```
cluster = ecs.Cluster(self, "Cluster")

service = ecs.Ec2Service(self, "Service", cluster=cluster)
```

```
Cluster cluster = new Cluster(this, "Cluster");
Ec2Service service = new Ec2Service(this, "Service",
        new Ec2ServiceProps.Builder().cluster(cluster).build());
```

```
var cluster = new Cluster(this, "Cluster");
var service = new Ec2Service(this, "Service", new Ec2ServiceProps { Cluster = cluster });
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  ecs "github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
)

cluster := ecs.NewCluster(stack, jsii.String("MyCluster"), &ecs.ClusterProps{})
service := ecs.NewEc2Service(stack, jsii.String("MyService"), &ecs.Ec2ServiceProps{
  Cluster: cluster,
})
```

### Referenzieren von Ressourcen in einem anderen Stack
<a name="resource-stack"></a>

Sie können auf Ressourcen in einem anderen Stack verweisen, sofern sie in derselben App definiert sind und sich in derselben AWS Umgebung befinden. Das folgende Muster wird im Allgemeinen verwendet:
+ Speichern Sie einen Verweis auf das Konstrukt als Attribut des Stacks, der die Ressource erzeugt. (Um einen Verweis auf den Stack des aktuellen Konstrukts zu erhalten, verwenden Sie`Stack.of(this)`.)
+ Übergeben Sie diese Referenz als Parameter oder Eigenschaft an den Konstruktor des Stacks, der die Ressource verbraucht. Der verbrauchende Stapel übergibt ihn dann als Eigenschaft an jedes Konstrukt, das ihn benötigt.

Das folgende Beispiel definiert einen Stapel`stack1`. Dieser Stack definiert einen Amazon S3 S3-Bucket und speichert einen Verweis auf das Bucket-Konstrukt als Attribut des Stacks. Dann definiert die App einen zweiten Stack`stack2`, der bei der Instanziierung einen Bucket akzeptiert. `stack2`könnte zum Beispiel eine AWS Glue-Tabelle definieren, die den Bucket für die Datenspeicherung verwendet.

**Example**  

```
const prod = { account: '123456789012', region: 'us-east-1' };

const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod });

// stack2 will take a property { bucket: IBucket }
const stack2 = new StackThatExpectsABucket(app, 'Stack2', {
  bucket: stack1.bucket,
  env: prod
});
```

```
const prod = { account: '123456789012', region: 'us-east-1' };

const stack1 = new StackThatProvidesABucket(app, 'Stack1', { env: prod });

// stack2 will take a property { bucket: IBucket }
const stack2 = new StackThatExpectsABucket(app, 'Stack2', {
  bucket: stack1.bucket,
  env: prod
});
```

```
prod = core.Environment(account="123456789012", region="us-east-1")

stack1 = StackThatProvidesABucket(app, "Stack1", env=prod)

# stack2 will take a property "bucket"
stack2 = StackThatExpectsABucket(app, "Stack2", bucket=stack1.bucket, env=prod)
```

```
// Helper method to build an environment
static Environment makeEnv(String account, String region) {
    return Environment.builder().account(account).region(region)
            .build();
}

App app = new App();

Environment prod = makeEnv("123456789012", "us-east-1");

StackThatProvidesABucket stack1 = new StackThatProvidesABucket(app, "Stack1",
        StackProps.builder().env(prod).build());

// stack2 will take an argument "bucket"
StackThatExpectsABucket stack2 = new StackThatExpectsABucket(app, "Stack,",
        StackProps.builder().env(prod).build(), stack1.bucket);
```

```
Amazon.CDK.Environment makeEnv(string account, string region)
{
    return new Amazon.CDK.Environment { Account = account, Region = region };
}

var prod = makeEnv(account: "123456789012", region: "us-east-1");

var stack1 = new StackThatProvidesABucket(app, "Stack1", new StackProps { Env = prod });

// stack2 will take a property "bucket"
var stack2 = new StackThatExpectsABucket(app, "Stack2", new StackProps { Env = prod,
    bucket = stack1.Bucket});
```

Wenn das AWS CDK feststellt, dass sich die Ressource in derselben Umgebung, aber in einem anderen Stapel befindet, synthetisiert es automatisch AWS CloudFormation [Exporte](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html) im produzierenden Stapel und einen [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html)im verbrauchenden Stapel, um diese Informationen von einem Stapel auf den anderen zu übertragen.

#### Behebung von Deadlocks bei Abhängigkeiten
<a name="resources-deadlock"></a>

Wenn Sie auf eine Ressource von einem Stapel in einem anderen Stapel verweisen, entsteht eine Abhängigkeit zwischen den beiden Stacks. Dadurch wird sichergestellt, dass sie in der richtigen Reihenfolge bereitgestellt werden. Nachdem die Stacks bereitgestellt wurden, ist diese Abhängigkeit konkret. Danach kann das Entfernen der Nutzung der gemeinsam genutzten Ressource aus dem verbrauchenden Stack zu einem unerwarteten Bereitstellungsfehler führen. Dies passiert, wenn zwischen den beiden Stacks eine weitere Abhängigkeit besteht, die eine Bereitstellung in derselben Reihenfolge erzwingt. Es kann auch ohne Abhängigkeit geschehen, wenn der produzierende Stack einfach vom CDK Toolkit so ausgewählt wird, dass er zuerst bereitgestellt wird. Der AWS CloudFormation Export wird aus dem produzierenden Stack entfernt, weil er nicht mehr benötigt wird. Die exportierte Ressource wird jedoch weiterhin im verbrauchenden Stack verwendet, da ihr Update noch nicht bereitgestellt wurde. Daher schlägt die Bereitstellung des Producer-Stacks fehl.

Um diesen Deadlock zu überwinden, entfernen Sie die Nutzung der gemeinsam genutzten Ressource aus dem verbrauchenden Stack. (Dadurch wird der automatische Export aus dem produzierenden Stack entfernt.) Als Nächstes fügen Sie denselben Export manuell zum Produktionsstapel hinzu und verwenden dabei genau dieselbe logische ID wie der automatisch generierte Export. Entfernen Sie die Nutzung der gemeinsam genutzten Ressource im verbrauchenden Stack und stellen Sie beide Stapel bereit. Entfernen Sie dann den manuellen Export (und die gemeinsam genutzte Ressource, falls sie nicht mehr benötigt wird) und stellen Sie beide Stapel erneut bereit. Die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#exportwbrvalueexportedvalue-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#exportwbrvalueexportedvalue-options)Methode des Stacks ist eine bequeme Möglichkeit, den manuellen Export für diesen Zweck zu erstellen. (Sehen Sie sich das Beispiel in der verlinkten Methodenreferenz an.)

### Verweisen auf Ressourcen in Ihrem Konto AWS
<a name="resources-external"></a>

Angenommen, Sie möchten eine Ressource verwenden, die bereits in Ihrem AWS Konto in Ihrer AWS CDK-App verfügbar ist. Dies kann eine Ressource sein, die über die Konsole, ein AWS SDK, direkt mit AWS CloudFormation oder in einer anderen AWS CDK-Anwendung definiert wurde. Sie können den ARN der Ressource (oder ein anderes identifizierendes Attribut oder eine Gruppe von Attributen) in ein Proxy-Objekt umwandeln. Das Proxy-Objekt dient als Referenz auf die Ressource, indem es eine statische Factory-Methode für die Klasse der Ressource aufruft.

Wenn Sie einen solchen Proxy erstellen, wird die externe Ressource **nicht** Teil Ihrer AWS CDK-App. Daher wirken sich Änderungen, die Sie am Proxy in Ihrer AWS CDK-App vornehmen, nicht auf die bereitgestellte Ressource aus. Der Proxy kann jedoch an jede AWS CDK-Methode übergeben werden, die eine Ressource dieses Typs benötigt.

Das folgende Beispiel zeigt, wie Sie auf einen Bucket verweisen, der auf einem vorhandenen Bucket mit dem ARN basiert`arn:aws:s3:::amzn-s3-demo-bucket1`, und auf eine Amazon Virtual Private Cloud, die auf einer vorhandenen VPC mit einer bestimmten ID basiert.

**Example**  

```
// Construct a proxy for a bucket by its name (must be same account)
s3.Bucket.fromBucketName(this, 'MyBucket', 'amzn-s3-demo-bucket1');

// Construct a proxy for a bucket by its full ARN (can be another account)
s3.Bucket.fromBucketArn(this, 'MyBucket', 'arn:aws:s3:::amzn-s3-demo-bucket1');

// Construct a proxy for an existing VPC from its attribute(s)
ec2.Vpc.fromVpcAttributes(this, 'MyVpc', {
  vpcId: 'vpc-1234567890abcde',
});
```

```
// Construct a proxy for a bucket by its name (must be same account)
s3.Bucket.fromBucketName(this, 'MyBucket', 'amzn-s3-demo-bucket1');

// Construct a proxy for a bucket by its full ARN (can be another account)
s3.Bucket.fromBucketArn(this, 'MyBucket', 'arn:aws:s3:::amzn-s3-demo-bucket1');

// Construct a proxy for an existing VPC from its attribute(s)
ec2.Vpc.fromVpcAttributes(this, 'MyVpc', {
  vpcId: 'vpc-1234567890abcde'
});
```

```
# Construct a proxy for a bucket by its name (must be same account)
s3.Bucket.from_bucket_name(self, "MyBucket", "amzn-s3-demo-bucket1")

# Construct a proxy for a bucket by its full ARN (can be another account)
s3.Bucket.from_bucket_arn(self, "MyBucket", "arn:aws:s3:::amzn-s3-demo-bucket1")

# Construct a proxy for an existing VPC from its attribute(s)
ec2.Vpc.from_vpc_attributes(self, "MyVpc", vpc_id="vpc-1234567890abcdef")
```

```
// Construct a proxy for a bucket by its name (must be same account)
Bucket.fromBucketName(this, "MyBucket", "amzn-s3-demo-bucket1");

// Construct a proxy for a bucket by its full ARN (can be another account)
Bucket.fromBucketArn(this, "MyBucket",
        "arn:aws:s3:::amzn-s3-demo-bucket1");

// Construct a proxy for an existing VPC from its attribute(s)
Vpc.fromVpcAttributes(this, "MyVpc", VpcAttributes.builder()
        .vpcId("vpc-1234567890abcdef").build());
```

```
// Construct a proxy for a bucket by its name (must be same account)
Bucket.FromBucketName(this, "MyBucket", "amzn-s3-demo-bucket1");

// Construct a proxy for a bucket by its full ARN (can be another account)
Bucket.FromBucketArn(this, "MyBucket", "arn:aws:s3:::amzn-s3-demo-bucket1");

// Construct a proxy for an existing VPC from its attribute(s)
Vpc.FromVpcAttributes(this, "MyVpc", new VpcAttributes
{
    VpcId = "vpc-1234567890abcdef"
});
```

```
// Define a proxy for a bucket by its name (must be same account)
s3.Bucket_FromBucketName(stack, jsii.String("MyBucket"), jsii.String("amzn-s3-demo-bucket1"))

// Define a proxy for a bucket by its full ARN (can be another account)
s3.Bucket_FromBucketArn(stack, jsii.String("MyBucket"), jsii.String("arn:aws:s3:::amzn-s3-demo-bucket1"))

// Define a proxy for an existing VPC from its attributes
ec2.Vpc_FromVpcAttributes(stack, jsii.String("MyVpc"), &ec2.VpcAttributes{
  VpcId: jsii.String("vpc-1234567890abcde"),
})
```

Schauen wir uns die [https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ec2.Vpc.html#static-fromwbrlookupscope-id-options](https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-ec2.Vpc.html#static-fromwbrlookupscope-id-options)Methode genauer an. Da das `ec2.Vpc` Konstrukt komplex ist, gibt es viele Möglichkeiten, die VPC auszuwählen, die mit Ihrer CDK-App verwendet werden soll. Um dieses Problem zu lösen, verfügt das VPC-Konstrukt über eine `fromLookup` statische Methode (Python:`from_lookup`), mit der Sie die gewünschte Amazon-VPC suchen können, indem Sie Ihr AWS Konto bei der Synthese abfragen.

Zur Verwendung muss das System`Vpc.fromLookup()`, das den Stack synthetisiert, Zugriff auf das Konto haben, dem die Amazon VPC gehört. Das liegt daran, dass das CDK Toolkit das Konto abfragt, um zum Zeitpunkt der Synthese die richtige Amazon VPC zu finden.

Darüber hinaus `Vpc.fromLookup()` funktioniert es nur in Stacks, die mit einem expliziten **Konto** und einer **Region** definiert sind (siehe [Umgebungen für](environments.md) das CDK). AWS Wenn das AWS CDK versucht, eine Amazon-VPC aus einem [umgebungsunabhängigen Stack](stacks.md#stack-api) zu suchen, weiß das CDK Toolkit nicht, welche Umgebung abgefragt werden muss, um die VPC zu finden.

Sie müssen ausreichende `Vpc.fromLookup()` Attribute angeben, um eine VPC in Ihrem AWS Konto eindeutig zu identifizieren. Beispielsweise kann es immer nur eine Standard-VPC geben, sodass es ausreichend ist, die VPC als Standard-VPC anzugeben.

**Example**  

```
ec2.Vpc.fromLookup(this, 'DefaultVpc', {
  isDefault: true
});
```

```
ec2.Vpc.fromLookup(this, 'DefaultVpc', {
  isDefault: true
});
```

```
ec2.Vpc.from_lookup(self, "DefaultVpc", is_default=True)
```

```
Vpc.fromLookup(this, "DefaultVpc", VpcLookupOptions.builder()
        .isDefault(true).build());
```

```
Vpc.FromLookup(this, id = "DefaultVpc", new VpcLookupOptions { IsDefault = true });
```

```
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{
  IsDefault: jsii.Bool(true),
})
```

Sie können die `tags` Eigenschaft auch verwenden, um nach einem Tag abzufragen VPCs . Sie können der Amazon VPC bei ihrer Erstellung Tags hinzufügen, indem Sie AWS CloudFormation oder das AWS CDK verwenden. Sie können Tags nach der Erstellung jederzeit mit der AWS Management Console, der AWS CLI oder einem AWS SDK bearbeiten. Zusätzlich zu allen Tags, die Sie selbst hinzufügen, fügt das AWS CDK allen VPCs erstellten Tags automatisch die folgenden Tags hinzu.
+  **Name** — Der Name der VPC.
+  **aws-cdk:subnet-name — Der Name des Subnetzes**.
+  **aws-cdk:subnet-type — Der Typ des Subnetzes: Öffentlich**, Privat oder Isoliert.

**Example**  

```
ec2.Vpc.fromLookup(this, 'PublicVpc',
    {tags: {'aws-cdk:subnet-type': "Public"}});
```

```
ec2.Vpc.fromLookup(this, 'PublicVpc',
    {tags: {'aws-cdk:subnet-type': "Public"}});
```

```
ec2.Vpc.from_lookup(self, "PublicVpc",
    tags={"aws-cdk:subnet-type": "Public"})
```

```
Vpc.fromLookup(this, "PublicVpc", VpcLookupOptions.builder()
        .tags(java.util.Map.of("aws-cdk:subnet-type", "Public"))  // Java 9 or later
        .build());
```

```
Vpc.FromLookup(this, id: "PublicVpc", new VpcLookupOptions
{
    Tags = new Dictionary<string, string> { ["aws-cdk:subnet-type"] = "Public" }
});
```

```
ec2.Vpc_FromLookup(this, jsii.String("DefaultVpc"), &ec2.VpcLookupOptions{
  Tags: &map[string]*string{"aws-cdk:subnet-type": jsii.String("Public")},
})
```

Die Ergebnisse von `Vpc.fromLookup()` werden in der Projektdatei zwischengespeichert. `cdk.context.json` (Siehe [Kontextwerte und AWS CDK](context.md).) Übergeben Sie diese Datei der Versionskontrolle, damit Ihre App weiterhin auf dieselbe Amazon VPC verweist. Dies funktioniert auch dann, wenn Sie später Ihre VPCs Attribute so ändern, dass eine andere VPC ausgewählt wird. Dies ist besonders wichtig, wenn Sie den Stack in einer Umgebung bereitstellen, die keinen Zugriff auf das AWS Konto hat, das die VPC definiert, z. B. [CDK](cdk-pipeline.md) Pipelines.

Sie können eine externe Ressource zwar überall verwenden, wo Sie eine ähnliche Ressource verwenden würden, die in Ihrer AWS CDK-App definiert ist, aber Sie können sie nicht ändern. Zum Beispiel bewirkt der Aufruf von `addToResourcePolicy` (Python:`add_to_resource_policy`) auf einem externen `s3.Bucket` Gerät nichts.

## Physische Namen der Ressourcen
<a name="resources-physical-names"></a>

Die logischen Namen der Ressourcen in unterscheiden AWS CloudFormation sich von den Namen der Ressourcen, die in der AWS Management Console angezeigt werden, nachdem sie von bereitgestellt wurden AWS CloudFormation. Das AWS CDK nennt diese endgültigen Namen *physische Namen*.

 AWS CloudFormation Könnte beispielsweise den Amazon S3 S3-Bucket mit der logischen ID `Stack2MyBucket4DD88B4F` und dem physischen Namen erstellen`stack2MyBucket4dd88b4f-iuv1rbv9z3to`.

Mithilfe der Eigenschaft `<resourceType>Name` können Sie beim Erstellen von Konstrukten, die Ressourcen repräsentieren, einen physischen Namen angeben. Im folgenden Beispiel wird ein Amazon S3 S3-Bucket mit dem physischen Namen erstellt`amzn-s3-demo-bucket`.

**Example**  

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: 'amzn-s3-demo-bucket',
});
```

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: 'amzn-s3-demo-bucket'
});
```

```
bucket = s3.Bucket(self, "MyBucket", bucket_name="amzn-s3-demo-bucket")
```

```
Bucket bucket = Bucket.Builder.create(this, "MyBucket")
        .bucketName("amzn-s3-demo-bucket").build();
```

```
var bucket = new Bucket(this, "MyBucket", new BucketProps { BucketName = "amzn-s3-demo-bucket" });
```

```
bucket := s3.NewBucket(this, jsii.String("MyBucket"), &s3.BucketProps{
  BucketName: jsii.String("amzn-s3-demo-bucket"),
})
```

Die Zuweisung physischer Namen zu Ressourcen hat einige Nachteile in AWS CloudFormation. Am wichtigsten ist jedoch, dass alle Änderungen an bereitgestellten Ressourcen, die einen Austausch von Ressourcen erfordern, wie z. B. Änderungen an den Eigenschaften einer Ressource, die nach der Erstellung unveränderlich sind, fehlschlagen, wenn einer Ressource ein physischer Name zugewiesen wurde. Wenn Sie in diesem Zustand landen, besteht die einzige Lösung darin, den AWS CloudFormation Stack zu löschen und dann die AWS CDK-App erneut bereitzustellen. Einzelheiten finden Sie in der [AWS CloudFormation Dokumentation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-name.html).

In einigen Fällen, z. B. beim Erstellen einer AWS CDK-App mit umgebungsübergreifenden Referenzen, sind physische Namen erforderlich, damit das AWS CDK ordnungsgemäß funktioniert. Wenn Sie sich in diesen Fällen nicht selbst die Mühe machen möchten, einen physischen Namen zu finden, können Sie ihn vom AWS CDK für Sie benennen lassen. Verwenden Sie dazu den speziellen Wert `PhysicalName.GENERATE_IF_NEEDED` wie folgt.

**Example**  

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: core.PhysicalName.GENERATE_IF_NEEDED,
});
```

```
const bucket = new s3.Bucket(this, 'MyBucket', {
  bucketName: core.PhysicalName.GENERATE_IF_NEEDED
});
```

```
bucket = s3.Bucket(self, "MyBucket",
                         bucket_name=core.PhysicalName.GENERATE_IF_NEEDED)
```

```
Bucket bucket = Bucket.Builder.create(this, "MyBucket")
        .bucketName(PhysicalName.GENERATE_IF_NEEDED).build();
```

```
var bucket = new Bucket(this, "MyBucket", new BucketProps
    { BucketName = PhysicalName.GENERATE_IF_NEEDED });
```

```
bucket := s3.NewBucket(this, jsii.String("MyBucket"), &s3.BucketProps{
  BucketName: awscdk.PhysicalName_GENERATE_IF_NEEDED(),
})
```

## Übergeben von eindeutigen Ressourcen-Identifikatoren
<a name="resources-identifiers"></a>

Wann immer möglich, sollten Sie Ressourcen als Referenz übergeben, wie im vorherigen Abschnitt beschrieben. Es gibt jedoch Fälle, in denen Sie keine andere Wahl haben, als mit einem ihrer Attribute auf eine Ressource zu verweisen. Zu den beispielhaften Anwendungsfällen gehören die folgenden:
+ Wenn Sie AWS CloudFormation Ressourcen auf niedriger Ebene verwenden.
+ Wenn Sie Ressourcen für die Laufzeitkomponenten einer AWS CDK-Anwendung verfügbar machen müssen, z. B. wenn Sie über Umgebungsvariablen auf Lambda-Funktionen verweisen.

Diese Identifikatoren sind als Attribute für die Ressourcen verfügbar, wie z. B. die folgenden.

**Example**  

```
bucket.bucketName
lambdaFunc.functionArn
securityGroup.groupArn
```

```
bucket.bucketName
lambdaFunc.functionArn
securityGroup.groupArn
```

```
bucket.bucket_name
lambda_func.function_arn
security_group_arn
```
Die AWS Java-CDK-Bindung verwendet Getter-Methoden für Attribute.  

```
bucket.getBucketName()
lambdaFunc.getFunctionArn()
securityGroup.getGroupArn()
```

```
bucket.BucketName
lambdaFunc.FunctionArn
securityGroup.GroupArn
```

```
bucket.BucketName()
fn.FunctionArn()
```

Das folgende Beispiel zeigt, wie ein generierter Bucket-Name an eine AWS Lambda-Funktion übergeben wird.

**Example**  

```
const bucket = new s3.Bucket(this, 'Bucket');

new lambda.Function(this, 'MyLambda', {
  // ...
  environment: {
    BUCKET_NAME: bucket.bucketName,
  },
});
```

```
const bucket = new s3.Bucket(this, 'Bucket');

new lambda.Function(this, 'MyLambda', {
  // ...
  environment: {
    BUCKET_NAME: bucket.bucketName
  }
});
```

```
bucket = s3.Bucket(self, "Bucket")

lambda.Function(self, "MyLambda", environment=dict(BUCKET_NAME=bucket.bucket_name))
```

```
final Bucket bucket = new Bucket(this, "Bucket");

Function.Builder.create(this, "MyLambda")
        .environment(java.util.Map.of(    // Java 9 or later
                "BUCKET_NAME", bucket.getBucketName()))
        .build();
```

```
var bucket = new Bucket(this, "Bucket");

new Function(this, "MyLambda", new FunctionProps
{
    Environment = new Dictionary<string, string>
    {
        ["BUCKET_NAME"] = bucket.BucketName
    }
});
```

```
bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{})
lambda.NewFunction(this, jsii.String("MyLambda"), &lambda.FunctionProps{
  Environment: &map[string]*string{"BUCKET_NAME": bucket.BucketName()},
})
```

## Erteilen von Berechtigungen zwischen Ressourcen
<a name="resources-grants"></a>

Konstrukte auf höherer Ebene ermöglichen die Erzielung von Berechtigungen mit den geringsten Rechten, indem sie einfache, absichtsbasierte bis ausdrückliche Berechtigungsanforderungen anbieten. APIs Viele Konstrukte bieten beispielsweise Erteilungsmethoden, mit denen Sie einer Entität (z. B. einer IAM-Rolle oder einem IAM-Benutzer) die Erlaubnis erteilen können, mit der Ressource zu arbeiten, ohne IAM-Berechtigungsanweisungen manuell erstellen zu müssen.

Grant-Methoden sind über Grants-Klassen verfügbar (z. B. `BucketGrants` für Amazon S3 S3-Buckets). Diese Klassen funktionieren sowohl mit L1- als auch mit L2-Konstrukten. L2-Konstrukte stellen der Einfachheit halber eine `grants` Eigenschaft zur Verfügung, aber Sie können eine Grants-Klasse auch direkt aus einem L1-Konstrukt erstellen. Sie können Grants-Klassen mit [Mixins](mixins.md) kombinieren, um L1-Konstrukten eine L2-ähnliche Benutzerfreundlichkeit zu bieten.

Im folgenden Beispiel werden die Berechtigungen erstellt, die es der Ausführungsrolle einer Lambda-Funktion ermöglichen, Objekte in einen bestimmten Amazon S3 S3-Bucket zu lesen und zu schreiben. Wenn der Amazon S3 S3-Bucket mit einem AWS KMS-Schlüssel verschlüsselt ist, gewährt diese Methode auch der Ausführungsrolle der Lambda-Funktion die Berechtigung, mit dem Schlüssel zu entschlüsseln.

**Example**  

```
if (bucket.grants.readWrite(func).success) {
  // ...
}
```

```
if ( bucket.grants.readWrite(func).success) {
  // ...
}
```

```
if bucket.grants.read_write(func).success:
    # ...
```

```
if (bucket.getGrants().readWrite(func).getSuccess()) {
    // ...
}
```

```
if (bucket.Grants.ReadWrite(func).Success)
{
    // ...
}
```

```
if *bucket.Grants().ReadWrite(function, nil).Success() {
  // ...
}
```

Die Grant-Methoden geben ein `iam.Grant` Objekt zurück. Verwenden Sie das `success` Attribut des `Grant` Objekts, um festzustellen, ob der Zuschuss tatsächlich gewährt wurde (z. B. wurde er möglicherweise nicht auf [externe Ressourcen](#resources-referencing) angewendet). Sie können auch die Methode `assertSuccess` (Python:`assert_success`) des `Grant` Objekts verwenden, um zu erzwingen, dass der Zuschuss erfolgreich beantragt wurde.

Wenn eine bestimmte Grant-Methode für den jeweiligen Anwendungsfall nicht verfügbar ist, können Sie eine generische Grant-Methode verwenden, um einen neuen Zuschuss mit einer bestimmten Liste von Aktionen zu definieren.

Das folgende Beispiel zeigt, wie einer Lambda-Funktion Zugriff auf die Amazon DynamoDB `CreateBackup` DynamoDB-Aktion gewährt wird.

**Example**  

```
table.grants.actions(func, 'dynamodb:CreateBackup');
```

```
table.grants.actions(func, 'dynamodb:CreateBackup');
```

```
table.grants.actions(func, "dynamodb:CreateBackup")
```

```
table.getGrants().actions(func, "dynamodb:CreateBackup");
```

```
table.Grants.Actions(func, "dynamodb:CreateBackup");
```

```
table := dynamodb.NewTable(this, jsii.String("MyTable"), &dynamodb.TableProps{})
table.Grants().Actions(function, jsii.String("dynamodb:CreateBackup"))
```

Für viele Ressourcen, wie z. B. Lambda-Funktionen, muss bei der Ausführung von Code eine Rolle übernommen werden. Mit einer Konfigurationseigenschaft können Sie eine `iam.IRole` angeben. Wenn keine Rolle angegeben ist, erstellt die Funktion automatisch eine Rolle speziell für diesen Zweck. Anschließend können Sie Grant-Methoden für die Ressourcen verwenden, um der Rolle Anweisungen hinzuzufügen.

Die Grant-Methoden basieren auf untergeordneten Ebenen APIs für den Umgang mit IAM-Richtlinien. Richtlinien werden als Objekte modelliert. [PolicyDocument](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyDocument.html) Fügen Sie mithilfe der Methode (Python:) Anweisungen direkt zu Rollen (oder der angehängten Rolle eines Konstrukts`add_to_role_policy`) oder mit der `addToRolePolicy` Methode (Python:) zur `Bucket` Richtlinie einer Ressource `addToResourcePolicy` (z. B. einer Richtlinie`add_to_resource_policy`) hinzu.

## Metriken und Alarme für Ressourcen
<a name="resources-metrics"></a>

Viele Ressourcen geben CloudWatch Metriken aus, mit denen Überwachungs-Dashboards und Alarme eingerichtet werden können. Konstrukte auf höherer Ebene verfügen über metrische Methoden, mit denen Sie auf die Metriken zugreifen können, ohne nach dem richtigen Namen suchen zu müssen.

Das folgende Beispiel zeigt, wie ein Alarm definiert wird, wenn `ApproximateNumberOfMessagesNotVisible` der Wert einer Amazon SQS SQS-Warteschlange 100 überschreitet.

**Example**  

```
import * as cw from '@aws-cdk/aws-cloudwatch';
import * as sqs from '@aws-cdk/aws-sqs';
import { Duration } from '@aws-cdk/core';

const queue = new sqs.Queue(this, 'MyQueue');

const metric = queue.metricApproximateNumberOfMessagesNotVisible({
  label: 'Messages Visible (Approx)',
  period: Duration.minutes(5),
  // ...
});
metric.createAlarm(this, 'TooManyMessagesAlarm', {
  comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
  threshold: 100,
  // ...
});
```

```
const cw = require('@aws-cdk/aws-cloudwatch');
const sqs = require('@aws-cdk/aws-sqs');
const { Duration } = require('@aws-cdk/core');

const queue = new sqs.Queue(this, 'MyQueue');

const metric = queue.metricApproximateNumberOfMessagesNotVisible({
  label: 'Messages Visible (Approx)',
  period: Duration.minutes(5)
  // ...
});
metric.createAlarm(this, 'TooManyMessagesAlarm', {
  comparisonOperator: cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
  threshold: 100
  // ...
});
```

```
import aws_cdk.aws_cloudwatch as cw
import aws_cdk.aws_sqs as sqs
from aws_cdk.core import Duration

queue = sqs.Queue(self, "MyQueue")
metric = queue.metric_approximate_number_of_messages_not_visible(
    label="Messages Visible (Approx)",
    period=Duration.minutes(5),
    # ...
)
metric.create_alarm(self, "TooManyMessagesAlarm",
    comparison_operator=cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
    threshold=100,
    # ...
)
```

```
import software.amazon.awscdk.core.Duration;
import software.amazon.awscdk.services.sqs.Queue;
import software.amazon.awscdk.services.cloudwatch.Metric;
import software.amazon.awscdk.services.cloudwatch.MetricOptions;
import software.amazon.awscdk.services.cloudwatch.CreateAlarmOptions;
import software.amazon.awscdk.services.cloudwatch.ComparisonOperator;

Queue queue = new Queue(this, "MyQueue");

Metric metric = queue
        .metricApproximateNumberOfMessagesNotVisible(MetricOptions.builder()
                .label("Messages Visible (Approx)")
                .period(Duration.minutes(5)).build());

metric.createAlarm(this, "TooManyMessagesAlarm", CreateAlarmOptions.builder()
                .comparisonOperator(ComparisonOperator.GREATER_THAN_THRESHOLD)
                .threshold(100)
                // ...
                .build());
```

```
using cdk = Amazon.CDK;
using cw = Amazon.CDK.AWS.CloudWatch;
using sqs = Amazon.CDK.AWS.SQS;

var queue = new sqs.Queue(this, "MyQueue");
var metric = queue.MetricApproximateNumberOfMessagesNotVisible(new cw.MetricOptions
{
    Label = "Messages Visible (Approx)",
    Period = cdk.Duration.Minutes(5),
    // ...
});
metric.CreateAlarm(this, "TooManyMessagesAlarm", new cw.CreateAlarmOptions
{
    ComparisonOperator = cw.ComparisonOperator.GREATER_THAN_THRESHOLD,
    Threshold = 100,
    // ..
});
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  cw "github.com/aws/aws-cdk-go/awscdk/v2/awscloudwatch"
  sqs "github.com/aws/aws-cdk-go/awscdk/v2/awssqs"
)

queue := sqs.NewQueue(this, jsii.String("MyQueue"), &sqs.QueueProps{})
metric := queue.MetricApproximateNumberOfMessagesNotVisible(&cw.MetricOptions{
  Label: jsii.String("Messages Visible (Approx)"),
  Period: awscdk.Duration_Minutes(jsii.Number(5)),
})

metric.CreateAlarm(this, jsii.String("TooManyMessagesAlarm"), &cw.CreateAlarmOptions{
  ComparisonOperator: cw.ComparisonOperator_GREATER_THAN_THRESHOLD,
  Threshold: jsii.Number(100),
})
```

Wenn es für eine bestimmte Metrik keine Methode gibt, können Sie die allgemeine Metrikmethode verwenden, um den Metriknamen manuell anzugeben.

Metriken können auch zu CloudWatch Dashboards hinzugefügt werden. Siehe [CloudWatch](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cloudwatch-readme.html).

## Netzwerkdatenverkehr
<a name="resources-traffic"></a>

In vielen Fällen müssen Sie Berechtigungen in einem Netzwerk aktivieren, damit eine Anwendung funktioniert, z. B. wenn die Recheninfrastruktur auf die Persistenzschicht zugreifen muss. Ressourcen, die Verbindungen herstellen oder darauf warten, stellen Methoden zur Verfügung, die den Datenfluss ermöglichen, einschließlich der Festlegung von Sicherheitsgruppenregeln oder Netzwerken ACLs.

 [IConnectable](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.IConnectable.html)Ressourcen haben eine `connections` Eigenschaft, die das Gateway zur Konfiguration der Netzwerkverkehrsregeln darstellt.

Mithilfe von `allow` Methoden ermöglichen Sie den Datenfluss auf einem bestimmten Netzwerkpfad. Das folgende Beispiel aktiviert HTTPS-Verbindungen zum Internet und eingehende Verbindungen von der Amazon EC2 Auto Scaling Scaling-Gruppe`fleet2`.

**Example**  

```
import * as asg from '@aws-cdk/aws-autoscaling';
import * as ec2 from '@aws-cdk/aws-ec2';

const fleet1: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/);

// Allow surfing the (secure) web
fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 }));

const fleet2: asg.AutoScalingGroup = asg.AutoScalingGroup(/*...*/);
fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
```

```
const asg = require('@aws-cdk/aws-autoscaling');
const ec2 = require('@aws-cdk/aws-ec2');

const fleet1 = asg.AutoScalingGroup();

// Allow surfing the (secure) web
fleet1.connections.allowTo(new ec2.Peer.anyIpv4(), new ec2.Port({ fromPort: 443, toPort: 443 }));

const fleet2 = asg.AutoScalingGroup();
fleet1.connections.allowFrom(fleet2, ec2.Port.AllTraffic());
```

```
import aws_cdk.aws_autoscaling as asg
import aws_cdk.aws_ec2 as ec2

fleet1 = asg.AutoScalingGroup( ... )

# Allow surfing the (secure) web
fleet1.connections.allow_to(ec2.Peer.any_ipv4(),
  ec2.Port(PortProps(from_port=443, to_port=443)))

fleet2 = asg.AutoScalingGroup( ... )
fleet1.connections.allow_from(fleet2, ec2.Port.all_traffic())
```

```
import software.amazon.awscdk.services.autoscaling.AutoScalingGroup;
import software.amazon.awscdk.services.ec2.Peer;
import software.amazon.awscdk.services.ec2.Port;

AutoScalingGroup fleet1 = AutoScalingGroup.Builder.create(this, "MyFleet")
        /* ... */.build();

// Allow surfing the (secure) Web
fleet1.getConnections().allowTo(Peer.anyIpv4(),
        Port.Builder.create().fromPort(443).toPort(443).build());

AutoScalingGroup fleet2 = AutoScalingGroup.Builder.create(this, "MyFleet2")
        /* ... */.build();
fleet1.getConnections().allowFrom(fleet2, Port.allTraffic());
```

```
using cdk = Amazon.CDK;
using asg = Amazon.CDK.AWS.AutoScaling;
using ec2 = Amazon.CDK.AWS.EC2;

// Allow surfing the (secure) Web
var fleet1 = new asg.AutoScalingGroup(this, "MyFleet", new asg.AutoScalingGroupProps { /* ... */ });
fleet1.Connections.AllowTo(ec2.Peer.AnyIpv4(), new ec2.Port(new ec2.PortProps
  { FromPort = 443, ToPort = 443 }));

var fleet2 = new asg.AutoScalingGroup(this, "MyFleet2", new asg.AutoScalingGroupProps { /* ... */ });
fleet1.Connections.AllowFrom(fleet2, ec2.Port.AllTraffic());
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  autoscaling "github.com/aws/aws-cdk-go/awscdk/v2/awsautoscaling"
  ec2 "github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
)

fleet1 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet1"), &autoscaling.AutoScalingGroupProps{})
fleet1.Connections().AllowTo(ec2.Peer_AnyIpv4(),ec2.NewPort(&ec2.PortProps{ FromPort: jsii.Number(443), ToPort: jsii.Number(443) }),jsii.String("secure web"))

fleet2 := autoscaling.NewAutoScalingGroup(this, jsii.String("MyFleet2"), &autoscaling.AutoScalingGroupProps{})
fleet1.Connections().AllowFrom(fleet2, ec2.Port_AllTraffic(),jsii.String("all traffic"))
```

Bestimmten Ressourcen sind Standardports zugeordnet. Beispiele hierfür sind der Listener eines Load Balancers auf dem öffentlichen Port und die Ports, auf denen die Datenbank-Engine Verbindungen für Instances einer Amazon RDS-Datenbank akzeptiert. In solchen Fällen können Sie eine strenge Netzwerkkontrolle erzwingen, ohne den Port manuell angeben zu müssen. Verwenden Sie dazu die `allowToDefaultPort` Methoden `allowDefaultPortFrom` und (Python:`allow_default_port_from`,`allow_to_default_port`).

Das folgende Beispiel zeigt, wie Verbindungen von einer beliebigen IPV4 Adresse und eine Verbindung von einer Auto Scaling Scaling-Gruppe aus für den Zugriff auf eine Datenbank aktiviert werden.

**Example**  

```
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access');

fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
```

```
listener.connections.allowDefaultPortFromAnyIpv4('Allow public access');

fleet.connections.allowToDefaultPort(rdsDatabase, 'Fleet can access database');
```

```
listener.connections.allow_default_port_from_any_ipv4("Allow public access")

fleet.connections.allow_to_default_port(rds_database, "Fleet can access database")
```

```
listener.getConnections().allowDefaultPortFromAnyIpv4("Allow public access");

fleet.getConnections().AllowToDefaultPort(rdsDatabase, "Fleet can access database");
```

```
listener.Connections.AllowDefaultPortFromAnyIpv4("Allow public access");

fleet.Connections.AllowToDefaultPort(rdsDatabase, "Fleet can access database");
```

```
listener.Connections().AllowDefaultPortFromAnyIpv4(jsii.String("Allow public Access"))
fleet.Connections().AllowToDefaultPort(rdsDatabase, jsii.String("Fleet can access database"))
```

## Behandlung von Ereignissen
<a name="resources-events"></a>

Einige Ressourcen können als Ereignisquellen dienen. Verwenden Sie die `addEventNotification` Methode (Python:`add_event_notification`), um ein Ereignisziel für einen bestimmten Ereignistyp zu registrieren, der von der Ressource ausgegeben wird. Darüber hinaus bieten `addXxxNotification` Methoden eine einfache Möglichkeit, einen Handler für gängige Ereignistypen zu registrieren.

Das folgende Beispiel zeigt, wie eine Lambda-Funktion ausgelöst wird, wenn ein Objekt zu einem Amazon S3 S3-Bucket hinzugefügt wird.

**Example**  

```
import * as s3nots from '@aws-cdk/aws-s3-notifications';

const handler = new lambda.Function(this, 'Handler', { /*…*/ });
const bucket = new s3.Bucket(this, 'Bucket');
bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
```

```
const s3nots = require('@aws-cdk/aws-s3-notifications');

const handler = new lambda.Function(this, 'Handler', { /*…*/ });
const bucket = new s3.Bucket(this, 'Bucket');
bucket.addObjectCreatedNotification(new s3nots.LambdaDestination(handler));
```

```
import aws_cdk.aws_s3_notifications as s3_nots

handler = lambda_.Function(self, "Handler", ...)
bucket = s3.Bucket(self, "Bucket")
bucket.add_object_created_notification(s3_nots.LambdaDestination(handler))
```

```
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.s3.notifications.LambdaDestination;

Function handler = Function.Builder.create(this, "Handler")/* ... */.build();
Bucket bucket = new Bucket(this, "Bucket");
bucket.addObjectCreatedNotification(new LambdaDestination(handler));
```

```
using lambda = Amazon.CDK.AWS.Lambda;
using s3 = Amazon.CDK.AWS.S3;
using s3Nots = Amazon.CDK.AWS.S3.Notifications;

var handler = new lambda.Function(this, "Handler", new lambda.FunctionProps { .. });
var bucket = new s3.Bucket(this, "Bucket");
bucket.AddObjectCreatedNotification(new s3Nots.LambdaDestination(handler));
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
  s3nots "github.com/aws/aws-cdk-go/awscdk/v2/awss3notifications"
)

handler := lambda.NewFunction(this, jsii.String("MyFunction"), &lambda.FunctionProps{})
bucket := s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{})
bucket.AddObjectCreatedNotification(s3nots.NewLambdaDestination(handler), nil)
```

## Richtlinien zur Entfernung
<a name="resources-removal"></a>

*Für Ressourcen, die persistente Daten verwalten, wie Datenbanken, Amazon S3 S3-Buckets und Amazon ECR-Registries, gilt eine Entfernungsrichtlinie.* Die Entfernungsrichtlinie gibt an, ob persistente Objekte gelöscht werden sollen, wenn der AWS CDK-Stapel, der sie enthält, zerstört wird. Die Werte, die die Entfernungsrichtlinie angeben, sind über die `RemovalPolicy` Aufzählung im AWS `core` CDK-Modul verfügbar.

**Anmerkung**  
Neben Ressourcen, die Daten dauerhaft speichern, können auch Ressourcen eine haben`removalPolicy`, die für einen anderen Zweck verwendet wird. Beispielsweise verwendet eine Lambda-Funktionsversion ein `removalPolicy` Attribut, um zu bestimmen, ob eine bestimmte Version beibehalten wird, wenn eine neue Version bereitgestellt wird. Diese haben im Vergleich zu den Entfernungsrichtlinien für einen Amazon S3 S3-Bucket oder eine DynamoDB-Tabelle unterschiedliche Bedeutungen und Standardeinstellungen.


| Wert | Bedeutung | 
| --- | --- | 
|   `RemovalPolicy.RETAIN`   |  Behält den Inhalt der Ressource bei, wenn der Stapel zerstört wird (Standard). Die Ressource ist aus dem Stapel verwaist und muss manuell gelöscht werden. Wenn Sie versuchen, den Stack erneut bereitzustellen, während die Ressource noch vorhanden ist, erhalten Sie aufgrund eines Namenskonflikts eine Fehlermeldung.  | 
|   `RemovalPolicy.DESTROY`   |  Die Ressource wird zusammen mit dem Stapel zerstört.  | 

 AWS CloudFormation entfernt keine Amazon S3 S3-Buckets, die Dateien enthalten, auch wenn ihre Entfernungsrichtlinie auf `DESTROY` eingestellt ist. Der Versuch, dies zu tun, ist ein AWS CloudFormation Fehler. Damit das AWS CDK vor der Zerstörung alle Dateien aus dem Bucket löscht, setzen Sie die `autoDeleteObjects` Eigenschaft des Buckets auf`true`.

Im Folgenden finden Sie ein Beispiel für die Erstellung eines Amazon S3 S3-Buckets mit `RemovalPolicy` der Einstellung of `DESTROY` und der `autoDeleteOjbects` Einstellung auf`true`.

**Example**  

```
import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';

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

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true
    });
  }
}
```

```
const cdk = require('@aws-cdk/core');
const s3 = require('@aws-cdk/aws-s3');

class CdkTestStack extends cdk.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true
    });
  }
}

module.exports = { CdkTestStack }
```

```
import aws_cdk.core as cdk
import aws_cdk.aws_s3 as s3

class CdkTestStack(cdk.stack):
    def __init__(self, scope: cdk.Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        bucket = s3.Bucket(self, "Bucket",
            removal_policy=cdk.RemovalPolicy.DESTROY,
            auto_delete_objects=True)
```

```
software.amazon.awscdk.core.*;
import software.amazon.awscdk.services.s3.*;

public class CdkTestStack extends Stack {
    public CdkTestStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkTestStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Bucket.Builder.create(this, "Bucket")
                .removalPolicy(RemovalPolicy.DESTROY)
                .autoDeleteObjects(true).build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

public CdkTestStack(Construct scope, string id, IStackProps props) : base(scope, id, props)
{
    new Bucket(this, "Bucket", new BucketProps {
        RemovalPolicy = RemovalPolicy.DESTROY,
        AutoDeleteObjects = true
    });
}
```

```
import (
  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/jsii-runtime-go"
  s3 "github.com/aws/aws-cdk-go/awscdk/v2/awss3"
)

s3.NewBucket(this, jsii.String("Bucket"), &s3.BucketProps{
  RemovalPolicy: awscdk.RemovalPolicy_DESTROY,
  AutoDeleteObjects: jsii.Bool(true),
})
```

Mithilfe der `applyRemovalPolicy()` Methode können Sie eine Entfernungsrichtlinie auch direkt auf die zugrunde liegende AWS CloudFormation Ressource anwenden. Diese Methode ist für einige statusbehaftete Ressourcen verfügbar, die keine `removalPolicy` Eigenschaft in den Requisiten ihrer L2-Ressource haben. Beispiele sind unter anderem:
+  AWS CloudFormation stapelt
+ Amazon-Cognito-Benutzerpools
+ Amazon DocumentDB DocumentDB-Datenbank-Instances
+ Amazon EC2 EC2-Volumen
+ Amazon OpenSearch Service-Domänen
+  FSx Amazon-Dateisysteme
+ Amazon-SQS-Warteschlangen

**Example**  

```
const resource = bucket.node.findChild('Resource') as cdk.CfnResource;
resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

```
const resource = bucket.node.findChild('Resource');
resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

```
resource = bucket.node.find_child('Resource')
resource.apply_removal_policy(cdk.RemovalPolicy.DESTROY);
```

```
CfnResource resource = (CfnResource)bucket.node.findChild("Resource");
resource.applyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

```
var resource = (CfnResource)bucket.node.findChild('Resource');
resource.ApplyRemovalPolicy(cdk.RemovalPolicy.DESTROY);
```

**Anmerkung**  
Das AWS CDK's `RemovalPolicy` bedeutet übersetzt's. AWS CloudFormation `DeletionPolicy` Die Standardeinstellung in AWS CDK besteht jedoch darin, die Daten beizubehalten, was das Gegenteil der Standardeinstellung ist. AWS CloudFormation 

# Identifikatoren und das CDK AWS
<a name="identifiers"></a>

Beim Erstellen von AWS Cloud Development Kit (AWS CDK) -Apps werden Sie viele Arten von Kennungen und Namen verwenden. Um das AWS CDK effektiv zu nutzen und Fehler zu vermeiden, ist es wichtig, die Arten von Identifikatoren zu verstehen.

Identifikatoren müssen innerhalb des Bereichs, in dem sie erstellt wurden, eindeutig sein. Sie müssen in Ihrer AWS CDK-Anwendung nicht global eindeutig sein.

Wenn Sie versuchen, einen Bezeichner mit demselben Wert innerhalb desselben Bereichs zu erstellen, löst das AWS CDK eine Ausnahme aus.

## Konstruieren IDs
<a name="identifiers-construct-ids"></a>

Der häufigste Bezeichner,`id`, ist der Bezeichner, der bei der Instanziierung eines Konstruktobjekts als zweites Argument übergeben wird. Dieser Bezeichner muss, wie alle Bezeichner, nur innerhalb des Bereichs, in dem er erstellt wurde, eindeutig sein. Dies ist das erste Argument bei der Instanziierung eines Konstruktobjekts.

**Anmerkung**  
Der `id` Wert eines Stacks ist auch der Bezeichner, mit dem Sie in der [AWS CDK-CLI-Referenz](cli.md) auf ihn verweisen.

Schauen wir uns ein Beispiel an, bei dem wir zwei Konstrukte mit dem Identifier `MyBucket` in unserer App haben. Das erste ist im Bereich des Stacks mit dem Identifier `Stack1` definiert. Der zweite ist im Gültigkeitsbereich eines Stacks mit dem Identifier definiert`Stack2`. Da sie in unterschiedlichen Bereichen definiert sind, verursacht dies keinen Konflikt und sie können problemlos in derselben App koexistieren.

**Example**  

```
import { App, Stack, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';

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

    new s3.Bucket(this, 'MyBucket');
  }
}

const app = new App();
new MyStack(app, 'Stack1');
new MyStack(app, 'Stack2');
```

```
const { App , Stack } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

class MyStack extends Stack {
  constructor(scope, id, props = {}) {
    super(scope, id, props);

    new s3.Bucket(this, 'MyBucket');
  }
}

const app = new App();
new MyStack(app, 'Stack1');
new MyStack(app, 'Stack2');
```

```
from aws_cdk import App, Construct, Stack, StackProps
from constructs import Construct
from aws_cdk import aws_s3 as s3

class MyStack(Stack):

    def __init__(self, scope: Construct, id: str, **kwargs):

        super().__init__(scope, id, **kwargs)
        s3.Bucket(self, "MyBucket")

app = App()
MyStack(app, 'Stack1')
MyStack(app, 'Stack2')
```

```
// MyStack.java
package com.myorg;

import software.amazon.awscdk.App;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.constructs.Construct;
import software.amazon.awscdk.services.s3.Bucket;

public class MyStack extends Stack {
    public MyStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public MyStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);
        new Bucket(this, "MyBucket");
    }
}

// Main.java
package com.myorg;

import software.amazon.awscdk.App;

public class Main {
    public static void main(String[] args) {
        App app = new App();
        new MyStack(app, "Stack1");
        new MyStack(app, "Stack2");
    }
}
```

```
using Amazon.CDK;
using constructs;
using Amazon.CDK.AWS.S3;

public class MyStack : Stack
{
    public MyStack(Construct scope, string id, IStackProps props) : base(scope, id, props)
    {
        new Bucket(this, "MyBucket");
    }
}

class Program
{
    static void Main(string[] args)
    {
        var app = new App();
        new MyStack(app, "Stack1");
        new MyStack(app, "Stack2");
    }
}
```

## Pfade
<a name="identifiers-paths"></a>

Die Konstrukte in einer AWS CDK-Anwendung bilden eine Hierarchie, die in der Klasse verwurzelt ist. `App` *Wir bezeichnen die Sammlung IDs von einem bestimmten Konstrukt, seinem Elternkonstrukt, seinem übergeordneten Konstrukt usw. bis zur Wurzel des Konstruktbaums als Pfad.*

Das AWS CDK zeigt Pfade in Ihren Vorlagen normalerweise als Zeichenfolge an. Die IDs von den Ebenen werden durch Schrägstriche getrennt, beginnend am Knoten unmittelbar unter der `App` Root-Instance, bei der es sich normalerweise um einen Stack handelt. Die Pfade der beiden Amazon S3 S3-Bucket-Ressourcen im vorherigen Codebeispiel lauten beispielsweise `Stack1/MyBucket` und`Stack2/MyBucket`.

Sie können programmgesteuert auf den Pfad eines beliebigen Konstrukts zugreifen, wie im folgenden Beispiel gezeigt. Dies erhält den Pfad von `myConstruct` (oder`my_construct`, wie Python-Entwickler ihn schreiben würden). Da sie innerhalb des Bereichs, in dem sie erstellt wurden, eindeutig sein IDs müssen, sind ihre Pfade innerhalb einer AWS CDK-Anwendung immer eindeutig.

**Example**  

```
const path: string = myConstruct.node.path;
```

```
const path = myConstruct.node.path;
```

```
path = my_construct.node.path
```

```
String path = myConstruct.getNode().getPath();
```

```
string path = myConstruct.Node.Path;
```

## Einzigartig IDs
<a name="identifiers-unique-ids"></a>

 AWS CloudFormation erfordert, dass alle logischen IDs Elemente in einer Vorlage eindeutig sind. Aus diesem Grund muss das AWS CDK in der Lage sein, für jedes Konstrukt in einer Anwendung eine eindeutige Kennung zu generieren. Ressourcen haben weltweit eindeutige Pfade (die Namen aller Bereiche vom Stack bis zu einer bestimmten Ressource). Daher generiert das AWS CDK die erforderlichen eindeutigen Identifikatoren, indem es die Elemente des Pfads verkettet und einen 8-stelligen Hash hinzufügt. (Der Hash ist notwendig, um verschiedene Pfade wie `A/B/C` und zu unterscheiden`A/BC`, die zu derselben Kennung führen würden. AWS CloudFormation AWS CloudFormation Bezeichner sind alphanumerisch und dürfen keine Schrägstriche oder andere Trennzeichen enthalten.) Das AWS CDK nennt diese Zeichenfolge die *eindeutige ID des Konstrukts.*

Im Allgemeinen sollte Ihre AWS CDK-App nichts über Unique wissen müssen. IDs Sie können jedoch programmgesteuert auf die eindeutige ID eines beliebigen Konstrukts zugreifen, wie im folgenden Beispiel gezeigt.

**Example**  

```
const uid: string = Names.uniqueId(myConstruct);
```

```
const uid = Names.uniqueId(myConstruct);
```

```
uid = Names.unique_id(my_construct)
```

```
String uid = Names.uniqueId(myConstruct);
```

```
string uid = Names.Uniqueid(myConstruct);
```

Die *Adresse* ist eine weitere Art von eindeutiger Kennung, die CDK-Ressourcen eindeutig unterscheidet. Er wurde vom SHA-1-Hash des Pfads abgeleitet und ist nicht für Menschen lesbar. Aufgrund seiner konstanten, relativ kurzen Länge (immer 42 Hexadezimalzeichen) ist er jedoch in Situationen nützlich, in denen die „traditionelle“ eindeutige ID möglicherweise zu lang ist. Einige Konstrukte verwenden möglicherweise die Adresse in der synthetisierten AWS CloudFormation Vorlage anstelle der eindeutigen ID. Auch hier sollte Ihre App im Allgemeinen nichts über die Adressen ihrer Konstrukte wissen müssen, aber Sie können die Adresse eines Konstrukts wie folgt abrufen.

**Example**  

```
const addr: string = myConstruct.node.addr;
```

```
const addr = myConstruct.node.addr;
```

```
addr = my_construct.node.addr
```

```
String addr = myConstruct.getNode().getAddr();
```

```
string addr = myConstruct.Node.Addr;
```

## Logisch IDs
<a name="identifiers-logical-ids"></a>

Unique IDs dienen als *logische Bezeichner* (oder *logische Namen*) von Ressourcen in den generierten AWS CloudFormation Vorlagen für Konstrukte, die Ressourcen darstellen AWS .

Der Amazon S3 S3-Bucket im vorherigen Beispiel, der innerhalb erstellt wurde, `Stack2` führt beispielsweise zu einer ` AWS::S3::Bucket` Ressource. Die logische ID der Ressource befindet sich `Stack2MyBucket4DD88B4F` in der resultierenden AWS CloudFormation Vorlage. (Einzelheiten darüber, wie dieser Bezeichner generiert wird, finden Sie unter [Unique IDs](#identifiers-unique-ids).)

### Stabilität der logischen ID
<a name="identifiers-logical-id-stability"></a>

Vermeiden Sie es, die logische ID einer Ressource zu ändern, nachdem sie erstellt wurde. AWS CloudFormation identifiziert Ressourcen anhand ihrer logischen ID. Wenn Sie also die logische ID einer Ressource ändern, AWS CloudFormation wird eine neue Ressource mit der neuen logischen ID erstellt und anschließend die vorhandene gelöscht. Je nach Ressourcentyp kann dies zu Betriebsunterbrechungen, Datenverlust oder beidem führen.

# Tokens und das AWS CDK
<a name="tokens"></a>

Im AWS Cloud Development Kit (AWS CDK) sind *Token* Platzhalter für Werte, die bei der Definition von Konstrukten oder der Synthese von Stacks nicht bekannt sind. Diese Werte werden bei der Bereitstellung vollständig aufgelöst, wenn Ihre eigentliche Infrastruktur erstellt wird. Bei der Entwicklung von AWS CDK-Anwendungen werden Sie mit Tokens arbeiten, um diese Werte in Ihrer gesamten Anwendung zu verwalten.

## Beispiel für ein Token
<a name="tokens-example"></a>

Im Folgenden finden Sie ein Beispiel für einen CDK-Stack, der ein Konstrukt für einen Amazon Simple Storage Service (Amazon S3) -Bucket definiert. Da der Name unseres Buckets noch nicht bekannt ist, `bucketName` wird der Wert für als Token gespeichert:

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';

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

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // Store value of the S3 bucket name
    const myBucketName = myBucket.bucketName;

    // Print the current value for the S3 bucket name at synthesis
    console.log("myBucketName: " + myBucketName);
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // Store value of the S3 bucket name
    const myBucketName = myBucket.bucketName;

    // Print the current value for the S3 bucket name at synthesis
    console.log("myBucketName: " + myBucketName);
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Stack
)
from constructs import Construct
from aws_cdk import aws_s3 as s3

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define an S3 bucket
        my_bucket = s3.Bucket(self, "myBucket")

        # Store the value of the S3 bucket name
        my_bucket_name = my_bucket.bucket_name

        # Print the current value for the S3 bucket name at synthesis
        print(f"myBucketName: {my_bucket_name}")
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.s3.Bucket;

import java.util.Map;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define an S3 bucket
        Bucket myBucket = Bucket.Builder.create(this, "myBucket")
            .build();

        // Store the token for the bucket name
        String myBucketName = myBucket.getBucketName();

        // Print the token at synthesis
        System.out.println("myBucketName: " + myBucketName);
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define an S3 bucket
            var myBucket = new Bucket(this, "myBucket");

            // Store the token for the bucket name
            var myBucketName = myBucket.BucketName;

            // Print the token at synthesis
            System.Console.WriteLine($"myBucketName: {myBucketName}");
        }
    }
}
```

```
package main

import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define an S3 bucket
	myBucket := awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{})

	// Store the token for the bucket name
	myBucketName := myBucket.BucketName()

	// Print the token at synthesis
	fmt.Println("myBucketName: ", *myBucketName)

	return stack
}

// ...
```
Wenn wir unseren `cdk synth` Stack synthetisieren, `myBucketName` wird der Wert für im Token-Format von `${Token[TOKEN.<1234>]}` angezeigt. Dieses Token-Format ergibt sich aus der Art und Weise, wie das AWS CDK Token kodiert. In diesem Beispiel ist das Token als Zeichenfolge codiert:  

```
$ cdk synth --quiet
myBucketName: ${Token[TOKEN.21]}
```
Da der Wert für unseren Bucket-Namen bei der Synthese nicht bekannt ist, wird das Token als `myBucket<unique-hash>` gerendert. Unsere AWS CloudFormation Vorlage verwendet die `Ref` systeminterne Funktion, um auf ihren Wert zu verweisen, der bei der Bereitstellung bekannt sein wird:  

```
Resources:
  myBucket<5AF9C99B>:
    # ...
Outputs:
  bucketNameOutput:
    Description: The name of the S3 bucket
    Value:
      Ref: myBucket<5AF9C99B>
```

Weitere Informationen darüber, wie der eindeutige Hash generiert wird, finden Sie unter [Logisch generiert IDs in Ihrer AWS CloudFormation Vorlage](configure-synth.md#how-synth-default-logical-ids).

## Tokens weitergeben
<a name="tokens-passing"></a>

Tokens können weitergegeben werden, als wären sie der tatsächliche Wert, den sie repräsentieren. Im Folgenden finden Sie ein Beispiel, das das Token für unseren Bucket-Namen an ein Konstrukt für eine AWS Lambda-Funktion übergibt:

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as lambda from 'aws-cdk-lib/aws-lambda';

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

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // ...

    // Define a Lambda function
    const myFunction = new lambda.Function(this, "myFunction", {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: "index.handler",
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      functionName: myBucketName + "Function", // Pass token for the S3 bucket name
      environment: {
        BUCKET_NAME: myBucketName, // Pass token for the S3 bucket name
      }
    });
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');
const lambda = require('aws-cdk-lib/aws-lambda');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // ...

    // Define a Lambda function
    const myFunction = new lambda.Function(this, 'myFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      functionName: myBucketName + 'Function', // Pass token for the S3 bucket name
      environment: {
        BUCKET_NAME: myBucketName, // Pass token for the S3 bucket name
      }
    });
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Stack
)
from constructs import Construct
from aws_cdk import aws_s3 as s3
from aws_cdk import aws_lambda as _lambda

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define an S3 bucket
        my_bucket = s3.Bucket(self, "myBucket")

        # ...

        # Define a Lambda function
        my_function = _lambda.Function(self, "myFunction",
            runtime=_lambda.Runtime.NODEJS_20_X,
            handler="index.handler",
            code=_lambda.Code.from_inline("""
                exports.handler = async function(event) {
                  return {
                    statusCode: 200,
                    body: JSON.stringify('Hello World!'),
                  };
                };
            """),
            function_name=f"{my_bucket_name}Function",  # Pass token for the S3 bucket name
            environment={
                "BUCKET_NAME": my_bucket_name  # Pass token for the S3 bucket name
            }
        )
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.lambda.Code;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;

import java.util.Map;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define an S3 bucket
        Bucket myBucket = Bucket.Builder.create(this, "myBucket")
            .build();

        // ...

        // Define a Lambda function
        Function myFunction = Function.Builder.create(this, "myFunction")
            .runtime(Runtime.NODEJS_20_X)
            .handler("index.handler")
            .code(Code.fromInline(
                "exports.handler = async function(event) {" +
                "return {" +
                "statusCode: 200," +
                "body: JSON.stringify('Hello World!')," +
                "};" +
                "};"
            ))
            .functionName(myBucketName + "Function") // Pass the token for the s3 bucket to the function construct
            .environment(Map.of("BUCKET_NAME", myBucketName))  // Pass the bucket name as environment variable
            .build();
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define an S3 bucket
            var myBucket = new Bucket(this, "myBucket");

            // ...

            // Define a Lambda function
            var myFunction = new Function(this, "myFunction", new FunctionProps
            {
                 Runtime = Runtime.NODEJS_20_X,
                 Handler = "index.handler",
                 Code = Code.FromInline(@"
                     exports.handler = async function(event) {
                       return {
                         statusCode: 200,
                         body: JSON.stringify('Hello World!'),
                       };
                     };
                 "),
                 // Pass the token for the S3 bucket name
                 Environment = new Dictionary<string, string>
                 {
                     { "BUCKET_NAME", myBucketName }
                 },
                 FunctionName = $"{myBucketName}Function" // Pass the token for the s3 bucket to the function construct
            });
        }
    }
}
```

```
package main

import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
	"github.com/aws/aws-cdk-go/awscdk/v2/awss3"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define an S3 bucket
	myBucket := awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{})

	// ...

	// Define a Lambda function
	myFunction := awslambda.NewFunction(stack, jsii.String("myFunction"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_20_X(),
		Handler: jsii.String("index.handler"),
		Code: awslambda.Code_FromInline(jsii.String(`
			exports.handler = async function(event) {
				return {
					statusCode: 200,
					body: JSON.stringify('Hello World!'),
				};
			};
		`)),
		FunctionName: jsii.String(fmt.Sprintf("%sFunction", *myBucketName)), // Pass the token for the S3 bucket to the function name
		Environment: &map[string]*string{
			"BUCKET_NAME": myBucketName,
		},
	})

	return stack
}
// ...
```
Wenn wir unsere Vorlage synthetisieren, werden die Funktionen `Ref` und die `Fn::Join` systemeigenen Funktionen verwendet, um die Werte zu spezifizieren, die bei der Bereitstellung bekannt sein werden:  

```
Resources:
  myBucket<5AF9C99B>:
    Type: AWS::S3::Bucket
    # ...
  myFunction<884E1557>:
    Type: AWS::Lambda::Function
    Properties:
      # ...
      Environment:
        Variables:
          BUCKET_NAME:
            Ref: myBucket<5AF9C99B>
      FunctionName:
        Fn::Join:
          - ""
          - - Ref: myBucket<5AF9C99B>
            - Function
      # ...
```

## Wie funktionieren Token-Kodierungen
<a name="tokens-work"></a>

Tokens sind Objekte, die die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IResolvable.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.IResolvable.html)Schnittstelle implementieren, die eine einzige `resolve` Methode enthält. Während der Synthese ruft das AWS CDK diese Methode auf, um den endgültigen Wert für Token in Ihrer CloudFormation Vorlage zu erzeugen.

**Anmerkung**  
Sie werden selten direkt mit der `IResolvable` Schnittstelle arbeiten. Sie werden höchstwahrscheinlich nur string-kodierte Versionen von Tokens sehen.

### Typen der Token-Codierung
<a name="tokens-work-types"></a>

Token sind am Syntheseprozess beteiligt, um beliebige Werte beliebigen Typs zu erzeugen. Andere Funktionen akzeptieren normalerweise nur Argumente grundlegender Typen wie `string` oder`number`. Um in diesen Fällen Tokens zu verwenden, können Sie sie in einen von drei Typen codieren, indem Sie statische Methoden für die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html)Klasse verwenden.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrstringvalue-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrstringvalue-options)um eine Zeichenkettenkodierung zu generieren (oder das Token-Objekt `.toString()` aufzurufen).
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrlistvalue-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrlistvalue-options)um eine Listenkodierung zu generieren.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrnumbervalue](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-aswbrnumbervalue)um eine numerische Kodierung zu generieren.

Diese nehmen einen beliebigen Wert, der ein sein kann`IResolvable`, und kodieren ihn in einen primitiven Wert des angegebenen Typs.

**Wichtig**  
Da es sich bei jedem der vorherigen Typen potenziell um ein codiertes Token handeln kann, sollten Sie vorsichtig sein, wenn Sie ihren Inhalt analysieren oder versuchen, ihn zu lesen. Wenn Sie beispielsweise versuchen, eine Zeichenfolge zu analysieren, um daraus einen Wert zu extrahieren, und es sich bei der Zeichenfolge um ein codiertes Token handelt, schlägt die Analyse fehl. Ebenso müssen Sie, wenn Sie versuchen, die Länge eines Arrays abzufragen oder mathematische Operationen mit einer Zahl durchzuführen, zunächst überprüfen, ob es sich nicht um kodierte Token handelt.

## Wie können Sie in Ihrer App nach Tokens suchen
<a name="tokens-check"></a>

Um zu überprüfen, ob ein Wert ein ungelöstes Token enthält, rufen Sie die Methode [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-iswbrunresolvedobj](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Token.html#static-iswbrunresolvedobj)(Python:`is_unresolved`) auf. Das folgende Beispiel prüft, ob der Wert für unseren Amazon S3 S3-Bucket-Namen ein Token ist. Wenn es sich nicht um ein Token handelt, überprüfen wir dann die Länge des Bucket-Namens:

**Example**  

```
// ...

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

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');
    // ...

    // Check if bucket name is a token. If not, check if length is less than 10 characters
    if (cdk.Token.isUnresolved(myBucketName)) {
      console.log("Token identified.");
    } else if (!cdk.Token.isUnresolved(myBucketName) && myBucketName.length > 10) {
      throw new Error('Maximum length for name is 10 characters.');
    };

    // ...
  }
}
```

```
const { Stack, Duration, Token, CfnOutput } = require('aws-cdk-lib');
// ...

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define an S3 bucket
    const myBucket = new s3.Bucket(this, 'myBucket');

    // ...

    // Check if bucket name is a token. If not, check if length is less than 10 characters
    if (Token.isUnresolved(myBucketName)) {
      console.log("Token identified.");
    } else if (!Token.isUnresolved(myBucketName) && myBucketName.length > 10) {
      throw new Error('Maximum length for name is 10 characters.');
    };

    // ...
  }
}
```

```
from aws_cdk import (
    Stack,
    Token
)
# ...

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define an S3 bucket
        my_bucket = s3.Bucket(self, "myBucket")

        # ...

        # Check if bucket name is a token. If not, check if length is less than 10 characters
        if Token.is_unresolved(my_bucket_name):
            print("Token identified.")
        elif not Token.is_unresolved(my_bucket_name) and len(my_bucket_name) < 10:
            raise ValueError("Maximum length for name is 10 characters.")

        # ...
```

```
// ...
import software.amazon.awscdk.Token;
import software.amazon.awscdk.services.s3.Bucket;
// ...

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define an S3 bucket
        Bucket myBucket = Bucket.Builder.create(this, "myBucket")
            .build();

        // ...

        // Get the bucket name
        String myBucketName = myBucket.getBucketName();

        // Check if the bucket name is a token. If not, check if length is less than 10 characters
        if (Token.isUnresolved(myBucketName)) {
            System.out.println("Token identified.");
        } else if (!Token.isUnresolved(myBucketName) && myBucketName.length() > 10) {
            throw new IllegalArgumentException("Maximum length for name is 10 characters.");
        }

        // ...
      }
    }
  }
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.S3;
using Amazon.CDK.AWS.Lambda;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define an S3 bucket
            var myBucket = new Bucket(this, "myBucket");

            // ...

            // Get the bucket name
            var myBucketName = myBucket.BucketName;

            // Check if bucket name is a token. If not, check if length is less than 10 characters
            if (Token.IsUnresolved(myBucketName))
            {
                System.Console.WriteLine("Token identified.");
            }
            else if (!Token.IsUnresolved(myBucketName) && myBucketName.Length > 10)
            {
                throw new System.Exception("Maximum length for name is 10 characters.");
            }

            // ...
        }
    }
}
```

```
// ...

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define an S3 bucket
	myBucket := awss3.NewBucket(stack, jsii.String("myBucket"), &awss3.BucketProps{})

	// ...

	// Check if the bucket name is unresolved (a token)
	if tokenUnresolved := awscdk.Token_IsUnresolved(myBucketName); tokenUnresolved != nil && *tokenUnresolved {
		fmt.Println("Token identified.")
	} else if tokenUnresolved != nil && !*tokenUnresolved && len(*myBucketName) > 10 {
		panic("Maximum length for name is 10 characters.")
	}

	// ...
}
```

Wenn wir ausführen`cdk synth`, `myBucketName` wird es als Token identifiziert:

```
$ cdk synth --quiet
Token identified.
```

**Anmerkung**  
Sie können Token-Kodierungen verwenden, um dem Typsystem zu entkommen. Sie könnten beispielsweise ein Token, das bei der Synthese einen Zahlenwert erzeugt, mit einer Zeichenkette codieren. Wenn Sie diese Funktionen verwenden, liegt es in Ihrer Verantwortung, dafür zu sorgen, dass Ihre Vorlage nach der Synthese wieder in einen brauchbaren Zustand übergeht.

## Arbeiten Sie mit String-codierten Tokens
<a name="tokens-string"></a>

Zeichenkettencodierte Token sehen wie folgt aus.

```
${TOKEN[Bucket.Name.1234]}
```

Sie können wie normale Zeichenketten weitergegeben und verkettet werden, wie im folgenden Beispiel gezeigt.

**Example**  

```
const functionName = bucket.bucketName + 'Function';
```

```
const functionName = bucket.bucketName + 'Function';
```

```
function_name = bucket.bucket_name + "Function"
```

```
String functionName = bucket.getBucketName().concat("Function");
```

```
string functionName = bucket.BucketName + "Function";
```

```
functionName := *bucket.BucketName() + "Function"
```

Sie können auch Zeichenketteninterpolation verwenden, sofern Ihre Sprache dies unterstützt, wie im folgenden Beispiel gezeigt.

**Example**  

```
const functionName = `${bucket.bucketName}Function`;
```

```
const functionName = `${bucket.bucketName}Function`;
```

```
function_name = f"{bucket.bucket_name}Function"
```

```
String functionName = String.format("%sFunction". bucket.getBucketName());
```

```
string functionName = $"${bucket.bucketName}Function";
```
Verwenden Sie `fmt.Sprintf` für ähnliche Funktionen:  

```
functionName := fmt.Sprintf("%sFunction", *bucket.BucketName())
```

Vermeiden Sie es, die Zeichenfolge auf andere Weise zu manipulieren. Wenn Sie beispielsweise eine Teilzeichenfolge einer Zeichenfolge verwenden, wird das Zeichenketten-Token wahrscheinlich beschädigt.

## Mit listencodierten Tokens arbeiten
<a name="tokens-list"></a>

Listenkodierte Token sehen wie folgt aus:

```
["#{TOKEN[Stack.NotificationArns.1234]}"]
```

Die einzig sichere Sache, die man mit diesen Listen machen kann, ist, sie direkt an andere Konstrukte weiterzugeben. Token in Form einer Zeichenkettenliste können nicht verkettet werden, und es kann auch kein Element aus dem Token entnommen werden. Der einzig sichere Weg, sie zu manipulieren, ist die Verwendung AWS CloudFormation intrinsischer Funktionen wie. [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-select.html)

## Arbeiten mit nummerencodierten Tokens
<a name="tokens-number"></a>

Zahlenkodierte Token sind eine Reihe winziger negativer Gleitkommazahlen, die wie folgt aussehen.

```
-1.8881545897087626e+289
```

Wie bei Listentokens können Sie den Zahlenwert nicht ändern, da das Zahlentokens dadurch wahrscheinlich beschädigt wird.

Im Folgenden finden Sie ein Beispiel für ein Konstrukt, das ein als Zahl codiertes Token enthält:

**Example**  

```
import { Stack, Duration, StackProps } from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as rds from 'aws-cdk-lib/aws-rds';
import * as ec2 from 'aws-cdk-lib/aws-ec2';

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

    // Define a new VPC
    const vpc = new ec2.Vpc(this, 'MyVpc', {
      maxAzs: 3,  // Maximum number of availability zones to use
    });

    // Define an RDS database cluster
    const dbCluster = new rds.DatabaseCluster(this, 'MyRDSCluster', {
      engine: rds.DatabaseClusterEngine.AURORA,
      instanceProps: {
        vpc,
      },
    });

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // Print the value for our token at synthesis
    console.log("portToken: " + portToken);
  }
}
```

```
const { Stack, Duration } = require('aws-cdk-lib');
const lambda = require('aws-cdk-lib/aws-lambda');
const rds = require('aws-cdk-lib/aws-rds');
const ec2 = require('aws-cdk-lib/aws-ec2');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define a new VPC
    const vpc = new ec2.Vpc(this, 'MyVpc', {
      maxAzs: 3,  // Maximum number of availability zones to use
    });

    // Define an RDS database cluster
    const dbCluster = new rds.DatabaseCluster(this, 'MyRDSCluster', {
      engine: rds.DatabaseClusterEngine.AURORA,
      instanceProps: {
        vpc,
      },
    });

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // Print the value for our token at synthesis
    console.log("portToken: " + portToken);
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Duration,
    Stack,
)
from aws_cdk import aws_rds as rds
from aws_cdk import aws_ec2 as ec2
from constructs import Construct

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define a new VPC
        vpc = ec2.Vpc(self, 'MyVpc',
            max_azs=3  # Maximum number of availability zones to use
        )

        # Define an RDS database cluster
        db_cluster = rds.DatabaseCluster(self, 'MyRDSCluster',
            engine=rds.DatabaseClusterEngine.AURORA,
            instance_props=rds.InstanceProps(
                vpc=vpc
            )
        )

        # Get the port token (this is a token encoded as a number)
        port_token = db_cluster.cluster_endpoint.port

        # Print the value for our token at synthesis
        print(f"portToken: {port_token}")
```

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.ec2.Vpc;
import software.amazon.awscdk.services.rds.DatabaseCluster;
import software.amazon.awscdk.services.rds.DatabaseClusterEngine;
import software.amazon.awscdk.services.rds.InstanceProps;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define a new VPC
        Vpc vpc = Vpc.Builder.create(this, "MyVpc")
            .maxAzs(3) // Maximum number of availability zones to use
            .build();

        // Define an RDS database cluster
        DatabaseCluster dbCluster = DatabaseCluster.Builder.create(this, "MyRDSCluster")
            .engine(DatabaseClusterEngine.AURORA)
            .instanceProps(InstanceProps.builder()
                .vpc(vpc)
                .build())
            .build();

        // Get the port token (this is a token encoded as a number)
        Number portToken = dbCluster.getClusterEndpoint().getPort();

        // Print the value for our token at synthesis
        System.out.println("portToken: " + portToken);
    }
}
```

```
using Amazon.CDK;
using Constructs;
using Amazon.CDK.AWS.EC2;
using Amazon.CDK.AWS.RDS;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define a new VPC
            var vpc = new Vpc(this, "MyVpc", new VpcProps
            {
                MaxAzs = 3  // Maximum number of availability zones to use
            });

            // Define an RDS database cluster
            var dbCluster = new DatabaseCluster(this, "MyRDSCluster", new DatabaseClusterProps
            {
                Engine = DatabaseClusterEngine.AURORA,  // Remove parentheses
                InstanceProps = new Amazon.CDK.AWS.RDS.InstanceProps // Specify RDS InstanceProps
                {
                    Vpc = vpc
                }
            });

            // Get the port token (this is a token encoded as a number)
            var portToken = dbCluster.ClusterEndpoint.Port;

            // Print the value for our token at synthesis
            System.Console.WriteLine($"portToken: {portToken}");
        }
    }
}
```

```
package main

import (
	"fmt"

	"github.com/aws/aws-cdk-go/awscdk/v2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsec2"
	"github.com/aws/aws-cdk-go/awscdk/v2/awsrds"
	"github.com/aws/constructs-go/constructs/v10"
	"github.com/aws/jsii-runtime-go"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define a new VPC
	vpc := awsec2.NewVpc(stack, jsii.String("MyVpc"), &awsec2.VpcProps{
		MaxAzs: jsii.Number(3), // Maximum number of availability zones to use
	})

	// Define an RDS database cluster
	dbCluster := awsrds.NewDatabaseCluster(stack, jsii.String("MyRDSCluster"), &awsrds.DatabaseClusterProps{
		Engine: awsrds.DatabaseClusterEngine_AURORA(),
		InstanceProps: &awsrds.InstanceProps{
			Vpc: vpc,
		},
	})

	// Get the port token (this is a token encoded as a number)
	portToken := dbCluster.ClusterEndpoint().Port()

	// Print the value for our token at synthesis
	fmt.Println("portToken: ", portToken)

	return stack
}

// ...
```

Wenn wir ausführen`cdk synth`, `portToken` wird der Wert für als nummerncodiertes Token angezeigt:

```
$ cdk synth --quiet
portToken: -1.8881545897087968e+289
```

### Übergeben Sie nummernkodierte Token
<a name="tokens-number-pass"></a>

Wenn Sie nummernkodierte Token an andere Konstrukte übergeben, kann es sinnvoll sein, sie zuerst in Zeichenketten zu konvertieren. Wenn Sie beispielsweise den Wert einer nummerierten Zeichenfolge als Teil einer verketteten Zeichenfolge verwenden möchten, hilft die Konvertierung bei der Lesbarkeit.

Im folgenden Beispiel `portToken` ist ein nummerencodiertes Token, das wir als Teil an unsere Lambda-Funktion übergeben möchten: `connectionString`

**Example**  

```
import { Stack, Duration, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...
import * as lambda from 'aws-cdk-lib/aws-lambda';

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

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Example connection string with the port token as a number
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portToken}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}
```

```
const { Stack, Duration, CfnOutput } = require('aws-cdk-lib');
// ...
const lambda = require('aws-cdk-lib/aws-lambda');

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Example connection string with the port token as a number
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portToken}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      runtime: lambda.Runtime.NODEJS_20_X,
      handler: 'index.handler',
      code: lambda.Code.fromInline(`
        exports.handler = async function(event) {
          return {
            statusCode: 200,
            body: JSON.stringify('Hello World!'),
          };
        };
      `),
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Duration,
    Stack,
    CfnOutput,
)
from aws_cdk import aws_lambda as _lambda
# ...

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define a new VPC
        # ...

        # Define an RDS database cluster
        # ...

        # Get the port token (this is a token encoded as a number)
        port_token = db_cluster.cluster_endpoint.port

        # ...

        # Example connection string with the port token as a number
        connection_string = f"jdbc:mysql://mydb.cluster.amazonaws.com:{port_token}/mydatabase"

        # Use the connection string as an environment variable in a Lambda function
        my_function = _lambda.Function(self, 'MyLambdaFunction',
            runtime=_lambda.Runtime.NODEJS_20_X,
            handler='index.handler',
            code=_lambda.Code.from_inline("""
                exports.handler = async function(event) {
                    return {
                        statusCode: 200,
                        body: JSON.stringify('Hello World!'),
                    };
                };
            """),
            environment={
                'DATABASE_CONNECTION_STRING': connection_string  # Using the port token as part of the string
            }
        )

        # Output the value of our connection string at synthesis
        print(f"connectionString: {connection_string}")

        # Output the connection string
        CfnOutput(self, 'ConnectionString',
            value=connection_string
        )
```

```
// ...
import software.amazon.awscdk.CfnOutput;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.lambda.Code;

import java.util.Map;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define a new VPC
        // ...

        // Define an RDS database cluster
        // ...

        // Get the port token (this is a token encoded as a number)
        Number portToken = dbCluster.getClusterEndpoint().getPort();

        // ...

        // Example connection string with the port token as a number
        String connectionString = "jdbc:mysql://mydb.cluster.amazonaws.com:" + portToken + "/mydatabase";

        // Use the connection string as an environment variable in a Lambda function
        Function myFunction = Function.Builder.create(this, "MyLambdaFunction")
            .runtime(Runtime.NODEJS_20_X)
            .handler("index.handler")
            .code(Code.fromInline(
                "exports.handler = async function(event) {\n" +
                "  return {\n" +
                "    statusCode: 200,\n" +
                "    body: JSON.stringify('Hello World!'),\n" +
                "  };\n" +
                "};"))
            .environment(Map.of(
                "DATABASE_CONNECTION_STRING", connectionString // Using the port token as part of the string
            ))
            .build();

        // Output the value of our connection string at synthesis
        System.out.println("connectionString: " + connectionString);

        // Output the connection string
        CfnOutput.Builder.create(this, "ConnectionString")
            .value(connectionString)
            .build();
    }
}
```

```
// ...
using Amazon.CDK.AWS.Lambda;
using Amazon.CDK.AWS.RDS;
using Amazon.CDK;
using Constructs;
using System;
using System.Collections.Generic;

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define a new VPC
            // ...

            // Define an RDS database cluster
            var dbCluster = new DatabaseCluster(this, "MyRDSCluster", new DatabaseClusterProps
            {
                // ... properties would go here
            });

            // Get the port token (this is a token encoded as a number)
            var portToken = dbCluster.ClusterEndpoint.Port;

            // ...

            // Example connection string with the port token as a number
            var connectionString = $"jdbc:mysql://mydb.cluster.amazonaws.com:{portToken}/mydatabase";

            // Use the connection string as an environment variable in a Lambda function
            var myFunction = new Function(this, "MyLambdaFunction", new FunctionProps
            {
                Runtime = Runtime.NODEJS_20_X,
                Handler = "index.handler",
                Code = Code.FromInline(@"
                    exports.handler = async function(event) {
                        return {
                            statusCode: 200,
                            body: JSON.stringify('Hello World!'),
                        };
                    };
                "),
                Environment = new Dictionary<string, string>
                {
                    { "DATABASE_CONNECTION_STRING", connectionString }  // Using the port token as part of the string
                }
            });

            // Output the value of our connection string at synthesis
            Console.WriteLine($"connectionString: {connectionString}");

            // Output the connection string
            new CfnOutput(this, "ConnectionString", new CfnOutputProps
            {
                Value = connectionString
            });
        }
    }
}
```

```
// ...
	"github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
)

type CdkDemoAppStackProps struct {
	awscdk.StackProps
}

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define a new VPC
	// ...

	// Define an RDS database cluster
	// ...

	// Get the port token (this is a token encoded as a number)
	portToken := dbCluster.ClusterEndpoint().Port()

	// ...

	// Example connection string with the port token as a number
	 connectionString := fmt.Sprintf("jdbc:mysql://mydb.cluster.amazonaws.com:%s/mydatabase", portToken)

	// Use the connection string as an environment variable in a Lambda function
	myFunction := awslambda.NewFunction(stack, jsii.String("MyLambdaFunction"), &awslambda.FunctionProps{
		Runtime: awslambda.Runtime_NODEJS_20_X(),
		Handler: jsii.String("index.handler"),
		Code: awslambda.Code_FromInline(jsii.String(`
			exports.handler = async function(event) {
				return {
					statusCode: 200,
					body: JSON.stringify('Hello World!'),
				};
			};
		`)),
		Environment: &map[string]*string{
			"DATABASE_CONNECTION_STRING": jsii.String(connectionString), // Using the port token as part of the string
		},
	})

	// Output the value of our connection string at synthesis
	fmt.Println("connectionString: ", connectionString)

	// Output the connection string
	awscdk.NewCfnOutput(stack, jsii.String("ConnectionString"), &awscdk.CfnOutputProps{
		Value: jsii.String(connectionString),
	})

	return stack
}

// ...
```

Wenn wir diesen Wert an übergeben`connectionString`, kann der Ausgabewert bei der Ausführung aufgrund der `cdk synth` nummerencodierten Zeichenfolge verwirrend sein:

```
$ cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:-1.888154589708796e+289/mydatabase
```

Um ein nummerenkodiertes Token in eine Zeichenfolge umzuwandeln, verwenden Sie. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tokenization.html#static-stringifywbrnumberx](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tokenization.html#static-stringifywbrnumberx) Im folgenden Beispiel konvertieren wir das nummerierte Token in eine Zeichenfolge, bevor wir unsere Verbindungszeichenfolge definieren:

**Example**  

```
import { Stack, Duration, Tokenization, CfnOutput, StackProps } from 'aws-cdk-lib';
// ...

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

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Convert the encoded number to an encoded string for use in the connection string
    const portAsString = Tokenization.stringifyNumber(portToken);

    // Example connection string with the port token as a string
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portAsString}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      // ...
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}
```

```
const { Stack, Duration, Tokenization, CfnOutput } = require('aws-cdk-lib');
// ...

class CdkDemoAppStack extends Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    // Define a new VPC
    // ...

    // Define an RDS database cluster
    // ...

    // Get the port token (this is a token encoded as a number)
    const portToken = dbCluster.clusterEndpoint.port;

    // ...

    // Convert the encoded number to an encoded string for use in the connection string
    const portAsString = Tokenization.stringifyNumber(portToken);

    // Example connection string with the port token as a string
    const connectionString = `jdbc:mysql://mydb.cluster.amazonaws.com:${portAsString}/mydatabase`;

    // Use the connection string as an environment variable in a Lambda function
    const myFunction = new lambda.Function(this, 'MyLambdaFunction', {
      // ...
      environment: {
        DATABASE_CONNECTION_STRING: connectionString,  // Using the port token as part of the string
      },
    });

    // Output the value of our connection string at synthesis
    console.log("connectionString: " + connectionString);

    // Output the connection string
    new CfnOutput(this, 'ConnectionString', {
      value: connectionString,
    });
  }
}

module.exports = { CdkDemoAppStack }
```

```
from aws_cdk import (
    Duration,
    Stack,
    Tokenization,
    CfnOutput,
)
# ...

class CdkDemoAppStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define a new VPC
        # ...

        # Define an RDS database cluster
        # ...

        # Get the port token (this is a token encoded as a number)
        port_token = db_cluster.cluster_endpoint.port

        # Convert the encoded number to an encoded string for use in the connection string
        port_as_string = Tokenization.stringify_number(port_token)

        # Example connection string with the port token as a string
        connection_string = f"jdbc:mysql://mydb.cluster.amazonaws.com:{port_as_string}/mydatabase"

        # Use the connection string as an environment variable in a Lambda function
        my_function = _lambda.Function(self, 'MyLambdaFunction',
            # ...
            environment={
                'DATABASE_CONNECTION_STRING': connection_string  # Using the port token as part of the string
            }
        )

        # Output the value of our connection string at synthesis
        print(f"connectionString: {connection_string}")

        # Output the connection string
        CfnOutput(self, 'ConnectionString',
            value=connection_string
        )
```

```
// ...
import software.amazon.awscdk.Tokenization;

public class CdkDemoAppStack extends Stack {
    public CdkDemoAppStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkDemoAppStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        // Define a new VPC
        // ...

        // Define an RDS database cluster
        // ...

        // Get the port token (this is a token encoded as a number)
        Number portToken = dbCluster.getClusterEndpoint().getPort();

        // ...

        // Convert the encoded number to an encoded string for use in the connection string
        String portAsString = Tokenization.stringifyNumber(portToken);

        // Example connection string with the port token as a string
        String connectionString = "jdbc:mysql://mydb.cluster.amazonaws.com:" + portAsString + "/mydatabase";

        // Use the connection string as an environment variable in a Lambda function
        Function myFunction = Function.Builder.create(this, "MyLambdaFunction")
            // ...
            .environment(Map.of(
                "DATABASE_CONNECTION_STRING", connectionString // Using the port token as part of the string
            ))
            .build();

        // Output the value of our connection string at synthesis
        System.out.println("connectionString: " + connectionString);

        // Output the connection string
        CfnOutput.Builder.create(this, "ConnectionString")
            .value(connectionString)
            .build();
    }
}
```

```
// ...

namespace CdkDemoApp
{
    public class CdkDemoAppStack : Stack
    {
        internal CdkDemoAppStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Define a new VPC
            // ...

            // Define an RDS database cluster
            // ...

            // Get the port token (this is a token encoded as a number)
            var portToken = dbCluster.ClusterEndpoint.Port;

            // ...

            // Convert the encoded number to an encoded string for use in the connection string
            var portAsString = Tokenization.StringifyNumber(portToken);

            // Example connection string with the port token as a string
            var connectionString = $"jdbc:mysql://mydb.cluster.amazonaws.com:{portAsString}/mydatabase";

            // Use the connection string as an environment variable in a Lambda function
            var myFunction = new Function(this, "MyLambdaFunction", new FunctionProps
            {
                // ...
                Environment = new Dictionary<string, string>
                {
                    { "DATABASE_CONNECTION_STRING", connectionString }  // Using the port token as part of the string
                }
            });

            // Output the value of our connection string at synthesis
            Console.WriteLine($"connectionString: {connectionString}");

            // Output the connection string
            new CfnOutput(this, "ConnectionString", new CfnOutputProps
            {
                Value = connectionString
            });
        }
    }
}
```

```
// ...

func NewCdkDemoAppStack(scope constructs.Construct, id string, props *CdkDemoAppStackProps) awscdk.Stack {
	var sprops awscdk.StackProps
	if props != nil {
		sprops = props.StackProps
	}
	stack := awscdk.NewStack(scope, &id, &sprops)

	// Define a new VPC
	// ...

	// Define an RDS database cluster
	// ...

	// Get the port token (this is a token encoded as a number)
	portToken := dbCluster.ClusterEndpoint().Port()

	// ...

	// Convert the encoded number to an encoded string for use in the connection string
	portAsString := awscdk.Tokenization_StringifyNumber(portToken)

	// Example connection string with the port token as a string
	connectionString := fmt.Sprintf("jdbc:mysql://mydb.cluster.amazonaws.com:%s/mydatabase", portAsString)

	// Use the connection string as an environment variable in a Lambda function
	myFunction := awslambda.NewFunction(stack, jsii.String("MyLambdaFunction"), &awslambda.FunctionProps{
		// ...
		Environment: &map[string]*string{
			"DATABASE_CONNECTION_STRING": jsii.String(connectionString), // Using the port token as part of the string
		},
	})

	// Output the value of our connection string at synthesis
	fmt.Println("connectionString: ", connectionString)

	// Output the connection string
	awscdk.NewCfnOutput(stack, jsii.String("ConnectionString"), &awscdk.CfnOutputProps{
		Value: jsii.String(connectionString),
	})

	fmt.Println(myFunction)

	return stack
}

// ...
```

Wenn wir ausführen`cdk synth`, wird der Wert für unsere Verbindungszeichenfolge in einem übersichtlicheren und klareren Format dargestellt:

```
$ cdk synth --quiet
connectionString: jdbc:mysql://mydb.cluster.amazonaws.com:${Token[TOKEN.242]}/mydatabase
```

## Faule Werte
<a name="tokens-lazy"></a>

Neben der Darstellung von Bereitstellungszeitwerten, wie z. B. AWS CloudFormation [Parametern](parameters.md), werden Tokens häufig auch zur Darstellung verzögerter Werte für die Synthesedauer verwendet. Dies sind Werte, für die der endgültige Wert bestimmt wird, bevor die Synthese abgeschlossen ist, jedoch nicht an dem Punkt, an dem der Wert konstruiert wird. Verwenden Sie Tokens, um einen literalen Zeichenketten- oder Zahlenwert an ein anderes Konstrukt zu übergeben, wobei der tatsächliche Wert zum Zeitpunkt der Synthese von einer Berechnung abhängen kann, die noch nicht durchgeführt wurde.

Sie können Tokens erstellen, die verzögerte Synth-Time-Werte darstellen, indem Sie statische Methoden für die `Lazy` Klasse verwenden, z. B. und. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Lazy.html#static-stringproducer-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Lazy.html#static-stringproducer-options) Diese Methoden akzeptieren ein Objekt, dessen `produce` Eigenschaft eine Funktion ist, die ein Kontextargument akzeptiert und beim Aufruf den endgültigen Wert zurückgibt.

Im folgenden Beispiel wird eine Auto Scaling Scaling-Gruppe erstellt, deren Kapazität nach ihrer Erstellung bestimmt wird.

**Example**  

```
let actualValue: number;

new AutoScalingGroup(this, 'Group', {
  desiredCapacity: Lazy.numberValue({
    produce(context) {
      return actualValue;
    }
  })
});

// At some later point
actualValue = 10;
```

```
let actualValue;

new AutoScalingGroup(this, 'Group', {
  desiredCapacity: Lazy.numberValue({
    produce(context) {
      return (actualValue);
    }
  })
});

// At some later point
actualValue = 10;
```

```
class Producer:
    def __init__(self, func):
        self.produce = func

actual_value = None

AutoScalingGroup(self, "Group",
    desired_capacity=Lazy.number_value(Producer(lambda context: actual_value))
)

# At some later point
actual_value = 10
```

```
double actualValue = 0;

class ProduceActualValue implements INumberProducer {

    @Override
    public Number produce(IResolveContext context) {
        return actualValue;
    }
}

AutoScalingGroup.Builder.create(this, "Group")
    .desiredCapacity(Lazy.numberValue(new ProduceActualValue())).build();

// At some later point
actualValue = 10;
```

```
public class NumberProducer : INumberProducer
{
    Func<Double> function;

    public NumberProducer(Func<Double> function)
    {
        this.function = function;
    }

    public Double Produce(IResolveContext context)
    {
        return function();
    }
}

double actualValue = 0;

new AutoScalingGroup(this, "Group", new AutoScalingGroupProps
{
    DesiredCapacity = Lazy.NumberValue(new NumberProducer(() => actualValue))
});

// At some later point
actualValue = 10;
```

## Konvertierung nach JSON
<a name="tokens-json"></a>

Manchmal möchten Sie eine JSON-Zeichenfolge mit beliebigen Daten erstellen, und Sie wissen möglicherweise nicht, ob die Daten Token enthalten. Um jede Datenstruktur korrekt mit JSON zu codieren, unabhängig davon, ob sie Token enthält, verwenden Sie die Methode [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#towbrjsonwbrstringobj-space](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#towbrjsonwbrstringobj-space), wie im folgenden Beispiel gezeigt.

**Example**  

```
const stack = Stack.of(this);
const str = stack.toJsonString({
  value: bucket.bucketName
});
```

```
const stack = Stack.of(this);
const str = stack.toJsonString({
  value: bucket.bucketName
});
```

```
stack = Stack.of(self)
string = stack.to_json_string(dict(value=bucket.bucket_name))
```

```
Stack stack = Stack.of(this);
String stringVal = stack.toJsonString(java.util.Map.of(    // Map.of requires Java 9+
        put("value", bucket.getBucketName())));
```

```
var stack = Stack.Of(this);
var stringVal = stack.ToJsonString(new Dictionary<string, string>
{
    ["value"] = bucket.BucketName
});
```

# Parameter und das AWS CDK
<a name="parameters"></a>

 *Parameter* sind benutzerdefinierte Werte, die bei der Bereitstellung bereitgestellt werden. [Parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) sind ein Feature von AWS CloudFormation. Da das AWS Cloud Development Kit (AWS CDK) AWS CloudFormation Vorlagen synthetisiert, bietet es auch Unterstützung für Bereitstellungszeitparameter.

## Über Parameter
<a name="parameters-about"></a>

Mithilfe des AWS CDK können Sie Parameter definieren, die dann in den Eigenschaften der von Ihnen erstellten Konstrukte verwendet werden können. Sie können auch Stacks bereitstellen, die Parameter enthalten.

Wenn Sie die AWS CloudFormation Vorlage mit der AWS CDK-CLI bereitstellen, geben Sie die Parameterwerte in der Befehlszeile an. Wenn Sie die Vorlage über die AWS CloudFormation Konsole bereitstellen, werden Sie zur Eingabe der Parameterwerte aufgefordert.

Im Allgemeinen raten wir davon ab, AWS CloudFormation Parameter mit dem AWS CDK zu verwenden. Die üblichen Methoden, Werte an AWS CDK-Apps zu übergeben, sind [Kontextwerte](context.md) und Umgebungsvariablen. Da sie zum Zeitpunkt der Synthese nicht verfügbar sind, können Parameterwerte nicht einfach für die Flusskontrolle und andere Zwecke in Ihrer CDK-App verwendet werden.

**Anmerkung**  
Um die Ablaufsteuerung mit Parametern durchzuführen, können Sie [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CfnCondition.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.CfnCondition.html)Konstrukte verwenden, obwohl dies im Vergleich zu systemeigenen Anweisungen umständlich ist. `if`

Bei der Verwendung von Parametern müssen Sie darauf achten, wie sich der Code, den Sie schreiben, bei der Bereitstellung und auch bei der Synthese verhält. Dies macht es schwieriger, Ihre AWS CDK-Anwendung zu verstehen und zu begründen, was in vielen Fällen nur wenig Nutzen bringt.

Im Allgemeinen ist es besser, wenn Ihre CDK-App die erforderlichen Informationen auf klar definierte Weise akzeptiert und sie direkt zur Deklaration von Konstrukten in Ihrer CDK-App verwendet. Eine ideale, mit AWS CDK generierte AWS CloudFormation Vorlage ist konkret, sodass zum Zeitpunkt der Bereitstellung keine Werte mehr spezifiziert werden müssen.

Es gibt jedoch Anwendungsfälle, für die AWS CloudFormation Parameter eindeutig geeignet sind. Wenn Sie beispielsweise über separate Teams verfügen, die die Infrastruktur definieren und bereitstellen, können Sie Parameter verwenden, um die generierten Vorlagen breiter nutzbar zu machen. Da das AWS CDK AWS CloudFormation Parameter unterstützt, können Sie das AWS CDK auch mit AWS Diensten verwenden, die AWS CloudFormation Vorlagen verwenden (wie Service Catalog). Diese AWS Dienste verwenden Parameter, um die Vorlage zu konfigurieren, die bereitgestellt wird.

## Weitere Informationen
<a name="parameters-learn"></a>

Anweisungen zur Entwicklung von CDK-Apps mit Parametern finden Sie unter [Verwenden von CloudFormation Parametern, um einen CloudFormation Wert abzurufen](get-cfn-param.md).

# Tags und das AWS CDK
<a name="tagging"></a>

Tags sind informative Schlüssel-Wert-Elemente, die Sie zu Konstrukten in Ihrer CDK-App hinzufügen können. AWS Ein Tag, der auf ein bestimmtes Konstrukt angewendet wird, gilt auch für alle seine markierbaren untergeordneten Objekte. Tags sind in der AWS CloudFormation Vorlage enthalten, die aus Ihrer App synthetisiert wurde, und werden auf die AWS Ressourcen angewendet, die sie bereitstellt. Sie können Tags verwenden, um Ressourcen für die folgenden Zwecke zu identifizieren und zu kategorisieren:
+ Vereinfachung der Verwaltung
+ Kostenzuordnung
+ Zugriffskontrolle
+ Alle anderen Zwecke, die Sie sich ausdenken

**Tipp**  
*Weitere Informationen darüber, wie Sie Tags mit Ihren AWS Ressourcen verwenden können, finden Sie im Whitepaper unter [Best Practices für das AWS Tagging von AWS Ressourcen](https://docs.aws.amazon.com/whitepapers/latest/tagging-best-practices/tagging-best-practices.html).*

## Verwenden von Markierungen
<a name="tagging-use"></a>

Die [Tags-Klasse](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html) umfasst die statische Methode`of()`, mit der Sie dem angegebenen Konstrukt Tags hinzufügen oder Tags daraus entfernen können.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#addkey-value-props](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#addkey-value-props)wendet ein neues Tag auf das angegebene Konstrukt und alle seine untergeordneten Objekte an.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#removekey-props](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Tags.html#removekey-props)entfernt ein Tag aus dem angegebenen Konstrukt und allen seinen untergeordneten Objekten, einschließlich Tags, die ein untergeordnetes Konstrukt möglicherweise auf sich selbst angewendet hat.

**Anmerkung**  
Das Tagging wird mithilfe von [Aspects und dem AWS CDK](aspects.md) implementiert. Aspekte sind eine Möglichkeit, eine Operation (z. B. Tagging) auf alle Konstrukte in einem bestimmten Bereich anzuwenden.

Im folgenden Beispiel wird der **Tag-Schlüssel** mit dem **Wertwert auf ein Konstrukt** angewendet.

**Example**  

```
Tags.of(myConstruct).add('key', 'value');
```

```
Tags.of(myConstruct).add('key', 'value');
```

```
Tags.of(my_construct).add("key", "value")
```

```
Tags.of(myConstruct).add("key", "value");
```

```
Tags.Of(myConstruct).Add("key", "value");
```

```
awscdk.Tags_Of(myConstruct).Add(jsii.String("key"), jsii.String("value"), &awscdk.TagProps{})
```

Im folgenden Beispiel wird der **Tag-Schlüssel** aus einem Konstrukt gelöscht.

**Example**  

```
Tags.of(myConstruct).remove('key');
```

```
Tags.of(myConstruct).remove('key');
```

```
Tags.of(my_construct).remove("key")
```

```
Tags.of(myConstruct).remove("key");
```

```
Tags.Of(myConstruct).Remove("key");
```

```
awscdk.Tags_Of(myConstruct).Remove(jsii.String("key"), &awscdk.TagProps{})
```

Wenn Sie `Stage` Konstrukte verwenden, wenden Sie das Tag auf der `Stage` Ebene oder darunter an. Beschriftungen werden nicht `Stage` grenzübergreifend angewendet.

## Tag-Prioritäten
<a name="tagging-priorities"></a>

Das AWS CDK wendet Tags rekursiv an und entfernt sie. Bei Konflikten gewinnt der Tagging-Vorgang mit der höchsten Priorität. (Prioritäten werden mithilfe der optionalen `priority` Eigenschaft festgelegt.) Wenn die Prioritäten von zwei Operationen identisch sind, gewinnt die Tagging-Operation, die sich am Ende des Konstruktionsbaums am nächsten befindet. Standardmäßig hat das Anwenden eines Tags eine Priorität von 100 (mit Ausnahme von direkt zu einer AWS CloudFormation Ressource hinzugefügten Tags, die eine Priorität von 50 haben). Die Standardpriorität für das Entfernen eines Tags ist 200.

Im Folgenden wird ein Tag mit der Priorität 300 auf ein Konstrukt angewendet.

**Example**  

```
Tags.of(myConstruct).add('key', 'value', {
  priority: 300
});
```

```
Tags.of(myConstruct).add('key', 'value', {
  priority: 300
});
```

```
Tags.of(my_construct).add("key", "value", priority=300)
```

```
Tags.of(myConstruct).add("key", "value", TagProps.builder()
        .priority(300).build());
```

```
Tags.Of(myConstruct).Add("key", "value", new TagProps { Priority = 300 });
```

```
awscdk.Tags_Of(myConstruct).Add(jsii.String("key"), jsii.String("value"), &awscdk.TagProps{
  Priority: jsii.Number(300),
})
```

## Optionale Eigenschaften
<a name="tagging-props"></a>

Mithilfe von [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.TagProps.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.TagProps.html)Stichwörtern können Sie genau festlegen, wie Tags auf Ressourcen angewendet oder aus Ressourcen entfernt werden. Alle anderen Eigenschaften sind optional.

 `applyToLaunchedInstances`(Python:`apply_to_launched_instances`)  
Nur für add () verfügbar. Standardmäßig werden Tags auf Instances angewendet, die in einer Auto Scaling Scaling-Gruppe gestartet wurden. Setzen Sie diese Eigenschaft auf **false**, um Instances zu ignorieren, die in einer Auto Scaling Scaling-Gruppe gestartet wurden.

 `includeResourceTypes`/`excludeResourceTypes`(Python:`include_resource_types`/`exclude_resource_types`)  
Verwenden Sie diese, um Tags nur für eine Teilmenge von Ressourcen zu manipulieren, basierend auf AWS CloudFormation Ressourcentypen. Standardmäßig wird die Operation auf alle Ressourcen im Konstruktionsunterbaum angewendet. Dies kann jedoch geändert werden, indem bestimmte Ressourcentypen ein- oder ausgeschlossen werden. Exclude hat Vorrang vor Include, wenn beide angegeben sind.

 `priority`   
Verwenden Sie diese Option, um die Priorität dieser Operation im Vergleich zu anderen `Tags.add()` `Tags.remove()` AND-Vorgängen festzulegen. Höhere Werte haben Vorrang vor niedrigeren Werten. Die Standardeinstellung ist 100 für Hinzufügevorgänge (50 für direkt auf AWS CloudFormation Ressourcen angewendete Tags) und 200 für Entfernungsvorgänge.

Im folgenden Beispiel wird der **Tagname** mit dem Wert **value** und der Priorität **100** auf Ressourcen des Typs ** AWS: :Xxx: :Yyy** im Konstrukt angewendet. Es wendet das Tag nicht auf Instances an, die in einer Amazon EC2 Auto Scaling Scaling-Gruppe gestartet wurden, oder auf Ressourcen des Typs ** AWS: :Xxx: :Zzz**. (Dies sind Platzhalter für zwei beliebige, aber unterschiedliche AWS CloudFormation Ressourcentypen.)

**Example**  

```
Tags.of(myConstruct).add('tagname', 'value', {
  applyToLaunchedInstances: false,
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 100,
});
```

```
Tags.of(myConstruct).add('tagname', 'value', {
  applyToLaunchedInstances: false,
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 100
});
```

```
Tags.of(my_construct).add("tagname", "value",
    apply_to_launched_instances=False,
    include_resource_types=["AWS::Xxx::Yyy"],
    exclude_resource_types=["AWS::Xxx::Zzz"],
    priority=100)
```

```
Tags.of(myConstruct).add("tagname", "value", TagProps.builder()
                .applyToLaunchedInstances(false)
                .includeResourceTypes(Arrays.asList("AWS::Xxx::Yyy"))
                .excludeResourceTypes(Arrays.asList("AWS::Xxx::Zzz"))
                .priority(100).build());
```

```
Tags.Of(myConstruct).Add("tagname", "value", new TagProps
{
    ApplyToLaunchedInstances = false,
    IncludeResourceTypes = ["AWS::Xxx::Yyy"],
    ExcludeResourceTypes = ["AWS::Xxx::Zzz"],
    Priority = 100
});
```

```
awscdk.Tags_Of(myConstruct).Add(jsii.String("tagname"), jsii.String("value"), &awscdk.TagProps{
  ApplyToLaunchedInstances: jsii.Bool(false),
  IncludeResourceTypes:     &[]*string{jsii.String("AWS::Xxx:Yyy")},
  ExcludeResourceTypes:     &[]*string{jsii.String("AWS::Xxx:Zzz")},
  Priority:                 jsii.Number(100),
})
```

**Im folgenden Beispiel wird das Tag **tagname** mit der Priorität **200** aus Ressourcen des Typs ** AWS: :Xxx: :Yyy** im Konstrukt entfernt, aber nicht aus Ressourcen des Typs AWS: :Xxx: :Zzz.**

**Example**  

```
Tags.of(myConstruct).remove('tagname', {
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 200,
});
```

```
Tags.of(myConstruct).remove('tagname', {
  includeResourceTypes: ['AWS::Xxx::Yyy'],
  excludeResourceTypes: ['AWS::Xxx::Zzz'],
  priority: 200
});
```

```
Tags.of(my_construct).remove("tagname",
    include_resource_types=["AWS::Xxx::Yyy"],
    exclude_resource_types=["AWS::Xxx::Zzz"],
    priority=200,)
```

```
Tags.of((myConstruct).remove("tagname", TagProps.builder()
        .includeResourceTypes(Arrays.asList("AWS::Xxx::Yyy"))
        .excludeResourceTypes(Arrays.asList("AWS::Xxx::Zzz"))
        .priority(100).build());
        )
```

```
Tags.Of(myConstruct).Remove("tagname", new TagProps
{
    IncludeResourceTypes = ["AWS::Xxx::Yyy"],
    ExcludeResourceTypes = ["AWS::Xxx::Zzz"],
    Priority = 100
});
```

```
awscdk.Tags_Of(myConstruct).Remove(jsii.String("tagname"), &awscdk.TagProps{
  IncludeResourceTypes: &[]*string{jsii.String("AWS::Xxx:Yyy")},
  ExcludeResourceTypes: &[]*string{jsii.String("AWS::Xxx:Zzz")},
  Priority:             jsii.Number(200),
})
```

## Beispiel
<a name="tagging-example"></a>

Im folgenden Beispiel wird der Tag-Schlüssel **StackType**mit Wert **TheBest**zu jeder Ressource hinzugefügt, die innerhalb des Namens erstellt wurde. `Stack` `MarketingSystem` Dann entfernt es es wieder aus allen Ressourcen außer Amazon EC2 VPC-Subnetzen. Das Ergebnis ist, dass das Tag nur auf die Subnetze angewendet wurde.

**Example**  

```
import { App, Stack, Tags } from 'aws-cdk-lib';

const app = new App();
const theBestStack = new Stack(app, 'MarketingSystem');

// Add a tag to all constructs in the stack
Tags.of(theBestStack).add('StackType', 'TheBest');

// Remove the tag from all resources except subnet resources
Tags.of(theBestStack).remove('StackType', {
  excludeResourceTypes: ['AWS::EC2::Subnet']
});
```

```
const { App, Stack, Tags } = require('aws-cdk-lib');

const app = new App();
const theBestStack = new Stack(app, 'MarketingSystem');

// Add a tag to all constructs in the stack
Tags.of(theBestStack).add('StackType', 'TheBest');

// Remove the tag from all resources except subnet resources
Tags.of(theBestStack).remove('StackType', {
  excludeResourceTypes: ['AWS::EC2::Subnet']
});
```

```
from aws_cdk import App, Stack, Tags

app = App();
the_best_stack = Stack(app, 'MarketingSystem')

# Add a tag to all constructs in the stack
Tags.of(the_best_stack).add("StackType", "TheBest")

# Remove the tag from all resources except subnet resources
Tags.of(the_best_stack).remove("StackType",
    exclude_resource_types=["AWS::EC2::Subnet"])
```

```
import software.amazon.awscdk.App;
import software.amazon.awscdk.Tags;

// Add a tag to all constructs in the stack
Tags.of(theBestStack).add("StackType", "TheBest");

// Remove the tag from all resources except subnet resources
Tags.of(theBestStack).remove("StackType", TagProps.builder()
        .excludeResourceTypes(Arrays.asList("AWS::EC2::Subnet"))
        .build());
```

```
using Amazon.CDK;

var app = new App();
var theBestStack = new Stack(app, 'MarketingSystem');

// Add a tag to all constructs in the stack
Tags.Of(theBestStack).Add("StackType", "TheBest");

// Remove the tag from all resources except subnet resources
Tags.Of(theBestStack).Remove("StackType", new TagProps
{
    ExcludeResourceTypes = ["AWS::EC2::Subnet"]
});
```

```
import "github.com/aws/aws-cdk-go/awscdk/v2"
app := awscdk.NewApp(nil)
theBestStack := awscdk.NewStack(app, jsii.String("MarketingSystem"), &awscdk.StackProps{})

// Add a tag to all constructs in the stack
awscdk.Tags_Of(theBestStack).Add(jsii.String("StackType"), jsii.String("TheBest"), &awscdk.TagProps{})

// Remove the tag from all resources except subnet resources
awscdk.Tags_Of(theBestStack).Add(jsii.String("StackType"), jsii.String("TheBest"), &awscdk.TagProps{
  ExcludeResourceTypes: &[]*string{jsii.String("AWS::EC2::Subnet")},
})
```

Der folgende Code erzielt dasselbe Ergebnis. Überlegen Sie, welcher Ansatz (Inklusion oder Ausschluss) Ihre Absicht klarer macht.

**Example**  

```
Tags.of(theBestStack).add('StackType', 'TheBest',
  { includeResourceTypes: ['AWS::EC2::Subnet']});
```

```
Tags.of(theBestStack).add('StackType', 'TheBest',
  { includeResourceTypes: ['AWS::EC2::Subnet']});
```

```
Tags.of(the_best_stack).add("StackType", "TheBest",
    include_resource_types=["AWS::EC2::Subnet"])
```

```
Tags.of(theBestStack).add("StackType", "TheBest", TagProps.builder()
        .includeResourceTypes(Arrays.asList("AWS::EC2::Subnet"))
        .build());
```

```
Tags.Of(theBestStack).Add("StackType", "TheBest", new TagProps {
    IncludeResourceTypes = ["AWS::EC2::Subnet"]
});
```

```
awscdk.Tags_Of(theBestStack).Add(jsii.String("StackType"), jsii.String("TheBest"), &awscdk.TagProps{
  IncludeResourceTypes: &[]*string{jsii.String("AWS::EC2::Subnet")},
})
```

## Markieren einzelner Konstrukte
<a name="tagging-single"></a>

 `Tags.of(scope).add(key, value)`ist die Standardmethode, um Konstrukten im CDK Tags hinzuzufügen. AWS Sein Tree-Walking-Verhalten, das rekursiv alle taggierbaren Ressourcen innerhalb des angegebenen Bereichs markiert, ist fast immer das, was Sie wollen. Manchmal müssen Sie jedoch ein bestimmtes, beliebiges Konstrukt (oder mehrere Konstrukte) taggen.

Ein solcher Fall beinhaltet das Anwenden von Tags, deren Wert von einer Eigenschaft des zu markierenden Konstrukts abgeleitet wird. Der Standardansatz für Tagging wendet rekursiv denselben Schlüssel und Wert auf alle passenden Ressourcen im Bereich an. Hier könnte der Wert jedoch für jedes markierte Konstrukt unterschiedlich sein.

Tags werden mithilfe von [Aspekten](aspects.md) implementiert, und das CDK ruft die `visit()` Methode des Tags für jedes Konstrukt innerhalb des von Ihnen angegebenen `Tags.of(scope)` Bereichs auf. Wir können `Tag.visit()` direkt aufrufen, um ein Tag auf ein einzelnes Konstrukt anzuwenden.

**Example**  

```
new cdk.Tag(key, value).visit(scope);
```

```
new cdk.Tag(key, value).visit(scope);
```

```
cdk.Tag(key, value).visit(scope)
```

```
Tag.Builder.create(key, value).build().visit(scope);
```

```
new Tag(key, value).Visit(scope);
```

```
awscdk.NewTag(key, value, &awscdk.TagProps{}).Visit(scope)
```

Sie können alle Konstrukte innerhalb eines Gültigkeitsbereichs taggen, die Werte der Tags jedoch von den Eigenschaften der einzelnen Konstrukte ableiten lassen. Schreiben Sie dazu einen Aspekt und wenden Sie das Tag in der `visit()` Methode des Aussehens an, wie im vorherigen Beispiel gezeigt. Fügen Sie dann den Aspekt mit dem gewünschten Bereich hinzu`Aspects.of(scope).add(aspect)`.

Im folgenden Beispiel wird jeder Ressource in einem Stapel, der den Pfad der Ressource enthält, ein Tag zugewiesen.

**Example**  

```
class PathTagger implements cdk.IAspect {
  visit(node: IConstruct) {
    new cdk.Tag("aws-cdk-path", node.node.path).visit(node);
  }
}

stack = new MyStack(app);
cdk.Aspects.of(stack).add(new PathTagger())
```

```
class PathTagger {
  visit(node) {
    new cdk.Tag("aws-cdk-path", node.node.path).visit(node);
  }
}

stack = new MyStack(app);
cdk.Aspects.of(stack).add(new PathTagger())
```

```
@jsii.implements(cdk.IAspect)
class PathTagger:
    def visit(self, node: IConstruct):
        cdk.Tag("aws-cdk-path", node.node.path).visit(node)

stack = MyStack(app)
cdk.Aspects.of(stack).add(PathTagger())
```

```
final class PathTagger implements IAspect {
	public void visit(IConstruct node) {
		Tag.Builder.create("aws-cdk-path", node.getNode().getPath()).build().visit(node);
	}
}

stack stack = new MyStack(app);
Aspects.of(stack).add(new PathTagger());
```

```
public class PathTagger : IAspect
{
    public void Visit(IConstruct node)
    {
        new Tag("aws-cdk-path", node.Node.Path).Visit(node);
    }
}

var stack = new MyStack(app);
Aspects.Of(stack).Add(new PathTagger);
```

**Tipp**  
Die Logik der bedingten Kennzeichnung, einschließlich Prioritäten, Ressourcentypen usw., ist in die `Tag` Klasse integriert. Sie können diese Funktionen verwenden, wenn Sie Tags auf beliebige Ressourcen anwenden. Das Tag wird nicht angewendet, wenn die Bedingungen nicht erfüllt sind. Außerdem kennzeichnet die `Tag` Klasse nur Ressourcen, die mit Tags versehen werden können, sodass Sie nicht testen müssen, ob ein Konstrukt markierbar ist, bevor Sie ein Tag anwenden.

# Vermögenswerte und das AWS CDK
<a name="assets"></a>

Assets sind lokale Dateien, Verzeichnisse oder Docker-Images, die in AWS CDK-Bibliotheken und Apps gebündelt werden können. Ein Asset kann beispielsweise ein Verzeichnis sein, das den Handlercode für eine AWS Lambda-Funktion enthält. Assets können jedes Artefakt darstellen, das die App für den Betrieb benötigt.

Das folgende Tutorial-Video bietet einen umfassenden Überblick über CDK-Assets und erklärt, wie Sie sie in Ihrer Infrastruktur als Code (IaC) verwenden können.

[![AWS Videos](http://img.youtube.com/vi/https://www.youtube.com/embed/jHNtXQmkKfw?rel=0/0.jpg)](http://www.youtube.com/watch?v=https://www.youtube.com/embed/jHNtXQmkKfw?rel=0)


Sie fügen Ressourcen hinzu APIs , die durch bestimmte AWS Konstrukte verfügbar gemacht werden. Wenn Sie beispielsweise ein [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html)Konstrukt definieren, können Sie mit der [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html#code](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html#code)Eigenschaft ein [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options)(Verzeichnis) übergeben. `Function`verwendet Assets, um den Inhalt des Verzeichnisses zu bündeln und ihn für den Code der Funktion zu verwenden. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrassetdirectory-props](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrassetdirectory-props)Verwendet in ähnlicher Weise ein Docker-Image, das aus einem lokalen Verzeichnis erstellt wurde, wenn eine Amazon ECS-Aufgabendefinition definiert wird.

## Vermögenswerte im Detail
<a name="assets-details"></a>

Wenn Sie in Ihrer App auf ein Asset verweisen, enthält die [Cloud-Assembly](deploy.md#deploy-how-synth-assemblies), die aus Ihrer Anwendung synthetisiert wird, Metadateninformationen mit Anweisungen für die AWS CDK-CLI. Die Anweisungen beinhalten, wo sich das Asset auf der lokalen Festplatte befindet und welche Art von Bündelung je nach Asset-Typ durchgeführt werden soll, z. B. ein zu komprimierendes Verzeichnis (zip) oder ein zu erstellendes Docker-Image.

Das AWS CDK generiert einen Quell-Hash für Assets. Dieser kann während der Erstellung verwendet werden, um festzustellen, ob sich der Inhalt eines Assets geändert hat.

Standardmäßig erstellt das AWS CDK eine Kopie des Assets im Cloud-Assembly-Verzeichnis, das standardmäßig auf`cdk.out`, unter dem Quell-Hash steht. Auf diese Weise ist die Cloud-Assembly eigenständig. Wenn sie also zur Bereitstellung auf einen anderen Host verschoben wurde, kann sie trotzdem bereitgestellt werden. Einzelheiten finden Sie unter [Cloud-Assemblys](deploy.md#deploy-how-synth-assemblies).

Wenn das AWS CDK eine App bereitstellt, die auf Assets verweist (entweder direkt über den App-Code oder über eine Bibliothek), bereitet die AWS CDK-CLI die Assets zunächst vor und veröffentlicht sie in einem Amazon S3 S3-Bucket oder Amazon ECR-Repository. (Der S3-Bucket oder das Repository wird beim Bootstrapping erstellt.) Erst dann werden die im Stack definierten Ressourcen bereitgestellt.

In diesem Abschnitt wird das im Framework APIs verfügbare Low-Level beschrieben.

## Arten von Vermögenswerten
<a name="assets-types"></a>

Das AWS CDK unterstützt die folgenden Arten von Vermögenswerten:

Amazon S3 S3-Ressourcen  
Dies sind lokale Dateien und Verzeichnisse, die das AWS CDK auf Amazon S3 hochlädt.

Docker-Image  
Dies sind Docker-Images, die das AWS CDK auf Amazon ECR hochlädt.

Diese Asset-Typen werden in den folgenden Abschnitten erklärt.

## Amazon S3 S3-Ressourcen
<a name="assets-types-s3"></a>

Sie können lokale Dateien und Verzeichnisse als Assets definieren, und das AWS CDK packt und lädt sie über das [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html)Modul auf Amazon S3 hoch.

Das folgende Beispiel definiert ein lokales Verzeichnis-Asset und ein Datei-Asset.

**Example**  

```
import { Asset } from 'aws-cdk-lib/aws-s3-assets';

// Archived and uploaded to Amazon S3 as a .zip file
const directoryAsset = new Asset(this, "SampleZippedDirAsset", {
  path: path.join(__dirname, "sample-asset-directory")
});

// Uploaded to Amazon S3 as-is
const fileAsset = new Asset(this, 'SampleSingleFileAsset', {
  path: path.join(__dirname, 'file-asset.txt')
});
```

```
const { Asset } = require('aws-cdk-lib/aws-s3-assets');

// Archived and uploaded to Amazon S3 as a .zip file
const directoryAsset = new Asset(this, "SampleZippedDirAsset", {
  path: path.join(__dirname, "sample-asset-directory")
});

// Uploaded to Amazon S3 as-is
const fileAsset = new Asset(this, 'SampleSingleFileAsset', {
  path: path.join(__dirname, 'file-asset.txt')
});
```

```
import os.path
dirname = os.path.dirname(__file__)

from aws_cdk.aws_s3_assets import Asset

# Archived and uploaded to Amazon S3 as a .zip file
directory_asset = Asset(self, "SampleZippedDirAsset",
  path=os.path.join(dirname, "sample-asset-directory")
)

# Uploaded to Amazon S3 as-is
file_asset = Asset(self, 'SampleSingleFileAsset',
  path=os.path.join(dirname, 'file-asset.txt')
)
```

```
import java.io.File;

import software.amazon.awscdk.services.s3.assets.Asset;

// Directory where app was started
File startDir = new File(System.getProperty("user.dir"));

// Archived and uploaded to Amazon S3 as a .zip file
Asset directoryAsset = Asset.Builder.create(this, "SampleZippedDirAsset")
                .path(new File(startDir, "sample-asset-directory").toString()).build();

// Uploaded to Amazon S3 as-is
Asset fileAsset = Asset.Builder.create(this, "SampleSingleFileAsset")
                .path(new File(startDir, "file-asset.txt").toString()).build();
```

```
using System.IO;
using Amazon.CDK.AWS.S3.Assets;

// Archived and uploaded to Amazon S3 as a .zip file
var directoryAsset = new Asset(this, "SampleZippedDirAsset", new AssetProps
{
    Path = Path.Combine(Directory.GetCurrentDirectory(), "sample-asset-directory")
});

// Uploaded to Amazon S3 as-is
var fileAsset = new Asset(this, "SampleSingleFileAsset", new AssetProps
{
    Path = Path.Combine(Directory.GetCurrentDirectory(), "file-asset.txt")
});
```

```
dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

awss3assets.NewAsset(stack, jsii.String("SampleZippedDirAsset"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "sample-asset-directory")),
})

awss3assets.NewAsset(stack, jsii.String("SampleSingleFileAsset"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "file-asset.txt")),
})
```

In den meisten Fällen müssen Sie das nicht direkt APIs im `aws-s3-assets` Modul verwenden. Module, die Ressourcen unterstützen`aws-lambda`, verfügen z. B. über praktische Methoden, mit denen Sie Assets verwenden können. Für Lambda-Funktionen können Sie mit der [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Code.html#static-fromwbrassetpath-options)statischen Methode ein Verzeichnis oder eine ZIP-Datei im lokalen Dateisystem angeben.

### Beispiel für eine Lambda-Funktion
<a name="assets-types-s3-lambda"></a>

Ein häufiger Anwendungsfall ist die Erstellung von Lambda-Funktionen mit dem Handlercode als Amazon S3 S3-Asset.

Im folgenden Beispiel wird ein Amazon S3 S3-Asset verwendet, um einen Python-Handler im lokalen Verzeichnis zu definieren`handler`. Es erstellt auch eine Lambda-Funktion mit dem lokalen Verzeichnis-Asset als `code` Eigenschaft. Es folgt der Python-Code für den Handler.

```
def lambda_handler(event, context):
  message = 'Hello World!'
  return {
    'message': message
  }
```

Der Code für die AWS Haupt-CDK-App sollte wie folgt aussehen.

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Constructs } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as path from 'path';

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

    new lambda.Function(this, 'myLambdaFunction', {
      code: lambda.Code.fromAsset(path.join(__dirname, 'handler')),
      runtime: lambda.Runtime.PYTHON_3_6,
      handler: 'index.lambda_handler'
    });
  }
}
```

```
const cdk = require('aws-cdk-lib');
const lambda = require('aws-cdk-lib/aws-lambda');
const path = require('path');

class HelloAssetStack extends cdk.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    new lambda.Function(this, 'myLambdaFunction', {
      code: lambda.Code.fromAsset(path.join(__dirname, 'handler')),
      runtime: lambda.Runtime.PYTHON_3_6,
      handler: 'index.lambda_handler'
    });
  }
}

module.exports = { HelloAssetStack }
```

```
from aws_cdk import Stack
from constructs import Construct
from aws_cdk import aws_lambda as lambda_

import os.path
dirname = os.path.dirname(__file__)

class HelloAssetStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        lambda_.Function(self, 'myLambdaFunction',
            code=lambda_.Code.from_asset(os.path.join(dirname, 'handler')),
            runtime=lambda_.Runtime.PYTHON_3_6,
            handler="index.lambda_handler")
```

```
import java.io.File;

import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;

public class HelloAssetStack extends Stack {

    public HelloAssetStack(final App scope, final String id) {
        this(scope, id, null);
    }

    public HelloAssetStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        File startDir = new File(System.getProperty("user.dir"));

        Function.Builder.create(this, "myLambdaFunction")
                .code(Code.fromAsset(new File(startDir, "handler").toString()))
                .runtime(Runtime.PYTHON_3_6)
                .handler("index.lambda_handler").build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.Lambda;
using System.IO;

public class HelloAssetStack : Stack
{
    public HelloAssetStack(Construct scope, string id, StackProps props) : base(scope, id, props)
    {
        new Function(this, "myLambdaFunction", new FunctionProps
        {
            Code = Code.FromAsset(Path.Combine(Directory.GetCurrentDirectory(), "handler")),
            Runtime = Runtime.PYTHON_3_6,
            Handler = "index.lambda_handler"
        });
    }
}
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
  "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
  "github.com/aws/constructs-go/constructs/v10"
  "github.com/aws/jsii-runtime-go"
)

func HelloAssetStack(scope constructs.Construct, id string, props *HelloAssetStackProps) awscdk.Stack {
  var sprops awscdk.StackProps
  if props != nil {
    sprops = props.StackProps
  }
  stack := awscdk.NewStack(scope, id, sprops)

  dirName, err := os.Getwd()
  if err != nil {
    panic(err)
  }

  awslambda.NewFunction(stack, jsii.String("myLambdaFunction"), awslambda.FunctionProps{
    Code: awslambda.AssetCode_FromAsset(jsii.String(path.Join(dirName, "handler")), awss3assets.AssetOptions{}),
    Runtime: awslambda.Runtime_PYTHON_3_6(),
    Handler: jsii.String("index.lambda_handler"),
  })

  return stack
}
```

Die `Function` Methode verwendet Assets, um den Inhalt des Verzeichnisses zu bündeln und ihn für den Code der Funktion zu verwenden.

**Tipp**  
`.jar`Java-Dateien sind ZIP-Dateien mit einer anderen Erweiterung. Diese werden unverändert in Amazon S3 hochgeladen, aber wenn sie als Lambda-Funktion bereitgestellt werden, werden die darin enthaltenen Dateien extrahiert, was Sie möglicherweise nicht möchten. Um dies zu vermeiden, platzieren Sie die `.jar` Datei in einem Verzeichnis und geben Sie dieses Verzeichnis als Asset an.

### Beispiel für Attribute zur Bereitstellungszeit
<a name="assets-types-s3-deploy"></a>

Amazon S3 S3-Objekttypen stellen auch [Bereitstellungszeitattribute zur](resources.md#resources-attributes) Verfügung, auf die in AWS CDK-Bibliotheken und Apps verwiesen werden kann. Der AWS CDK-CLI-Befehl `cdk synth` zeigt Asset-Eigenschaften als AWS CloudFormation Parameter an.

Im folgenden Beispiel werden Bereitstellungszeitattribute verwendet, um den Speicherort eines Image-Assets als Umgebungsvariablen an eine Lambda-Funktion zu übergeben. (Die Art der Datei spielt keine Rolle; das hier verwendete PNG-Bild ist nur ein Beispiel.)

**Example**  

```
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
import * as path from 'path';

const imageAsset = new Asset(this, "SampleAsset", {
  path: path.join(__dirname, "images/my-image.png")
});

new lambda.Function(this, "myLambdaFunction", {
  code: lambda.Code.asset(path.join(__dirname, "handler")),
  runtime: lambda.Runtime.PYTHON_3_6,
  handler: "index.lambda_handler",
  environment: {
    'S3_BUCKET_NAME': imageAsset.s3BucketName,
    'S3_OBJECT_KEY': imageAsset.s3ObjectKey,
    'S3_OBJECT_URL': imageAsset.s3ObjectUrl
  }
});
```

```
const { Asset } = require('aws-cdk-lib/aws-s3-assets');
const path = require('path');

const imageAsset = new Asset(this, "SampleAsset", {
  path: path.join(__dirname, "images/my-image.png")
});

new lambda.Function(this, "myLambdaFunction", {
  code: lambda.Code.asset(path.join(__dirname, "handler")),
  runtime: lambda.Runtime.PYTHON_3_6,
  handler: "index.lambda_handler",
  environment: {
    'S3_BUCKET_NAME': imageAsset.s3BucketName,
    'S3_OBJECT_KEY': imageAsset.s3ObjectKey,
    'S3_OBJECT_URL': imageAsset.s3ObjectUrl
  }
});
```

```
import os.path

import aws_cdk.aws_lambda as lambda_
from aws_cdk.aws_s3_assets import Asset

dirname = os.path.dirname(__file__)

image_asset = Asset(self, "SampleAsset",
    path=os.path.join(dirname, "images/my-image.png"))

lambda_.Function(self, "myLambdaFunction",
    code=lambda_.Code.asset(os.path.join(dirname, "handler")),
    runtime=lambda_.Runtime.PYTHON_3_6,
    handler="index.lambda_handler",
    environment=dict(
        S3_BUCKET_NAME=image_asset.s3_bucket_name,
        S3_OBJECT_KEY=image_asset.s3_object_key,
        S3_OBJECT_URL=image_asset.s3_object_url))
```

```
import java.io.File;

import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.lambda.Function;
import software.amazon.awscdk.services.lambda.Runtime;
import software.amazon.awscdk.services.s3.assets.Asset;

public class FunctionStack extends Stack {
    public FunctionStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        File startDir = new File(System.getProperty("user.dir"));

        Asset imageAsset = Asset.Builder.create(this, "SampleAsset")
                .path(new File(startDir, "images/my-image.png").toString()).build())

        Function.Builder.create(this, "myLambdaFunction")
                .code(Code.fromAsset(new File(startDir, "handler").toString()))
                .runtime(Runtime.PYTHON_3_6)
                .handler("index.lambda_handler")
                .environment(java.util.Map.of(    // Java 9 or later
                    "S3_BUCKET_NAME", imageAsset.getS3BucketName(),
                    "S3_OBJECT_KEY", imageAsset.getS3ObjectKey(),
                    "S3_OBJECT_URL", imageAsset.getS3ObjectUrl()))
                .build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.Lambda;
using Amazon.CDK.AWS.S3.Assets;
using System.IO;
using System.Collections.Generic;

var imageAsset = new Asset(this, "SampleAsset", new AssetProps
{
    Path = Path.Combine(Directory.GetCurrentDirectory(), @"images\my-image.png")
});

new Function(this, "myLambdaFunction", new FunctionProps
{
    Code = Code.FromAsset(Path.Combine(Directory.GetCurrentDirectory(), "handler")),
    Runtime = Runtime.PYTHON_3_6,
    Handler = "index.lambda_handler",
    Environment = new Dictionarystring, string
    {
        ["S3_BUCKET_NAME"] = imageAsset.S3BucketName,
        ["S3_OBJECT_KEY"] = imageAsset.S3ObjectKey,
        ["S3_OBJECT_URL"] = imageAsset.S3ObjectUrl
    }
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awslambda"
  "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

imageAsset := awss3assets.NewAsset(stack, jsii.String("SampleAsset"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "images/my-image.png")),
})

awslambda.NewFunction(stack, jsii.String("myLambdaFunction"), awslambda.FunctionProps{
  Code: awslambda.AssetCode_FromAsset(jsii.String(path.Join(dirName, "handler"))),
  Runtime: awslambda.Runtime_PYTHON_3_6(),
  Handler: jsii.String("index.lambda_handler"),
  Environment: map[string]*string{
    "S3_BUCKET_NAME": imageAsset.S3BucketName(),
    "S3_OBJECT_KEY": imageAsset.S3ObjectKey(),
    "S3_URL": imageAsset.S3ObjectUrl(),
  },
})
```

### Berechtigungen
<a name="assets-types-s3-permissions"></a>

Wenn Sie Amazon S3 S3-Assets direkt über das [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets-readme.html)Modul, die IAM-Rollen, -Benutzer oder -Gruppen verwenden und Sie Assets während der Laufzeit lesen müssen, gewähren Sie diesen Assets über die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets.Asset.html#grantwbrreadgrantee](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3_assets.Asset.html#grantwbrreadgrantee)Methode IAM-Berechtigungen.

Das folgende Beispiel gewährt einer IAM-Gruppe Leseberechtigungen für ein Datei-Asset.

**Example**  

```
import { Asset } from 'aws-cdk-lib/aws-s3-assets';
import * as path from 'path';

const asset = new Asset(this, 'MyFile', {
  path: path.join(__dirname, 'my-image.png')
});

const group = new iam.Group(this, 'MyUserGroup');
asset.grantRead(group);
```

```
const { Asset } = require('aws-cdk-lib/aws-s3-assets');
const path = require('path');

const asset = new Asset(this, 'MyFile', {
  path: path.join(__dirname, 'my-image.png')
});

const group = new iam.Group(this, 'MyUserGroup');
asset.grantRead(group);
```

```
from aws_cdk.aws_s3_assets import Asset
import aws_cdk.aws_iam as iam

import os.path
dirname = os.path.dirname(__file__)

        asset = Asset(self, "MyFile",
            path=os.path.join(dirname, "my-image.png"))

        group = iam.Group(self, "MyUserGroup")
        asset.grant_read(group)
```

```
import java.io.File;

import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.iam.Group;
import software.amazon.awscdk.services.s3.assets.Asset;

public class GrantStack extends Stack {
    public GrantStack(final App scope, final String id, final StackProps props) {
        super(scope, id, props);

        File startDir = new File(System.getProperty("user.dir"));

        Asset asset = Asset.Builder.create(this, "SampleAsset")
                .path(new File(startDir, "images/my-image.png").toString()).build();

        Group group = new Group(this, "MyUserGroup");
        asset.grantRead(group);   }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.IAM;
using Amazon.CDK.AWS.S3.Assets;
using System.IO;

var asset = new Asset(this, "MyFile", new AssetProps {
    Path = Path.Combine(Path.Combine(Directory.GetCurrentDirectory(), @"images\my-image.png"))
});

var group = new Group(this, "MyUserGroup");
asset.GrantRead(group);
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsiam"
  "github.com/aws/aws-cdk-go/awscdk/v2/awss3assets"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awss3assets.NewAsset(stack, jsii.String("MyFile"), awss3assets.AssetProps{
  Path: jsii.String(path.Join(dirName, "my-image.png")),
})

group := awsiam.NewGroup(stack, jsii.String("MyUserGroup"), awsiam.GroupProps{})

asset.GrantRead(group)
```

## Docker-Image-Ressourcen
<a name="assets-types-docker"></a>

Das AWS CDK unterstützt das Bündeln lokaler Docker-Images als Assets über das Modul. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr_assets-readme.html)

Das folgende Beispiel definiert ein Docker-Image, das lokal erstellt und an Amazon ECR übertragen wird. Images werden aus einem lokalen Docker-Kontextverzeichnis (mit einer Docker-Datei) erstellt und über die AWS CDK-CLI oder die CI/CD-Pipeline Ihrer App auf Amazon ECR hochgeladen. Die Bilder können natürlich in Ihrer CDK-App referenziert werden. AWS 

**Example**  

```
import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});
```

```
const { DockerImageAsset } = require('aws-cdk-lib/aws-ecr-assets');

const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});
```

```
from aws_cdk.aws_ecr_assets import DockerImageAsset

import os.path
dirname = os.path.dirname(__file__)

asset = DockerImageAsset(self, 'MyBuildImage',
    directory=os.path.join(dirname, 'my-image'))
```

```
import software.amazon.awscdk.services.ecr.assets.DockerImageAsset;

File startDir = new File(System.getProperty("user.dir"));

DockerImageAsset asset = DockerImageAsset.Builder.create(this, "MyBuildImage")
            .directory(new File(startDir, "my-image").toString()).build();
```

```
using System.IO;
using Amazon.CDK.AWS.ECR.Assets;

var asset = new DockerImageAsset(this, "MyBuildImage", new DockerImageAssetProps
{
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "my-image")
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecrassets"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyBuildImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "my-image")),
})
```

Das `my-image` Verzeichnis muss ein Dockerfile enthalten. Die AWS CDK-CLI erstellt daraus ein Docker-Image`my-image`, überträgt es in ein Amazon ECR-Repository und gibt den Namen des Repositorys als AWS CloudFormation Parameter für Ihren Stack an. Docker-Image-Asset-Typen stellen [Attribute zur Bereitstellungszeit](resources.md#resources-attributes) bereit, auf die in CDK-Bibliotheken und Apps verwiesen werden kann. AWS Der AWS CDK-CLI-Befehl `cdk synth` zeigt Asset-Eigenschaften als AWS CloudFormation Parameter an.

### Beispiel für eine Amazon ECS-Aufgabendefinition
<a name="assets-types-docker-ecs"></a>

Ein häufiger Anwendungsfall ist die Erstellung eines Amazon ECS [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.TaskDefinition.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.TaskDefinition.html)zum Ausführen von Docker-Containern. Das folgende Beispiel gibt den Speicherort eines Docker-Image-Assets an, das das AWS CDK lokal erstellt und an Amazon ECR überträgt.

**Example**  

```
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as ecr_assets from 'aws-cdk-lib/aws-ecr-assets';
import * as path from 'path';

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

const asset = new ecr_assets.DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromDockerImageAsset(asset)
});
```

```
const ecs = require('aws-cdk-lib/aws-ecs');
const ecr_assets = require('aws-cdk-lib/aws-ecr-assets');
const path = require('path');

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

const asset = new ecr_assets.DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image')
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromDockerImageAsset(asset)
});
```

```
import aws_cdk.aws_ecs as ecs
import aws_cdk.aws_ecr_assets as ecr_assets

import os.path
dirname = os.path.dirname(__file__)

task_definition = ecs.FargateTaskDefinition(self, "TaskDef",
    memory_limit_mib=1024,
    cpu=512)

asset = ecr_assets.DockerImageAsset(self, 'MyBuildImage',
    directory=os.path.join(dirname, 'my-image'))

task_definition.add_container("my-other-container",
    image=ecs.ContainerImage.from_docker_image_asset(asset))
```

```
import java.io.File;

import software.amazon.awscdk.services.ecs.FargateTaskDefinition;
import software.amazon.awscdk.services.ecs.ContainerDefinitionOptions;
import software.amazon.awscdk.services.ecs.ContainerImage;

import software.amazon.awscdk.services.ecr.assets.DockerImageAsset;

File startDir = new File(System.getProperty("user.dir"));

FargateTaskDefinition taskDefinition = FargateTaskDefinition.Builder.create(
        this, "TaskDef").memoryLimitMiB(1024).cpu(512).build();

DockerImageAsset asset = DockerImageAsset.Builder.create(this, "MyBuildImage")
            .directory(new File(startDir, "my-image").toString()).build();

taskDefinition.addContainer("my-other-container",
        ContainerDefinitionOptions.builder()
            .image(ContainerImage.fromDockerImageAsset(asset))
            .build();
)
```

```
using System.IO;
using Amazon.CDK.AWS.ECS;
using Amazon.CDK.AWS.Ecr.Assets;

var taskDefinition = new FargateTaskDefinition(this, "TaskDef", new FargateTaskDefinitionProps
{
    MemoryLimitMiB = 1024,
    Cpu = 512
});

var asset = new DockerImageAsset(this, "MyBuildImage", new DockerImageAssetProps
{
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "my-image")
});

taskDefinition.AddContainer("my-other-container", new ContainerDefinitionOptions
{
    Image = ContainerImage.FromDockerImageAsset(asset)
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecrassets"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

taskDefinition := awsecs.NewTaskDefinition(stack, jsii.String("TaskDef"), awsecs.TaskDefinitionProps{
  MemoryMiB: jsii.String("1024"),
  Cpu: jsii.String("512"),
})

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyBuildImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "my-image")),
})

taskDefinition.AddContainer(jsii.String("MyOtherContainer"), awsecs.ContainerDefinitionOptions{
  Image: awsecs.ContainerImage_FromDockerImageAsset(asset),
})
```

### Beispiel für Attribute zur Bereitstellungszeit
<a name="assets-types-docker-deploy"></a>

Das folgende Beispiel zeigt, wie Sie die Bereitstellungszeitattribute verwenden `repository` und `imageUri` eine Amazon ECS-Aufgabendefinition mit dem Starttyp AWS Fargate erstellen. Beachten Sie, dass für die Amazon ECR-Repo-Suche das Tag des Bilds und nicht dessen URI erforderlich ist. Daher schneiden wir es vom Ende der URI des Assets ab.

**Example**  

```
import * as ecs from 'aws-cdk-lib/aws-ecs';
import * as path from 'path';
import { DockerImageAsset } from 'aws-cdk-lib/aws-ecr-assets';

const asset = new DockerImageAsset(this, 'my-image', {
  directory: path.join(__dirname, "..", "demo-image")
});

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromEcrRepository(asset.repository, asset.imageUri.split(":").pop())
});
```

```
const ecs = require('aws-cdk-lib/aws-ecs');
const path = require('path');
const { DockerImageAsset } = require('aws-cdk-lib/aws-ecr-assets');

const asset = new DockerImageAsset(this, 'my-image', {
  directory: path.join(__dirname, "..", "demo-image")
});

const taskDefinition = new ecs.FargateTaskDefinition(this, "TaskDef", {
  memoryLimitMiB: 1024,
  cpu: 512
});

taskDefinition.addContainer("my-other-container", {
  image: ecs.ContainerImage.fromEcrRepository(asset.repository, asset.imageUri.split(":").pop())
});
```

```
import aws_cdk.aws_ecs as ecs
from aws_cdk.aws_ecr_assets import DockerImageAsset

import os.path
dirname = os.path.dirname(__file__)

asset = DockerImageAsset(self, 'my-image',
    directory=os.path.join(dirname, "..", "demo-image"))

task_definition = ecs.FargateTaskDefinition(self, "TaskDef",
    memory_limit_mib=1024, cpu=512)

task_definition.add_container("my-other-container",
    image=ecs.ContainerImage.from_ecr_repository(
        asset.repository, asset.image_uri.rpartition(":")[-1]))
```

```
import java.io.File;

import software.amazon.awscdk.services.ecr.assets.DockerImageAsset;

import software.amazon.awscdk.services.ecs.FargateTaskDefinition;
import software.amazon.awscdk.services.ecs.ContainerDefinitionOptions;
import software.amazon.awscdk.services.ecs.ContainerImage;

File startDir = new File(System.getProperty("user.dir"));

DockerImageAsset asset = DockerImageAsset.Builder.create(this, "my-image")
            .directory(new File(startDir, "demo-image").toString()).build();

FargateTaskDefinition taskDefinition = FargateTaskDefinition.Builder.create(
        this, "TaskDef").memoryLimitMiB(1024).cpu(512).build();

// extract the tag from the asset's image URI for use in ECR repo lookup
String imageUri = asset.getImageUri();
String imageTag = imageUri.substring(imageUri.lastIndexOf(":") + 1);

taskDefinition.addContainer("my-other-container",
        ContainerDefinitionOptions.builder().image(ContainerImage.fromEcrRepository(
                asset.getRepository(), imageTag)).build());
```

```
using System.IO;
using Amazon.CDK.AWS.ECS;
using Amazon.CDK.AWS.ECR.Assets;

var asset = new DockerImageAsset(this, "my-image", new DockerImageAssetProps {
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "demo-image")
});

var taskDefinition = new FargateTaskDefinition(this, "TaskDef", new FargateTaskDefinitionProps
{
    MemoryLimitMiB = 1024,
    Cpu = 512
});

taskDefinition.AddContainer("my-other-container", new ContainerDefinitionOptions
{
    Image = ContainerImage.FromEcrRepository(asset.Repository, asset.ImageUri.Split(":").Last())
});
```

```
import (
  "os"
  "path"

  "github.com/aws/aws-cdk-go/awscdk/v2"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecrassets"
  "github.com/aws/aws-cdk-go/awscdk/v2/awsecs"
)

dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "demo-image")),
})

taskDefinition := awsecs.NewFargateTaskDefinition(stack, jsii.String("TaskDef"), awsecs.FargateTaskDefinitionProps{
  MemoryLimitMiB: jsii.Number(1024),
  Cpu: jsii.Number(512),
})

taskDefinition.AddContainer(jsii.String("MyOtherContainer"), awsecs.ContainerDefinitionOptions{
  Image: awsecs.ContainerImage_FromEcrRepository(asset.Repository(), asset.ImageTag()),
})
```

### Beispiel für die Erstellung von Argumenten
<a name="assets-types-docker-build"></a>

Sie können benutzerdefinierte Build-Argumente für den Docker-Build-Schritt über die Eigenschaftsoption `buildArgs` (Python:`build_args`) angeben, wenn die AWS CDK-CLI das Image während der Bereitstellung erstellt.

**Example**  

```
const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image'),
  buildArgs: {
    HTTP_PROXY: 'http://10.20.30.2:1234'
  }
});
```

```
const asset = new DockerImageAsset(this, 'MyBuildImage', {
  directory: path.join(__dirname, 'my-image'),
  buildArgs: {
    HTTP_PROXY: 'http://10.20.30.2:1234'
  }
});
```

```
asset = DockerImageAsset(self, "MyBuildImage",
    directory=os.path.join(dirname, "my-image"),
    build_args=dict(HTTP_PROXY="http://10.20.30.2:1234"))
```

```
DockerImageAsset asset = DockerImageAsset.Builder.create(this, "my-image"),
            .directory(new File(startDir, "my-image").toString())
            .buildArgs(java.util.Map.of(    // Java 9 or later
                "HTTP_PROXY", "http://10.20.30.2:1234"))
            .build();
```

```
var asset = new DockerImageAsset(this, "MyBuildImage", new DockerImageAssetProps {
    Directory = Path.Combine(Directory.GetCurrentDirectory(), "my-image"),
    BuildArgs = new Dictionarystring, string
    {
        ["HTTP_PROXY"] = "http://10.20.30.2:1234"
    }
});
```

```
dirName, err := os.Getwd()
if err != nil {
  panic(err)
}

asset := awsecrassets.NewDockerImageAsset(stack, jsii.String("MyBuildImage"), awsecrassets.DockerImageAssetProps{
  Directory: jsii.String(path.Join(dirName, "my-image")),
  BuildArgs: map[string]*string{
    "HTTP_PROXY": jsii.String("http://10.20.30.2:1234"),
  },
})
```

### Berechtigungen
<a name="assets-types-docker-permissions"></a>

Wenn Sie ein Modul verwenden, das Docker-Image-Assets unterstützt, z. B. verwaltet das AWS CDK die Berechtigungen für Sie [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs-readme.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs-readme.html), wenn Sie Assets direkt oder über [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrecrwbrrepositoryrepository-tag](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecs.ContainerImage.html#static-fromwbrecrwbrrepositoryrepository-tag)(Python:`from_ecr_repository`) verwenden. Wenn Sie Docker-Image-Assets direkt verwenden, stellen Sie sicher, dass der Principal, der die Daten verwendet, über die Rechte zum Abrufen des Images verfügt.

In den meisten Fällen sollten Sie [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#grantwbrpullgrantee](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#grantwbrpullgrantee)method (Python:`grant_pull`) verwenden. Dadurch wird die IAM-Richtlinie des Principals geändert, sodass er Bilder aus diesem Repository abrufen kann. Wenn sich der Principal, der das Image abruft, nicht in demselben Konto befindet oder wenn es sich um einen AWS Dienst handelt, der keine Rolle in Ihrem Konto einnimmt (z. B. AWS CodeBuild), müssen Sie Pull-Berechtigungen für die Ressourcenrichtlinie und nicht für die Richtlinie des Prinzipals gewähren. Verwenden Sie die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#addwbrtowbrresourcewbrpolicystatement](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ecr.Repository.html#addwbrtowbrresourcewbrpolicystatement)Methode (Python:`add_to_resource_policy`), um die entsprechenden Prinzipalberechtigungen zu gewähren.

## AWS CloudFormation Metadaten der Ressource
<a name="assets-cfn"></a>

**Anmerkung**  
Dieser Abschnitt ist nur für Konstruktautoren relevant. In bestimmten Situationen müssen Tools wissen, dass eine bestimmte CFN-Ressource ein lokales Asset verwendet. Sie können beispielsweise die AWS SAM-CLI verwenden, um Lambda-Funktionen lokal zu Debugging-Zwecken aufzurufen. Einzelheiten finden Sie unter [AWS SAM-Integration](tools.md#sam).

Um solche Anwendungsfälle zu ermöglichen, greifen externe Tools auf eine Reihe von Metadateneinträgen zu AWS CloudFormation Ressourcen zurück:
+  `aws:asset:path`— Verweist auf den lokalen Pfad des Assets.
+  `aws:asset:property`— Der Name der Ressourceneigenschaft, in der das Asset verwendet wird.

Mithilfe dieser beiden Metadateneinträge können Tools erkennen, ob Ressourcen von einer bestimmten Ressource verwendet werden, und erweiterte lokale Benutzererfahrungen ermöglichen.

Verwenden Sie die Methode `asset.addResourceMetadata` (Python:`add_resource_metadata`), um diese Metadateneinträge zu einer Ressource hinzuzufügen.

# Genehmigungen und das AWS CDK
<a name="permissions"></a>

Die AWS Construct Library verwendet einige gängige, weit verbreitete Idiome zur Verwaltung von Zugriffen und Berechtigungen. Das IAM-Modul bietet Ihnen die Tools, die Sie zur Verwendung dieser Redewendungen benötigen.

 AWS CDK verwendet, AWS CloudFormation um Änderungen bereitzustellen. An jeder Bereitstellung ist ein Akteur beteiligt (entweder ein Entwickler oder ein automatisiertes System), der die AWS CloudFormation Bereitstellung startet. Dabei nimmt der Akteur eine oder mehrere IAM-Identitäten (Benutzer oder Rollen) an und übergibt optional eine Rolle an. AWS CloudFormation

Wenn Sie AWS IAM Identity Center verwenden, um sich als Benutzer zu authentifizieren, stellt der Single Sign-On-Anbieter kurzlebige Sitzungsanmeldedaten bereit, die Sie berechtigen, als vordefinierte IAM-Rolle zu agieren. *Informationen dazu, wie das AWS CDK AWS Anmeldeinformationen aus der IAM Identity Center-Authentifizierung erhält, finden Sie unter Grundlegendes zur IAM Identity Center-Authentifizierung im Referenzhandbuch und im [Tools-Referenzhandbuch](https://docs.aws.amazon.com/sdkref/latest/guide/understanding-sso.html). AWS SDKs *

## Prinzipale
<a name="permissions-principals"></a>

Ein IAM-Prinzipal ist eine authentifizierte AWS Entität, die einen Benutzer, einen Dienst oder eine Anwendung darstellt, die anrufen kann. AWS APIs Die AWS Construct-Bibliothek unterstützt die Angabe von Prinzipalen auf verschiedene flexible Weise, um ihnen Zugriff auf Ihre Ressourcen zu gewähren. AWS 

In Sicherheitskontexten bezieht sich der Begriff „Principal“ speziell auf authentifizierte Entitäten wie Benutzer. Objekte wie Gruppen und Rollen *repräsentieren* keine Benutzer (und andere authentifizierte Entitäten), sondern *identifizieren* sie indirekt, um Berechtigungen zu gewähren.

Wenn Sie beispielsweise eine IAM-Gruppe erstellen, können Sie der Gruppe (und damit ihren Mitgliedern) Schreibzugriff auf eine Amazon RDS-Tabelle gewähren. Die Gruppe selbst ist jedoch kein Principal, da sie keine einzelne Entität darstellt (Sie können sich auch nicht bei einer Gruppe anmelden).

In der IAM-Bibliothek des CDK implementieren Klassen, die Prinzipale direkt oder indirekt identifizieren, die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IPrincipal.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IPrincipal.html)Schnittstelle, sodass diese Objekte synonym in Zugriffsrichtlinien verwendet werden können. Allerdings sind nicht alle von ihnen Prinzipale im Sinne der Sicherheit. Zu diesen Objekten gehören:

1. IAM-Ressourcen wie [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html), und [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html) 

1. Dienstprinzipale () `new iam.[ServicePrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ServicePrincipal.html)('service.amazonaws.com')`

1. Föderierte Prinzipale () `new iam.[FederatedPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.FederatedPrincipal.html)('cognito-identity.amazonaws.com')`

1. Kontoprinzipale () `new iam.[AccountPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.AccountPrincipal.html)('0123456789012')`

1. Kanonische Benutzerprinzipale () `new iam.[CanonicalUserPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.CanonicalUserPrincipal.html)('79a59d[…​]7ef2be')`

1.  AWS Leiter der Organizations () `new iam.[OrganizationPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.OrganizationPrincipal.html)('org-id')`

1. Beliebige ARN-Prinzipale () `new iam.[ArnPrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ArnPrincipal.html)(res.arn)`

1. Und `iam.[CompositePrincipal](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.CompositePrincipal.html)(principal1, principal2, …​)` um mehreren Prinzipalen zu vertrauen

## Gewährungen
<a name="permissions-grants"></a>

Viele Konstrukte stellen Ressourcen dar, auf die zugegriffen werden kann, z. B. ein Amazon S3 S3-Bucket oder eine Amazon DynamoDB-Tabelle. Für diese können Sie einer anderen Entität Zugriff gewähren. Je nach Konstrukt gibt es zwei Möglichkeiten, dies zu tun: mithilfe der entsprechenden Grants-Klasse (z. B. `BucketGrants` für Amazon S3 S3-Buckets) oder mithilfe von Methoden im Konstrukt selbst, deren Namen mit **grant** beginnen. Ersteres wird bevorzugt, da sie verwendet werden können, um auf dieselbe Weise Zugriff auf L1- und L2-Ressourcen zu gewähren. Um eine Instanz einer Grants-Klasse zu erstellen, verwenden Sie deren Factory-Methode:

**Example**  

```
BucketGrants.fromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.fromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.from_bucket(bucket) # bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.fromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

```
BucketGrants.FromBucket(bucket); // bucket can be either a Bucket (L2) or a CfnBucket (L1)
```

Grants-Klassen bieten Methoden, um spezifische Berechtigungen für den Zugriff auf ihre Ressource zu erteilen. `BucketGrants`Hat beispielsweise Methoden `read` und `readWrite` (Python:`read`,`read_write`), um das Lesen bzw. read/write den Zugriff von einer Entität auf den Bucket zu ermöglichen. Die Entität muss nicht genau wissen, welche Amazon S3 S3-IAM-Berechtigungen für die Ausführung dieser Operationen erforderlich sind.

Das erste Argument der Methoden in einer Grants-Klasse (oder der **Grant-Methoden** in den Ressourcen selbst) ist immer vom Typ [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IGrantable.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.IGrantable.html). Diese Schnittstelle steht für Entitäten, denen Berechtigungen erteilt werden können. Das heißt, sie stellt Ressourcen mit Rollen dar, z. B. die IAM-Objekte [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html), und [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html).

Anderen Entitäten können ebenfalls Berechtigungen erteilt werden. Später in diesem Thema zeigen wir beispielsweise, wie Sie einem CodeBuild Projekt Zugriff auf einen Amazon S3 S3-Bucket gewähren. Im Allgemeinen wird die zugehörige Rolle über eine `role` Eigenschaft der Entität abgerufen, der Zugriff gewährt wird.

Ressourcen, die Ausführungsrollen verwenden, wie z. B. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda.Function.html), implementieren ebenfalls`IGrantable`, sodass Sie ihnen direkt Zugriff gewähren können, anstatt ihnen Zugriff auf ihre Rolle zu gewähren. Wenn `bucket` es sich beispielsweise um einen Amazon S3 S3-Bucket und um eine Lambda-Funktion `function` handelt, gewährt der folgende Code der Funktion Lesezugriff auf den Bucket.

Der Einfachheit halber bieten L2-Konstrukte auch eine `grants` Eigenschaft, die eine Instanz der entsprechenden Grants-Klasse zurückgibt.

**Example**  

```
bucket.grants.read(function);
```

```
bucket.grants.read(function);
```

```
bucket.grants.read(function)
```

```
bucket.getGrants().read(function);
```

```
bucket.Grants.Read(function);
```

Manchmal müssen Berechtigungen angewendet werden, während Ihr Stack bereitgestellt wird. Ein solcher Fall ist, wenn Sie einer AWS CloudFormation benutzerdefinierten Ressource Zugriff auf eine andere Ressource gewähren. Die benutzerdefinierte Ressource wird während der Bereitstellung aufgerufen, daher muss sie zum Zeitpunkt der Bereitstellung über die angegebenen Berechtigungen verfügen.

Ein anderer Fall ist, wenn ein Dienst überprüft, ob für die Rolle, die Sie ihm übergeben, die richtigen Richtlinien angewendet wurden. (Einige AWS Dienste tun dies, um sicherzustellen, dass Sie nicht vergessen haben, die Richtlinien festzulegen.) In diesen Fällen schlägt die Bereitstellung möglicherweise fehl, wenn die Berechtigungen zu spät angewendet werden.

Um zu erzwingen, dass die Berechtigungen des Grants angewendet werden, bevor eine weitere Ressource erstellt wird, können Sie eine Abhängigkeit vom Grant selbst hinzufügen, wie hier gezeigt. Obwohl der Rückgabewert von Grant-Methoden üblicherweise verworfen wird, gibt jede Grant-Methode tatsächlich ein `iam.Grant` Objekt zurück.

**Example**  

```
const grant = bucket.grants.read(lambda);
const custom = new CustomResource(...);
custom.node.addDependency(grant);
```

```
const grant = bucket.grants.read(lambda);
const custom = new CustomResource(...);
custom.node.addDependency(grant);
```

```
grant = bucket.grants.read(function)
custom = CustomResource(...)
custom.node.add_dependency(grant)
```

```
Grant grant = bucket.getGrants().read(function);
CustomResource custom = new CustomResource(...);
custom.node.addDependency(grant);
```

```
var grant = bucket.Grants.Read(function);
var custom = new CustomResource(...);
custom.node.AddDependency(grant);
```

## Rollen
<a name="permissions-roles"></a>

Das IAM-Paket enthält ein [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html)Konstrukt, das IAM-Rollen repräsentiert. Der folgende Code erstellt eine neue Rolle, die dem EC2 Amazon-Service vertraut.

**Example**  

```
import * as iam from 'aws-cdk-lib/aws-iam';

const role = new iam.Role(this, 'Role', {
  assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),   // required
});
```

```
const iam = require('aws-cdk-lib/aws-iam');

const role = new iam.Role(this, 'Role', {
  assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com')   // required
});
```

```
import aws_cdk.aws_iam as iam

role = iam.Role(self, "Role",
          assumed_by=iam.ServicePrincipal("ec2.amazonaws.com")) # required
```

```
import software.amazon.awscdk.services.iam.Role;
import software.amazon.awscdk.services.iam.ServicePrincipal;

Role role = Role.Builder.create(this, "Role")
        .assumedBy(new ServicePrincipal("ec2.amazonaws.com")).build();
```

```
using Amazon.CDK.AWS.IAM;

var role = new Role(this, "Role", new RoleProps
{
    AssumedBy = new ServicePrincipal("ec2.amazonaws.com"),   // required
});
```

Sie können einer Rolle Berechtigungen hinzufügen, indem Sie die [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement)Methode der Rolle (Python:`add_to_policy`) aufrufen und eine übergeben, [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html)die die hinzuzufügende Regel definiert. Die Anweisung wird der Standardrichtlinie der Rolle hinzugefügt. Wenn keine Anweisung vorhanden ist, wird eine erstellt.

Das folgende Beispiel fügt der Rolle für die Aktionen `ec2:SomeAction` und für die Ressourcen `bucket` und `s3:AnotherAction` `otherRole` (Python:`other_role`) eine `Deny` Richtlinienanweisung hinzu, unter der Bedingung, dass der autorisierte Dienst autorisiert ist AWS CodeBuild.

**Example**  

```
role.addToPolicy(new iam.PolicyStatement({
  effect: iam.Effect.DENY,
  resources: [bucket.bucketArn, otherRole.roleArn],
  actions: ['ec2:SomeAction', 's3:AnotherAction'],
  conditions: {StringEquals: {
    'ec2:AuthorizedService': 'codebuild.amazonaws.com',
}}}));
```

```
role.addToPolicy(new iam.PolicyStatement({
  effect: iam.Effect.DENY,
  resources: [bucket.bucketArn, otherRole.roleArn],
  actions: ['ec2:SomeAction', 's3:AnotherAction'],
  conditions: {StringEquals: {
    'ec2:AuthorizedService': 'codebuild.amazonaws.com'
}}}));
```

```
role.add_to_policy(iam.PolicyStatement(
    effect=iam.Effect.DENY,
    resources=[bucket.bucket_arn, other_role.role_arn],
    actions=["ec2:SomeAction", "s3:AnotherAction"],
    conditions={"StringEquals": {
        "ec2:AuthorizedService": "codebuild.amazonaws.com"}}
))
```

```
role.addToPolicy(PolicyStatement.Builder.create()
        .effect(Effect.DENY)
        .resources(Arrays.asList(bucket.getBucketArn(), otherRole.getRoleArn()))
        .actions(Arrays.asList("ec2:SomeAction", "s3:AnotherAction"))
        .conditions(java.util.Map.of(    // Map.of requires Java 9 or later
            "StringEquals", java.util.Map.of(
                "ec2:AuthorizedService", "codebuild.amazonaws.com")))
        .build());
```

```
role.AddToPolicy(new PolicyStatement(new PolicyStatementProps
{
    Effect = Effect.DENY,
    Resources = new string[] { bucket.BucketArn, otherRole.RoleArn },
    Actions = new string[] { "ec2:SomeAction", "s3:AnotherAction" },
    Conditions = new Dictionary<string, object>
    {
        ["StringEquals"] = new Dictionary<string, string>
        {
            ["ec2:AuthorizedService"] = "codebuild.amazonaws.com"
        }
    }
}));
```

Im vorherigen Beispiel haben wir eine neue [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html)Inline mit dem [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#addwbrtowbrpolicystatement)(Python:`add_to_policy`) -Aufruf erstellt. Sie können auch eine bestehende oder eine von Ihnen geänderte Grundsatzerklärung übergeben. Das [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html)Objekt verfügt über [zahlreiche Methoden](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html#methods) zum Hinzufügen von Prinzipalen, Ressourcen, Bedingungen und Aktionen.

Wenn Sie ein Konstrukt verwenden, für dessen korrekte Funktion eine Rolle erforderlich ist, können Sie einen der folgenden Schritte ausführen:
+ Übergeben Sie eine vorhandene Rolle, wenn Sie das Konstruktobjekt instanziieren.
+ Lassen Sie das Konstrukt eine neue Rolle für Sie erstellen und vertrauen Sie dabei dem entsprechenden Dienstprinzipal. Im folgenden Beispiel wird ein solches Konstrukt verwendet: ein CodeBuild Projekt.

**Example**  

```
import * as codebuild from 'aws-cdk-lib/aws-codebuild';

// imagine roleOrUndefined is a function that might return a Role object
// under some conditions, and undefined under other conditions
const someRole: iam.IRole | undefined = roleOrUndefined();

const project = new codebuild.Project(this, 'Project', {
  // if someRole is undefined, the Project creates a new default role,
  // trusting the codebuild.amazonaws.com service principal
  role: someRole,
});
```

```
const codebuild = require('aws-cdk-lib/aws-codebuild');

// imagine roleOrUndefined is a function that might return a Role object
// under some conditions, and undefined under other conditions
const someRole = roleOrUndefined();

const project = new codebuild.Project(this, 'Project', {
  // if someRole is undefined, the Project creates a new default role,
  // trusting the codebuild.amazonaws.com service principal
  role: someRole
});
```

```
import aws_cdk.aws_codebuild as codebuild

# imagine role_or_none is a function that might return a Role object
# under some conditions, and None under other conditions
some_role = role_or_none();

project = codebuild.Project(self, "Project",
# if role is None, the Project creates a new default role,
# trusting the codebuild.amazonaws.com service principal
role=some_role)
```

```
import software.amazon.awscdk.services.iam.Role;
import software.amazon.awscdk.services.codebuild.Project;

// imagine roleOrNull is a function that might return a Role object
// under some conditions, and null under other conditions
Role someRole = roleOrNull();

// if someRole is null, the Project creates a new default role,
// trusting the codebuild.amazonaws.com service principal
Project project = Project.Builder.create(this, "Project")
        .role(someRole).build();
```

```
using Amazon.CDK.AWS.CodeBuild;

// imagine roleOrNull is a function that might return a Role object
// under some conditions, and null under other conditions
var someRole = roleOrNull();

// if someRole is null, the Project creates a new default role,
// trusting the codebuild.amazonaws.com service principal
var project = new Project(this, "Project", new ProjectProps
{
    Role = someRole
});
```

Sobald das Objekt erstellt wurde, ist die Rolle (unabhängig davon, ob die übergebene Rolle oder die vom Konstrukt erstellte Standardrolle) als Eigenschaft verfügbar`role`. Diese Eigenschaft ist jedoch nicht für externe Ressourcen verfügbar. Daher haben diese Konstrukte eine `addToRolePolicy` (Python:`add_to_role_policy`) -Methode.

Die Methode tut nichts, wenn das Konstrukt eine externe Ressource ist, und ruft andernfalls die `addToPolicy` (Python:`add_to_policy`) -Methode der `role` Eigenschaft auf. Das erspart Ihnen die Mühe, den undefinierten Fall explizit zu behandeln.

Das folgende Beispiel zeigt:

**Example**  

```
// project is imported into the CDK application
const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName');

// project is imported, so project.role is undefined, and this call has no effect
project.addToRolePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,   // ... and so on defining the policy
}));
```

```
// project is imported into the CDK application
const project = codebuild.Project.fromProjectName(this, 'Project', 'ProjectName');

// project is imported, so project.role is undefined, and this call has no effect
project.addToRolePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW   // ... and so on defining the policy
}));
```

```
# project is imported into the CDK application
project = codebuild.Project.from_project_name(self, 'Project', 'ProjectName')

# project is imported, so project.role is undefined, and this call has no effect
project.add_to_role_policy(iam.PolicyStatement(
  effect=iam.Effect.ALLOW,   # ... and so on defining the policy
  )
)
```

```
// project is imported into the CDK application
Project project = Project.fromProjectName(this, "Project", "ProjectName");

// project is imported, so project.getRole() is null, and this call has no effect
project.addToRolePolicy(PolicyStatement.Builder.create()
        .effect(Effect.ALLOW)   // .. and so on defining the policy
        .build();
)
```

```
// project is imported into the CDK application
var project = Project.FromProjectName(this, "Project", "ProjectName");

// project is imported, so project.role is null, and this call has no effect
project.AddToRolePolicy(new PolicyStatement(new PolicyStatementProps
{
    Effect = Effect.ALLOW, // ... and so on defining the policy
}));
```

## Ressourcenrichtlinien
<a name="permissions-resource-policies"></a>

Für einige Ressourcen AWS, wie Amazon S3 S3-Buckets und IAM-Rollen, gibt es auch eine Ressourcenrichtlinie. Diese Konstrukte haben eine `addToResourcePolicy` Methode (Python:`add_to_resource_policy`), die a [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.PolicyStatement.html)als Argument verwendet. Jede Richtlinienanweisung, die zu einer Ressourcenrichtlinie hinzugefügt wird, muss mindestens einen Prinzipal angeben.

Im folgenden Beispiel `bucket` gewährt der [Amazon S3 S3-Bucket](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_s3.Bucket.html) eine Rolle mit der entsprechenden `s3:SomeAction` Berechtigung für sich selbst.

**Example**  

```
bucket.addToResourcePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  actions: ['s3:SomeAction'],
  resources: [bucket.bucketArn],
  principals: [role]
}));
```

```
bucket.addToResourcePolicy(new iam.PolicyStatement({
  effect: iam.Effect.ALLOW,
  actions: ['s3:SomeAction'],
  resources: [bucket.bucketArn],
  principals: [role]
}));
```

```
bucket.add_to_resource_policy(iam.PolicyStatement(
    effect=iam.Effect.ALLOW,
    actions=["s3:SomeAction"],
    resources=[bucket.bucket_arn],
    principals=role))
```

```
bucket.addToResourcePolicy(PolicyStatement.Builder.create()
        .effect(Effect.ALLOW)
        .actions(Arrays.asList("s3:SomeAction"))
        .resources(Arrays.asList(bucket.getBucketArn()))
        .principals(Arrays.asList(role))
        .build());
```

```
bucket.AddToResourcePolicy(new PolicyStatement(new PolicyStatementProps
{
    Effect = Effect.ALLOW,
    Actions = new string[] { "s3:SomeAction" },
    Resources = new string[] { bucket.BucketArn },
    Principals = new IPrincipal[] { role }
}));
```

## Verwendung externer IAM-Objekte
<a name="permissions-existing"></a>

Wenn Sie einen IAM-Benutzer, Prinzipal, Gruppe oder Rolle außerhalb Ihrer AWS CDK-App definiert haben, können Sie dieses IAM-Objekt in Ihrer CDK-App verwenden. AWS Erstellen Sie dazu einen Verweis darauf mit seinem ARN oder seinem Namen. (Verwenden Sie den Namen für Benutzer, Gruppen und Rollen.) Die zurückgegebene Referenz kann dann verwendet werden, um Berechtigungen zu erteilen oder Richtlinienerklärungen zu erstellen, wie zuvor erläutert.
+ Für Benutzer rufen Sie an [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrarnscope-id-userarn](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrarnscope-id-userarn)oder [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrnamescope-id-username](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.User.html#static-fromwbruserwbrnamescope-id-username). `User.fromUserAttributes()`ist ebenfalls verfügbar, bietet aber derzeit die gleiche Funktionalität wie`User.fromUserArn()`.
+ Für Prinzipale instanziieren Sie ein Objekt. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ArnPrincipal.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ArnPrincipal.html)
+ Rufen Sie für Gruppen oder an. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html#static-fromwbrgroupwbrarnscope-id-grouparn](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Group.html#static-fromwbrgroupwbrarnscope-id-grouparn)
+ Rufen Sie für Rollen an [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrarnscope-id-rolearn-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrarnscope-id-rolearn-options)oder [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrnamescope-id-rolename](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Role.html#static-fromwbrrolewbrnamescope-id-rolename).

Richtlinien (einschließlich verwalteter Richtlinien) können mit den folgenden Methoden auf ähnliche Weise verwendet werden. Sie können Verweise auf diese Objekte überall dort verwenden, wo eine IAM-Richtlinie erforderlich ist.
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Policy.html#static-fromwbrpolicywbrnamescope-id-policyname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.Policy.html#static-fromwbrpolicywbrnamescope-id-policyname) 
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrarnscope-id-managedpolicyarn](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrarnscope-id-managedpolicyarn) 
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrnamescope-id-managedpolicyname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrmanagedwbrpolicywbrnamescope-id-managedpolicyname) 
+  [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrawswbrmanagedwbrpolicywbrnamemanagedpolicyname](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam.ManagedPolicy.html#static-fromwbrawswbrmanagedwbrpolicywbrnamemanagedpolicyname) 

**Anmerkung**  
Wie bei allen Verweisen auf externe AWS Ressourcen können Sie externe IAM-Objekte in Ihrer CDK-App nicht ändern.

# Kontextwerte und das CDK AWS
<a name="context"></a>

Kontextwerte sind Schlüssel-Wert-Paare, die einer App, einem Stack oder einem Konstrukt zugeordnet werden können. Sie können Ihrer App aus einer Datei (normalerweise entweder `cdk.json` oder `cdk.context.json` in Ihrem Projektverzeichnis) oder über die Befehlszeile bereitgestellt werden.

Das CDK Toolkit verwendet Kontext, um Werte zwischenzuspeichern, die während der Synthese von Ihrem AWS Konto abgerufen wurden. Zu den Werten gehören die Availability Zones in Ihrem Konto oder die Amazon Machine Image (AMI) -IDs, die derzeit für Amazon EC2 EC2-Instances verfügbar sind. Da diese Werte von Ihrem AWS Konto bereitgestellt werden, können sie sich zwischen den Ausführungen Ihrer CDK-Anwendung ändern. Dies macht sie zu einer potenziellen Quelle unbeabsichtigter Änderungen. Das Caching-Verhalten des CDK Toolkits „friert“ diese Werte für Ihre CDK-App ein, bis Sie sich entscheiden, die neuen Werte zu akzeptieren.

Stellen Sie sich das folgende Szenario ohne Kontext-Caching vor. Nehmen wir an, Sie haben „aktuelles Amazon Linux“ als AMI für Ihre Amazon EC2 EC2-Instances angegeben und eine neue Version dieses AMI wurde veröffentlicht. Wenn Sie dann das nächste Mal Ihren CDK-Stack bereitstellen, würden Ihre bereits bereitgestellten Instances das veraltete („falsche“) AMI verwenden und müssten aktualisiert werden. Ein Upgrade würde dazu führen, dass all Ihre vorhandenen Instances durch neue ersetzt werden, was wahrscheinlich unerwartet und unerwünscht wäre.

Stattdessen zeichnet das CDK die Verfügbarkeit Ihres Kontos AMIs in der `cdk.context.json` Datei Ihres Projekts auf und verwendet den gespeicherten Wert für future Synthesevorgänge. Auf diese Weise AMIs ist die Liste von keine potenzielle Änderungsquelle mehr. Sie können auch sicher sein, dass Ihre Stapel immer zu denselben AWS CloudFormation Vorlagen synthetisiert werden.

Nicht alle Kontextwerte sind zwischengespeicherte Werte aus Ihrer Umgebung. AWS [AWS CDK-Feature-Flags](featureflags.md) sind ebenfalls Kontextwerte. Sie können auch Ihre eigenen Kontextwerte für Ihre Apps oder Konstrukte erstellen.

Kontextschlüssel sind Zeichenketten. Werte können jeden Typ haben, der von JSON unterstützt wird: Zahlen, Zeichenketten, Arrays oder Objekte.

**Tipp**  
Wenn Ihre Konstrukte ihre eigenen Kontextwerte erstellen, nehmen Sie den Paketnamen Ihrer Bibliothek in die Schlüssel auf, damit sie nicht mit den Kontextwerten anderer Pakete in Konflikt geraten.

Viele Kontextwerte sind einer bestimmten AWS Umgebung zugeordnet, und eine bestimmte CDK-App kann in mehr als einer Umgebung bereitgestellt werden. Der Schlüssel für solche Werte umfasst das AWS Konto und die Region, sodass Werte aus verschiedenen Umgebungen nicht miteinander in Konflikt geraten.

Der folgende Kontextschlüssel veranschaulicht das vom AWS CDK verwendete Format, einschließlich Konto und Region.

```
availability-zones:account=123456789012:region=eu-central-1
```

**Wichtig**  
Zwischengespeicherte Kontextwerte werden vom AWS CDK und seinen Konstrukten verwaltet, einschließlich Konstrukten, die Sie schreiben können. Fügen Sie zwischengespeicherte Kontextwerte nicht hinzu oder ändern Sie sie nicht, indem Sie Dateien manuell bearbeiten. Es kann jedoch nützlich sein, `cdk.context.json` gelegentlich nachzuschauen, welche Werte zwischengespeichert werden. Kontextwerte, die keine zwischengespeicherten Werte darstellen, sollten unter dem `context` Schlüssel von gespeichert werden. `cdk.json` Auf diese Weise werden sie nicht gelöscht, wenn zwischengespeicherte Werte gelöscht werden.

## Quellen von Kontextwerten
<a name="context-construct"></a>

Kontextwerte können Ihrer AWS CDK-App auf sechs verschiedene Arten zur Verfügung gestellt werden:
+ Automatisch vom AWS Girokonto.
+ Über die `--context` Option zum `cdk` Befehl. (Diese Werte sind immer Zeichenketten.)
+ In der `cdk.context.json` Datei des Projekts.
+ Im `context` Schlüssel der `cdk.json` Projektdatei.
+ Im `context` Schlüssel Ihrer `~/.cdk.json` Datei.
+ In Ihrer AWS CDK-App mit der `construct.node.setContext()` Methode.

In der Projektdatei speichert `cdk.context.json` das AWS CDK die von Ihrem Konto abgerufenen Kontextwerte im Cache. AWS Durch diese Vorgehensweise werden unerwartete Änderungen an Ihren Bereitstellungen vermieden, wenn beispielsweise eine neue Availability Zone eingeführt wird. Das AWS CDK schreibt keine Kontextdaten in eine der anderen aufgelisteten Dateien.

**Wichtig**  
Weil sie Teil des Status Ihrer Anwendung sind `cdk.json` und zusammen mit dem Rest des Quellcodes Ihrer App der Quellcodeverwaltung unterliegen `cdk.context.json` müssen. Andernfalls können Bereitstellungen in anderen Umgebungen (z. B. einer CI-Pipeline) zu inkonsistenten Ergebnissen führen.

Kontextwerte beziehen sich auf das Konstrukt, mit dem sie erstellt wurden. Sie sind für untergeordnete Konstrukte sichtbar, nicht jedoch für Eltern oder Geschwister. Kontextwerte, die vom AWS CDK Toolkit (dem `cdk` Befehl) festgelegt werden, können automatisch, aus einer Datei oder aus der Option festgelegt werden. `--context` Kontextwerte aus diesen Quellen werden implizit im Konstrukt festgelegt. `App` Daher sind sie für jedes Konstrukt in jedem Stapel in der App sichtbar.

Ihre App kann mithilfe der `construct.node.tryGetContext` Methode einen Kontextwert lesen. Wenn der angeforderte Eintrag im aktuellen Konstrukt oder einem seiner übergeordneten Objekte nicht gefunden wird, lautet das Ergebnis`undefined`. (Alternativ könnte das Ergebnis das Äquivalent Ihrer Sprache sein, z. B. `None` in Python.)

## Context-Methoden
<a name="context-methods"></a>

Das AWS CDK unterstützt mehrere Kontextmethoden, mit denen AWS CDK-Apps Kontextinformationen aus der Umgebung abrufen können. AWS Mit dieser Methode können Sie beispielsweise eine Liste der Availability Zones abrufen, die in einem bestimmten AWS Konto und einer bestimmten Region verfügbar sind. [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones)

Im Folgenden sind die Kontextmethoden aufgeführt:

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_route53.HostedZone.html#static-fromwbrlookupscope-id-query](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_route53.HostedZone.html#static-fromwbrlookupscope-id-query)   
Ruft die gehosteten Zonen in Ihrem Konto ab.

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones)   
Ruft die unterstützten Availability Zones ab.

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ssm.StringParameter.html#static-valuewbrfromwbrlookupscope-parametername](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ssm.StringParameter.html#static-valuewbrfromwbrlookupscope-parametername)   
Ruft einen Wert aus dem Amazon EC2 Systems Manager Manager-Parameterspeicher der aktuellen Region ab.

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Vpc.html#static-fromwbrlookupscope-id-options](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Vpc.html#static-fromwbrlookupscope-id-options)   
Ruft die vorhandenen Amazon Virtual Private Clouds in Ihren Konten ab.

 [https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.LookupMachineImage.html](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.LookupMachineImage.html)   
Sucht nach einem Maschinen-Image zur Verwendung mit einer NAT-Instance in einer Amazon Virtual Private Cloud.

Wenn ein erforderlicher Kontextwert nicht verfügbar ist, benachrichtigt die AWS CDK-App das CDK Toolkit darüber, dass die Kontextinformationen fehlen. Als Nächstes fragt die CLI das aktuelle AWS Konto nach den Informationen ab und speichert die resultierenden Kontextinformationen in der `cdk.context.json` Datei. Anschließend führt sie die AWS CDK-App erneut mit den Kontextwerten aus.

## Kontext anzeigen und verwalten
<a name="context-viewing"></a>

Verwenden Sie den `cdk context` Befehl, um die Informationen in Ihrer `cdk.context.json` Datei anzuzeigen und zu verwalten. Um diese Informationen zu sehen, verwenden Sie den `cdk context` Befehl ohne Optionen. Die Ausgabe sollte etwa wie folgt aussehen.

```
Context found in cdk.json:

┌───┬─────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────┐
│ # │ Key                                                         │ Value                                                   │
├───┼─────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤
│ 1 │ availability-zones:account=123456789012:region=eu-central-1 │ [ "eu-central-1a", "eu-central-1b", "eu-central-1c" ]   │
├───┼─────────────────────────────────────────────────────────────┼─────────────────────────────────────────────────────────┤
│ 2 │ availability-zones:account=123456789012:region=eu-west-1    │ [ "eu-west-1a", "eu-west-1b", "eu-west-1c" ]            │
└───┴─────────────────────────────────────────────────────────────┴─────────────────────────────────────────────────────────┘

Run

  cdk context --reset KEY_OR_NUMBER

 to remove a context key. If it is a cached value, it will be refreshed on the next

  cdk synth

.
```

Um einen Kontextwert zu entfernen`cdk context --reset`, führen Sie den Befehl aus und geben Sie dabei den entsprechenden Schlüssel oder die Zahl des Werts an. Im folgenden Beispiel wird der Wert entfernt, der dem zweiten Schlüssel im vorherigen Beispiel entspricht. Dieser Wert steht für die Liste der Availability Zones in der Region Europa (Irland).

```
cdk context --reset 2
```

```
Context value
availability-zones:account=123456789012:region=eu-west-1
reset. It will be refreshed on the next SDK synthesis run.
```

Wenn Sie also auf die neueste Version des Amazon Linux AMI aktualisieren möchten, verwenden Sie das vorherige Beispiel, um den Kontextwert kontrolliert zu aktualisieren und ihn zurückzusetzen. Synthetisieren Sie dann Ihre App und stellen Sie sie erneut bereit.

```
$ cdk synth
```

Um alle gespeicherten Kontextwerte für Ihre App zu löschen`cdk context --clear`, führen Sie Folgendes aus.

```
$ cdk context --clear
```

Nur in gespeicherte Kontextwerte `cdk.context.json` können zurückgesetzt oder gelöscht werden. Das AWS CDK berührt keine anderen Kontextwerte. Um zu verhindern, dass ein Kontextwert mithilfe dieser Befehle zurückgesetzt wird, können Sie den Wert daher nach `cdk.json` kopieren.

## AWS CDK Toolkit-Flag `--context`
<a name="context-cli"></a>

Verwenden Sie die Option `--context` (kurz), um während der Synthese oder Bereitstellung Werte `-c` für den Laufzeitkontext an Ihre CDK-App zu übergeben.

```
$ cdk synth --context key=value MyStack
```

Um mehrere Kontextwerte anzugeben, wiederholen Sie die `--context` Option beliebig oft und geben Sie jedes Mal ein Schlüssel-Wert-Paar an.

```
$ cdk synth --context key1=value1 --context key2=value2 MyStack
```

Bei der Synthese mehrerer Stapel werden die angegebenen Kontextwerte an alle Stapel übergeben. Um einzelnen Stacks unterschiedliche Kontextwerte zur Verfügung zu stellen, verwenden Sie entweder unterschiedliche Schlüssel für die Werte oder mehrere OR-Befehle. `cdk synth` `cdk deploy`

Von der Befehlszeile übergebene Kontextwerte sind immer Zeichenketten. Wenn ein Wert normalerweise von einem anderen Typ ist, muss Ihr Code darauf vorbereitet sein, den Wert zu konvertieren oder zu analysieren. Möglicherweise werden Kontextwerte, die keine Zeichenfolge sind, auf andere Weise bereitgestellt (z. B. in`cdk.context.json`). Um sicherzustellen, dass diese Art von Wert wie erwartet funktioniert, stellen Sie vor der Konvertierung sicher, dass es sich bei dem Wert um eine Zeichenfolge handelt.

## Beispiel
<a name="context-example"></a>

Im Folgenden finden Sie ein Beispiel für die Verwendung einer vorhandenen Amazon VPC im AWS CDK-Kontext.

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as ec2 from 'aws-cdk-lib/aws-ec2';
import { Construct } from 'constructs';

export class ExistsVpcStack extends cdk.Stack {

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

    super(scope, id, props);

    const vpcid = this.node.tryGetContext('vpcid');
    const vpc = ec2.Vpc.fromLookup(this, 'VPC', {
      vpcId: vpcid,
    });

    const pubsubnets = vpc.selectSubnets({subnetType: ec2.SubnetType.PUBLIC});

    new cdk.CfnOutput(this, 'publicsubnets', {
      value: pubsubnets.subnetIds.toString(),
    });
  }
}
```

```
const cdk = require('aws-cdk-lib');
const ec2 = require('aws-cdk-lib/aws-ec2');

class ExistsVpcStack extends cdk.Stack {

  constructor(scope, id, props) {

    super(scope, id, props);

    const vpcid = this.node.tryGetContext('vpcid');
    const vpc = ec2.Vpc.fromLookup(this, 'VPC', {
      vpcId: vpcid
    });

    const pubsubnets = vpc.selectSubnets({subnetType: ec2.SubnetType.PUBLIC});

    new cdk.CfnOutput(this, 'publicsubnets', {
      value: pubsubnets.subnetIds.toString()
    });
  }
}

module.exports = { ExistsVpcStack }
```

```
import aws_cdk as cdk
import aws_cdk.aws_ec2 as ec2
from constructs import Construct

class ExistsVpcStack(cdk.Stack):

    def __init__(scope: Construct, id: str, **kwargs):

        super().__init__(scope, id, **kwargs)

        vpcid = self.node.try_get_context("vpcid")
        vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=vpcid)

        pubsubnets = vpc.select_subnets(subnetType=ec2.SubnetType.PUBLIC)

        cdk.CfnOutput(self, "publicsubnets",
            value=pubsubnets.subnet_ids.to_string())
```

```
import software.amazon.awscdk.CfnOutput;

import software.amazon.awscdk.services.ec2.Vpc;
import software.amazon.awscdk.services.ec2.VpcLookupOptions;
import software.amazon.awscdk.services.ec2.SelectedSubnets;
import software.amazon.awscdk.services.ec2.SubnetSelection;
import software.amazon.awscdk.services.ec2.SubnetType;
import software.constructs.Construct;

public class ExistsVpcStack extends Stack {
    public ExistsVpcStack(Construct context, String id) {
        this(context, id, null);
    }

    public ExistsVpcStack(Construct context, String id, StackProps props) {
        super(context, id, props);

        String vpcId = (String)this.getNode().tryGetContext("vpcid");
        Vpc vpc = (Vpc)Vpc.fromLookup(this, "VPC", VpcLookupOptions.builder()
                .vpcId(vpcId).build());

        SelectedSubnets pubSubNets = vpc.selectSubnets(SubnetSelection.builder()
                .subnetType(SubnetType.PUBLIC).build());

        CfnOutput.Builder.create(this, "publicsubnets")
                .value(pubSubNets.getSubnetIds().toString()).build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.EC2;
using Constructs;

class ExistsVpcStack : Stack
{
    public ExistsVpcStack(Construct scope, string id, StackProps props) : base(scope, id, props)
    {
        var vpcId = (string)this.Node.TryGetContext("vpcid");
        var vpc = Vpc.FromLookup(this, "VPC", new VpcLookupOptions
        {
            VpcId = vpcId
        });

        SelectedSubnets pubSubNets = vpc.SelectSubnets([new SubnetSelection
        {
            SubnetType = SubnetType.PUBLIC
        }]);

        new CfnOutput(this, "publicsubnets", new CfnOutputProps {
            Value = pubSubNets.SubnetIds.ToString()
        });
    }
}
```

Sie können `cdk diff` es verwenden, um die Auswirkungen der Übergabe eines Kontextwerts in der Befehlszeile zu sehen:

```
$ cdk diff -c vpcid=vpc-0cb9c31031d0d3e22
```

```
Stack ExistsvpcStack
Outputs
[+] Output publicsubnets publicsubnets: {"Value":"subnet-06e0ea7dd302d3e8f,subnet-01fc0acfb58f3128f"}
```

Die resultierenden Kontextwerte können wie hier gezeigt angezeigt werden.

```
$ cdk context -j
```

```
{
  "vpc-provider:account=123456789012:filter.vpc-id=vpc-0cb9c31031d0d3e22:region=us-east-1": {
    "vpcId": "vpc-0cb9c31031d0d3e22",
    "availabilityZones": [
      "us-east-1a",
      "us-east-1b"
    ],
    "privateSubnetIds": [
      "subnet-03ecfc033225be285",
      "subnet-0cded5da53180ebfa"
    ],
    "privateSubnetNames": [
      "Private"
    ],
    "privateSubnetRouteTableIds": [
      "rtb-0e955393ced0ada04",
      "rtb-05602e7b9f310e5b0"
    ],
    "publicSubnetIds": [
      "subnet-06e0ea7dd302d3e8f",
      "subnet-01fc0acfb58f3128f"
    ],
    "publicSubnetNames": [
      "Public"
    ],
    "publicSubnetRouteTableIds": [
      "rtb-00d1fdfd823c82289",
      "rtb-04bb1969b42969bcb"
    ]
  }
}
```

# AWS CDK-Feature-Flags
<a name="featureflags"></a>

Das AWS CDK verwendet *Feature-Flags*, um potenziell schädliche Verhaltensweisen in einer Version zu aktivieren. Flags werden als [Kontextwerte und die AWS CDK-Werte](context.md) in `cdk.json` (oder`~/.cdk.json`) gespeichert. Sie werden nicht durch die `cdk context --clear` Befehle `cdk context --reset` oder entfernt.

Feature-Flags sind standardmäßig deaktiviert. Bestehende Projekte, bei denen das Flag nicht angegeben ist, funktionieren mit späteren AWS CDK-Versionen weiterhin wie zuvor. Neue Projekte, die mit `cdk init` Include-Flags erstellt wurden, aktivieren alle Funktionen, die in der Version verfügbar waren, mit der das Projekt erstellt wurde. Bearbeiten Sie`cdk.json`, um alle Flags zu deaktivieren, für die Sie das frühere Verhalten bevorzugen. Sie können auch Flags hinzufügen, um nach dem Upgrade des AWS CDK neue Verhaltensweisen zu aktivieren.

[Eine Liste aller aktuellen Feature-Flags finden Sie im AWS GitHub CDK-Repository unter FEATURE\$1FLAGS.md.](https://github.com/aws/aws-cdk/blob/main/packages/aws-cdk-lib/cx-api/FEATURE_FLAGS.md) Eine Beschreibung aller neuen Feature-Flags, die `CHANGELOG` in dieser Version hinzugefügt wurden, finden Sie in einer bestimmten Version.

## Rückkehr zum Verhalten von Version 1
<a name="featureflags-disabling"></a>

In CDK v2 wurden die Standardeinstellungen für einige Feature-Flags gegenüber Version 1 geändert. Sie können diese wieder auf setzen, um `false` zu einem bestimmten AWS CDK v1-Verhalten zurückzukehren. Verwenden Sie den `cdk diff` Befehl, um die Änderungen an Ihrer synthetisierten Vorlage zu überprüfen und festzustellen, ob eines dieser Flags benötigt wird.

 `@aws-cdk/core:newStyleStackSynthesis`   
Verwenden Sie die neue Stack-Synthesemethode, die Bootstrap-Ressourcen mit bekannten Namen voraussetzt. Erfordert [modernes Bootstrapping](bootstrapping.md), ermöglicht aber wiederum CI/CD über [CDK Pipelines](cdk-pipeline.md) und kontenübergreifende Bereitstellungen von Haus aus.

 `@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId`   
Wenn Ihre Anwendung mehrere Amazon API Gateway Gateway-API-Schlüssel verwendet und diese Nutzungsplänen zuordnet.

 `@aws-cdk/aws-rds:lowercaseDbIdentifier`   
Wenn Ihre Anwendung Amazon RDS-Datenbank-Instances oder Datenbankcluster verwendet und die ID für diese explizit angibt.

 `@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021`   
Wenn Ihre Anwendung die Sicherheitsrichtlinie TLS\$1V1\$12\$12019 mit Amazon-Distributionen verwendet. CloudFront CDK v2 verwendet standardmäßig die Sicherheitsrichtlinie 2.2\$12021. TLSv1

 `@aws-cdk/core:stackRelativeExports`   
Wenn Ihre Anwendung mehrere Stacks verwendet und Sie auf Ressourcen von einem Stack in einem anderen verweisen, bestimmt dies, ob für die Erstellung von Exporten ein absoluter oder relativer Pfad verwendet wird. AWS CloudFormation 

 `@aws-cdk/aws-lambda:recognizeVersionProps`   
Wenn auf gesetzt`false`, bezieht das CDK Metadaten mit ein, wenn es erkennt, ob sich eine Lambda-Funktion geändert hat. Dies kann zu Bereitstellungsfehlern führen, wenn nur die Metadaten geändert wurden, da doppelte Versionen nicht zulässig sind. Sie müssen dieses Flag nicht rückgängig machen, wenn Sie mindestens eine Änderung an allen Lambda-Funktionen in Ihrer Anwendung vorgenommen haben.

Die Syntax für das Zurücksetzen dieser Flags `cdk.json` wird hier gezeigt.

```
{
  "context": {
    "@aws-cdk/core:newStyleStackSynthesis": false,
    "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": false,
    "@aws-cdk/aws-cloudfront:defaultSecurityPolicyTLSv1.2_2021": false,
    "@aws-cdk/aws-rds:lowercaseDbIdentifier": false,
    "@aws-cdk/core:stackRelativeExports": false,
    "@aws-cdk/aws-lambda:recognizeVersionProps": false
  }
}
```

# Aspekte und das AWS CDK
<a name="aspects"></a>

Aspekte sind eine Möglichkeit, eine Operation auf alle Konstrukte in einem bestimmten Bereich anzuwenden. Der Aspekt könnte die Konstrukte modifizieren, beispielsweise durch Hinzufügen von Tags. Oder es könnte etwas über den Zustand der Konstrukte überprüfen, z. B. sicherstellen, dass alle Buckets verschlüsselt sind.

Um einen Aspekt auf ein Konstrukt und alle Konstrukte desselben Gültigkeitsbereichs anzuwenden, rufen Sie ` [Aspects](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Aspects.html#static-ofscope).of(<SCOPE>).add()` mit einem neuen Aspekt auf, wie im folgenden Beispiel gezeigt.

**Example**  

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.of(my_construct).add(SomeAspect(...))
```

```
Aspects.of(myConstruct).add(new SomeAspect(...));
```

```
Aspects.Of(myConstruct).add(new SomeAspect(...));
```

```
awscdk.Aspects_Of(stack).Add(awscdk.NewTag(...))
```

Das AWS CDK verwendet Aspekte, um [Ressourcen zu taggen](tagging.md), aber das Framework kann auch für andere Zwecke verwendet werden. Sie können es beispielsweise verwenden, um die AWS CloudFormation Ressourcen zu validieren oder zu ändern, die durch Konstrukte auf höherer Ebene für Sie definiert sind.

## Aspekte im Vergleich zu Mixins
<a name="aspects-vs-mixins"></a>

Aspekte und [Mixins](mixins.md) modifizieren beide Konstrukte, unterscheiden sich jedoch darin, wann und wie sie angewendet werden:


| Feature | Aspekte | Mixins | 
| --- | --- | --- | 
|   **Wenn angewendet**   |  Während der Synthese, nachdem der gesamte andere Code ausgeführt wurde.  |  Sofort, wenn aufgerufen `.with()` wird.  | 
|   **Scope**   |  Alle Konstrukte in einem bestimmten Bereich, einschließlich der später hinzugefügten Konstrukte.  |  Nur die Konstrukte, auf die Sie sie explizit anwenden.  | 
|   **Style**   |  Deklarativ — Sie legen eine Regel fest und das CDK wendet sie an.  |  Unverzichtbar — Sie entscheiden, was und wo angewendet werden soll.  | 
|   **Am besten geeignet für**   |  Validierung, Einhaltung von Vorschriften, Kennzeichnung, allgemeine Richtlinien.  |  Hinzufügen bestimmter Funktionen zu einzelnen Ressourcen.  | 

Verwenden Sie Aspekte, wenn Sie Regeln für Ihre gesamte Anwendung durchsetzen oder überprüfen möchten, ob Konstrukte bestimmte Kriterien erfüllen. Verwenden Sie Mixins, wenn Sie einem bestimmten Konstrukt ein bestimmtes Feature hinzufügen möchten.

Aspekte und Mixins können zusammen verwendet werden. Beispielsweise können Sie Mixins verwenden, um einzelne Ressourcen zu konfigurieren, und Aspekte, um zu überprüfen, ob alle Ressourcen in einem Stack die Sicherheitsanforderungen Ihres Unternehmens erfüllen.

## Aspekte im Detail
<a name="aspects-detail"></a>

Aspekte orientieren sich am [Besuchermuster](https://en.wikipedia.org/wiki/Visitor_pattern). Ein Aspekt ist eine Klasse, die die folgende Schnittstelle implementiert.

**Example**  

```
interface IAspect {
   visit(node: IConstruct): void;}
```
JavaScript hat keine Schnittstellen als Sprachfunktion. Daher ist ein Aspekt einfach eine Instanz einer Klasse mit einer `visit` Methode, die den Knoten akzeptiert, auf dem operiert werden soll.
Python hat keine Schnittstellen als Sprachfunktion. Daher ist ein Aspekt einfach eine Instanz einer Klasse mit einer `visit` Methode, die den Knoten akzeptiert, auf dem operiert werden soll.

```
public interface IAspect {
    public void visit(Construct node);
}
```

```
public interface IAspect
{
    void Visit(IConstruct node);
}
```

```
type IAspect interface {
  Visit(node constructs.IConstruct)
}
```

Wenn Sie aufrufen`Aspects.of(<SCOPE>).add(…​)`, fügt das Konstrukt den Aspekt zu einer internen Liste von Aspekten hinzu. Sie können die Liste mit abrufen`Aspects.of(<SCOPE>)`.

Während der [Vorbereitungsphase](deploy.md#deploy-how-synth-app) ruft das AWS CDK die `visit` Methode des Objekts für das Konstrukt und jedes seiner untergeordneten Objekte in der Reihenfolge von oben nach unten auf.

Es steht der `visit` Methode frei, alles am Konstrukt zu ändern. Wandeln Sie in stark typisierten Sprachen das empfangene Konstrukt in einen spezifischeren Typ um, bevor Sie auf konstruktspezifische Eigenschaften oder Methoden zugreifen.

Aspekte breiten sich nicht über `Stage` Konstruktgrenzen hinweg aus, da sie in sich abgeschlossen und nach der Definition `Stages` unveränderlich sind. Wenden Sie Aspekte auf das `Stage` Konstrukt selbst (oder auf eine niedrigere Ebene) an, wenn Sie möchten, dass sie Konstrukte innerhalb von besuchen. `Stage`

## Beispiel
<a name="aspects-example"></a>

Im folgenden Beispiel wird überprüft, ob für alle im Stack erstellten Buckets die Versionsverwaltung aktiviert ist. Der Aspekt fügt den Konstrukten, bei denen die Überprüfung fehlschlägt, eine Fehleranmerkung hinzu. Dies führt dazu, dass der `synth` Vorgang fehlschlägt und die Bereitstellung der resultierenden Cloud-Assembly verhindert wird.

**Example**  

```
class BucketVersioningChecker implements IAspect {
  public visit(node: IConstruct): void {
    // See that we're dealing with a CfnBucket
    if (node instanceof s3.CfnBucket) {

      // Check for versioning property, exclude the case where the property
      // can be a token (IResolvable).
      if (!node.versioningConfiguration
        || (!Tokenization.isResolvable(node.versioningConfiguration)
            && node.versioningConfiguration.status !== 'Enabled')) {
        Annotations.of(node).addError('Bucket versioning is not enabled');
      }
    }
  }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
class BucketVersioningChecker {
   visit(node) {
    // See that we're dealing with a CfnBucket
    if ( node instanceof s3.CfnBucket) {

      // Check for versioning property, exclude the case where the property
      // can be a token (IResolvable).
      if (!node.versioningConfiguration
        || !Tokenization.isResolvable(node.versioningConfiguration)
            && node.versioningConfiguration.status !== 'Enabled')) {
        Annotations.of(node).addError('Bucket versioning is not enabled');
      }
    }
  }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
@jsii.implements(cdk.IAspect)
class BucketVersioningChecker:

  def visit(self, node):
    # See that we're dealing with a CfnBucket
    if isinstance(node, s3.CfnBucket):

      # Check for versioning property, exclude the case where the property
      # can be a token (IResolvable).
      if (not node.versioning_configuration or
              not Tokenization.is_resolvable(node.versioning_configuration)
                  and node.versioning_configuration.status != "Enabled"):
          Annotations.of(node).add_error('Bucket versioning is not enabled')

# Later, apply to the stack
Aspects.of(stack).add(BucketVersioningChecker())
```

```
public class BucketVersioningChecker implements IAspect
{
    @Override
    public void visit(Construct node)
    {
        // See that we're dealing with a CfnBucket
        if (node instanceof CfnBucket)
        {
            CfnBucket bucket = (CfnBucket)node;
            Object versioningConfiguration = bucket.getVersioningConfiguration();
            if (versioningConfiguration == null ||
                    !Tokenization.isResolvable(versioningConfiguration.toString()) &&
                    !versioningConfiguration.toString().contains("Enabled"))
                Annotations.of(bucket.getNode()).addError("Bucket versioning is not enabled");
        }
    }
}

// Later, apply to the stack
Aspects.of(stack).add(new BucketVersioningChecker());
```

```
class BucketVersioningChecker : Amazon.Jsii.Runtime.Deputy.DeputyBase, IAspect
{
    public void Visit(IConstruct node)
    {
        // See that we're dealing with a CfnBucket
        if (node is CfnBucket)
        {
            var bucket = (CfnBucket)node;
            if (bucket.VersioningConfiguration is null ||
                    !Tokenization.IsResolvable(bucket.VersioningConfiguration) &&
                    !bucket.VersioningConfiguration.ToString().Contains("Enabled"))
                Annotations.Of(bucket.Node).AddError("Bucket versioning is not enabled");
        }
    }
}

// Later, apply to the stack
Aspects.Of(stack).add(new BucketVersioningChecker());
```