

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

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

Nel CloudFormation modello, puoi specificare una funzione Lambda come destinazione di una risorsa personalizzata. Quando utilizzi la proprietà `ZipFile` per specificare il codice sorgente della [funzione](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html), puoi caricare il modulo `cfn-response` per inviare le risposte dalla funzione Lambda a una risorsa personalizzata. Il modulo `cfn-response` è una libreria che semplifica l’invio di risposte alla risorsa personalizzata che ha invocato la funzione Lambda. Il modulo ha un metodo `send` che invia un [oggetto di risposta](crpg-ref.md#crpg-ref-responses) a una risorsa personalizzata mediante un URL prefirmato Amazon S3 (`ResponseURL`).

Il modulo `cfn-response` è disponibile solo quando si utilizza la proprietà `ZipFile` per scrivere il codice d’origine. Il modulo non è disponibile per il codice di origine archiviato in bucket Amazon S3. Per il codice nei bucket, è necessario scrivere funzioni proprie per inviare le risposte.

**Nota**  
Dopo l’esecuzione del metodo `send`, la funzione Lambda termina, perciò tutto quello che si scrive dopo quel metodo verrà ignorato.

## Caricamento del modulo `cfn-response`
<a name="cfn-lambda-function-code-cfnresponsemodule-loading"></a>

Per le funzioni Node.js, utilizza la funzione `require()` per caricare il modulo `cfn-response`. Ad esempio, il seguente esempio di codice crea un oggetto `cfn-response` con il nome `response`:

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

Per Python, utilizza l’istruzione `import` per caricare il modulo `cfnresponse`, come mostrato nel seguente esempio:

**Nota**  
Utilizzare questa istruzione di importazione esatta. Se si utilizzano altre varianti di istruzione di importazione, CloudFormation non include il modulo di risposta.

```
import cfnresponse
```

## Parametri del metodo `send`
<a name="cfn-lambda-function-code-cfnresponsemodule-send-parameters"></a>

Si possono utilizzare i seguenti parametri con il metodo `send`:

`event`  
I campi in una [richiesta di risorse personalizzata](crpg-ref.md#crpg-ref-requesttypes).

`context`  
Un oggetto, specifico per le funzioni Lambda, che è possibile utilizzare per specificare quando la funzione e qualsiasi callback hanno completato l’esecuzione o per accedere alle informazioni dall’interno dell’ambiente di esecuzione Lambda. Per ulteriori informazioni, consulta [Building Lambda functions with Node.js](https://docs.aws.amazon.com/lambda/latest/dg/lambda-nodejs.html) nella *Guida per gli sviluppatori di AWS Lambda *.

`responseStatus`  
Se la funzione è stata completata. Utilizza le costanti del modulo `cfnresponse` per specificare lo stato: `SUCCESS` per esecuzioni di successo e `FAILED` per esecuzioni non riuscite.

`responseData`  
Il campo `Data` di un [oggetto di risposta](crpg-ref.md#crpg-ref-responses) della risorsa personalizzata. I dati corrispondono a un elenco di coppie nome-valore.

`physicalResourceId`  
Opzionale. L’ID univoco della risorsa personalizzata che ha invocato la funzione. Per impostazione predefinita, il modulo utilizza il nome del flusso di log di Amazon CloudWatch Logs associato alla funzione Lambda.  
Il valore restituito per un `PhysicalResourceId` può modificare le operazioni personalizzate di aggiornamento delle risorse. Se il valore restituito è lo stesso, viene considerato un aggiornamento normale. Se il valore restituito è diverso, CloudFormation riconosce l'aggiornamento come sostituto e invia una richiesta di eliminazione alla vecchia risorsa. Per ulteriori informazioni, consulta [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`  
Opzionale. Indica se nascondere o meno l’output della risorsa personalizzata quando viene recuperata utilizzando la funzione `Fn::GetAtt`. Se impostato su `true`, tutti i valori restituiti vengono mascherati con asterischi (\$1\$1\$1\$1\$1), ad eccezione delle informazioni archiviate nelle posizioni specificate di seguito. Di default, il valore è `false`.  
L’utilizzo dell’attributo `NoEcho` non maschera le informazioni memorizzate nei seguenti elementi:  
+ La sezione dei `Metadata` modelli. CloudFormation non trasforma, modifica o oscura le informazioni incluse nella `Metadata` sezione. Per ulteriori informazioni, vedere [Metadati](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/metadata-section-structure.html).
+ Sezione dei modelli `Outputs`. Per ulteriori informazioni, consulta [Output](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html).
+ Attributo `Metadata` di una definizione di risorsa. Per ulteriori informazioni, consulta [Attributo `Metadata`](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-attribute-metadata.html).
Si consiglia vivamente di non utilizzare questi meccanismi per includere informazioni sensibili, come password o segreti.
Per ulteriori informazioni sull’utilizzo di `NoEcho` per mascherare le informazioni sensibili, consulta la best practice [Non incorporare le credenziali nei modelli](security-best-practices.md#creds).

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

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

In questo esempio Node.js, la funzione in linea Lambda utilizza un valore di input e lo moltiplica per 5. Le funzioni in linea sono particolarmente utili per le funzioni più piccole perché consentono di specificare il codice di origine direttamente nel modello, invece di creare un pacchetto e caricarlo in un bucket Amazon S3. La funzione utilizza il metodo `cfn-response` `send` per inviare il risultato alla risorsa personalizzata che la richiama.

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

In questo esempio Python, la funzione inline Lambda utilizza un valore intero e lo moltiplica per 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")
```

## Codice di origine del modulo
<a name="cfn-lambda-function-code-cfnresponsemodule-source"></a>

**Topics**
+ [Codice sorgente asincrono di Node.js](#cfn-lambda-function-code-cfnresponsemodule-source-nodejs-async)
+ [Codice sorgente Node.js](#cfn-lambda-function-code-cfnresponsemodule-source-nodejs)
+ [Codice sorgente Python](#cfn-lambda-function-code-cfnresponsemodule-source-python)

### Codice sorgente asincrono di Node.js
<a name="cfn-lambda-function-code-cfnresponsemodule-source-nodejs-async"></a>

Il seguente è il codice sorgente del modulo di risposta per le funzioni Node.js se il gestore è asincrono. Esaminarlo per comprendere ciò che il modulo fa e per facilitare l’implementazione di funzioni di risposta personalizzate.

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

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

Il seguente è il codice sorgente del modulo di risposta per le funzioni Node.js se il gestore non è asincrono. Esaminarlo per comprendere ciò che il modulo fa e per facilitare l’implementazione di funzioni di risposta personalizzate.

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

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

Il seguente è il codice sorgente del modulo di risposta per le funzioni 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)
```