

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.

# 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)
```