

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

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

Dans votre CloudFormation modèle, vous pouvez spécifier une fonction Lambda comme cible d'une ressource personnalisée. Lorsque vous utilisez la propriété `ZipFile` pour définir le code source de votre [fonction](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html), vous pouvez charger le module `cfn-response` afin d’envoyer des réponses depuis votre fonction Lambda à une ressource personnalisée. Le module `cfn-response` est une bibliothèque qui simplifie l’envoi de réponses à la ressource personnalisée ayant invoqué votre fonction Lambda. Ce module contient une méthode `send` qui transmet un [objet de réponse](crpg-ref.md#crpg-ref-responses) à une ressource personnalisée au moyen d’une URL présignée Amazon S3 (appelée `ResponseURL`).

Le module `cfn-response` est disponible uniquement lorsque vous utilisez la propriété `ZipFile` pour écrire votre code source. Il n'est pas disponible pour le code source stocké dans des compartiments Amazon S3. Pour le code stocké dans des compartiments , vous devez écrire vos propres fonctions pour envoyer des réponses.

**Note**  
Après l'exécution de la méthode `send`, la fonction Lambda s'arrête. Dès lors, tout ce que vous écrivez après cette méthode est ignoré.

## Chargement du module `cfn-response`
<a name="cfn-lambda-function-code-cfnresponsemodule-loading"></a>

Pour les fonctions Node.js, utilisez la fonction `require()` pour charger le module `cfn-response`. Par exemple, l'exemple de code suivant crée un objet `cfn-response` avec le nom `response` :

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

Pour Python, utilisez l'instruction `import` pour charger le module `cfnresponse`, comme illustré dans l'exemple suivant :

**Note**  
Utilisez cette instruction import exacte. CloudFormation n'inclura pas le module de réponse si vous utilisez d'autres variantes de l'instruction d'importation.

```
import cfnresponse
```

## Paramètres de la méthode `send`
<a name="cfn-lambda-function-code-cfnresponsemodule-send-parameters"></a>

Vous pouvez utiliser les paramètres suivants avec la méthode `send`.

`event`  
Champs d'une [demande de ressource personnalisée](crpg-ref.md#crpg-ref-requesttypes).

`context`  
Objet propre aux fonctions Lambda qui vous permet de spécifier à quel moment l'exécution de la fonction et des rappels se termine ou pour accéder aux informations à partir de l'environnement d'exécution Lambda. Pour plus d’informations, consultez [Création de fonctions Lambda avec Node.js](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html) dans le *Guide du développeur AWS Lambda *.

`responseStatus`  
Indique si la fonction a été exécutée avec succès. Utilisez les constantes du `cfnresponse` pour spécifier le statut `SUCCESS` pour les exécutions réussies et `FAILED` pour celles qui ont échoué.

`responseData`  
Champ `Data` de l'[objet de réponse](crpg-ref.md#crpg-ref-responses) d'une ressource personnalisée. Les données sont une liste de paires nom-valeur.

`physicalResourceId`  
Facultatif. Identifiant unique de la ressource personnalisée qui appelé la fonction. Par défaut, le module utilise le nom du flux de journal Amazon CloudWatch Logs associé à la fonction Lambda.  
La valeur renvoyée pour un `PhysicalResourceId` peut modifier les opérations de mise à jour des ressources personnalisées. Si la valeur renvoyée est la même, on considère qu'il s'agit d'une mise à jour normale. Si la valeur renvoyée est différente, CloudFormation reconnaît la mise à jour comme un remplacement et envoie une demande de suppression à l'ancienne ressource. Pour de plus amples informations, veuillez consulter [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`  
Facultatif. Indique s'il faut masquer la sortie de la ressource personnalisée lorsque celle-ci est récupérée à l'aide de la fonction `Fn::GetAtt`. Si cette valeur est définie sur `true`, toutes les valeurs renvoyées sont masquées par des astérisques (\$1\$1\$1\$1\$1), à l'exception des informations stockées dans les emplacements spécifiés ci-dessous. Cette valeur est `false` par défaut.  
L'utilisation de l'attribut `NoEcho` ne masque aucune information stockée dans les lieux suivants :  
+ La section des `Metadata` modèles. CloudFormation ne transforme, ne modifie ni n'expédie aucune information que vous incluez dans `Metadata` cette section. Pour de plus amples informations, veuillez consulter [Métadonnées](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html).
+ La section de modèle `Outputs` Pour de plus amples informations, veuillez consulter [Sorties](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)
+ L’attribut `Metadata` d'une définition de ressource. Pour plus d'informations, voir la section consécrée à l'[Attribut `Metadata`](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-metadata.html).
Nous vous recommandons vivement de ne pas utiliser ces mécanismes pour inclure des informations sensibles, telles que des mots de passe ou des secrets.
Pour plus d’informations sur l’utilisation de `NoEcho` pour masquer les informations sensibles, consultez la bonne pratique [N'incorporez pas d'informations d'identification dans vos modèles](security-best-practices.md#creds).

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

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

Dans l'exemple Node.js suivant, la fonction Lambda en ligne multiplie une valeur d'entrée par 5. Les fonctions en ligne sont particulièrement utiles pour les fonctions de petite ampleur, car elles vous permettent de spécifier le code source directement dans le modèle au lieu de créer un package et de l'importer dans un compartiment Amazon S3. Cette fonction utilise la méthode `cfn-response` `send` pour renvoyer le résultat à la ressource personnalisée qui l'a appelée.

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

Dans l'exemple Python suivant, la fonction Lambda en ligne multiplie un entier par 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")
```

## Code source du module
<a name="cfn-lambda-function-code-cfnresponsemodule-source"></a>

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

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

Le code suivant représente le module de réponse pour les fonctions Node.js lorsque le gestionnaire est asynchrone. Examinez-le pour comprendre ce que fait le module et pour vous aider à mettre en œuvre vos propres fonctions de réponse.

```
// 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=*****');
}
```

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

Le code suivant représente le module de réponse pour les fonctions Node.js lorsque le gestionnaire n’est pas asynchrone. Examinez-le pour comprendre ce que fait le module et pour vous aider à mettre en œuvre vos propres fonctions de réponse.

```
// 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();
}
```

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

Le code suivant représente le module de réponse pour les fonctions Python :

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