

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

# Invoca una AWS Lambda funzione in una pipeline in CodePipeline
<a name="actions-invoke-lambda-function"></a>

[AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/) è un servizio di elaborazione che consente di eseguire del codice senza la necessità di effettuare il provisioning o la gestione dei server. Puoi creare funzioni Lambda e aggiungerle come azioni nelle tue pipeline. Poiché Lambda consente di scrivere funzioni per eseguire quasi tutte le attività, è possibile personalizzare il funzionamento della pipeline. 

**Importante**  
Non registrate l'evento JSON CodePipeline inviato a Lambda perché ciò può comportare la registrazione delle credenziali utente nei log. CloudWatch Il CodePipeline ruolo utilizza un evento JSON per passare credenziali temporanee a Lambda sul campo. `artifactCredentials` Per un evento di esempio, consultare [Evento JSON di esempio](#actions-invoke-lambda-function-json-event-example).

Ecco alcuni modi in cui le funzioni Lambda possono essere utilizzate nelle pipeline:
+ Per creare risorse su richiesta in una fase di una pipeline, utilizzarle CloudFormation ed eliminarle in un'altra fase.
+ Distribuire versioni delle applicazioni senza tempi di inattività con una funzione Lambda che scambia i valori CNAME. AWS Elastic Beanstalk 
+ Da distribuire su istanze Docker di Amazon ECS.
+ Per eseguire il backup delle risorse prima della compilazione o della distribuzione mediante la creazione di uno snapshot AMI.
+ Per aggiungere l'integrazione con i prodotti di terze parti alla pipeline, ad esempio l'invio di messaggi a un client IRC.

**Nota**  
La creazione e l'esecuzione di funzioni Lambda potrebbero comportare addebiti sul tuo AWS account. Per ulteriori informazioni, consultare [Prezzi](https://aws.amazon.com/lambda/pricing/).

Questo argomento presuppone che tu conosca AWS CodePipeline AWS Lambda e sappia come creare pipeline, funzioni e le politiche e i ruoli IAM da cui dipendono. Questo argomento illustra come:
+ Crea una funzione Lambda che verifica se una pagina Web è stata distribuita correttamente.
+ Configura i ruoli di esecuzione CodePipeline e Lambda e le autorizzazioni necessarie per eseguire la funzione come parte della pipeline.
+ Modifica una pipeline per aggiungere la funzione Lambda come azione. 
+ Testare l'operazione rilasciando manualmente una modifica.

**Nota**  
Quando si utilizza Cross-region Lambda invoke action CodePipeline in, lo stato dell'esecuzione lambda che utilizza [PutJobSuccessResult[PutJobFailureResult](https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_PutJobFailureResult.html)](https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_PutJobSuccessResult.html)e deve essere inviato alla AWS regione in cui è presente la funzione Lambda e non alla regione in cui esiste. CodePipeline 

Questo argomento include funzioni di esempio per dimostrare la flessibilità dell'utilizzo delle funzioni Lambda in: CodePipeline 
+ [Basic Lambda function](#LambdaSample1)
  + Creazione di una funzione Lambda di base da utilizzare con. CodePipeline
  + Se si restituisce un esito positivo o negativo, viene visualizzato il link **Dettagli** relativo all'azione. CodePipeline 
+ [Funzione Python di esempio che utilizza un modello AWS CloudFormation](#actions-invoke-lambda-function-samples-python-cloudformation)
  + Utilizzo di parametri utente codificati in formato JSON per inoltrare più valori di configurazione alla funzione (`get_user_params`).
  + Interazione con artefatti .zip in un bucket dedicato agli artefatti (`get_template`).
  + Utilizzo di un token di prosecuzione per monitorare un processo asincrono dall'esecuzione prolungata (`continue_job_later`). Ciò consente all'azione di continuare e alla funzione di avere successo anche se supera un tempo di esecuzione di quindici minuti (un limite in Lambda).

Ogni funzione di esempio include informazioni sulle autorizzazioni che è necessario aggiungere al ruolo. *Per informazioni sui limiti in AWS Lambda, consulta [Limits nella Developer Guide](https://docs.aws.amazon.com/lambda/latest/dg/limits.html).AWS Lambda *

**Importante**  
Il codice di esempio, i ruoli e le policy inclusi in questo argomento sono solo esempi e vengono forniti senza alcuna modifica.

**Topics**
+ [

## Fase 1: creazione di una pipeline
](#actions-invoke-lambda-function-create-test-pipeline)
+ [

## Fase 2: Creare la funzione Lambda
](#actions-invoke-lambda-function-create-function)
+ [

## Passaggio 3: aggiungere la funzione Lambda a una pipeline nella console CodePipeline
](#actions-invoke-lambda-function-add-action)
+ [

## Fase 4: testare la pipeline con la funzione Lambda
](#actions-invoke-lambda-function-test-function)
+ [

## Fase 5: fasi successive
](#actions-invoke-lambda-function-next-steps)
+ [

## Evento JSON di esempio
](#actions-invoke-lambda-function-json-event-example)
+ [

## Funzioni di esempio aggiuntive
](#actions-invoke-lambda-function-samples)

## Fase 1: creazione di una pipeline
<a name="actions-invoke-lambda-function-create-test-pipeline"></a>

In questo passaggio, crei una pipeline a cui successivamente aggiungerai la funzione Lambda. Questa è la stessa pipeline creata in [CodePipeline tutorial](tutorials.md). Se la pipeline è ancora configurata per il tuo account e si trova nella stessa regione in cui prevedi di creare la funzione Lambda, puoi saltare questo passaggio.

**Per creare la pipeline**

1. Segui i primi tre passaggi [Tutorial: creazione di una semplice pipeline (bucket S3)](tutorials-simple-s3.md) per creare un bucket Amazon S3, CodeDeploy risorse e una pipeline in due fasi. Scegli l'opzione Amazon Linux per i tuoi tipi di istanze. È possibile usare qualsiasi nome per la pipeline, ma i passaggi descritti in questa sezione utilizzano MyLambdaTestPipeline. 

1. Nella pagina di stato della pipeline, nell' CodeDeploy azione, scegli **Dettagli**. Nella pagina dei dettagli di distribuzione del gruppo di distribuzione, scegliere un ID istanza dall'elenco. 

1. Nella console Amazon EC2, nella scheda **Dettagli** dell'istanza, copia l'indirizzo IP in ** IPv4 Indirizzo pubblico** (ad esempio,**192.0.2.4**). Utilizzare questo indirizzo come la destinazione della funzione in AWS Lambda.

**Nota**  
La politica del ruolo di servizio predefinita per CodePipeline include le autorizzazioni Lambda necessarie per richiamare la funzione. Tuttavia, se hai modificato il ruolo di default del servizio o ne hai selezionato un altro, verifica che la policy del ruolo includa le autorizzazioni `lambda:InvokeFunction` e `lambda:ListFunctions`. Altrimenti, le pipeline che includono azioni Lambda falliranno.

## Fase 2: Creare la funzione Lambda
<a name="actions-invoke-lambda-function-create-function"></a>

In questo passaggio, crei una funzione Lambda che effettua una richiesta HTTP e verifica la presenza di una riga di testo su una pagina Web. Come parte di questo passaggio, devi anche creare una policy IAM e un ruolo di esecuzione Lambda. Per ulteriori informazioni, consulta [Modello di autorizzazioni](https://docs.aws.amazon.com/lambda/latest/dg/intro-permission-model.html#lambda-intro-execution-role) nella *Guida per gli sviluppatori di AWS Lambda *. 

**Per creare il ruolo di esecuzione**

1. Accedi Console di gestione AWS e apri la console IAM all'indirizzo [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. Seleziona **Policy**, quindi scegli **Create Policy** (Crea policy). Scegli la scheda **JSON** e quindi incolla la seguente policy nel campo.

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	  
     "Statement": [
       {
         "Action": [ 
           "logs:*"
         ],
         "Effect": "Allow", 
         "Resource": "arn:aws:logs:*:*:*"
       },
       {
         "Action": [
           "codepipeline:PutJobSuccessResult",
           "codepipeline:PutJobFailureResult"
           ],
           "Effect": "Allow",
           "Resource": "*"
        }
     ]
   }
   ```

------

1. Scegliere **Esamina policy**.

1. Nella pagina **Review policy (Rivedi policy)**, in **Name (Nome)**, digita un nome per la policy (ad esempio, **CodePipelineLambdaExecPolicy**). In **Description (Descrizione)**, immetti **Enables Lambda to execute code**. 

   Scegli **Crea policy**.
**Nota**  
Queste sono le autorizzazioni minime richieste per l'interazione di una funzione Lambda con Amazon CodePipeline . CloudWatch Se desideri espandere questo criterio per consentire funzioni che interagiscono con altre AWS risorse, devi modificare questo criterio per consentire le azioni richieste da tali funzioni Lambda.

1. Nella pagina del pannello di controllo delle policy, scegli **Roles (Ruoli)** e quindi seleziona **Create role (Crea ruolo)**.

1. Nella pagina **Crea ruolo**, scegli **Servizio AWS**. Scegli **Lambda**, quindi seleziona **Next: Permissions (Successivo: Autorizzazioni)**.

1. Nella pagina **Attach permissions policies (Collega policy autorizzazioni)**, seleziona la casella di controllo accanto a **CodePipelineLambdaExecPolicy** e quindi scegli **Next: Tags (Successivo: Tag)**. Scegli **Prossimo: Rivedi**.

1. Nella pagina **Review (Rivedi)**, in **Role name (Nome ruolo)**, immetti il nome e scegli **Create role (Crea ruolo)**.<a name="LambdaSample1"></a>

**Per creare la funzione Lambda di esempio da utilizzare con CodePipeline**

1. Accedi a Console di gestione AWS e apri la AWS Lambda console all'indirizzo [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/).

1. Nella pagina **Functions (Funzioni)**, scegli **Create function (Crea funzione)**.
**Nota**  
Se vedi una pagina di **benvenuto** anziché la pagina **Lambda**, scegli **Inizia subito**.

1. Nella pagina **Create function (Crea funzione)**, scegliere **Author from scratch (Crea da zero)**. In **Nome funzione**, inserisci un nome per la tua funzione Lambda (ad esempio,**MyLambdaFunctionForAWSCodePipeline**). In **Runtime**, scegli **Node.js 20.x**.

1. In **Role (Ruolo)** seleziona **Choose an existing role (Scegli un ruolo esistente)**. In **Existing role (Ruolo esistente)**, scegli il ruolo e quindi seleziona **Create function (Crea funzione)**.

   Viene visualizzata la pagina dei dettagli per la funzione creata.

1. Copia il codice seguente nella casella **Function code (Codice funzione)**:
**Nota**  
L'oggetto evento, sotto la CodePipeline chiave.job, contiene i dettagli del [lavoro](https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_JobDetails.html). Per un esempio completo del CodePipeline ritorno dell'evento JSON a Lambda, vedi. [Evento JSON di esempio](#actions-invoke-lambda-function-json-event-example)

   ```
   import { CodePipelineClient, PutJobSuccessResultCommand, PutJobFailureResultCommand } from "@aws-sdk/client-codepipeline";
   import http from 'http';
   import assert from 'assert';
    
   export const handler = (event, context) => {
    
       const codepipeline = new CodePipelineClient();
    
       // Retrieve the Job ID from the Lambda action
       const jobId = event["CodePipeline.job"].id;
    
       // Retrieve the value of UserParameters from the Lambda action configuration in CodePipeline, in this case a URL which will be
       // health checked by this function.
       const url = event["CodePipeline.job"].data.actionConfiguration.configuration.UserParameters;
    
       // Notify CodePipeline of a successful job
       const putJobSuccess = async function(message) {
           const command = new PutJobSuccessResultCommand({
               jobId: jobId
           });
            try {
                await codepipeline.send(command);
                context.succeed(message);
            } catch (err) {
                context.fail(err); 
            }
       };
    
       // Notify CodePipeline of a failed job
       const putJobFailure = async function(message) {
           const command = new PutJobFailureResultCommand({
               jobId: jobId,
               failureDetails: {
                   message: JSON.stringify(message),
                   type: 'JobFailed',
                   externalExecutionId: context.awsRequestId
               }
           });
           await codepipeline.send(command);
           context.fail(message);
       };
    
       // Validate the URL passed in UserParameters
       if(!url || url.indexOf('http://') === -1) {
           putJobFailure('The UserParameters field must contain a valid URL address to test, including http:// or https://');  
           return;
       }
    
       // Helper function to make a HTTP GET request to the page.
       // The helper will test the response and succeed or fail the job accordingly
       const getPage = function(url, callback) {
           var pageObject = {
               body: '',
               statusCode: 0,
               contains: function(search) {
                   return this.body.indexOf(search) > -1;
               }
           };
           http.get(url, function(response) {
               pageObject.body = '';
               pageObject.statusCode = response.statusCode;
    
               response.on('data', function (chunk) {
                   pageObject.body += chunk;
               });
    
               response.on('end', function () {
                   callback(pageObject);
               });
    
               response.resume();
           }).on('error', function(error) {
               // Fail the job if our request failed
               putJobFailure(error);
           });
       };
    
       getPage(url, function(returnedPage) {
           try {
               // Check if the HTTP response has a 200 status
               assert(returnedPage.statusCode === 200);
               // Check if the page contains the text "Congratulations"
               // You can change this to check for different text, or add other tests as required
               assert(returnedPage.contains('Congratulations'));
    
               // Succeed the job
               putJobSuccess("Tests passed.");
           } catch (ex) {
               // If any of the assertions failed then fail the job
               putJobFailure(ex);
           }
       });
   };
   ```

1. Non modificare i valori predefiniti per **Handler** e **Role (Ruolo)**, **CodePipelineLambdaExecRole**. 

1. In **Basic settings (Impostazioni di base)**, per **Timeout (Timeout)**, immetti **20** secondi.

1. Scegli **Save** (Salva).

## Passaggio 3: aggiungere la funzione Lambda a una pipeline nella console CodePipeline
<a name="actions-invoke-lambda-function-add-action"></a>

In questo passaggio, aggiungi una nuova fase alla pipeline, quindi aggiungi un'azione Lambda che richiama la tua funzione in quella fase.

**Per aggiungere una fase**

1. [Accedi Console di gestione AWS e apri la CodePipeline console all'indirizzo http://console.aws.amazon. com/codesuite/codepipeline/home](https://console.aws.amazon.com/codesuite/codepipeline/home).

1. Nella pagina **Welcome (Benvenuto)**, scegliere la pipeline creata.

1. Nella pagina di visualizzazione della pipeline, scegliere **Edit (Modifica)**.

1. Nella pagina **Modifica**, scegli **\$1 Aggiungi fase** per aggiungere una fase dopo la fase di distribuzione con l' CodeDeploy azione. Immettere un nome per la fase (ad esempio **LambdaStage**), quindi scegliere **Add stage (Aggiungi fase)**.
**Nota**  
Puoi anche scegliere di aggiungere l'azione Lambda a una fase esistente. A scopo dimostrativo, stiamo aggiungendo la funzione Lambda come unica azione in una fase per consentirti di visualizzarne facilmente l'avanzamento man mano che gli artefatti avanzano attraverso una pipeline.

1. Scegliere **\$1 Add action group (\$1 Aggiungi gruppo di operazioni)**. In **Modifica azione**, in **Nome azione**, inserisci un nome per l'azione Lambda (ad esempio,**MyLambdaAction**). Alla voce **Provider**, scegliere **AWS Lambda**. In **Nome funzione**, scegli o inserisci il nome della tua funzione Lambda (ad esempio,**MyLambdaFunctionForAWSCodePipeline**). **In **Parametri utente**, specifica l'indirizzo IP per l'istanza Amazon EC2 che hai copiato in precedenza (ad esempio,**http://*192.0.2.4***), quindi scegli Fine.** 
**Nota**  
Questa sezione utilizza un indirizzo IP, ma in uno scenario reale è possibile fornire invece il nome del proprio sito web registrato (ad esempio **http://*www.example.com***). *Per ulteriori informazioni sui dati e sui gestori degli eventi in AWS Lambda, consulta [Programming Model](https://docs.aws.amazon.com/lambda/latest/dg/programming-model-v2.html) nella Developer Guide.AWS Lambda *

1. Nella pagina **Edit action (Modifica operazione)**, scegli **Save (Salva)**.

## Fase 4: testare la pipeline con la funzione Lambda
<a name="actions-invoke-lambda-function-test-function"></a>

Per testare la funzione, rilasciare la modifica più recente tramite la pipeline. 

**Per utilizzare la console per eseguire la versione più recente di un artefatto attraverso una pipeline**

1. **Nella pagina dei dettagli della pipeline, scegli Release change.** In questo modo viene eseguita la revisione più recente disponibile in ogni percorso di origine specificato in un'operazione origine tramite la pipeline.

1. Quando l'azione Lambda è completa, scegli il link **Dettagli** per visualizzare il flusso di log della funzione in Amazon CloudWatch, inclusa la durata fatturata dell'evento. Se la funzione non funziona, il CloudWatch log fornisce informazioni sulla causa.

## Fase 5: fasi successive
<a name="actions-invoke-lambda-function-next-steps"></a>

Ora che hai creato con successo una funzione Lambda e l'hai aggiunta come azione in una pipeline, puoi provare quanto segue:
+ Aggiungi altre azioni Lambda al tuo stage per controllare altre pagine Web.
+ Modifica la funzione Lambda per verificare la presenza di una stringa di testo diversa.
+ [Esplora le funzioni Lambda](https://docs.aws.amazon.com/lambda/latest/dg/use-cases.html) e crea e aggiungi le tue funzioni Lambda alle pipeline.

![\[Un' AWS Lambda azione che attraversa una pipeline.\]](http://docs.aws.amazon.com/it_it/codepipeline/latest/userguide/images/codepipeline-lambda-action-add-2-inprog-pol.png)


Dopo aver finito di sperimentare la funzione Lambda, valuta la possibilità di rimuoverla dalla pipeline, eliminarla AWS Lambda da ed eliminare il ruolo da IAM per evitare possibili addebiti. Per ulteriori informazioni, consulta [Modifica una tubazione in CodePipeline](pipelines-edit.md), [Eliminare una tubazione in CodePipeline](pipelines-delete.md) ed [Eliminazione dei ruoli o dei profili delle istanze](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_manage_delete.html).

## Evento JSON di esempio
<a name="actions-invoke-lambda-function-json-event-example"></a>

L'esempio seguente mostra un esempio di evento JSON inviato a CodePipeline Lambda da. La struttura dell'evento è simile alla risposta a `[GetJobDetails API](https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_GetJobDetails.html)`, ma senza i tipi di dati `actionTypeId` e `pipelineContext`. Nell'evento in formato JSON e nella risposta all'API `GetJobDetails` sono inclusi due dettagli di configurazione dell'operazione, `FunctionName` e `UserParameters`. I valori contenuti *red italic text* sono esempi o spiegazioni, non valori reali. 

```
{
    "CodePipeline.job": {
        "id": "11111111-abcd-1111-abcd-111111abcdef",
        "accountId": "111111111111",
        "data": {
            "actionConfiguration": {
                "configuration": {
                    "FunctionName": "MyLambdaFunctionForAWSCodePipeline",
                    "UserParameters": "some-input-such-as-a-URL"
                }
            },
            "inputArtifacts": [
                {
                    "location": {
                        "s3Location": {
                            "bucketName": "the name of the bucket configured as the pipeline artifact store in Amazon S3, for example codepipeline-us-east-2-1234567890",
                            "objectKey": "the name of the application, for example CodePipelineDemoApplication.zip"
                        },
                        "type": "S3"
                    },
                    "revision": null,
                    "name": "ArtifactName"
                }
            ],
            "outputArtifacts": [],
            "artifactCredentials": {
                "secretAccessKey": "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
                "sessionToken": "MIICiTCCAfICCQD6m7oRw0uXOjANBgkqhkiG9w
 0BAQUFADCBiDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZ
 WF0dGxlMQ8wDQYDVQQKEwZBbWF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIw
 EAYDVQQDEwlUZXN0Q2lsYWMxHzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5
 jb20wHhcNMTEwNDI1MjA0NTIxWhcNMTIwNDI0MjA0NTIxWjCBiDELMAkGA1UEBh
 MCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8wDQYDVQQKEwZBb
 WF6b24xFDASBgNVBAsTC0lBTSBDb25zb2xlMRIwEAYDVQQDEwlUZXN0Q2lsYWMx
 HzAdBgkqhkiG9w0BCQEWEG5vb25lQGFtYXpvbi5jb20wgZ8wDQYJKoZIhvcNAQE
 BBQADgY0AMIGJAoGBAMaK0dn+a4GmWIWJ21uUSfwfEvySWtC2XADZ4nB+BLYgVI
 k60CpiwsZ3G93vUEIO3IyNoH/f0wYK8m9TrDHudUZg3qX4waLG5M43q7Wgc/MbQ
 ITxOUSQv7c7ugFFDzQGBzZswY6786m86gpEIbb3OhjZnzcvQAaRHhdlQWIMm2nr
 AgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAtCu4nUhVVxYUntneD9+h8Mg9q6q+auN
 KyExzyLwaxlAoo7TJHidbtS4J5iNmZgXL0FkbFFBjvSfpJIlJ00zbhNYS5f6Guo
 EDmFJl0ZxBHjJnyp378OD8uTs7fLvjx79LjSTbNYiytVbZPQUQ5Yaxu2jXnimvw
 3rrszlaEXAMPLE=",
                "accessKeyId": "AKIAIOSFODNN7EXAMPLE"
            },
            "continuationToken": "A continuation token if continuing job",
            "encryptionKey": { 
              "id": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab",
              "type": "KMS"
            }
        }
    }
}
```

## Funzioni di esempio aggiuntive
<a name="actions-invoke-lambda-function-samples"></a>

Le seguenti funzioni Lambda di esempio mostrano funzionalità aggiuntive che è possibile utilizzare per le pipeline. CodePipeline Per utilizzare queste funzioni, potrebbe essere necessario modificare la policy per il ruolo di esecuzione Lambda, come indicato nell'introduzione di ogni esempio.

**Topics**
+ [

### Funzione Python di esempio che utilizza un modello AWS CloudFormation
](#actions-invoke-lambda-function-samples-python-cloudformation)

### Funzione Python di esempio che utilizza un modello AWS CloudFormation
<a name="actions-invoke-lambda-function-samples-python-cloudformation"></a>

L'esempio seguente mostra una funzione che crea o aggiorna uno stack basato su un modello fornito CloudFormation . Il modello crea un bucket Amazon S3. È a solo a scopo dimostrativo, per ridurre al minimo i costi. Teoricamente, bisognerebbe eliminare lo stack prima caricare qualsiasi cosa sul bucket. Se carichi file nel bucket, non puoi eliminare il bucket quando elimini lo stack. Per eliminare il bucket deve prima eliminare tutto il suo contenuto. 

Questo esempio di Python presuppone che tu abbia una pipeline che utilizza un bucket Amazon S3 come azione di origine o che tu abbia accesso a un bucket Amazon S3 con versione che puoi usare con la pipeline. Crei il CloudFormation modello, lo comprimi e lo carichi in quel bucket come file.zip. È necessario quindi aggiungere alla pipeline un'operazione sorgente che recupera tale file.zip dal bucket.

**Nota**  
Se Amazon S3 è il fornitore di origine per la tua pipeline, puoi comprimere il file o i file sorgente in un unico .zip e caricare il file.zip nel tuo bucket di origine. È inoltre possibile caricare un singolo file decompresso; tuttavia, le operazioni a valle che si aspettano un file con estensione .zip avranno esito negativo.

Questo esempio illustra:
+ L'utilizzo di parametri utente codificati in formato JSON per inoltrare più valori di configurazione alla funzione (`get_user_params`).
+ L'interazione con artefatti .zip in un bucket dedicato agli artefatti (`get_template`).
+ L'utilizzo di un token di prosecuzione per monitorare un processo asincrono dall'esecuzione prolungata (`continue_job_later`). Ciò consente all'azione di continuare e alla funzione di avere successo anche se supera un tempo di esecuzione di quindici minuti (un limite in Lambda).

Per utilizzare questa funzione Lambda di esempio, la policy per il ruolo di esecuzione Lambda deve disporre di `Allow` autorizzazioni in Amazon CloudFormation S3 e CodePipeline, come illustrato in questa politica di esempio:

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "logs:*"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Action": [
                "codepipeline:PutJobSuccessResult",
                "codepipeline:PutJobFailureResult"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Action": [
                "cloudformation:DescribeStacks",
                "cloudformation:CreateStack",
                "cloudformation:UpdateStack"
            ],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Action": [
                "s3:*"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}
```

------

Per creare il CloudFormation modello, apri un qualsiasi editor di testo semplice e copia e incolla il codice seguente:

```
{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Description" : "CloudFormation template which creates an S3 bucket",
  "Resources" : {
    "MySampleBucket" : {
      "Type" : "AWS::S3::Bucket",
      "Properties" : {
      }
    }
  },
  "Outputs" : {
    "BucketName" : {
      "Value" : { "Ref" : "MySampleBucket" },
      "Description" : "The name of the S3 bucket"
    }
  } 
}
```

Salvare il contenuto come file JSON con il nome **template.json** in una cartella denominata **template-package**. Crea un file compresso (.zip) di questa directory e del file denominato **template-package.zip** e carica il file compresso in un bucket Amazon S3 con versione. Se si dispone già di un bucket configurato per la pipeline, è possibile utilizzarlo. Quindi, modificare la pipeline per aggiungere un'operazione sorgente che recupera il file .zip. Assegna un nome all'output per questa azione. *MyTemplate* Per ulteriori informazioni, consulta [Modifica una tubazione in CodePipeline](pipelines-edit.md).

**Nota**  
La funzione Lambda di esempio prevede questi nomi di file e una struttura compressa. Tuttavia, puoi sostituire questo esempio con il tuo CloudFormation modello. Se utilizzi il tuo modello, assicurati di modificare la politica per il ruolo di esecuzione Lambda per consentire qualsiasi funzionalità aggiuntiva richiesta CloudFormation dal modello.

**Per aggiungere il codice seguente come funzione in Lambda**

1. Apri la console Lambda e scegli **Crea** funzione.

1. Nella pagina **Create function (Crea funzione)**, scegliere **Author from scratch (Crea da zero)**. In **Nome funzione**, inserisci un nome per la tua funzione Lambda.

1. In **Runtime**, scegli **Python 2.7**.

1. In **Scegli o crea un ruolo di esecuzione**, seleziona **Usa un ruolo esistente**. In **Existing role (Ruolo esistente)**, scegli il ruolo e quindi seleziona **Create function (Crea funzione)**.

   Viene visualizzata la pagina dei dettagli per la funzione creata.

1. Copia il codice seguente nella casella **Function code (Codice funzione)**:

   ```
   from __future__ import print_function
   from boto3.session import Session
   
   import json
   import urllib
   import boto3
   import zipfile
   import tempfile
   import botocore
   import traceback
   
   print('Loading function')
   
   cf = boto3.client('cloudformation')
   code_pipeline = boto3.client('codepipeline')
   
   def find_artifact(artifacts, name):
       """Finds the artifact 'name' among the 'artifacts'
       
       Args:
           artifacts: The list of artifacts available to the function
           name: The artifact we wish to use
       Returns:
           The artifact dictionary found
       Raises:
           Exception: If no matching artifact is found
       
       """
       for artifact in artifacts:
           if artifact['name'] == name:
               return artifact
               
       raise Exception('Input artifact named "{0}" not found in event'.format(name))
   
   def get_template(s3, artifact, file_in_zip):
       """Gets the template artifact
       
       Downloads the artifact from the S3 artifact store to a temporary file
       then extracts the zip and returns the file containing the CloudFormation
       template.
       
       Args:
           artifact: The artifact to download
           file_in_zip: The path to the file within the zip containing the template
           
       Returns:
           The CloudFormation template as a string
           
       Raises:
           Exception: Any exception thrown while downloading the artifact or unzipping it
       
       """
       tmp_file = tempfile.NamedTemporaryFile()
       bucket = artifact['location']['s3Location']['bucketName']
       key = artifact['location']['s3Location']['objectKey']
       
       with tempfile.NamedTemporaryFile() as tmp_file:
           s3.download_file(bucket, key, tmp_file.name)
           with zipfile.ZipFile(tmp_file.name, 'r') as zip:
               return zip.read(file_in_zip)   
      
   def update_stack(stack, template):
       """Start a CloudFormation stack update
       
       Args:
           stack: The stack to update
           template: The template to apply
           
       Returns:
           True if an update was started, false if there were no changes
           to the template since the last update.
           
       Raises:
           Exception: Any exception besides "No updates are to be performed."
       
       """
       try:
           cf.update_stack(StackName=stack, TemplateBody=template)
           return True
           
       except botocore.exceptions.ClientError as e:
           if e.response['Error']['Message'] == 'No updates are to be performed.':
               return False
           else:
               raise Exception('Error updating CloudFormation stack "{0}"'.format(stack), e)
   
   def stack_exists(stack):
       """Check if a stack exists or not
       
       Args:
           stack: The stack to check
           
       Returns:
           True or False depending on whether the stack exists
           
       Raises:
           Any exceptions raised .describe_stacks() besides that
           the stack doesn't exist.
           
       """
       try:
           cf.describe_stacks(StackName=stack)
           return True
       except botocore.exceptions.ClientError as e:
           if "does not exist" in e.response['Error']['Message']:
               return False
           else:
               raise e
   
   def create_stack(stack, template):
       """Starts a new CloudFormation stack creation
       
       Args:
           stack: The stack to be created
           template: The template for the stack to be created with
           
       Throws:
           Exception: Any exception thrown by .create_stack()
       """
       cf.create_stack(StackName=stack, TemplateBody=template)
    
   def get_stack_status(stack):
       """Get the status of an existing CloudFormation stack
       
       Args:
           stack: The name of the stack to check
           
       Returns:
           The CloudFormation status string of the stack such as CREATE_COMPLETE
           
       Raises:
           Exception: Any exception thrown by .describe_stacks()
           
       """
       stack_description = cf.describe_stacks(StackName=stack)
       return stack_description['Stacks'][0]['StackStatus']
     
   def put_job_success(job, message):
       """Notify CodePipeline of a successful job
       
       Args:
           job: The CodePipeline job ID
           message: A message to be logged relating to the job status
           
       Raises:
           Exception: Any exception thrown by .put_job_success_result()
       
       """
       print('Putting job success')
       print(message)
       code_pipeline.put_job_success_result(jobId=job)
     
   def put_job_failure(job, message):
       """Notify CodePipeline of a failed job
       
       Args:
           job: The CodePipeline job ID
           message: A message to be logged relating to the job status
           
       Raises:
           Exception: Any exception thrown by .put_job_failure_result()
       
       """
       print('Putting job failure')
       print(message)
       code_pipeline.put_job_failure_result(jobId=job, failureDetails={'message': message, 'type': 'JobFailed'})
    
   def continue_job_later(job, message):
       """Notify CodePipeline of a continuing job
       
       This will cause CodePipeline to invoke the function again with the
       supplied continuation token.
       
       Args:
           job: The JobID
           message: A message to be logged relating to the job status
           continuation_token: The continuation token
           
       Raises:
           Exception: Any exception thrown by .put_job_success_result()
       
       """
       
       # Use the continuation token to keep track of any job execution state
       # This data will be available when a new job is scheduled to continue the current execution
       continuation_token = json.dumps({'previous_job_id': job})
       
       print('Putting job continuation')
       print(message)
       code_pipeline.put_job_success_result(jobId=job, continuationToken=continuation_token)
   
   def start_update_or_create(job_id, stack, template):
       """Starts the stack update or create process
       
       If the stack exists then update, otherwise create.
       
       Args:
           job_id: The ID of the CodePipeline job
           stack: The stack to create or update
           template: The template to create/update the stack with
       
       """
       if stack_exists(stack):
           status = get_stack_status(stack)
           if status not in ['CREATE_COMPLETE', 'ROLLBACK_COMPLETE', 'UPDATE_COMPLETE']:
               # If the CloudFormation stack is not in a state where
               # it can be updated again then fail the job right away.
               put_job_failure(job_id, 'Stack cannot be updated when status is: ' + status)
               return
           
           were_updates = update_stack(stack, template)
           
           if were_updates:
               # If there were updates then continue the job so it can monitor
               # the progress of the update.
               continue_job_later(job_id, 'Stack update started')  
               
           else:
               # If there were no updates then succeed the job immediately 
               put_job_success(job_id, 'There were no stack updates')    
       else:
           # If the stack doesn't already exist then create it instead
           # of updating it.
           create_stack(stack, template)
           # Continue the job so the pipeline will wait for the CloudFormation
           # stack to be created.
           continue_job_later(job_id, 'Stack create started') 
   
   def check_stack_update_status(job_id, stack):
       """Monitor an already-running CloudFormation update/create
       
       Succeeds, fails or continues the job depending on the stack status.
       
       Args:
           job_id: The CodePipeline job ID
           stack: The stack to monitor
       
       """
       status = get_stack_status(stack)
       if status in ['UPDATE_COMPLETE', 'CREATE_COMPLETE']:
           # If the update/create finished successfully then
           # succeed the job and don't continue.
           put_job_success(job_id, 'Stack update complete')
           
       elif status in ['UPDATE_IN_PROGRESS', 'UPDATE_ROLLBACK_IN_PROGRESS', 
       'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 'CREATE_IN_PROGRESS', 
       'ROLLBACK_IN_PROGRESS', 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS']:
           # If the job isn't finished yet then continue it
           continue_job_later(job_id, 'Stack update still in progress') 
          
       else:
           # If the Stack is a state which isn't "in progress" or "complete"
           # then the stack update/create has failed so end the job with
           # a failed result.
           put_job_failure(job_id, 'Update failed: ' + status)
   
   def get_user_params(job_data):
       """Decodes the JSON user parameters and validates the required properties.
       
       Args:
           job_data: The job data structure containing the UserParameters string which should be a valid JSON structure
           
       Returns:
           The JSON parameters decoded as a dictionary.
           
       Raises:
           Exception: The JSON can't be decoded or a property is missing.
           
       """
       try:
           # Get the user parameters which contain the stack, artifact and file settings
           user_parameters = job_data['actionConfiguration']['configuration']['UserParameters']
           decoded_parameters = json.loads(user_parameters)
               
       except Exception as e:
           # We're expecting the user parameters to be encoded as JSON
           # so we can pass multiple values. If the JSON can't be decoded
           # then fail the job with a helpful message.
           raise Exception('UserParameters could not be decoded as JSON')
       
       if 'stack' not in decoded_parameters:
           # Validate that the stack is provided, otherwise fail the job
           # with a helpful message.
           raise Exception('Your UserParameters JSON must include the stack name')
       
       if 'artifact' not in decoded_parameters:
           # Validate that the artifact name is provided, otherwise fail the job
           # with a helpful message.
           raise Exception('Your UserParameters JSON must include the artifact name')
       
       if 'file' not in decoded_parameters:
           # Validate that the template file is provided, otherwise fail the job
           # with a helpful message.
           raise Exception('Your UserParameters JSON must include the template file name')
       
       return decoded_parameters
       
   def setup_s3_client(job_data):
       """Creates an S3 client
       
       Uses the credentials passed in the event by CodePipeline. These
       credentials can be used to access the artifact bucket.
       
       Args:
           job_data: The job data structure
           
       Returns:
           An S3 client with the appropriate credentials
           
       """
       key_id = job_data['artifactCredentials']['accessKeyId']
       key_secret = job_data['artifactCredentials']['secretAccessKey']
       session_token = job_data['artifactCredentials']['sessionToken']
       
       session = Session(aws_access_key_id=key_id,
           aws_secret_access_key=key_secret,
           aws_session_token=session_token)
       return session.client('s3', config=botocore.client.Config(signature_version='s3v4'))
   
   def lambda_handler(event, context):
       """The Lambda function handler
       
       If a continuing job then checks the CloudFormation stack status
       and updates the job accordingly.
       
       If a new job then kick of an update or creation of the target
       CloudFormation stack.
       
       Args:
           event: The event passed by Lambda
           context: The context passed by Lambda
           
       """
       try:
           # Extract the Job ID
           job_id = event['CodePipeline.job']['id']
           
           # Extract the Job Data 
           job_data = event['CodePipeline.job']['data']
           
           # Extract the params
           params = get_user_params(job_data)
           
           # Get the list of artifacts passed to the function
           artifacts = job_data['inputArtifacts']
           
           stack = params['stack']
           artifact = params['artifact']
           template_file = params['file']
           
           if 'continuationToken' in job_data:
               # If we're continuing then the create/update has already been triggered
               # we just need to check if it has finished.
               check_stack_update_status(job_id, stack)
           else:
               # Get the artifact details
               artifact_data = find_artifact(artifacts, artifact)
               # Get S3 client to access artifact with
               s3 = setup_s3_client(job_data)
               # Get the JSON template file out of the artifact
               template = get_template(s3, artifact_data, template_file)
               # Kick off a stack update or create
               start_update_or_create(job_id, stack, template)  
   
       except Exception as e:
           # If any other exceptions which we didn't expect are raised
           # then fail the job and log the exception message.
           print('Function failed due to exception.') 
           print(e)
           traceback.print_exc()
           put_job_failure(job_id, 'Function exception: ' + str(e))
         
       print('Function complete.')   
       return "Complete."
   ```

1. Lascia **Handler** al valore predefinito e lascia **Role** al nome selezionato o creato in precedenza,**CodePipelineLambdaExecRole**. 

1. In **Basic settings (Impostazioni di base)**, per **Timeout**, sostituisci l'impostazione predefinita di 3 secondi con **20**.

1. Scegli **Save** (Salva).

1. Dalla CodePipeline console, modifica la pipeline per aggiungere la funzione come azione in una fase della pipeline. Scegli **Modifica** per la fase della pipeline che desideri modificare e scegli **Aggiungi** gruppo di azioni. Nella pagina **Modifica azione**, in **Nome azione**, inserisci un nome per l'azione. In **Action provider**, scegli **Lambda**. 

   In **Inserisci artefatti**, scegli. `MyTemplate` In **UserParameters**, devi fornire una stringa JSON con tre parametri:
   + Stack name (Nome stack)
   + CloudFormation nome del modello e percorso del file
   + Artefatto di input

   Utilizzare le parentesi graffe (\$1\$1) e separare i parametri con virgole. Ad esempio, per creare uno stack denominato, per una pipeline con l'elemento di input*MyTestStack*, in **UserParameters**, inserisci: \$1"stack»:» «*MyTemplate*, "file» :"template-package/template.json», "artifact»:» *MyTestStack* «\$1. *MyTemplate*
**Nota**  
**Anche se avete specificato l'artefatto di input in, dovete specificare anche questo artefatto di input per l'azione in Input artifacts. **UserParameters****

1. Salva le modifiche alla pipeline, quindi rilascia manualmente una modifica per testare l'azione e la funzione Lambda.