

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à.

# Risorse personalizzate supportate da Lambda
<a name="template-custom-resources-lambda"></a>

Quando associ una funzione Lambda a una risorsa personalizzata, la funzione viene richiamata ogni volta che la risorsa personalizzata viene creata, aggiornata o eliminata. CloudFormation chiama un'API Lambda per richiamare la funzione e per trasmettere tutti i dati della richiesta (ad esempio il tipo di richiesta e le proprietà delle risorse) alla funzione. La potenza e la personalizzazione delle funzioni Lambda, combinate con, CloudFormation consentono un'ampia gamma di scenari, come la ricerca dinamica delle IDs AMI durante la creazione dello stack o l'implementazione e l'utilizzo di funzioni di utilità, come le funzioni di inversione delle stringhe.

Per un’introduzione alle risorse personalizzate e al loro funzionamento, consulta [Funzionamento delle risorse personalizzate](template-custom-resources.md#how-custom-resources-work).

**Topics**
+ [Procedura guidata: crea un meccanismo di ritardo con una risorsa personalizzata supportata da Lambda](walkthrough-lambda-backed-custom-resources.md)
+ [Modulo `cfn-response`](cfn-lambda-function-code-cfnresponsemodule.md)

# Procedura guidata: crea un meccanismo di ritardo con una risorsa personalizzata supportata da Lambda
<a name="walkthrough-lambda-backed-custom-resources"></a>

Questa procedura dettagliata mostra come configurare e avviare una risorsa personalizzata supportata da Lambda utilizzando un modello di esempio. CloudFormation Questo modello crea un meccanismo di ritardo che sospende le implementazioni di stack per un tempo specificato. Questa operazione può essere utile quando devi introdurre ritardi intenzionali durante il provisioning delle risorse, ad esempio quando aspetti che le risorse si stabilizzino prima di creare risorse dipendenti.

**Nota**  
Sebbene in precedenza le risorse personalizzate supportate da Lambda fossero consigliate per il recupero dell'AMI IDs, ora consigliamo di utilizzare i parametri. AWS Systems Manager Questo approccio rende i modelli più riutilizzabili e più facili da mantenere. Per ulteriori informazioni, consulta [Ottenimento di un valore in testo normale da Systems Manager Parameter Store](dynamic-references-ssm.md). 

**Topics**
+ [Panoramica di](#walkthrough-lambda-backed-custom-resources-overview)
+ [Modello di esempio](#walkthrough-lambda-backed-custom-resources-sample-template)
+ [Procedura guidata per il modello di esempio](#walkthrough-lambda-backed-custom-resources-sample-template-walkthrough)
+ [Prerequisiti](#walkthrough-lambda-backed-custom-resources-prerequisites)
+ [Avviare lo stack](#walkthrough-lambda-backed-custom-resources-createfunction-createstack)
+ [Pulizia delle risorse](#walkthrough-lambda-backed-custom-resources-createfunction-cleanup)
+ [Informazioni correlate](#w2aac11c45b9c24b9c23)

## Panoramica di
<a name="walkthrough-lambda-backed-custom-resources-overview"></a>

Il modello di stack di esempio utilizzato in questa procedura guidata crea una risorsa personalizzata supportata da Lambda che introduce un ritardo configurabile (60 secondi per impostazione predefinita) durante la creazione dello stack. Il ritardo si verifica durante gli aggiornamenti dello stack solo quando vengono modificate le proprietà della risorsa personalizzata.

Il modello esegue il provisioning delle seguenti risorse:
+ Una risorsa personalizzata.
+ Una funzione Lambda.
+ un ruolo IAM che consente a Lambda di scrivere i log. CloudWatch

Definisce inoltre due output:
+ Il tempo effettivo di attesa della funzione.
+ Un identificativo univoco generato durante ogni esecuzione della funzione Lambda.



**Nota**  
CloudFormation è un servizio gratuito, ma Lambda addebita in base al numero di richieste per le funzioni e al tempo di esecuzione del codice. Per ulteriori informazioni sui prezzi di Lambda, consulta la pagina [Prezzi di AWS Lambda](https://aws.amazon.com/lambda/pricing/).

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

Puoi consultare di seguito il modello di esempio della risorsa personalizzata supportata da Lambda con il meccanismo di ritardo:

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

## Procedura guidata per il modello di esempio
<a name="walkthrough-lambda-backed-custom-resources-sample-template-walkthrough"></a>

I seguenti frammenti spiegano le parti rilevanti del modello di esempio per aiutarti a comprendere come la funzione Lambda viene associata a una risorsa personalizzata e il relativo output.

[AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html)risorsa `CFNWaiter`  
La risorsa `AWS::Lambda::Function` specifica il codice sorgente, il nome del gestore, l’ambiente di runtime e il nome della risorsa Amazon (ARN) del ruolo di esecuzione della funzione.  
La proprietà `Handler` è impostata su `index.handler` poiché utilizza un codice sorgente Python. [Per ulteriori informazioni sugli identificatori dei gestori accettati quando si utilizzano codici sorgente di funzioni in linea, vedere Code. AWS::Lambda::Function ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lambda-function-code.html#cfn-lambda-function-code-zipfile)  
Il `Runtime` è specificato come `python3.9` poiché il file di origine è un codice Python.  
Il `Timeout` è impostato su 900 secondi.  
La proprietà `Role` utilizza la funzione `Fn::GetAtt` per ottenere l’ARN del ruolo di esecuzione `LambdaExecutionRole` dichiarato nella risorsa `AWS::IAM::Role` all’interno del modello.  
La proprietà `Code` definisce il codice di funzione in linea utilizzando una funzione Python. La funzione Python nel modello di esempio esegue le seguenti operazioni:  
+ Crea un ID univoco utilizzando l’UUID.
+ Verifica se la richiesta è di creazione o aggiornamento.
+ Entra in sospensione per il tempo specificato in `ServiceTimeout` durante le richieste `Create` o `Update`.
+ Restituisce il tempo di attesa e l’ID univoco.

### 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)risorsa `LambdaExecutionRole`  
La risorsa `AWS::IAM:Role` crea un ruolo di esecuzione per la funzione Lambda, che include una policy di assunzione del ruolo che consente a Lambda di utilizzarlo. Contiene anche una politica che consente l'accesso ai CloudWatch registri.

### 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)risorsa `CFNWaiterCustomResource`  
La risorsa personalizzata si collega alla funzione Lambda con il relativo ARN utilizzando `!GetAtt CFNWaiter.Arn`. Implementerà un tempo di attesa di 60 secondi per le operazioni di creazione e aggiornamento, come impostato in `ServiceTimeout`. La risorsa verrà invocata per un’operazione di aggiornamento solo se le proprietà vengono modificate.

### 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`  
Gli `Outputs` di questo modello sono `TimeWaited` e `WaiterId`. Il valore `TimeWaited` usa una funzione `Fn::GetAtt` per fornire la quantità di tempo in cui la risorsa waiter ha effettivamente atteso. Il `WaiterId` usa una funzione `Fn::GetAtt` per fornire l’ID univoco generato e associato all’esecuzione.

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

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

È necessario disporre delle autorizzazioni IAM per utilizzare tutti i servizi corrispondenti, come CloudFormation Lambda e.

## Avviare lo stack
<a name="walkthrough-lambda-backed-custom-resources-createfunction-createstack"></a>

**Per creare lo stack**

1. Trova il modello che preferisci (YAML o JSON) dalla sezione [Modello di esempio](#walkthrough-lambda-backed-custom-resources-sample-template) e salvalo sul computer con il nome `samplelambdabackedcustomresource.template`.

1. Apri la CloudFormation console all'indirizzo. [https://console.aws.amazon.com/cloudformation/](https://console.aws.amazon.com/cloudformation/)

1. Dalla pagina **Stack**, scegli **Crea stack** in alto a destra, poi scegli **Con nuove risorse (standard)**.

1. In **Prerequisito - Prepara modello**, seleziona **Scegli un modello esistente**.

1. In **Specifica modello**, scegli **Carica un file di modello**, poi seleziona **Scegli file**.

1. Seleziona il file di modello `samplelambdabackedcustomresource.template` salvato in precedenza.

1. Scegli **Next (Successivo)**.

1. In **Nome stack**, digita **SampleCustomResourceStack** e scegli **Avanti**.

1. Per questa procedura guidata, non è necessario aggiungere tag o specificare impostazioni avanzate, quindi selezionare **Next (Avanti)**.

1. Assicurati che il nome dello stack sia corretto, quindi seleziona **Crea**.

La creazione dello stack potrebbe richiedere alcuni minuti. CloudFormation È possibile controllare l’avanzamento negli eventi per lo stack. Per ulteriori informazioni, consulta [Visualizza le informazioni sullo stack dalla console CloudFormation](cfn-console-view-stack-data-resources.md).

Se la creazione dello stack avviene correttamente, vengono create tutte le risorse nello stack, come la funzione Lambda e la risorsa personalizzata. Hai utilizzato correttamente una funzione Lambda e una risorsa personalizzata.

[Se la funzione Lambda restituisce un errore, visualizza i log della funzione nella CloudWatch console Logs.](https://console.aws.amazon.com/cloudwatch/home#logs:) Il nome del flusso di log è l'ID fisico della risorsa personalizzata, che puoi trovare visualizzando le risorse dello stack. Per ulteriori informazioni, consulta [Visualizza i dati di log](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#ViewingLogData) nella *Amazon CloudWatch User Guide*.

## Pulizia delle risorse
<a name="walkthrough-lambda-backed-custom-resources-createfunction-cleanup"></a>

Elimina lo stack per cancellare tutte le risorse dello stack create in modo da non pagare per le risorse superflue.

**Per eliminare lo stack**

1. Dalla CloudFormation console, scegli lo **SampleCustomResourceStack**stack.

1. Scegliere **Actions (Operazioni)** e poi **Delete Stack (Elimina stack)**.

1. Nel messaggio di conferma, scegliere **Yes, Delete (Sì, elimina)**.

Tutte le risorse create vengono eliminate.

Ora che sai come creare e utilizzare una risorsa personalizzata supportata da Lambda, puoi usare il modello e il codice di esempio di questa procedura guidata per creare e sperimentare con altri stack e altre funzioni.

## Informazioni correlate
<a name="w2aac11c45b9c24b9c23"></a>
+ [CloudFormation Riferimento a risorse personalizzate](crpg-ref.md)
+ [AWS::CloudFormation::CustomResource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudformation-customresource.html)

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