

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.

# Erstellen Sie eine benutzerdefinierte Bereitstellungslogik mit benutzerdefinierten Ressourcen
<a name="template-custom-resources"></a>

Benutzerdefinierte Ressourcen bieten Ihnen die Möglichkeit, benutzerdefinierte Bereitstellungslogik in Ihre CloudFormation Vorlagen zu schreiben und sie jedes Mal CloudFormation auszuführen, wenn Sie einen Stack erstellen, aktualisieren (falls Sie die benutzerdefinierte Ressource geändert haben) oder löschen. Dies kann nützlich sein, wenn Ihre Bereitstellungsanforderungen komplexe Logiken oder Workflows beinhalten, die mit CloudFormation den integrierten Ressourcentypen nicht ausgedrückt werden können.

Beispielsweise möchten Sie möglicherweise Ressourcen einbeziehen, die nicht als CloudFormation Ressourcentypen verfügbar sind. Sie können diese Ressourcen mithilfe von benutzerdefinierten Ressourcen einschließen. Auf diese Weise können Sie immer noch alle Ihre zugehörigen Ressourcen in einem einzigen Stapel verwalten.

Um eine benutzerdefinierte Ressource in Ihrer CloudFormation Vorlage zu definieren, verwenden Sie den `Custom::MyCustomResourceTypeName` Ressourcentyp `AWS::CloudFormation::CustomResource` oder. Benutzerdefinierte Ressourcen benötigen eine Eigenschaft, das Service-Token, das angibt, wohin Anfragen CloudFormation gesendet werden, z. B. ein Amazon SNS SNS-Thema oder eine Lambda-Funktion.

In den folgenden Themen finden Sie Informationen über die Verwendung von benutzerdefinierten Ressourcen.

**Topics**
+ [So funktionieren benutzerdefinierte Ressourcen](#how-custom-resources-work)
+ [Zeitüberschreitung bei der Antwort](#response-timeout)
+ [CloudFormation Referenz für benutzerdefinierte Ressourcenanfragen und Antworten](crpg-ref.md)
+ [Amazon SNS-gestützte benutzerdefinierte Ressourcen](template-custom-resources-sns.md)
+ [Lambda-gestützte benutzerdefinierte Ressourcen](template-custom-resources-lambda.md)

**Anmerkung**  
Die CloudFormation Registrierung und die benutzerdefinierten Ressourcen bieten jeweils ihre eigenen Vorteile. Benutzerdefinierte Ressourcen bieten die folgenden Vorteile:  
Sie brauchen die Ressource nicht zu registrieren.
Sie können eine ganze Ressource als Teil einer Vorlage einfügen, ohne sich zu registrieren.
Unterstützt die Operationen,`Create`,`Update` und `Delete` .
Zu den Vorteilen, die registrierungsbasierte Ressourcen bieten, gehören die folgenden:  
Unterstützt die Modellierung, Provisionierung und Verwaltung von Anwendungsressourcen von Drittanbietern
Unterstützt die Vorgänge `Create`, `Read`, `Update`, `Delete` und `List` (`CRUDL`)
Unterstützt die Drifterkennung für Ressourcentypen privater und Drittanbieter
Im Gegensatz zu benutzerdefinierten Ressourcen müssen registrierungsbasierte Ressourcen kein Amazon SNS-Thema oder Lambda-Funktion zur Durchführung von `CRUDL`-Vorgängen verknüpfen. Weitere Informationen finden Sie unter [Erweiterungen mit der CloudFormation Registry verwalten](registry.md).

## So funktionieren benutzerdefinierte Ressourcen
<a name="how-custom-resources-work"></a>

Der allgemeine Prozess zur Einrichtung einer neuen benutzerdefinierten Ressource umfasst die folgenden Schritte. An diesen Schritten sind zwei Rollen beteiligt: der *Anbieter einer benutzerdefinierten Ressource* der die benutzerdefinierte Ressource besitzt und der *Vorlagenentwickler* der eine Vorlage erstellt, die einen benutzerdefinierten Ressourcentyp enthält. Dies kann dieselbe Person sein, aber wenn nicht, sollte der Anbieter der benutzerdefinierten Ressourcen mit dem Entwickler der Vorlage zusammenarbeiten.

1. Der Anbieter für benutzerdefinierte Ressourcen schreibt eine Logik, die bestimmt, wie Anfragen von der benutzerdefinierten Ressource behandelt CloudFormation und Aktionen für diese ausgeführt werden. 

1. Der benutzerdefinierte Ressourcenanbieter erstellt das Amazon SNS SNS-Thema oder die Lambda-Funktion, an die Anfragen gesendet CloudFormation werden können. Das Amazon SNS-Thema oder die Lambda-Funktion muss sich in der gleichen Region befinden, in der der Stack erstellt wird.

1. Der benutzerdefinierte Ressourcenanbieter übergibt den Amazon SNS-Topic-ARN oder Lambda-Funktions-ARN an den Vorlagenentwickler.

1. Der Vorlagenentwickler definiert die benutzerdefinierte Ressource in seiner CloudFormation Vorlage. Dazu gehören ein Service-Token und alle Eingabedatenparameter. Das Service-Token und die Struktur der Eingabedaten werden von dem benutzerdefinierten Ressourcenanbieter definiert. Das Service-Token gibt den Amazon SNS-Topic-ARN oder Lambda-Funktions-ARN an und ist immer erforderlich, aber die Eingabedaten sind je nach benutzerdefinierter Ressource optional.

Wenn nun jemand die Vorlage verwendet, um die benutzerdefinierte Ressource zu erstellen, zu aktualisieren oder zu löschen, CloudFormation sendet er eine Anfrage an das angegebene Service-Token und wartet dann auf eine Antwort, bevor er mit dem Stack-Vorgang fortfährt. 

Im Folgenden ist der Ablauf für die Erstellung eines Stapels aus der Vorlage zusammengefasst: 

1. CloudFormation sendet eine Anfrage an das angegebene Service-Token. Die Anfrage enthält Informationen wie den Anfragetyp und eine vorsignierte Amazon S3 S3-Bucket-URL, an die die benutzerdefinierte Ressource Antworten sendet. Weitere Informationen zu den in der Anforderung enthaltenen Informationen finden Sie unter [CloudFormation Referenz für benutzerdefinierte Ressourcenanfragen und Antworten](crpg-ref.md).

   Die folgenden Beispieldaten zeigen, was in einer `Create` Anfrage CloudFormation enthalten ist. In diesem Beispiel `ResourceProperties` können CloudFormation Sie eine benutzerdefinierte Nutzlast erstellen, die an die Lambda-Funktion gesendet werden soll.

   ```
   {
      "RequestType" : "Create",
      "RequestId" : "unique id for this create request",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::TestResource",
      "LogicalResourceId" : "MyTestResource",
      "ResourceProperties" : {
         "Name" : "Value",
         "List" : [ "1", "2", "3" ]
      }
   }
   ```

1. Der benutzerdefinierte Ressourcenanbieter verarbeitet die CloudFormation Anfrage und gibt eine Antwort von `SUCCESS` oder `FAILED` an die vorsignierte URL zurück. Der custom resource provider gibt die Antwort in einer JSON-formatierten Datei zurück und lädt diese zu der vorsignierten S3-URL hoch. Weitere Informationen finden Sie unter [Hochladen von Objekten mit Vorsignierung URLs](https://docs.aws.amazon.com/AmazonS3/latest/userguide/PresignedUrlUploadObject.html) im *Amazon Simple Storage Service-Benutzerhandbuch*.

   Der custom resource provider kann in der Antwort auch Name-Wert-Paare angeben, auf die der template developer zugreifen kann. Die Antwort kann beispielsweise Ausgabedaten enthalten, wenn die Anforderung erfolgreich war, oder eine Fehlermeldung, wenn die Anforderung fehlgeschlagen ist. Weitere Informationen zu Antworten finden Sie unter [CloudFormation Referenz für benutzerdefinierte Ressourcenanfragen und Antworten](crpg-ref.md).
**Wichtig**  
Wenn die Namen-Wert-Paare vertrauliche Informationen enthalten, sollten Sie das `NoEcho`-Feld benutzen, um die Ausgabe der benutzerdefinierten Ressource zu maskieren. Andernfalls sind die Werte durch die Eigenschaftswerte APIs dieser Oberfläche sichtbar (z. B.`DescribeStackEvents`).  
Weitere Informationen über die Verwendung von `NoEcho` zur Maskierung sensibler Informationen finden Sie in der bewährten Methode [Keine Anmeldeinformationen in Vorlagen einbetten](security-best-practices.md#creds) .

   Der custom resource provider ist für das Erkennen und Beantworten der Anforderung verantwortlich. Bei Amazon SNS SNS-Benachrichtigungen muss der Anbieter benutzerdefinierter Ressourcen beispielsweise Benachrichtigungen abhören und beantworten, die an einen bestimmten Themen-ARN gesendet werden. CloudFormation wartet und wartet auf eine Antwort an der Stelle mit der vorab signierten URL.

   In den folgenden Beispieldaten wird gezeigt, was eine benutzerdefinierte Ressourcen in eine Antwort einschließen kann:

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique id for this create request",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MyTestResource",
      "PhysicalResourceId" : "TestResource1",
      "Data" : {
         "OutputName1" : "Value1",
         "OutputName2" : "Value2",
      }
   }
   ```

1. Nachdem Sie eine `SUCCESS` Antwort erhalten haben, wird mit dem CloudFormation Stack-Vorgang fortgefahren. Wenn keine `FAILED`-Antwort oder gar keine Antwort zurückgegeben wird, schlägt der Vorgang fehl. Alle Ausgabedaten von der benutzerdefinierten Ressource werden am Speicherort der vorsignierten URL gespeichert. Der Vorlagenentwickler kann diese Daten mithilfe der GetAtt Funktion [Fn::](resources-section-structure.md#resource-properties-getatt) abrufen.

**Anmerkung**  
Wenn Sie verwenden AWS PrivateLink, müssen benutzerdefinierte Ressourcen in der VPC Zugriff auf CloudFormation -spezifische S3-Buckets haben. Benutzerdefinierte Ressourcen müssen Antworten an eine vorsignierte Amazon S3-URL senden. Wenn sie keine Antworten an Amazon S3 senden können, erhalten sie CloudFormation keine Antwort und der Stack-Vorgang schlägt fehl. Weitere Informationen finden Sie unter [Zugriff CloudFormation über einen Schnittstellenendpunkt (AWS PrivateLink)](vpc-interface-endpoints.md).

## Zeitüberschreitung bei der Antwort
<a name="response-timeout"></a>

Der Standard-Timeout für Ihre benutzerdefinierte Ressource beträgt 3600 Sekunden (1 Stunde). Wenn während dieser Zeit keine Antwort empfangen wird, schlägt der Stapelvorgang fehl.

Sie können den Timeout-Wert anpassen, je nachdem, wie lange die Antwort von der benutzerdefinierten Ressource voraussichtlich dauern wird. Wenn Sie beispielsweise eine benutzerdefinierte Ressource bereitstellen, die eine Lambda-Funktion aufruft, von der erwartet wird, dass sie innerhalb von fünf Minuten antwortet, können Sie in der Stack-Vorlage eine Zeitüberschreitung von fünf Minuten festlegen, indem Sie die Eigenschaft `ServiceTimeout` angeben. Weitere Informationen finden Sie unter [CloudFormation Referenz für benutzerdefinierte Ressourcenanfragen und Antworten](crpg-ref.md). Auf diese Weise schlägt der Stack-Vorgang nach fünf Minuten fehl, wenn in der Lambda-Funktion ein Fehler auftritt, der dazu führt, dass sie hängen bleibt, CloudFormation anstatt die ganze Stunde zu warten. 

Achten Sie jedoch darauf, den Timeout-Wert nicht zu niedrig anzusetzen. Um unerwartete Timeouts zu vermeiden, stellen Sie sicher, dass Ihre benutzerdefinierte Ressource genügend Zeit hat, um die erforderlichen Aktionen durchzuführen und eine Antwort zurückzugeben.

# CloudFormation Referenz für benutzerdefinierte Ressourcenanfragen und Antworten
<a name="crpg-ref"></a>

CloudFormation verwaltet benutzerdefinierte Ressourcen über ein Request-Response-Protokoll, das mit Ihrem Anbieter für benutzerdefinierte Ressourcen kommuniziert. Jede Anfrage umfasst einen Anforderungstyp (`Create``Update`, oder`Delete`) und folgt diesem allgemeinen Arbeitsablauf:

1. Ein Vorlagenentwickler definiert eine benutzerdefinierte Ressource mit einem `ServiceToken` und `ServiceTimeout` in der Vorlage und initiiert einen Stack-Vorgang.

1. CloudFormation sendet über SNS oder Lambda eine JSON-Anfrage an den Anbieter benutzerdefinierter Ressourcen.

1. Der benutzerdefinierte Ressourcenanbieter verarbeitet die Anfrage und gibt eine JSON-Antwort an eine vorsignierte Amazon S3 S3-Bucket-URL zurück, bevor der Timeout-Zeitraum abläuft.

1. CloudFormation liest die Antwort und fährt mit dem Stack-Vorgang fort. Wenn vor Ablauf des Timeouts keine Antwort eingeht, gilt die Anfrage als nicht erfolgreich und der Stack-Vorgang schlägt fehl.

Weitere Informationen finden Sie unter [So funktionieren benutzerdefinierte Ressourcen](template-custom-resources.md#how-custom-resources-work).

In diesem Abschnitt werden die Struktur, die Parameter und die erwarteten Antworten für jeden Anforderungstyp beschrieben.

**Anmerkung**  
Die Gesamtgröße des Antworttexts darf 4 096 Bytes nicht überschreiten.

## Einrichtung der Vorlage
<a name="crpg-ref-template-setup"></a>

Bei der Definition einer benutzerdefinierten Ressource in einer Vorlage verwendet [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html)der Vorlagenentwickler die folgenden Eigenschaften:

`ServiceToken`  
Ein Amazon SNS SNS-Themen-ARN oder eine Lambda-Funktions-ARN aus derselben Region wie der Stack.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ServiceTimeout`  
Die maximale Zeit in Sekunden, bis das Timeout eines benutzerdefinierten Ressourcenvorgangs abläuft. Es muss ein Wert zwischen 1 und 3600 sein. Standard: 3600 Sekunden (1 Stunde).  
*Required*: No  
*Typ:* Zeichenfolge

Zusätzliche Ressourceneigenschaften werden unterstützt. Ressourceneigenschaften werden wie `ResourceProperties` in der Anfrage enthalten sein. Der benutzerdefinierte Ressourcenanbieter muss ermitteln, welche Eigenschaften gültig sind und welche Werte zulässig sind.

## Objekt anfordern
<a name="crpg-ref-requesttypes"></a>

------
#### [ Create ]

Wenn der Vorlagenentwickler einen Stapel erstellt, der eine benutzerdefinierte Ressource enthält, CloudFormation sendet er eine Anfrage mit der `RequestType` Einstellung auf`Create`.

Erstellenanforderungen enthalten die folgenden Felder:

`RequestType`  
`Create`.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`RequestId`  
Eine eindeutige ID für die Anforderung.  
Kombinieren Sie `StackId` mit `RequestId` und es bildet sich ein Wert, mit dem Sie eine Anforderung für eine bestimmte benutzerdefinierte Ressource eindeutig identifizieren können.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`StackId`  
Der Amazon-Ressourcenname (ARN), der den Stack identifiziert, der die benutzerdefinierte Ressource enthält.  
Kombinieren Sie `StackId` mit `RequestId` und es bildet sich ein Wert, mit dem Sie eine Anforderung für eine bestimmte benutzerdefinierte Ressource eindeutig identifizieren können.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ResponseURL`  
Die Antwort-URL identifiziert einen vorsignierten S3-Bucket, der Antworten vom Anbieter für benutzerdefinierte Ressourcen empfängt. CloudFormation  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ResourceType`  
Der vom Developer der Vorlagen gewählte Ressourcentyp der benutzerdefinierten Ressource in der CloudFormation -Vorlage. Namen für benutzerdefinierte Ressourcentypen dürfen bis zu 60 Zeichen lang sein und sowohl alphanumerische Zeichen als auch folgende Zeichen enthalten: `_@-`.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`LogicalResourceId`  
Der vom Entwickler der Vorlagen gewählte Name (logische ID) der benutzerdefinierten Ressource in der CloudFormation -Vorlage.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ResourceProperties`  
Dieses Feld enthält den Inhalt des `Properties`-Objekts, das vom Vorlagen-Entwickler gesendet wurde. Sein Inhalt wird durch benutzerdefinierte Ressourcenanbieter definiert.  
*Required*: No  
*Typ*: JSON-Objekt

*Beispiel*

```
{
   "RequestType" : "Create",
   "RequestId" : "unique-request-id",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/id",
   "ResponseURL" : "pre-signed-url-for-create-response",
   "ResourceType" : "Custom::MyCustomResourceType",
   "LogicalResourceId" : "resource-logical-id",
   "ResourceProperties" : {
      "key1" : "string",
      "key2" : [ "list" ],
      "key3" : { "key4" : "map" }
   }
}
```

------
#### [ Update ]

Wenn der Vorlagenentwickler Änderungen an den Eigenschaften einer benutzerdefinierten Ressource innerhalb der Vorlage vornimmt und den Stack aktualisiert, CloudFormation sendet er eine Anfrage an den Anbieter für benutzerdefinierte Ressourcen mit der `RequestType` Einstellung auf`Update`. Das bedeutet, dass Ihr benutzerdefinierter Ressourcencode keine Änderungen in den Ressourcen erkennen muss, da er weiß, dass sich seine Eigenschaften geändert haben, wenn der Anfragetyp `Update`ist.

Aktualisierungsanforderungen enthalten die folgenden Felder:

`RequestType`  
`Update`.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`RequestId`  
Eine eindeutige ID für die Anforderung.  
Kombinieren Sie `StackId` mit `RequestId` und es bildet sich ein Wert, mit dem Sie eine Anforderung für eine bestimmte benutzerdefinierte Ressource eindeutig identifizieren können.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`StackId`  
Der Amazon-Ressourcenname (ARN), der den Stack identifiziert, der die benutzerdefinierte Ressource enthält.  
Kombinieren Sie `StackId` mit `RequestId` und es bildet sich ein Wert, mit dem Sie eine Anforderung für eine bestimmte benutzerdefinierte Ressource eindeutig identifizieren können.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ResponseURL`  
Die Antwort-URL identifiziert einen vorsignierten S3-Bucket, der Antworten vom Anbieter für benutzerdefinierte Ressourcen empfängt. CloudFormation  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ResourceType`  
Der vom Developer der Vorlagen gewählte Ressourcentyp der benutzerdefinierten Ressource in der CloudFormation -Vorlage. Namen für benutzerdefinierte Ressourcentypen dürfen bis zu 60 Zeichen lang sein und sowohl alphanumerische Zeichen als auch folgende Zeichen enthalten: `_@-`. Bei einer Aktualisierung kann der Typ nicht geändert werden.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`LogicalResourceId`  
Der vom Entwickler der Vorlagen gewählte Name (logische ID) der benutzerdefinierten Ressource in der CloudFormation -Vorlage.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`PhysicalResourceId`  
Eine benutzerdefinierte, vom Ressourcenanbieter definierte physische ID, die für diesen Anbieter eindeutig ist.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ResourceProperties`  
Dieses Feld enthält den Inhalt des `Properties`-Objekts, das vom Vorlagen-Entwickler gesendet wurde. Sein Inhalt wird durch benutzerdefinierte Ressourcenanbieter definiert.  
*Required*: No  
*Typ*: JSON-Objekt

`OldResourceProperties`  
Wird nur für `Update`-Anforderungen verwendet. Gibt die bisherigen Ressourceneigenschafts-Werte an, die der Vorlagenentwickler zu einem früheren Zeitpunkt in der CloudFormation -Vorlage deklariert hatte.  
*Erforderlich*: Ja  
*Typ*: JSON-Objekt

*Beispiel*

```
{
   "RequestType" : "Update",
   "RequestId" : "unique-request-id",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/id",
   "ResponseURL" : "pre-signed-url-for-update-response",
   "ResourceType" : "Custom::MyCustomResourceType",
   "LogicalResourceId" : "resource-logical-id",
   "PhysicalResourceId" : "provider-defined-physical-id",
   "ResourceProperties" : {
      "key1" : "new-string",
      "key2" : [ "new-list" ],
      "key3" : { "key4" : "new-map" }
   },
   "OldResourceProperties" : {
      "key1" : "string",
      "key2" : [ "list" ],
      "key3" : { "key4" : "map" }
   }
}
```

------
#### [ Delete ]

Wenn der Vorlagenentwickler den Stack löscht oder die benutzerdefinierte Ressource aus der Vorlage entfernt und dann den Stapel aktualisiert, CloudFormation sendet er eine Anfrage mit `RequestType` der Einstellung auf. `Delete`

Anforderungen zum Löschen enthalten die folgenden Felder:

`RequestType`  
`Delete`.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`RequestId`  
Eine eindeutige ID für die Anforderung.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`StackId`  
Der Amazon-Ressourcenname (ARN), der den Stack identifiziert, der die benutzerdefinierte Ressource enthält.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ResponseURL`  
Die Antwort-URL identifiziert einen vorsignierten S3-Bucket, der Antworten vom Anbieter für benutzerdefinierte Ressourcen empfängt. CloudFormation  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ResourceType`  
Der vom Developer der Vorlagen gewählte Ressourcentyp der benutzerdefinierten Ressource in der CloudFormation -Vorlage. Namen für benutzerdefinierte Ressourcentypen dürfen bis zu 60 Zeichen lang sein und sowohl alphanumerische Zeichen als auch folgende Zeichen enthalten: `_@-`.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`LogicalResourceId`  
Der vom Entwickler der Vorlagen gewählte Name (logische ID) der benutzerdefinierten Ressource in der CloudFormation -Vorlage.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`PhysicalResourceId`  
Eine benutzerdefinierte, vom Ressourcenanbieter definierte physische ID, die für diesen Anbieter eindeutig ist.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`ResourceProperties`  
Dieses Feld enthält den Inhalt des `Properties`-Objekts, das vom Vorlagen-Entwickler gesendet wurde. Sein Inhalt wird durch benutzerdefinierte Ressourcenanbieter definiert.  
*Required*: No  
*Typ*: JSON-Objekt

*Beispiel*

```
{
   "RequestType" : "Delete",
   "RequestId" : "unique-request-id",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/id",
   "ResponseURL" : "pre-signed-url-for-delete-response",
   "ResourceType" : "Custom::MyCustomResourceType",
   "LogicalResourceId" : "resource-logical-id",
   "PhysicalResourceId" : "provider-defined-physical-id",
   "ResourceProperties" : {
      "key1" : "string",
      "key2" : [ "list" ],
      "key3" : { "key4" : "map" }
   }
}
```

------

## Antwortobjekt
<a name="crpg-ref-responses"></a>

Der benutzerdefinierte Ressourcenanbieter sendet für alle Anforderungstypen eine Antwort an die vorsignierte URL. Wenn der benutzerdefinierte Ressourcenanbieter keine Antwort sendet, CloudFormation wartet er, bis das Zeitlimit für den Vorgang überschritten wird.

Die Antwort muss ein JSON-Objekt mit den folgenden Feldern sein:

`Status`  
Es muss entweder `SUCCESS` oder `FAILED` sein.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`RequestId`  
Eine eindeutige ID für die Anforderung. Kopieren Sie diesen Wert genau so, wie er in der Anfrage erscheint.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`StackId`  
Der Amazon-Ressourcenname (ARN), der den Stack identifiziert, der die benutzerdefinierte Ressource enthält. Kopieren Sie diesen Wert genau so, wie er in der Anfrage erscheint.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`LogicalResourceId`  
Der vom Entwickler der Vorlagen gewählte Name (logische ID) der benutzerdefinierten Ressource in der CloudFormation -Vorlage. Kopieren Sie diesen Wert genau so, wie er in der Anfrage erscheint.  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`PhysicalResourceId`  
Dieser Wert sollte eine eindeutige Kennung für den Anbieter der benutzerdefinierten Ressource sein und kann bis zu 1 KB groß sein. Der Wert muss eine nicht leere Zeichenfolge sein und muss für alle Antworten für dieselbe Ressource identisch sein.  
Beim Aktualisieren von benutzerdefinierten Ressourcen `PhysicalResourceId` bestimmt der zurückgegebene Wert für das Aktualisierungsverhalten. Wenn der Wert gleich bleibt, wird dies CloudFormation als normales Update betrachtet. Wenn sich der Wert ändert, CloudFormation interpretiert das Update als Ersatz und sendet eine Löschanforderung an die alte Ressource. Weitere Informationen finden Sie unter [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html).  
*Erforderlich*: Ja  
*Typ:* Zeichenfolge

`Reason`  
Beschreibt den Grund für eine Reaktion auf einen Fehler.  
Erforderlich, wenn `Status` ein `FAILED` ist. Er ist andernfalls optional.  
*Required*: Conditional  
*Typ:* Zeichenfolge

`NoEcho`  
Gibt an, ob die Ausgabe der benutzerdefinierten Ressource maskiert wird, wenn sie mithilfe der `Fn::GetAtt`-Funktion abgerufen wird. Wenn diese Option auf `true` gesetzt ist. werden alle zurückgegebenen Werte mit Sternchen (\$1\$1\$1\$1\$1) maskiert *außer denen, die im `Metadata` Abschnitt der Vorlage* gespeichert sind. CloudFormation transformiert, ändert oder bearbeitet keine Informationen im `Metadata` Abschnitt. Der Standardwert ist `false`.  
Weitere Informationen über die Verwendung von `NoEcho` zur Maskierung sensibler Informationen finden Sie in der bewährten Methode [Keine Anmeldeinformationen in Vorlagen einbetten](security-best-practices.md#creds) .  
Nur für `Update` Antworten `Create` und verfügbar. Wird für `Delete` Antworten nicht unterstützt.  
*Required*: No  
*Typ*: Boolesch

`Data`  
Die vom benutzerdefinierten Ressourcenanbieter definierten Namen-Wert-Paare, die mit der Antwort gesendet werden. Sie können auf die hier namentlich angegebenen Werte in der Vorlage mit `Fn::GetAtt` zugreifen.  
Nur für `Create` `Update` Antworten verfügbar. Wird für `Delete` Antworten nicht unterstützt.  
Wenn die Namen-Wert-Paare vertrauliche Informationen enthalten, sollten Sie das `NoEcho`-Feld benutzen, um die Ausgabe der benutzerdefinierten Ressource zu maskieren. Andernfalls sind die Werte durch APIs diese Oberflächeneigenschaftswerte (z. B.`DescribeStackEvents`) sichtbar.
*Required*: No  
*Typ*: JSON-Objekt

### Beispiele für erfolgreiche Antworten
<a name="crpg-ref-success-response-examples"></a>

#### `Create`und `Update` Antwort
<a name="crpg-ref-success-response-example-1"></a>

```
{
   "Status": "SUCCESS",
   "RequestId": "unique-request-id",
   "StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/name/id",
   "LogicalResourceId": "resource-logical-id", 
   "PhysicalResourceId": "provider-defined-physical-id",
   "NoEcho": true,
   "Data": {
      "key1": "value1",
      "key2": "value2"
   }
}
```

#### `Delete`-Antwort
<a name="crpg-ref-success-response-example-2"></a>

```
{
   "Status": "SUCCESS",
   "RequestId": "unique-request-id",
   "StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/name/id",
   "LogicalResourceId": "resource-logical-id", 
   "PhysicalResourceId": "provider-defined-physical-id"
}
```

### Beispiel für eine gescheiterte Antwort
<a name="crpg-ref-failed-response-example"></a>

```
{
   "Status": "FAILED",
   "RequestId": "unique-request-id",
   "StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/name/id",
   "LogicalResourceId": "resource-logical-id",
   "PhysicalResourceId": "provider-defined-physical-id",
   "Reason": "Required failure reason string"
}
```

# Amazon SNS-gestützte benutzerdefinierte Ressourcen
<a name="template-custom-resources-sns"></a>

Das folgende Thema zeigt Ihnen, wie Sie eine benutzerdefinierte Ressource mit einem Service-Token konfigurieren, das das Amazon SNS SNS-Thema angibt, CloudFormation an das Anfragen gesendet werden. Sie lernen auch die Abfolge von Ereignissen und Nachrichten kennen, die als Ergebnis der Erstellung, Aktualisierung und Löschung eines benutzerdefinierten Ressourcenstapels gesendet und empfangen werden.

Bei benutzerdefinierten Ressourcen und Amazon SNS können Sie Szenarien wie das Hinzufügen neuer Ressourcen zu einem Stack und das Einfügen dynamischer Daten in einen Stack ermöglichen. Wenn Sie beispielsweise einen Stack erstellen, CloudFormation können Sie eine `Create` Anfrage an ein Thema senden, das von einer Anwendung überwacht wird, die auf einer Amazon EC2 EC2-Instance ausgeführt wird. Die Amazon-SNS-Benachrichtigung löst aus, dass die Anwendung weitere Bereitstellungsaufgaben ausführt, z. B. das Abrufen eines Pools von erlaubten Elastic-IP-Adressen. Danach sendet die Anwendung eine Antwort (und alle Ausgabedaten), in der Sie aufgefordert werden, mit dem Stack-Vorgang CloudFormation fortzufahren.

Wenn Sie ein Amazon SNS SNS-Thema als Ziel einer benutzerdefinierten Ressource angeben, CloudFormation sendet bei Stack-Vorgängen, die die benutzerdefinierte Ressource betreffen, Nachrichten an das angegebene SNS-Thema. Um diese Nachrichten zu verarbeiten und die erforderlichen Aktionen durchzuführen, müssen Sie einen unterstützten Endpunkt bei dem SNS-Thema abonniert haben.

Eine Einführung in benutzerdefinierte Ressourcen und ihre Funktionsweise finden Sie unter [So funktionieren benutzerdefinierte Ressourcen](template-custom-resources.md#how-custom-resources-work). Informationen über Amazon SNS und dessen Funktionsweise finden Sie im [Amazon-Simple-Notification-Service-Entwicklerleitfaden](https://docs.aws.amazon.com/sns/latest/dg/).

## Verwendung von Amazon SNS zur Erstellung benutzerdefinierter Ressourcen
<a name="walkthrough-custom-resources-sns-adding-nonaws-resource"></a>

**Topics**
+ [Schritt 1: Erstellen des Stacks](#crpg-walkthrough-stack-creation)
+ [Schritt 2: Stack-Updates](#crpg-walkthrough-stack-updates)
+ [Schritt 3: Löschen des Stacks](#crpg-walkthrough-stack-deletion)

### Schritt 1: Erstellen des Stacks
<a name="crpg-walkthrough-stack-creation"></a>

1. <a name="crpg-walkthrough-stack-creation-customer-template"></a>Der Vorlagenentwickler erstellt einen CloudFormation Stack, der eine benutzerdefinierte Ressource enthält. 

   In der Vorlage unten verwenden wir den benutzerdefinierten Ressourcentyp `Custom::SeleniumTester` für die benutzerdefinierte Ressource mit der logischen ID `MySeleniumTest`. Benutzerdefinierte Ressourcentypnamen müssen alphanumerisch sein und können maximal 60 Zeichen enthalten. 

   Der benutzerdefinierte Ressourcentyp wird mit einem Diensttoken, optionalen anbieterspezifischen Eigenschaften und optionalen [Fn:: GetAtt](resources-section-structure.md#resource-properties-getatt) -Attributen deklariert, die vom benutzerdefinierten Ressourcenanbieter definiert werden. Diese Eigenschaften und Attribute können verwendet werden, um Informationen vom template developer an custom resource provider zu übergeben und umgekehrt. Das Service-Token gibt ein Amazon SNS-Thema an, das der Ressourcenanbieter konfiguriert hat.

   ```
   {
      "AWSTemplateFormatVersion" : "2010-09-09",
      "Resources" : {
         "MySeleniumTest" : {
            "Type": "Custom::SeleniumTester",
            "Version" : "1.0",
            "Properties" : {
               "ServiceToken": "arn:aws:sns:us-west-2:123456789012:CRTest",
               "seleniumTester" : "SeleniumTest()",
               "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ],
               "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
            }
         }
      },
      "Outputs" : {
         "topItem" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] }
         },
         "numRespondents" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] }
         }
      }
   }
   ```
**Anmerkung**  
Die Namen und Werte der Daten, mit `Fn::GetAtt` denen zugegriffen wird, werden vom benutzerdefinierten Ressourcenanbieter während der Antwort des Anbieters auf zurückgegeben. CloudFormation Wenn der custom resource provider von einem Drittanbieter stammt, muss der template developer die Namen dieser Rückgabewerte vom custom resource provider abrufen.

1. <a name="crpg-walkthrough-stack-creation-provider-request"></a>CloudFormation sendet eine Amazon SNS SNS-Benachrichtigung an den Ressourcenanbieter mit einer`"RequestType" : "Create"`, die Informationen über den Stack, die benutzerdefinierten Ressourceneigenschaften aus der Stack-Vorlage und eine S3-URL für die Antwort enthält.

   Das SNS-Thema, das zum Senden der Benachrichtigung verwendet wird, ist in die Vorlage in der `ServiceToken`-Eigenschaft eingebettet. Um die Verwendung eines hartcodierten Werts zu vermeiden, kann ein Vorlagen-Entwickler einen Vorlagenparameter verwenden, sodass der Wert zu dem Zeitpunkt eingegeben wird, wenn der Stack gelauncht wird.

   Das folgende Beispiel zeigt eine `Create`-Anforderung einer benutzerdefinierten Ressource, die einen benutzerdefinierten Ressourcentypnamen, `Custom::SeleniumTester`, enthält, der mit der `LogicalResourceId` `MySeleniumTester` erstellt wurde:

   ```
   {
      "RequestType" : "Create",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::SeleniumTester",
      "LogicalResourceId" : "MySeleniumTester",
      "ResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
      }
   }
   ```

   Ausführliche Informationen über das Anfrageobjekt für `Create`-Anfragen finden Sie im Thema [Referenz für Anfrage und Antwort](crpg-ref.md) .

1. <a name="crpg-walkthrough-stack-creation-provider-response"></a>Der custom resource provider verarbeitet die Daten, die von template developer gesendet werden und bestimmt, ob die `Create`-Anforderung erfolgreich war. Der Ressourcenanbieter verwendet dann die von gesendete S3-URL CloudFormation , um eine Antwort entweder `SUCCESS` oder `FAILED` zu senden.

   Je nach Antworttyp werden unterschiedliche Antwortfelder von CloudFormation erwartet. Informationen über die Antwortfelder für einen bestimmten Anfragetyp finden Sie in der Dokumentation für diesen Anfragetyp im Abschnitt [Referenz für Anfrage und Antwort](crpg-ref.md) .

   Als Antwort auf eine Erstellungs- oder Aktualisierungsanfrage kann der benutzerdefinierte Ressourcenanbieter Datenelemente in das Feld `Data` der Antwort zurückgeben. Dabei handelt es sich um Name-Wert-Paare und die *Namen* entsprechen den `Fn::GetAtt`-Attributen mit der benutzerdefinierten Ressource in der Stack-Vorlage. Die *Werte* sind die Daten, die zurückgegeben werden, wenn der Vorlagen-Entwickler `Fn::GetAtt` für die Ressource mit dem Attributnamen aufruft.

   Nachfolgend finden Sie eine Beispielantwort einer benutzerdefinierten Ressource:

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1",
      "Data" : {
         "resultsPage" : "http://www.myexampledomain/test-results/guid",
         "lastUpdate" : "2012-11-14T03:30Z"
      }
   }
   ```

   Ausführliche Informationen über das Antwortobjekt für `Create`-Anfragen finden Sie im Thema [Referenz für Anfrage und Antwort](crpg-ref.md) .

   Die `StackId`, `RequestId` und `LogicalResourceId`-Felder müssen wörtlich aus der Anforderung kopiert werden.

1. <a name="crpg-walkthrough-stack-creation-stack-status"></a> CloudFormation deklariert den Stack-Status als `CREATE_COMPLETE` oder`CREATE_FAILED`. Wenn der Stack erfolgreich erstellt wurde, kann der Vorlagenentwickler die Ausgabewerte der erstellten benutzerdefinierten Ressource verwenden, indem er mit [Fn:: GetAtt](resources-section-structure.md#resource-properties-getatt) auf sie zugreift.

   Die benutzerdefinierte Ressourcenvorlage, die zur Veranschaulichung verwendet wird, verwendete `Fn::GetAtt` zum Kopieren von Ressourcenausgaben in die Stack-Ausgabe:

   ```
   "Outputs" : {
      "topItem" : {
         "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] }
      },
      "numRespondents" : {
         "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] }
      }
   }
   ```

### Schritt 2: Stack-Updates
<a name="crpg-walkthrough-stack-updates"></a>

Um einen vorhandenen Stack zu aktualisieren, müssen Sie eine Vorlage übermitteln, die Updates für die Eigenschaften von Ressourcen im Stack angibt, wie im folgenden Beispiel dargestellt. CloudFormation aktualisiert nur die Ressourcen, für die Änderungen in der Vorlage angegeben sind. Weitere Informationen finden Sie unter [Verstehen des Aktualisierungsverhaltens von Stack-Ressourcen](using-cfn-updating-stacks-update-behaviors.md).

Sie können benutzerdefinierte Ressourcen aktualisieren, bei denen eine der zugrunde liegenden physischen Ressourcen ersetzt werden muss. Wenn Sie eine benutzerdefinierte Ressource in einer CloudFormation Vorlage aktualisieren, CloudFormation sendet eine Aktualisierungsanforderung an diese benutzerdefinierte Ressource. Wenn eine benutzerdefinierte Ressource ersetzt werden muss, muss die neu benutzerdefinierte Ressource eine Antwort mit der neuen physischen ID senden. When CloudFormation die Antwort empfängt, wird die `PhysicalResourceId` der alten und der neuen benutzerdefinierten Ressource verglichen. Wenn sie unterschiedlich sind, CloudFormation erkennt das Update als Ersatz und sendet eine Löschanfrage an die alte Ressource, wie unter gezeigt[Schritt 3: Löschen des Stacks](#crpg-walkthrough-stack-deletion).

**Anmerkung**  
Wenn Sie keine Änderungen an der benutzerdefinierten Ressource vorgenommen haben, CloudFormation werden während eines Stack-Updates keine Anfragen an sie gesendet.

1. <a name="crpg-walkthrough-stack-updates-customer-template"></a>Der template developer initiiert ein Update für den Stack, der eine benutzerdefinierte Ressource enthält. Während eines Update kann template developer neue Eigenschaften in der Stack-Vorlage angeben.

   Nachfolgend sehen Sie ein Beispiel für ein `Update` am der Stack-Vorlage mithilfe eines benutzerdefinierten Ressourcentyps:

   ```
   {
      "AWSTemplateFormatVersion" : "2010-09-09",
      "Resources" : {
         "MySeleniumTest" : {
            "Type": "Custom::SeleniumTester",
            "Version" : "1.0",
            "Properties" : {
               "ServiceToken": "arn:aws:sns:us-west-2:123456789012:CRTest",
               "seleniumTester" : "SeleniumTest()",
               "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
                  "http://mynewsite.com" ],
               "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ]
            }
         }
      },
      "Outputs" : {
         "topItem" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "resultsPage"] }
         },
         "numRespondents" : {
            "Value" : { "Fn::GetAtt" : ["MySeleniumTest", "lastUpdate"] }
         }
      }
   }
   ```

1. <a name="crpg-walkthrough-stack-updates-provider-request"></a>CloudFormation sendet eine Amazon SNS SNS-Benachrichtigung an den Ressourcenanbieter mit einer`"RequestType" : "Update"`, die ähnliche Informationen wie der `Create` Anruf enthält, außer dass das `OldResourceProperties` Feld die alten Ressourceneigenschaften und die aktualisierten (falls vorhanden) Ressourceneigenschaften ResourceProperties enthält.

   Es folgt ein Beispiel für eine `Update`-Anforderung.

   ```
   {
      "RequestType" : "Update",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::SeleniumTester",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1",
      "ResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
            "http://mynewsite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ]
      },
      "OldResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4" ]
      }
   }
   ```

   Ausführliche Informationen über das Anfrageobjekt für `Update`-Anfragen finden Sie im Thema [Referenz für Anfrage und Antwort](crpg-ref.md) .

1. <a name="crpg-walkthrough-stack-updates-provider-response"></a>Der benutzerdefinierte Ressourcenanbieter verarbeitet die von CloudFormation gesendeten Daten. Die benutzerdefinierte Ressource führt das Update durch und sendet eine Antwort entweder `SUCCESS` oder `FAILED` an die S3-URL. CloudFormation vergleicht dann `PhysicalResourceIDs` die alten und neuen benutzerdefinierten Ressourcen. Wenn sie unterschiedlich sind, CloudFormation erkennt, dass für das Update ein Ersatz erforderlich ist, und sendet eine Löschanforderung an die alte Ressource. Das folgende Beispiel zeigt die custom resource provider-Antwort auf eine `Update`-Anforderung.

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester2"
   }
   ```

   Ausführliche Informationen über das Antwortobjekt für `Update`-Anfragen finden Sie im Thema [Referenz für Anfrage und Antwort](crpg-ref.md) .

   Die `StackId`, `RequestId` und `LogicalResourceId`-Felder müssen wörtlich aus der Anforderung kopiert werden.

1. <a name="crpg-walkthrough-stack-updates-stack-status"></a>CloudFormation deklariert den Stack-Status als `UPDATE_COMPLETE` oder`UPDATE_FAILED`. Wenn das Update fehlschlägt, wird der Stack zurückgesetzt. Wenn der Stack erfolgreich aktualisiert wurde, kann der template developer auf neue Ausgabewerte der erstellten benutzerdefinierten mit `Fn::GetAtt` zugreifen.

### Schritt 3: Löschen des Stacks
<a name="crpg-walkthrough-stack-deletion"></a>

1. <a name="crpg-walkthrough-stack-deletion-customer-template"></a>Der Vorlagen-Entwickler löscht einen Stack, der eine benutzerdefinierte Ressource enthält. CloudFormation ruft die aktuellen Eigenschaften, die in der Stack-Vorlage angegeben sind, zusammen mit dem SNS-Thema ab und bereitet sich darauf vor, eine Anforderung an den benutzerdefinierten Ressourcenanbieter zu stellen.

1. <a name="crpg-walkthrough-stack-deletion-provider-request"></a>CloudFormation sendet eine Amazon SNS SNS-Benachrichtigung an den Ressourcenanbieter mit einer`"RequestType" : "Delete"`, die aktuelle Informationen über den Stack, die benutzerdefinierten Ressourceneigenschaften aus der Stack-Vorlage und eine S3-URL für die Antwort enthält.

   Immer wenn Sie einen Stapel löschen oder ein Update vornehmen, bei dem die benutzerdefinierte Ressource entfernt oder ersetzt wird, werden `PhysicalResourceId` die alten und neuen benutzerdefinierten Ressourcen CloudFormation verglichen. Wenn sie unterschiedlich sind, CloudFormation erkennt das Update als Ersatz und sendet eine Löschanforderung für die alte Ressource (`OldPhysicalResource`), wie im folgenden Beispiel für eine `Delete` Anfrage gezeigt.

   ```
   {
      "RequestType" : "Delete",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "ResponseURL" : "http://pre-signed-S3-url-for-response",
      "ResourceType" : "Custom::SeleniumTester",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1",
      "ResourceProperties" : {
         "seleniumTester" : "SeleniumTest()",
         "endpoints" : [ "http://mysite.com", "http://myecommercesite.com/", "http://search.mysite.com",
            "http://mynewsite.com" ],
         "frequencyOfTestsPerHour" : [ "3", "2", "4", "3" ]
      }
   }
   ```

   Ausführliche Informationen über das Anfrageobjekt für `Delete`-Anfragen finden Sie im Thema [Referenz für Anfrage und Antwort](crpg-ref.md) .

   `DescribeStackResource`, `DescribeStackResources` und `ListStackResources` zeigen den benutzerdefinierten Namen an, wenn er angegeben wurde.

1. <a name="crpg-walkthrough-stack-deletion-provider-response"></a>Der benutzerdefinierte Ressourcenanbieter verarbeitet die von gesendeten Daten CloudFormation und stellt fest, ob die `Delete` Anfrage erfolgreich war. Der Ressourcenanbieter verwendet dann die von gesendete S3-URL CloudFormation , um eine Antwort entweder `SUCCESS` oder zu senden`FAILED`. Wenn Sie eine benutzerdefinierte Ressource löschen möchten, muss custom resource provider erfolgreich auf eine Löschenanfrage antworten.

   Das folgende Beispiel zeigt die custom resource provider-Antwort auf eine `Delete`-Anforderung.

   ```
   {
      "Status" : "SUCCESS",
      "RequestId" : "unique-request-id",
      "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10",
      "LogicalResourceId" : "MySeleniumTester",
      "PhysicalResourceId" : "Tester1"
   }
   ```

   Ausführliche Informationen über das Antwortobjekt für `Delete`-Anfragen finden Sie im Thema [Referenz für Anfrage und Antwort](crpg-ref.md) .

   Die `StackId`, `RequestId` und `LogicalResourceId`-Felder müssen wörtlich aus der Anforderung kopiert werden.

1. <a name="crpg-walkthrough-stack-updates-stack-status-delete"></a>CloudFormation deklariert den Stack-Status als `DELETE_COMPLETE` oder`DELETE_FAILED`.

# Lambda-gestützte benutzerdefinierte Ressourcen
<a name="template-custom-resources-lambda"></a>

Wenn Sie eine Lambda-Funktion einer benutzerdefinierten Ressource zuordnen, wird die Funktion immer dann aufgerufen, wenn die benutzerdefinierte Ressource erstellt, aktualisiert oder gelöscht wird. CloudFormation ruft eine Lambda-API auf, um die Funktion aufzurufen und alle Anforderungsdaten (z. B. Anforderungstyp und Ressourceneigenschaften) an die Funktion zu übergeben. Die Leistungsfähigkeit und Anpassungsfähigkeit von Lambda-Funktionen in Kombination mit CloudFormation ermöglichen eine Vielzahl von Szenarien, z. B. das dynamische Nachschlagen von AMI IDs während der Stack-Erstellung oder die Implementierung und Verwendung von Hilfsfunktionen wie String-Reversal-Funktionen.

Eine Einführung in benutzerdefinierte Ressourcen und ihre Funktionsweise finden Sie unter [So funktionieren benutzerdefinierte Ressourcen](template-custom-resources.md#how-custom-resources-work).

**Topics**
+ [Exemplarische Vorgehensweise: Erstellen Sie einen Verzögerungsmechanismus mit einer Lambda-gestützten benutzerdefinierten Ressource](walkthrough-lambda-backed-custom-resources.md)
+ [`cfn-response`-Modul](cfn-lambda-function-code-cfnresponsemodule.md)

# Exemplarische Vorgehensweise: Erstellen Sie einen Verzögerungsmechanismus mit einer Lambda-gestützten benutzerdefinierten Ressource
<a name="walkthrough-lambda-backed-custom-resources"></a>

In dieser exemplarischen Vorgehensweise wird anhand einer Beispielvorlage gezeigt, wie Sie eine Lambda-gestützte benutzerdefinierte Ressource konfigurieren und starten. CloudFormation Diese Vorlage erstellt einen Verzögerungsmechanismus, der Stack-Bereitstellungen für eine bestimmte Zeit pausiert. Dies kann nützlich sein, wenn Sie bei der Bereitstellung von Ressourcen bewusst Verzögerungen einführen müssen, z. B. wenn Sie darauf warten, dass sich Ressourcen stabilisieren, bevor abhängige Ressourcen erstellt werden.

**Anmerkung**  
Während zuvor Lambda-gestützte benutzerdefinierte Ressourcen für das Abrufen von AMI empfohlen wurden IDs, empfehlen wir jetzt die Verwendung von Parametern. AWS Systems Manager Dieser Ansatz macht Ihre Vorlagen wiederverwendbarer und einfacher zu verwalten. Weitere Informationen finden Sie unter [Abrufen eines Klartextwertes aus dem Systems Manager Parameter Store](dynamic-references-ssm.md). 

**Topics**
+ [-Übersicht](#walkthrough-lambda-backed-custom-resources-overview)
+ [Beispielvorlage](#walkthrough-lambda-backed-custom-resources-sample-template)
+ [Exemplarische Vorgehensweise für eine Vorlage](#walkthrough-lambda-backed-custom-resources-sample-template-walkthrough)
+ [Voraussetzungen](#walkthrough-lambda-backed-custom-resources-prerequisites)
+ [Starten des Stapels](#walkthrough-lambda-backed-custom-resources-createfunction-createstack)
+ [Bereinigen von Ressourcen](#walkthrough-lambda-backed-custom-resources-createfunction-cleanup)
+ [Ähnliche Informationen](#w2aac11c45b9c24b9c23)

## -Übersicht
<a name="walkthrough-lambda-backed-custom-resources-overview"></a>

Die in dieser exemplarischen Vorgehensweise verwendete Beispielstapelvorlage erstellt eine Lambda-gestützte benutzerdefinierte Ressource. Diese benutzerdefinierte Ressource führt zu einer konfigurierbaren Verzögerung (standardmäßig 60 Sekunden) bei der Stack-Erstellung. Die Verzögerung tritt bei Stack-Aktualisierungen nur auf, wenn die Eigenschaften der benutzerdefinierten Ressource geändert werden.

Die Vorlage enthält die folgenden Ressourcen:
+ eine benutzerdefinierte Ressource,
+ eine Lambda-Funktion und
+ eine IAM-Rolle, in die Lambda Logs schreiben kann. CloudWatch

Sie definiert auch zwei Ausgaben:
+ Die tatsächliche Zeit, zu der die Funktion gewartet hat.
+ Eine eindeutige Kennung, die bei jeder Ausführung der Lambda-Funktion generiert wird.



**Anmerkung**  
CloudFormation ist ein kostenloser Service, aber Lambda berechnet Gebühren auf der Grundlage der Anzahl der Anfragen für Ihre Funktionen und der Zeit, in der Ihr Code ausgeführt wird. Weitere Informationen über Lambda-Preise finden Sie unter [AWS Lambda Preisgestaltung](https://aws.amazon.com/lambda/pricing/).

## Beispielvorlage
<a name="walkthrough-lambda-backed-custom-resources-sample-template"></a>

Sie können die Lambda-gestützte Beispielvorlage für benutzerdefinierte Ressourcen mit dem Verzögerungsmechanismus unten sehen:

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-json"></a>

```
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Resources": {
    "LambdaExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": { "Service": ["lambda.amazonaws.com"] },
            "Action": ["sts:AssumeRole"]
          }]
        },
        "Path": "/",
        "Policies": [{
          "PolicyName": "AllowLogs",
          "PolicyDocument": {
            "Statement": [{
              "Effect": "Allow",
              "Action": ["logs:*"],
              "Resource": "*"
            }]
          }
        }]
      }
    },
    "CFNWaiter": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Handler": "index.handler",
        "Runtime": "python3.9",
        "Timeout": 900,
        "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] },
        "Code": {
          "ZipFile": { "Fn::Join": ["\n", [
            "from time import sleep",
            "import json",
            "import cfnresponse",
            "import uuid",
            "",
            "def handler(event, context):",
            "  wait_seconds = 0",
            "  id = str(uuid.uuid1())",
            "  if event[\"RequestType\"] in [\"Create\", \"Update\"]:",
            "    wait_seconds = int(event[\"ResourceProperties\"].get(\"ServiceTimeout\", 0))",
            "    sleep(wait_seconds)",
            "  response = {",
            "    \"TimeWaited\": wait_seconds,",
            "    \"Id\": id ",
            "  }",
            "  cfnresponse.send(event, context, cfnresponse.SUCCESS, response, \"Waiter-\"+id)"
          ]]}
        }
      }
    },
    "CFNWaiterCustomResource": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": { "Fn::GetAtt": ["CFNWaiter", "Arn"] },
        "ServiceTimeout": 60
      }
    }
  },
  "Outputs": {
    "TimeWaited": {
      "Value": { "Fn::GetAtt": ["CFNWaiterCustomResource", "TimeWaited"] },
      "Export": { "Name": "TimeWaited" }
    },
    "WaiterId": {
      "Value": { "Fn::GetAtt": ["CFNWaiterCustomResource", "Id"] },
      "Export": { "Name": "WaiterId" }
    }
  }
}
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-yaml"></a>

```
AWSTemplateFormatVersion: "2010-09-09"
Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
      Policies:
        - PolicyName: "AllowLogs"
          PolicyDocument:
            Statement:
              - Effect: "Allow"
                Action:
                  - "logs:*"
                Resource: "*"
  CFNWaiter:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Runtime: python3.9 
      Timeout: 900
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile:
          !Sub |
          from time import sleep
          import json
          import cfnresponse
          import uuid
​
          def handler(event, context):
            wait_seconds = 0
            id = str(uuid.uuid1())
            if event["RequestType"] in ["Create", "Update"]:
              wait_seconds = int(event["ResourceProperties"].get("ServiceTimeout", 0))
              sleep(wait_seconds)
            response = {
              "TimeWaited": wait_seconds,
              "Id": id 
            }
            cfnresponse.send(event, context, cfnresponse.SUCCESS, response, "Waiter-"+id)
  CFNWaiterCustomResource:
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken: !GetAtt CFNWaiter.Arn
      ServiceTimeout: 60
Outputs:
  TimeWaited:
    Value: !GetAtt CFNWaiterCustomResource.TimeWaited
    Export:
      Name: TimeWaited
  WaiterId:
    Value: !GetAtt CFNWaiterCustomResource.Id
    Export:
      Name: WaiterId
```

## Exemplarische Vorgehensweise für eine Vorlage
<a name="walkthrough-lambda-backed-custom-resources-sample-template-walkthrough"></a>

Die folgenden Schnipsel erläutern relevante Teile der Beispielvorlage, damit Sie verstehen, wie die Lambda-Funktion mit einer benutzerdefinierten Ressource verknüpft ist und die Ausgabe verstehen.

[AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html)Ressource `CFNWaiter`  
-Bei der `AWS::Lambda::Function` Ressource gilt der Quellcode der Funktion, der Handler-Name, die Laufzeitumgebung sowie der Amazon Resource Name (ARN) der Ausführungsrolle.  
Die `Handler` Eigenschaft ist auf gesetzt, `index.handler` da sie einen Python-Quellcode verwendet. Weitere Informationen zu akzeptierten Handler-Identifikatoren bei der Verwendung von Quellcodes für Inline-Funktionen finden Sie unter [ AWS::Lambda::Function Code](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html#cfn-lambda-function-code-zipfile).  
Das `Runtime` wird als `python3.9` angegeben, da die Quelldatei ein Python-Code ist.  
Der Wert `Timeout` ist auf 900 Sekunden eingestellt.  
Die Eigenschaft `Role` verwendet die Funktion `Fn::GetAtt`, um den ARN der Ausführungsrolle `LambdaExecutionRole` zu erhalten, die in der Ressource `AWS::IAM::Role` in der Vorlage deklariert ist.  
Die Eigenschaft `Code` definiert den Funktionscode inline mit einer Python-Funktion. Die Python-Funktion in der Beispielvorlage macht Folgendes:  
+ Erstellen Sie eine eindeutige ID mit der UUID
+ Prüfen Sie, ob die Anfrage eine Erstellungs- oder Aktualisierungsanfrage ist
+ Ruhezustand für die für `ServiceTimeout` angegebene Dauer während `Create` oder `Update` Anfragen
+ Geben Sie die Wartezeit und die eindeutige ID zurück

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-lambda-resource-json"></a>

```
...
    "CFNWaiter": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Handler": "index.handler",
        "Runtime": "python3.9",
        "Timeout": 900,
        "Role": { "Fn::GetAtt": ["LambdaExecutionRole", "Arn"] },
        "Code": {
          "ZipFile": { "Fn::Join": ["\n", [
            "from time import sleep",
            "import json",
            "import cfnresponse",
            "import uuid",
            "",
            "def handler(event, context):",
            "  wait_seconds = 0",
            "  id = str(uuid.uuid1())",
            "  if event[\"RequestType\"] in [\"Create\", \"Update\"]:",
            "    wait_seconds = int(event[\"ResourceProperties\"].get(\"ServiceTimeout\", 0))",
            "    sleep(wait_seconds)",
            "  response = {",
            "    \"TimeWaited\": wait_seconds,",
            "    \"Id\": id ",
            "  }",
            "  cfnresponse.send(event, context, cfnresponse.SUCCESS, response, \"Waiter-\"+id)"
          ]]}
        }
      }
    },
...
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-lambda-resource-yaml"></a>

```
...
  CFNWaiter:
    Type: AWS::Lambda::Function
    Properties:
      Handler: index.handler
      Runtime: python3.9 
      Timeout: 900
      Role: !GetAtt LambdaExecutionRole.Arn
      Code:
        ZipFile:
          !Sub |
          from time import sleep
          import json
          import cfnresponse
          import uuid
​
          def handler(event, context):
            wait_seconds = 0
            id = str(uuid.uuid1())
            if event["RequestType"] in ["Create", "Update"]:
              wait_seconds = int(event["ResourceProperties"].get("ServiceTimeout", 0))
              sleep(wait_seconds)
            response = {
              "TimeWaited": wait_seconds,
              "Id": id 
            }
            cfnresponse.send(event, context, cfnresponse.SUCCESS, response, "Waiter-"+id)
...
```

[AWS::IAM::Role](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-iam-role.html)Ressource `LambdaExecutionRole`  
Die Ressource `AWS::IAM:Role` erstellt eine Ausführungsrolle für die Lambda-Funktion, die eine "assume role"-Richtlinie enthält, die es Lambda erlaubt, sie zu verwenden. Es enthält auch eine Richtlinie, die den Zugriff auf CloudWatch Protokolle ermöglicht.

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-iam-role-json"></a>

```
...
    "LambdaExecutionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "AssumeRolePolicyDocument": {
          "Statement": [{
            "Effect": "Allow",
            "Principal": { "Service": ["lambda.amazonaws.com"] },
            "Action": ["sts:AssumeRole"]
          }]
        },
        "Path": "/",
        "Policies": [{
          "PolicyName": "AllowLogs",
          "PolicyDocument": {
            "Statement": [{
              "Effect": "Allow",
              "Action": ["logs:*"],
              "Resource": "*"
            }]
          }
        }]
      }
    },
...
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-iam-role-yaml"></a>

```
...
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
      Policies:
        - PolicyName: "AllowLogs"
          PolicyDocument:
            Statement:
              - Effect: "Allow"
                Action:
                  - "logs:*"
                Resource: "*"
...
```

[AWS::CloudFormation::CustomResource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html)Ressource `CFNWaiterCustomResource`  
Die benutzerdefinierte Ressource verlinkt auf die Lambda-Funktion mit ihrem ARN über `!GetAtt CFNWaiter.Arn`. Es wird eine Wartezeit von 60 Sekunden für Erstellungs- und Aktualisierungsvorgänge implementiert, wie in `ServiceTimeout`festgelegt. Die Ressource wird nur dann für einen Aktualisierungsvorgang aufgerufen, wenn die Eigenschaften geändert werden.

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-custom-resource-json"></a>

```
...
    "CFNWaiterCustomResource": {
      "Type": "AWS::CloudFormation::CustomResource",
      "Properties": {
        "ServiceToken": { "Fn::GetAtt": ["CFNWaiter", "Arn"] },
        "ServiceTimeout": 60
      }
    }
  },
...
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-custom-resource-yaml"></a>

```
...
  CFNWaiterCustomResource:
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken: !GetAtt CFNWaiter.Arn
      ServiceTimeout: 60
...
```

`Outputs`  
Die `Outputs` dieser Vorlage sind die `TimeWaited` und die `WaiterId`. Der `TimeWaited`-Wert verwendet eine `Fn::GetAtt`-Funktion, um die Zeit anzugeben, die die Kellnerressource tatsächlich gewartet hat. Die `WaiterId`-Funktion verwendet eine `Fn::GetAtt`-Funktion, um die eindeutige ID bereitzustellen, die erzeugt und mit der Ausführung verknüpft wurde.

### JSON
<a name="walkthrough-lambda-backed-custom-resources-sample-template-output-json"></a>

```
...
  "Outputs": {
    "TimeWaited": {
      "Value": { "Fn::GetAtt": ["CFNWaiterCustomResource", "TimeWaited"] },
      "Export": { "Name": "TimeWaited" }
    },
    "WaiterId": {
      "Value": { "Fn::GetAtt": ["CFNWaiterCustomResource", "Id"] },
      "Export": { "Name": "WaiterId" }
    }
  }
}
...
```

### YAML
<a name="walkthrough-lambda-backed-custom-resources-sample-template-output-yaml"></a>

```
...
Outputs:
  TimeWaited:
    Value: !GetAtt CFNWaiterCustomResource.TimeWaited
    Export:
      Name: TimeWaited
  WaiterId:
    Value: !GetAtt CFNWaiterCustomResource.Id
    Export:
      Name: WaiterId
...
```

## Voraussetzungen
<a name="walkthrough-lambda-backed-custom-resources-prerequisites"></a>

Sie benötigen IAM-Berechtigungen, um alle entsprechenden Dienste wie Lambda und verwenden zu können. CloudFormation

## Starten des Stapels
<a name="walkthrough-lambda-backed-custom-resources-createfunction-createstack"></a>

**So erstellen Sie den Stack**

1. Suchen Sie die gewünschte Vorlage (YAML oder JSON) aus dem Abschnitt [Beispielvorlage](#walkthrough-lambda-backed-custom-resources-sample-template) und speichern Sie sie auf Ihrem Rechner unter dem Namen `samplelambdabackedcustomresource.template`.

1. Öffnen Sie die CloudFormation Konsole unter. [https://console.aws.amazon.com/cloudformation/](https://console.aws.amazon.com/cloudformation/)

1. Wählen Sie auf der Seite **Stack** oben rechts **Stack erstellen** und dann **Mit neuen Ressourcen (Standard)**.

1. Für **Voraussetzung - Vorlage vorbereiten**wählen Sie **Vorhandene Vorlage auswählen**.

1. Für **Vorlage angeben**, wählen Sie **Eine Vorlagendatei hochladen**und dann **Datei auswählen**.

1. Wählen Sie die Vorlagendatei `samplelambdabackedcustomresource.template`, die Sie zuvor gespeichert haben.

1. Wählen Sie **Weiter** aus.

1. Für **Stapelname**, geben Sie **SampleCustomResourceStack** ein und wählen **Weiter**.

1. Für diese Anleitung müssen Sie keine Tags hinzufügen oder erweiterte Einstellungen angeben, wählen Sie daher **Weiter** aus.

1. Vergewissern Sie sich, dass der Name des Stapels korrekt ist, und wählen Sie dann **Erstellen**.

Es kann mehrere Minuten dauern CloudFormation , bis Ihr Stack erstellt ist. Betrachten Sie die Stack-Ereignisse, um den Fortschritt zu überwachen. Weitere Informationen finden Sie unter [Stack-Informationen von der CloudFormation Konsole aus anzeigen](cfn-console-view-stack-data-resources.md).

Wenn die Stack-Erstellung erfolgreich war, wurden alle Ressourcen im Stack, wie die Lambda-Funktion und die benutzerdefinierte Ressource, erstellt. Sie haben erfolgreich eine Lambda-Funktion und eine benutzerdefinierte Ressource verwendet.

Wenn die Lambda-Funktion einen Fehler zurückgibt, sehen Sie sich die Protokolle der Funktion in der CloudWatch [Logs-Konsole](https://console.aws.amazon.com/cloudwatch/home#logs:) an. Der Name des Protokollstreams ist die physische ID der benutzerdefinierten Ressource, die Sie durch Anzeigen der Ressourcen des Stacks finden können. Weitere Informationen finden Sie unter [Protokolldaten anzeigen](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#ViewingLogData) im * CloudWatch Amazon-Benutzerhandbuch*.

## Bereinigen von Ressourcen
<a name="walkthrough-lambda-backed-custom-resources-createfunction-cleanup"></a>

Löschen Sie den Stack, um alle Stack-Ressourcen zu bereinigen, die Sie erstellt haben, damit Ihnen keine unnötigen Ressourcen in Rechnung gestellt werden.

**So löschen Sie den Stack**

1. Wählen Sie in der CloudFormation Konsole den **SampleCustomResourceStack**Stack aus.

1. Wählen Sie die Option **Actions** und anschließend **Delete Stack** aus.

1. Wählen Sie im Bestätigungsdialogfeld **Yes, Delete** aus.

Alle erstellten Ressourcen werden gelöscht.

Da Sie nun wissen, wie Sie Lambda-gestützte benutzerdefinierte Ressourcen erstellen und verwenden können, können Sie die Beispielvorlage und den Code aus dieser Anleitung verwenden, um andere Stacks und Funktionen zu erstellen und mit ihnen zu experimentieren.

## Ähnliche Informationen
<a name="w2aac11c45b9c24b9c23"></a>
+ [CloudFormation Referenz für benutzerdefinierte Ressourcen](crpg-ref.md)
+ [AWS::CloudFormation::CustomResource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html)

# `cfn-response`-Modul
<a name="cfn-lambda-function-code-cfnresponsemodule"></a>

In Ihrer CloudFormation Vorlage können Sie eine Lambda-Funktion als Ziel einer benutzerdefinierten Ressource angeben. Wenn Sie die Eigenschaft `ZipFile` verwenden, um den-Quellcode Ihrer [Funktion](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html) anzugeben, können Sie das `cfn-response`-Modul laden, um Antworten von Ihrer Lambda-Funktion an eine benutzerdefinierte Ressource zu senden. Das Modul `cfn-response` ist eine Bibliothek, die das Senden von Antworten an die benutzerdefinierte Ressource, die Ihre Lambda-Funktion aufgerufen hat, vereinfacht. Das Modul verfügt über eine `send`-Methode, die ein-[Antwortobjekt](crpg-ref.md#crpg-ref-responses) über eine von Amazon S3 vorgegebene URL (die `ResponseURL`) an eine benutzerdefinierte Ressource sendet.

Das `cfn-response`-Modul ist nur verfügbar, wenn Sie die `ZipFile`-Eigenschaft verwenden, um Ihren Quell-Code zu schreiben. Es ist für Quellcode, der in Amazon S3-Buckets gespeichert wird, nicht verfügbar. Für Code in -Buckets müssen Sie eigene Funktionen schreiben um Antworten senden zu können.

**Anmerkung**  
Nach dem Ausführen der `send`-Methode wird die Lambda-Funktion beendet, und alles, was Sie nach dieser Methode schreiben, wird ignoriert.

## Laden des `cfn-response`-Moduls
<a name="cfn-lambda-function-code-cfnresponsemodule-loading"></a>

Verwenden Sie bei Node.js-Funktionen die `require()`-Funktion, um das `cfn-response`-Modul zu laden. Im folgenden Codebeispiel wird ein `cfn-response`-Objekt mit dem Namen `response` erstellt:

```
var response = require('cfn-response');
```

Verwenden Sie bei Python die `import`-Anweisung, um das `cfnresponse`-Modul zu laden, wie im folgenden Beispiel veranschaulicht:

**Anmerkung**  
Verwenden Sie genau dieses Import-Statement Wenn Sie andere Varianten desselben Import-Anweisung verwenden, beachtet CloudFormation das Antwortmodul nicht.

```
import cfnresponse
```

## Parameter für die `send`-Methode
<a name="cfn-lambda-function-code-cfnresponsemodule-send-parameters"></a>

Mit der `send`-Methode können Sie die folgenden Parameter verwenden.

`event`  
Die Felder in einer [benutzerdefinierten Ressourcenanforderung](crpg-ref.md#crpg-ref-requesttypes).

`context`  
Ein Objekt, das für Lambda-Funktionen festgelegt wurde und das Sie verwenden können, um festzulegen, wann die Funktion und alle Callbacks abschließend ausgeführt wurden, oder um aus der Lambda-Ausführungsumgebung auf Informationen zuzugreifen. Weitere Informationen finden Sie unter [Erstellen von Lambda-Funktionen mit Node.js](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html) im *AWS Lambda -Entwicklerleitfaden*.

`responseStatus`  
Gibt an, ob die Funktion erfolgreich abgeschlossen wurde. Verwenden Sie die `cfnresponse`-Modulkonstanten, um den Status festzulegen: `SUCCESS` für erfolgreiche Ausführungen und `FAILED` für fehlgeschlagene Ausführungen.

`responseData`  
Das `Data`-Feld für ein benutzerdefiniertes Ressourcen-[Antwortobjekt](crpg-ref.md#crpg-ref-responses). Die Daten sind eine Liste von Name-Wert-Paaren.

`physicalResourceId`  
Optional. Die eindeutige Kennung der benutzerdefinierten Ressource, die die Funktion aufgerufen hat. Standardmäßig verwendet das Modul den Namen des Amazon CloudWatch Logs-Protokollstreams, der mit der Lambda-Funktion verknüpft ist.  
Der für eine `PhysicalResourceId` zurückgegebene Wert kann benutzerdefinierte Vorgänge zur Ressourcenaktualisierung ändern. Wenn der zurückgegebene Wert derselbe ist, wird es als normale Aktualisierung betrachtet. Wenn der zurückgegebene Wert anders ist, CloudFormation erkennt das Update als Ersatz und sendet eine Löschanforderung an die alte Ressource. Weitere Informationen finden Sie unter [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html).

`noEcho`  
Optional. Gibt an, ob die Ausgabe der benutzerdefinierten Ressource maskiert wird, wenn sie mithilfe der Funktion `Fn::GetAtt` abgerufen wird. Wird „`true`“ festgelegt, werden alle zurückgegebenen Werte mit Sternchen (\$1\$1\$1\$1\$1) maskiert, mit Ausnahme der Informationen, die an den folgenden Speicherorten gespeichert sind. Dieser Wert ist standardmäßig `false`.  
Durch die Verwendung des `NoEcho`-Attributs werden keine Informationen maskiert, die im Folgenden gespeichert sind:  
+ Der `Metadata` Vorlagenbereich. CloudFormation transformiert, modifiziert oder redigiert keine Informationen, die Sie in den `Metadata` Abschnitt aufnehmen. Weitere Informationen finden Sie unter [Metadaten](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html).
+ Der `Outputs`-Vorlagenabschnitt. Weitere Informationen finden Sie unter [Ausgaben](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html):
+ Das `Metadata`-Attribut einer Ressourcendefinition. Weitere Informationen finden Sie unter [`Metadata`-Attribut](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-metadata.html).
Es wird dringend empfohlen, diese Mechanismen nicht zu verwenden, um vertrauliche Informationen wie Passwörter oder Geheimnisse einzugeben.
Weitere Informationen über die Verwendung von `NoEcho` zur Maskierung sensibler Informationen finden Sie in der bewährten Methode [Keine Anmeldeinformationen in Vorlagen einbetten](security-best-practices.md#creds) .

## Beispiele
<a name="cfn-lambda-function-code-cfnresponsemodule-examples"></a>

### Node.js
<a name="cfn-lambda-function-code-zipfile-examplenodejs"></a>

Im folgenden Beispiel für Node.js verwendet die eingebettete Lambda-Funktion einen Eingabewert und multipliziert diesen mit 5. Eingebettete bzw. Inline-Funktionen sind besonders nützlich für kleinere Funktionen, da Sie den Quellcode hiermit direkt in einer Vorlage festlegen können, statt ein Paket zu erstellen und dieses in einen Amazon S3-Bucket hochzuladen. Die Funktion verwendet die `cfn-response` `send`-Methode zum Senden des Ergebnisses zurück an die benutzerdefinierte Ressource, die sie aufgerufen hat.

#### JSON
<a name="cfn-lambda-function-code-zipfile-examplenodejs.json"></a>

```
"ZipFile": { "Fn::Join": ["", [
  "var response = require('cfn-response');",
  "exports.handler = function(event, context) {",
  "  var input = parseInt(event.ResourceProperties.Input);",
  "  var responseData = {Value: input * 5};",
  "  response.send(event, context, response.SUCCESS, responseData);",
  "};"
]]}
```

#### YAML
<a name="cfn-lambda-function-code-zipfile-examplenodejs-yaml"></a>

```
ZipFile: >
  var response = require('cfn-response');
  exports.handler = function(event, context) {
    var input = parseInt(event.ResourceProperties.Input);
    var responseData = {Value: input * 5};
    response.send(event, context, response.SUCCESS, responseData);
  };
```

### Python
<a name="cfn-lambda-function-code-zipfile-examplepython"></a>

Im folgenden Beispiel für Python verwendet die Lambda-Inline-Funktion einen Ganzzahlwert und multipliziert diesen mit 5.

#### JSON
<a name="cfn-lambda-function-code-zipfile-examplepython.json"></a>

```
"ZipFile" : { "Fn::Join" : ["\n", [
  "import json",
  "import cfnresponse",
  "def handler(event, context):",
  "   responseValue = int(event['ResourceProperties']['Input']) * 5",
  "   responseData = {}",
  "   responseData['Data'] = responseValue",
  "   cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, \"CustomResourcePhysicalID\")"
]]}
```

#### YAML
<a name="cfn-lambda-function-code-zipfile-examplepython.yaml"></a>

```
ZipFile: |
  import json
  import cfnresponse
  def handler(event, context):
    responseValue = int(event['ResourceProperties']['Input']) * 5
    responseData = {}
    responseData['Data'] = responseValue
    cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID")
```

## Modul-Quellcode
<a name="cfn-lambda-function-code-cfnresponsemodule-source"></a>

**Topics**
+ [Asynchroner Node.js Quellcode](#cfn-lambda-function-code-cfnresponsemodule-source-nodejs-async)
+ [Node.js Quellcode](#cfn-lambda-function-code-cfnresponsemodule-source-nodejs)
+ [Python Quellcode](#cfn-lambda-function-code-cfnresponsemodule-source-python)

### Asynchroner Node.js Quellcode
<a name="cfn-lambda-function-code-cfnresponsemodule-source-nodejs-async"></a>

Im Folgenden finden Sie den Quellcode des Antwortmoduls für die Node.js-Funktionen, wenn der Handler asynchron ist. Überprüfen Sie den Code, um zu verstehen, was das Modul tut, und um die Implementierung in Ihre eigenen Antwortfunktionen zu vereinfachen.

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0

exports.SUCCESS = "SUCCESS";
exports.FAILED = "FAILED";

exports.send = function(event, context, responseStatus, responseData, physicalResourceId, noEcho) {

    return new Promise((resolve, reject) => {
        var responseBody = JSON.stringify({
            Status: responseStatus,
            Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
            PhysicalResourceId: physicalResourceId || context.logStreamName,
            StackId: event.StackId,
            RequestId: event.RequestId,
            LogicalResourceId: event.LogicalResourceId,
            NoEcho: noEcho || false,
            Data: responseData
        });

        console.log("Response body:\n", responseBody);

        var https = require("https");
        var url = require("url");

        var parsedUrl = url.parse(event.ResponseURL);
        var options = {
            hostname: parsedUrl.hostname,
            port: 443,
            path: parsedUrl.path,
            method: "PUT",
            headers: {
                "content-type": "",
                "content-length": responseBody.length
            }
        };

        var request = https.request(options, function(response) {
            console.log("Status code: " + parseInt(response.statusCode));
            resolve(context.done());
        });

        request.on("error", function(error) {
            console.log("send(..) failed executing https.request(..): " + maskCredentialsAndSignature(error));
            reject(context.done(error));
        });

        request.write(responseBody);
        request.end();
    })
}
 
function maskCredentialsAndSignature(message) {
    return message.replace(/X-Amz-Credential=[^&\s]+/i, 'X-Amz-Credential=*****')
        .replace(/X-Amz-Signature=[^&\s]+/i, 'X-Amz-Signature=*****');
}
```

### Node.js Quellcode
<a name="cfn-lambda-function-code-cfnresponsemodule-source-nodejs"></a>

Im Folgenden finden Sie den Quellcode des Antwortmoduls für die Node.js-Funktionen, wenn der Handler nicht asynchron ist. Überprüfen Sie den Code, um zu verstehen, was das Modul tut, und um die Implementierung in Ihre eigenen Antwortfunktionen zu vereinfachen.

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT-0
 
exports.SUCCESS = "SUCCESS";
exports.FAILED = "FAILED";

exports.send = function(event, context, responseStatus, responseData, physicalResourceId, noEcho) {

    var responseBody = JSON.stringify({
        Status: responseStatus,
        Reason: "See the details in CloudWatch Log Stream: " + context.logStreamName,
        PhysicalResourceId: physicalResourceId || context.logStreamName,
        StackId: event.StackId,
        RequestId: event.RequestId,
        LogicalResourceId: event.LogicalResourceId,
        NoEcho: noEcho || false,
        Data: responseData
    });

    console.log("Response body:\n", responseBody);

    var https = require("https");
    var url = require("url");

    var parsedUrl = url.parse(event.ResponseURL);
    var options = {
        hostname: parsedUrl.hostname,
        port: 443,
        path: parsedUrl.path,
        method: "PUT",
        headers: {
            "content-type": "",
            "content-length": responseBody.length
        }
    };

    var request = https.request(options, function(response) {
        console.log("Status code: " + parseInt(response.statusCode));
        context.done();
    });

    request.on("error", function(error) {
        console.log("send(..) failed executing https.request(..): " + maskCredentialsAndSignature(error));
        context.done();
    });

    request.write(responseBody);
    request.end();
}
```

### Python Quellcode
<a name="cfn-lambda-function-code-cfnresponsemodule-source-python"></a>

Im Folgenden finden Sie den Quellcode des Antwortmoduls für Python-Funktionen:

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0
 
from __future__ import print_function
import urllib3
import json
import re

SUCCESS = "SUCCESS"
FAILED = "FAILED"

http = urllib3.PoolManager()


def send(event, context, responseStatus, responseData, physicalResourceId=None, noEcho=False, reason=None):
    responseUrl = event['ResponseURL']

    responseBody = {
        'Status' : responseStatus,
        'Reason' : reason or "See the details in CloudWatch Log Stream: {}".format(context.log_stream_name),
        'PhysicalResourceId' : physicalResourceId or context.log_stream_name,
        'StackId' : event['StackId'],
        'RequestId' : event['RequestId'],
        'LogicalResourceId' : event['LogicalResourceId'],
        'NoEcho' : noEcho,
        'Data' : responseData
    }

    json_responseBody = json.dumps(responseBody)

    print("Response body:")
    print(json_responseBody)

    headers = {
        'content-type' : '',
        'content-length' : str(len(json_responseBody))
    }

    try:
        response = http.request('PUT', responseUrl, headers=headers, body=json_responseBody)
        print("Status code:", response.status)


    except Exception as e:

        print("send(..) failed executing http.request(..):", mask_credentials_and_signature(e))
 
 
def mask_credentials_and_signature(message):
    message = re.sub(r'X-Amz-Credential=[^&\s]+', 'X-Amz-Credential=*****', message, flags=re.IGNORECASE)
    return re.sub(r'X-Amz-Signature=[^&\s]+', 'X-Amz-Signature=*****', message, flags=re.IGNORECASE)
```