

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

# Crea funzioni Lambda per valutare le risorse per Lambda Hooks
<a name="lambda-hooks-create-lambda-function"></a>

CloudFormation Lambda Hooks consente di eseguire valutazioni CloudFormation e AWS Cloud Control API operazioni in base al proprio codice personalizzato. Hook può bloccare l'esecuzione di un'operazione o inviare un avviso al chiamante e consentire all'operazione di continuare. Quando crei un Lambda Hook, puoi configurarlo per intercettare e valutare le seguenti operazioni: CloudFormation 
+ Operazioni sulle risorse
+ Operazioni di stack
+ Operazioni di modifica del set

**Topics**
+ [Sviluppo di un Lambda Hook](#lambda-hooks-create-lambda-function-develop)
+ [Valutazione delle operazioni relative alle risorse con Lambda Hooks](#lambda-hooks-create-lambda-function-resource)
+ [Valutazione delle operazioni degli stack con Lambda Hooks](#lambda-hooks-create-lambda-function-stack)
+ [Valutazione delle operazioni relative ai set di modifiche con Lambda Hooks](#lambda-hooks-create-lambda-function-change-set)

## Sviluppo di un Lambda Hook
<a name="lambda-hooks-create-lambda-function-develop"></a>

Quando gli Hooks richiamano la tua Lambda, aspetteranno fino a 30 secondi affinché Lambda valuti l'input. Lambda restituirà una risposta JSON che indica se l'Hook è riuscito o meno.

**Topics**
+ [Richiedi input](#lambda-hooks-create-lambda-function-request-input)
+ [Input di risposta](#lambda-hooks-create-lambda-function-request-response)
+ [Esempi](#lambda-hooks-create-lambda-function-request-example)

### Richiedi input
<a name="lambda-hooks-create-lambda-function-request-input"></a>

L'input passato alla funzione Lambda dipende dall'operazione di destinazione Hook (esempi: stack, resource o change set). 

### Input di risposta
<a name="lambda-hooks-create-lambda-function-request-response"></a>

Per comunicare a Hooks se la richiesta è riuscita o meno, la funzione Lambda deve restituire una risposta JSON.

Di seguito è riportato un esempio di forma della risposta che Hooks si aspetta:

```
{ 
  "HookStatus": "SUCCESS" or "FAILED" or "IN_PROGRESS", 
  "errorCode": "NonCompliant" or "InternalFailure"
  "message": String, 
  "clientRequestToken": String,
  "CallbackContext": None, 
  "callbackDelaySeconds": Integer,
  "annotations": [
    {
      "annotationName": String,
      "status": "PASSED" or "FAILED" or "SKIPPED",
      "statusMessage": String,
      "remediationMessage": String,
      "remediationLink": String,
      "severityLevel": "INFORMATIONAL" or "LOW" or "MEDIUM" or "HIGH" or "CRITICAL"
    }
  ]
}
```

HookStatus  <a name="lambda-hook-response-hookstatus"></a>
Lo stato dell'Hook. Questo è un campo obbligatorio.  
*Valori validi*: (`SUCCESS`\$1 `FAILED` \$1`IN_PROGRESS`)  
Un Hook può tornare `IN_PROGRESS` 3 volte. Se non viene restituito alcun risultato, l'Hook fallirà. Per un Lambda Hook, ciò significa che la funzione Lambda può essere richiamata fino a 3 volte.

errorCode  <a name="lambda-hook-response-errorcode"></a>
Indica se l'operazione è stata valutata e ritenuta non valida o se si sono verificati errori all'interno dell'Hook che hanno impedito la valutazione. Questo campo è obbligatorio se l'Hook fallisce.  
*Valori validi*: (`NonCompliant`\$1`InternalFailure`)

message  <a name="lambda-hook-response-message"></a>
Il messaggio al chiamante che indica il motivo per cui l'Hook ha avuto esito positivo o negativo.  
Durante la valutazione CloudFormation delle operazioni, questo campo viene troncato a 4096 caratteri.  
Quando si valutano le operazioni dell'API Cloud Control, questo campo viene troncato a 1024 caratteri.

clientRequestToken  <a name="lambda-hook-response-clientrequesttoken"></a>
Il token di richiesta che è stato fornito come input alla richiesta Hook. Questo è un campo obbligatorio.

CallbackContext  <a name="lambda-hook-response-callbackcontext"></a>
Se indichi che `hookStatus` è`IN_PROGRESS`, passi un contesto aggiuntivo che viene fornito come input quando la funzione Lambda viene reinvocata.

callbackDelaySeconds  <a name="lambda-hook-response-callbackdelayseconds"></a>
Quanto tempo devono aspettare gli Hook per richiamare nuovamente questo Hook.

annotations  <a name="lambda-hook-response-annotations"></a>
Una serie di oggetti di annotazione che forniscono ulteriori dettagli e indicazioni per la correzione.     
Nome dell'annotazione  
Un identificatore per l'annotazione.  
status  
Lo stato di invocazione di Hook. Ciò è utile quando le annotazioni rappresentano una logica con una valutazione pass/fail simile a una regola Guard.   
*Valori validi*: (\$1 \$1) `PASSED` `FAILED` `SKIPPED`  
statusMessage  
Spiegazione dello stato specifico.  
Messaggio di riparazione  
Suggerimento per correggere uno stato. `FAILED` Ad esempio, se in una risorsa manca la crittografia, puoi indicare come aggiungere la crittografia alla configurazione della risorsa.  
Link di riparazione  
Un URL HTTP per ulteriori indicazioni sulla riparazione.  
severityLevel  
Definisce il rischio relativo associato a qualsiasi violazione di questo tipo. Quando si assegnano i livelli di gravità ai risultati della chiamata Hook, è possibile fare riferimento al [framework di AWS Security Hub CSPM gravità](https://docs.aws.amazon.com/securityhub/latest/userguide/asff-required-attributes.html#Severity) come esempio di come strutturare categorie di gravità significative.   
*Valori validi*: (`INFORMATIONAL`\$1 \$1 \$1 \$1`LOW`) `MEDIUM` `HIGH` `CRITICAL`

### Esempi
<a name="lambda-hooks-create-lambda-function-request-example"></a>

Di seguito è riportato un esempio di risposta riuscita:

```
{ 
  "hookStatus": "SUCCESS",
  "message": "compliant",
  "clientRequestToken": "123avjdjk31"  
}
```

Di seguito è riportato un esempio di risposta non riuscita:

```
{ 
  "hookStatus": "FAILED",
  "errorCode": "NonCompliant",
  "message": "S3 Bucket Versioning must be enabled.",
  "clientRequestToken": "123avjdjk31"
 }
```

## Valutazione delle operazioni relative alle risorse con Lambda Hooks
<a name="lambda-hooks-create-lambda-function-resource"></a>

Ogni volta che crei, aggiorni o elimini una risorsa, questa viene considerata un'operazione relativa alle risorse. Ad esempio, se esegui l'aggiornamento di uno CloudFormation stack che crea una nuova risorsa, hai completato un'operazione sulla risorsa. Quando crei, aggiorni o elimini una risorsa utilizzando l'API Cloud Control, anche questa viene considerata un'operazione relativa alle risorse. Puoi configurare il tuo CloudFormation Lambda Hook per la destinazione `RESOURCE` e `CLOUD_CONTROL` le operazioni nella configurazione Hook`TargetOperations`.

**Nota**  
Il gestore `delete` Hook viene richiamato solo quando una risorsa viene eliminata utilizzando un trigger operativo dall'API Cloud Control o. `delete-resource` CloudFormation `delete-stack`

**Topics**
+ [Sintassi di input delle risorse Lambda Hook](#lambda-hooks-create-lambda-function-resource-input)
+ [Esempio di input per la modifica delle risorse Lambda Hook](#lambda-hooks-create-lambda-function-resource-example)
+ [Esempio di funzione Lambda per le operazioni sulle risorse](#lambda-hooks-create-lambda-function-resource-example-function)

### Sintassi di input delle risorse Lambda Hook
<a name="lambda-hooks-create-lambda-function-resource-input"></a>

Quando la tua Lambda viene richiamata per un'operazione su una risorsa, riceverai un input JSON contenente le proprietà della risorsa, le proprietà proposte e il contesto attorno alla chiamata di Hook.

Di seguito è riportato un esempio di forma dell'input JSON:

```
{
    "awsAccountId": String,
    "stackId": String,
    "changeSetId": String,
    "hookTypeName": String,
    "hookTypeVersion": String,
    "hookModel": {
        "LambdaFunction": String
    },
    "actionInvocationPoint": "CREATE_PRE_PROVISION" or "UPDATE_PRE_PROVISION" or "DELETE_PRE_PROVISION"
    "requestData": {
        "targetName": String,
        "targetType": String,
        "targetLogicalId": String,
        "targetModel": {
            "resourceProperties": {...},
            "previousResourceProperties": {...}
        }
    },
    "requestContext": {
        "invocazione": 1,
        "CallbackContext": null
    }
}
```

`awsAccountId`  <a name="lambda-hook-resource-awsaccountid"></a>
L'ID del Account AWS contenitore della risorsa da valutare.

`stackId`  <a name="lambda-hook-resource-stackid"></a>
L'ID dello stack di cui CloudFormation fa parte questa operazione. Questo campo è vuoto se il chiamante è Cloud Control API.

`changeSetId`  <a name="lambda-hook-resource-changesetid"></a>
L'ID del set di modifiche che ha avviato la chiamata di Hook. Questo valore è vuoto se la modifica delle risorse è stata avviata dall'API Cloud Control o dalle operazioni, o. `create-stack` `update-stack` `delete-stack`

`hookTypeName`  <a name="lambda-hook-resource-hooktypename"></a>
Il nome dell'Hook in esecuzione.

`hookTypeVersion`  <a name="lambda-hook-resource-hooktypeversion"></a>
La versione dell'Hook in esecuzione.

`hookModel`  <a name="lambda-hook-resource-hookmodel"></a>  
`LambdaFunction`  <a name="lambda-hook-resource-hookmodel-lambdafunction"></a>
L'attuale Lambda ARN richiamato dall'Hook.

`actionInvocationPoint`  <a name="lambda-hook-resource-actioninvocationpoint"></a>
Il punto esatto della logica di provisioning in cui viene eseguito l'Hook.  
*Valori validi*: (`CREATE_PRE_PROVISION`\$1 `UPDATE_PRE_PROVISION` \$1`DELETE_PRE_PROVISION`)

`requestData`  <a name="lambda-hook-resource-requestdata"></a>  
`targetName`  <a name="lambda-hook-resource-requestdata-targetname"></a>
Il tipo di oggetto da valutare, ad esempio,`AWS::S3::Bucket`.  
`targetType`  <a name="lambda-hook-resource-requestdata-targettype"></a>
Il tipo di oggetto da valutare, ad esempio. `AWS::S3::Bucket` Per le risorse fornite con l'API Cloud Control, questo valore sarà. `RESOURCE`  
`targetLogicalId`  <a name="lambda-hook-resource-requestdata-targetlogicalid"></a>
L'ID logico della risorsa da valutare. Se l'origine dell'invocazione di Hook è CloudFormation, questo sarà l'ID della risorsa logica definito nel modello. CloudFormation Se l'origine di questa chiamata di Hook è l'API Cloud Control, questo sarà un valore costruito.  
`targetModel`  <a name="lambda-hook-resource-requestdata-targetmodel"></a>  
`resourceProperties`  <a name="lambda-hook-resource-requestdata-targetmodel-resourceproperties"></a>
Le proprietà proposte della risorsa da modificare. Se la risorsa viene eliminata, questo valore sarà vuoto.   
`previousResourceProperties`  <a name="lambda-hook-resource-requestdata-targetmodel-previousresourceproperties"></a>
Le proprietà attualmente associate alla risorsa da modificare. Se la risorsa viene creata, questo valore sarà vuoto.

`requestContext`  <a name="lambda-hook-resource-requestcontext"></a>  
invocazione  <a name="lambda-hook-resource-requestcontext-invocation"></a>
L'attuale tentativo di eseguire l'Hook.   
CallbackContext  <a name="lambda-hook-resource-requestcontext-callbackcontext"></a>
Se Hook è stato impostato su ed è `callbackContext` stato restituito`IN_PROGRESS`, sarà qui dopo la reinvocazione.

### Esempio di input per la modifica delle risorse Lambda Hook
<a name="lambda-hooks-create-lambda-function-resource-example"></a>

L'input di esempio seguente mostra un Lambda Hook che riceverà la definizione della `AWS::DynamoDB::Table` risorsa da aggiornare, dove l'`ReadCapacityUnits`of `ProvisionedThroughput` viene modificato da 3 a 10. Questi sono i dati a disposizione di Lambda per la valutazione.

```
{
    "awsAccountId": "123456789012",
    "stackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/MyStack/1a2345b6-0000-00a0-a123-00abc0abc000",
    "hookTypeName": "my::lambda::resourcehookfunction",
    "hookTypeVersion": "00000008",
    "hookModel": {
        "LambdaFunction": "arn:aws:lambda:us-west-2:123456789012:function:MyFunction"
    },
    "actionInvocationPoint": "UPDATE_PRE_PROVISION",
    "requestData": {
        "targetName": "AWS::DynamoDB::Table",
        "targetType": "AWS::DynamoDB::Table",
        "targetLogicalId": "DDBTable",
        "targetModel": {
            "resourceProperties": {
                "AttributeDefinitions": [
                    {
                        "AttributeType": "S",
                        "AttributeName": "Album"
                    },
                    {
                        "AttributeType": "S",
                        "AttributeName": "Artist"
                    }
                ],
                "ProvisionedThroughput": {
                    "WriteCapacityUnits": 5,
                    "ReadCapacityUnits": 10
                },
                "KeySchema": [
                    {
                        "KeyType": "HASH",
                        "AttributeName": "Album"
                    },
                    {
                        "KeyType": "RANGE",
                        "AttributeName": "Artist"
                    }
                ]
            },
            "previousResourceProperties": {
                "AttributeDefinitions": [
                    {
                        "AttributeType": "S",
                        "AttributeName": "Album"
                    },
                    {
                        "AttributeType": "S",
                        "AttributeName": "Artist"
                    }
                ],
                "ProvisionedThroughput": {
                    "WriteCapacityUnits": 5,
                    "ReadCapacityUnits": 5
                },
                "KeySchema": [
                    {
                        "KeyType": "HASH",
                        "AttributeName": "Album"
                    },
                    {
                        "KeyType": "RANGE",
                        "AttributeName": "Artist"
                    }
                ]
            }
        }
    },
    "requestContext": {
        "invocation": 1,
        "callbackContext": null
    }    
}
```

Per visualizzare tutte le proprietà disponibili per il tipo di risorsa, consulta [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-dynamodb-table.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-dynamodb-table.html).

### Esempio di funzione Lambda per le operazioni sulle risorse
<a name="lambda-hooks-create-lambda-function-resource-example-function"></a>

Di seguito è riportata una semplice funzione che fallisce qualsiasi aggiornamento delle risorse a DynamoDB, che tenta di impostare of su un `ReadCapacity` valore `ProvisionedThroughput` maggiore di 10. Se l'Hook ha successo, al chiamante verrà visualizzato il messaggio "ReadCapacity è configurato correttamente». Se la richiesta non viene convalidata, l'Hook avrà esito negativo e lo stato «ReadCapacity non può essere superiore a 10».

------
#### [ Node.js ]

```
export const handler = async (event, context) => {
    var targetModel = event?.requestData?.targetModel;
    var targetName = event?.requestData?.targetName;
    var response = {
        "hookStatus": "SUCCESS",
        "message": "ReadCapacity is correctly configured.",
        "clientRequestToken": event.clientRequestToken
    };

    if (targetName == "AWS::DynamoDB::Table") {
        var readCapacity = targetModel?.resourceProperties?.ProvisionedThroughput?.ReadCapacityUnits;
        if (readCapacity > 10) {
            response.hookStatus = "FAILED";
            response.errorCode = "NonCompliant";
            response.message = "ReadCapacity must be cannot be more than 10.";
        }
    }
    return response;
};
```

------
#### [ Python ]

```
import json
                            
def lambda_handler(event, context):
    # Using dict.get() for safe access to nested dictionary values
    request_data = event.get('requestData', {})
    target_model = request_data.get('targetModel', {})
    target_name = request_data.get('targetName', '')
    
    response = {
        "hookStatus": "SUCCESS",
        "message": "ReadCapacity is correctly configured.",
        "clientRequestToken": event.get('clientRequestToken')
    }
    
    if target_name == "AWS::DynamoDB::Table":
        # Safely navigate nested dictionary
        resource_properties = target_model.get('resourceProperties', {})
        provisioned_throughput = resource_properties.get('ProvisionedThroughput', {})
        read_capacity = provisioned_throughput.get('ReadCapacityUnits')
        
        if read_capacity and read_capacity > 10:
            response['hookStatus'] = "FAILED"
            response['errorCode'] = "NonCompliant"
            response['message'] = "ReadCapacity must be cannot be more than 10."
    
    return response
```

------

## Valutazione delle operazioni degli stack con Lambda Hooks
<a name="lambda-hooks-create-lambda-function-stack"></a>

Ogni volta che crei, aggiorni o elimini uno stack con un nuovo modello, puoi configurare il tuo CloudFormation Lambda Hook per iniziare a valutare il nuovo modello e potenzialmente bloccare il proseguimento dell'operazione dello stack. Puoi configurare il tuo CloudFormation Lambda Hook per eseguire `STACK` operazioni mirate nella configurazione Hook`TargetOperations`.

**Topics**
+ [Sintassi di input dello stack Lambda Hook](#lambda-hooks-create-lambda-function-stack-input)
+ [Esempio di input per la modifica dello stack Lambda Hook](#lambda-hooks-create-lambda-function-stack-example)
+ [Esempio di funzione Lambda per operazioni in pila](#lambda-hooks-create-lambda-function-stack-example-function)

### Sintassi di input dello stack Lambda Hook
<a name="lambda-hooks-create-lambda-function-stack-input"></a>

Quando la tua Lambda viene richiamata per un'operazione stack, riceverai una richiesta JSON contenente il contesto di invocazione Hook e il contesto di richiesta. `actionInvocationPoint` A causa delle dimensioni dei CloudFormation modelli e della dimensione di input limitata accettata dalle funzioni Lambda, i modelli effettivi vengono archiviati in un oggetto Amazon S3. L'input di `requestData` include un URL rassegnato di Amazon S3 a un altro oggetto, che contiene la versione attuale e precedente del modello.

Di seguito è riportato un esempio di forma dell'input JSON:

```
{
    "clientRequesttoken": String,
    "awsAccountId": String,
    "stackID": String,
    "changeSetId": String,
    "hookTypeName": String,
    "hookTypeVersion": String,
    "hookModel": {
        "LambdaFunction":String
    },
    "actionInvocationPoint": "CREATE_PRE_PROVISION" or "UPDATE_PRE_PROVISION" or "DELETE_PRE_PROVISION"
    "requestData": {
        "targetName": "STACK",
        "targetType": "STACK",
        "targetLogicalId": String,
        "payload": String (S3 Presigned URL)
    },
    "requestContext": {
        "invocation": Integer,
        "callbackContext": String
    }
}
```

`clientRequesttoken`  <a name="lambda-hook-stack-clientrequesttoken"></a>
Il token di richiesta fornito come input alla richiesta Hook. Questo è un campo obbligatorio.

`awsAccountId`  <a name="lambda-hook-stack-awsaccountid"></a>
L'ID dello stack Account AWS contenente lo stack da valutare.

`stackID`  <a name="lambda-hook-stack-stackid"></a>
L'ID dello stack. CloudFormation 

`changeSetId`  <a name="lambda-hook-stack-changesetid"></a>
L'ID del set di modifiche che ha avviato l'invocazione di Hook. Questo valore è vuoto se la modifica dello stack è stata avviata dall'API Cloud Control o dalle operazioni,, or. `create-stack` `update-stack` `delete-stack`

`hookTypeName`  <a name="lambda-hook-stack-hooktypename"></a>
Il nome dell'Hook in esecuzione.

`hookTypeVersion`  <a name="lambda-hook-stack-hooktypeversion"></a>
La versione dell'Hook in esecuzione.

`hookModel`  <a name="lambda-hook-stack-hookmodel"></a>  
`LambdaFunction`  <a name="lambda-hook-stack-hookmodel-lambdafunction"></a>
L'attuale Lambda ARN richiamato dall'Hook.

`actionInvocationPoint`  <a name="lambda-hook-stack-actioninvocationpoint"></a>
Il punto esatto della logica di provisioning in cui viene eseguito l'Hook.  
*Valori validi*: (`CREATE_PRE_PROVISION`\$1 `UPDATE_PRE_PROVISION` \$1`DELETE_PRE_PROVISION`)

`requestData`  <a name="lambda-hook-stack-requestdata"></a>  
`targetName`  <a name="lambda-hook-stack-requestdata-targetname"></a>
Questo valore sarà`STACK`.  
`targetType`  <a name="lambda-hook-stack-requestdata-targettype"></a>
Questo valore sarà`STACK`.  
`targetLogicalId`  <a name="lambda-hook-stack-requestdata-targetlogicalid"></a>
Il nome dello stack.  
`payload`  <a name="lambda-hook-stack-requestdata-payload"></a>
L'URL predefinito di Amazon S3 contenente un oggetto JSON con le definizioni del modello correnti e precedenti.

`requestContext`  <a name="lambda-hook-stack-requestcontext"></a>
Se l'Hook viene reinvocato, questo oggetto verrà impostato.    
`invocation`  <a name="lambda-hook-stack-requestcontext-invocation"></a>
L'attuale tentativo di eseguire l'Hook.  
`callbackContext`  <a name="lambda-hook-stack-requestcontext-callbackcontext"></a>
Se l'Hook è stato impostato su `IN_PROGRESS` ed `callbackContext` è stato restituito, sarà qui dopo la reinvocazione.

La `payload` proprietà nei dati della richiesta è un URL che il codice deve recuperare. Una volta ricevuto l'URL, si ottiene un oggetto con lo schema seguente:

```
{
    "template": String,
    "previousTemplate": String
}
```

`template`  <a name="lambda-hook-stack-payload-template"></a>
Il CloudFormation modello completo fornito a `create-stack` or`update-stack`. Può essere una stringa JSON o YAML a seconda di ciò che è stato fornito. CloudFormation  
Nelle `delete-stack` operazioni, questo valore sarà vuoto.

`previousTemplate`  <a name="lambda-hook-stack-payload-previoustemplate"></a>
Il CloudFormation modello precedente. Può essere una stringa JSON o YAML a seconda di cosa è stata fornita. CloudFormation  
Nelle `delete-stack` operazioni, questo valore sarà vuoto.

### Esempio di input per la modifica dello stack Lambda Hook
<a name="lambda-hooks-create-lambda-function-stack-example"></a>

Di seguito è riportato un esempio di input per la modifica dello stack. Hook sta valutando una modifica che aggiorna `ObjectLockEnabled` a true e aggiunge una coda Amazon SQS:

```
{
    "clientRequestToken": "f8da6d11-b23f-48f4-814c-0fb6a667f50e",
    "awsAccountId": "123456789012",
    "stackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/MyStack/1a2345b6-0000-00a0-a123-00abc0abc000",
    "changeSetId": null,
    "hookTypeName": "my::lambda::stackhook",
    "hookTypeVersion": "00000008",
    "hookModel": {
        "LambdaFunction": "arn:aws:lambda:us-west-2:123456789012:function:MyFunction"
    },
    "actionInvocationPoint": "UPDATE_PRE_PROVISION",
    "requestData": {
        "targetName": "STACK",
        "targetType": "STACK",
        "targetLogicalId": "my-cloudformation-stack",
        "payload": "https://s3......"
    },
    "requestContext": {
        "invocation": 1,
        "callbackContext": null
    }
}
```

Questo è un esempio `payload` di: `requestData`

```
{
    "template": "{\"Resources\":{\"S3Bucket\":{\"Type\":\"AWS::S3::Bucket\",\"Properties\":{\"ObjectLockEnabled\":true}},\"SQSQueue\":{\"Type\":\"AWS::SQS::Queue\",\"Properties\":{\"QueueName\":\"NewQueue\"}}}}",
    "previousTemplate": "{\"Resources\":{\"S3Bucket\":{\"Type\":\"AWS::S3::Bucket\",\"Properties\":{\"ObjectLockEnabled\":false}}}}"
}
```

### Esempio di funzione Lambda per operazioni in pila
<a name="lambda-hooks-create-lambda-function-stack-example-function"></a>

L'esempio seguente è una semplice funzione che scarica il payload dell'operazione stack, analizza il modello JSON e restituisce. `SUCCESS`

------
#### [ Node.js ]

```
export const handler = async (event, context) => {
    var targetType = event?.requestData?.targetType;
    var payloadUrl = event?.requestData?.payload;
    
    var response = {
        "hookStatus": "SUCCESS",
        "message": "Stack update is compliant",
        "clientRequestToken": event.clientRequestToken
    };
    try {
        const templateHookPayloadRequest = await fetch(payloadUrl);
        const templateHookPayload = await templateHookPayloadRequest.json()
        if (templateHookPayload.template)  {
            // Do something with the template templateHookPayload.template
            // JSON or YAML
        }
        if (templateHookPayload.previousTemplate) {
            // Do something with the template templateHookPayload.previousTemplate
            // JSON or YAML        
        }        
    } catch (error) {
        console.log(error);
        response.hookStatus = "FAILED";
        response.message = "Failed to evaluate stack operation.";
        response.errorCode = "InternalFailure";
    }
    return response;
};
```

------
#### [ Python ]

Per usare Python, devi importare la `requests` libreria. A tale scopo, è necessario includere la libreria nel pacchetto di distribuzione durante la creazione della funzione Lambda. *Per ulteriori informazioni, consulta [Creazione di un pacchetto di distribuzione.zip con dipendenze](https://docs.aws.amazon.com/lambda/latest/dg/python-package.html#python-package-create-dependencies) nella Guida per gli AWS Lambda sviluppatori.*

```
import json
import requests

def lamnbda_handler(event, context):
    # Safely access nested dictionary values
    request_data = event.get('requestData', {})
    target_type = request_data.get('targetType')
    payload_url = request_data.get('payload')
    
    response = {
        "hookStatus": "SUCCESS",
        "message": "Stack update is compliant",
        "clientRequestToken": event.get('clientRequestToken')
    }
    
    try:
        # Fetch the payload
        template_hook_payload_request = requests.get(payload_url)
        template_hook_payload_request.raise_for_status()  # Raise an exception for bad responses
        template_hook_payload = template_hook_payload_request.json()
        
        if 'template' in template_hook_payload:
            # Do something with the template template_hook_payload['template']
            # JSON or YAML
            pass
        
        if 'previousTemplate' in template_hook_payload:
            # Do something with the template template_hook_payload['previousTemplate']
            # JSON or YAML
            pass

    except Exception as error:
        print(error)
        response['hookStatus'] = "FAILED"
        response['message'] = "Failed to evaluate stack operation."
        response['errorCode'] = "InternalFailure"
    
    return response
```

------

## Valutazione delle operazioni relative ai set di modifiche con Lambda Hooks
<a name="lambda-hooks-create-lambda-function-change-set"></a>

Ogni volta che crei un set di modifiche, puoi configurare il tuo CloudFormation Lambda Hook per valutare prima il nuovo set di modifiche e potenzialmente bloccarne l'esecuzione. Puoi configurare il tuo CloudFormation Lambda Hook per eseguire `CHANGE_SET` operazioni mirate nella configurazione Hook`TargetOperations`.

**Topics**
+ [Sintassi di input del set di modifiche Lambda Hook](#lambda-hooks-create-lambda-function-change-set-input)
+ [Esempio di input di modifica del set di modifiche Lambda Hook](#lambda-hooks-create-lambda-function-change-set-example)
+ [Esempio di funzione Lambda per le operazioni sui set di modifiche](#lambda-hooks-create-lambda-function-change-set-example-function)

### Sintassi di input del set di modifiche Lambda Hook
<a name="lambda-hooks-create-lambda-function-change-set-input"></a>

L'input per le operazioni sui set di modifiche è simile alle operazioni sullo stack, ma il payload del set include `requestData` anche un elenco di modifiche alle risorse introdotte dal set di modifiche.

Di seguito è riportato un esempio di forma dell'input JSON:

```
{
    "clientRequesttoken": String,
    "awsAccountId": String,
    "stackID": String,
    "changeSetId": String,
    "hookTypeName": String,
    "hookTypeVersion": String,
    "hookModel": {
        "LambdaFunction":String
    },
    "requestData": {
        "targetName": "CHANGE_SET",
        "targetType": "CHANGE_SET",
        "targetLogicalId": String,
        "payload": String (S3 Presigned URL)
    },
    "requestContext": {
        "invocation": Integer,
        "callbackContext": String
    }
}
```

`clientRequesttoken`  <a name="lambda-hook-change-set-clientrequesttoken"></a>
Il token di richiesta fornito come input alla richiesta Hook. Questo è un campo obbligatorio.

`awsAccountId`  <a name="lambda-hook-change-set-awsaccountid"></a>
L'ID dello stack Account AWS contenente lo stack da valutare.

`stackID`  <a name="lambda-hook-change-set-stackid"></a>
L'ID dello stack. CloudFormation 

`changeSetId`  <a name="lambda-hook-change-set-changesetid"></a>
L'ID del set di modifiche che ha avviato l'invocazione di Hook.

`hookTypeName`  <a name="lambda-hook-change-set-hooktypename"></a>
Il nome dell'Hook in esecuzione.

`hookTypeVersion`  <a name="lambda-hook-change-set-hooktypeversion"></a>
La versione dell'Hook in esecuzione.

`hookModel`  <a name="lambda-hook-change-set-hookmodel"></a>  
`LambdaFunction`  <a name="lambda-hook-change-set-hookmodel-lambdafunction"></a>
L'attuale Lambda ARN richiamato dall'Hook.

`requestData`  <a name="lambda-hook-change-set-requestdata"></a>  
`targetName`  <a name="lambda-hook-change-set-requestdata-targetname"></a>
Questo valore sarà. `CHANGE_SET`  
`targetType`  <a name="lambda-hook-change-set-requestdata-targettype"></a>
Questo valore sarà`CHANGE_SET`.  
`targetLogicalId`  <a name="lambda-hook-change-set-requestdata-targetlogicalid"></a>
Il set di modifiche ARN..  
`payload`  <a name="lambda-hook-change-set-requestdata-payload"></a>
L'URL predefinito di Amazon S3 contenente un oggetto JSON con il modello corrente e un elenco di modifiche introdotte da questo set di modifiche.

`requestContext`  <a name="lambda-hook-change-set-requestcontext"></a>
Se l'Hook viene reinvocato, questo oggetto verrà impostato.    
`invocation`  <a name="lambda-hook-change-set-requestcontext-invocation"></a>
L'attuale tentativo di eseguire l'Hook.  
`callbackContext`  <a name="lambda-hook-change-set-requestcontext-callbackcontext"></a>
Se l'Hook è stato impostato su `IN_PROGRESS` ed `callbackContext` è stato restituito, sarà qui dopo la reinvocazione.

La `payload` proprietà nei dati della richiesta è un URL che il codice deve recuperare. Una volta ricevuto l'URL, si ottiene un oggetto con lo schema seguente:

```
{
    "template": String,
    "changedResources": [
        {
            "action": String,
            "beforeContext": JSON String,
            "afterContext": JSON String,
            "lineNumber": Integer,
            "logicalResourceId": String,
            "resourceType": String
        }
    ]
}
```

`template`  <a name="lambda-hook-change-set-payload-template"></a>
Il CloudFormation modello completo fornito a `create-stack` or`update-stack`. Può essere una stringa JSON o YAML a seconda di ciò che è stato fornito. CloudFormation

`changedResources`  <a name="lambda-hook-change-set-payload-changed-resources"></a>
Un elenco di risorse modificate.    
`action`  <a name="lambda-hook-change-set-payload-changed-resources-action"></a>
Il tipo di modifica applicata alla risorsa.  
*Valori validi*: (`CREATE`\$1 `UPDATE` \$1`DELETE`)  
`beforeContext`  <a name="lambda-hook-change-set-payload-changed-resources-beforecontext"></a>
Una stringa JSON delle proprietà della risorsa prima della modifica. Questo valore è nullo quando la risorsa viene creata. Tutti i valori booleani e numerici in questa stringa JSON sono STRINGS.  
`afterContext`  <a name="lambda-hook-change-set-payload-changed-resources-aftercontext"></a>
Una stringa JSON delle proprietà delle risorse se questo set di modifiche viene eseguito. Questo valore è nullo quando la risorsa viene eliminata. Tutti i valori booleani e numerici in questa stringa JSON sono STRINGS.  
`lineNumber`  <a name="lambda-hook-change-set-payload-changed-resources-linenumber"></a>
Il numero di riga del modello che ha causato questa modifica. Se l'azione è, `DELETE` questo valore sarà nullo.   
`logicalResourceId`  <a name="lambda-hook-change-set-payload-changed-resources-logicalresourceid"></a>
L'ID della risorsa logica della risorsa da modificare.  
`resourceType`  <a name="lambda-hook-change-set-payload-changed-resources-resourcetype"></a>
Il tipo di risorsa che viene modificata.

### Esempio di input di modifica del set di modifiche Lambda Hook
<a name="lambda-hooks-create-lambda-function-change-set-example"></a>

Di seguito è riportato un esempio di input di modifica del set di modifiche. Nell'esempio seguente, è possibile visualizzare le modifiche introdotte dal set di modifiche. La prima modifica consiste nell'eliminare una coda chiamata. `CoolQueue` La seconda modifica consiste nell'aggiungere una nuova coda chiamata. `NewCoolQueue` L'ultima modifica è un aggiornamento di`DynamoDBTable`.

```
{
    "clientRequestToken": "f8da6d11-b23f-48f4-814c-0fb6a667f50e",
    "awsAccountId": "123456789012",
    "stackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/MyStack/1a2345b6-0000-00a0-a123-00abc0abc000",
    "changeSetId": "arn:aws:cloudformation:us-west-2:123456789012:changeSet/SampleChangeSet/1a2345b6-0000-00a0-a123-00abc0abc000",
    "hookTypeName": "my::lambda::changesethook",
    "hookTypeVersion": "00000008",
    "hookModel": {
        "LambdaFunction": "arn:aws:lambda:us-west-2:123456789012:function:MyFunction"
    },
    "actionInvocationPoint": "CREATE_PRE_PROVISION",
    "requestData": {
        "targetName": "CHANGE_SET",
        "targetType": "CHANGE_SET",
        "targetLogicalId": "arn:aws:cloudformation:us-west-2:123456789012:changeSet/SampleChangeSet/1a2345b6-0000-00a0-a123-00abc0abc000",
        "payload": "https://s3......"
    },
    "requestContext": {
        "invocation": 1,
        "callbackContext": null
    }
}
```

Questo è un esempio `payload` di`requestData.payload`:

```
{
  template: 'Resources:\n' +
    '  DynamoDBTable:\n' +
    '    Type: AWS::DynamoDB::Table\n' +
    '    Properties:\n' +
    '      AttributeDefinitions:\n' +
    '        - AttributeName: "PK"\n' +
    '          AttributeType: "S"\n' +
    '      BillingMode: "PAY_PER_REQUEST"\n' +
    '      KeySchema:\n' +
    '        - AttributeName: "PK"\n' +
    '          KeyType: "HASH"\n' +
    '      PointInTimeRecoverySpecification:\n' +
    '        PointInTimeRecoveryEnabled: false\n' +
    '  NewSQSQueue:\n' +
    '    Type: AWS::SQS::Queue\n' +
    '    Properties:\n' +
    '      QueueName: "NewCoolQueue"',
  changedResources: [
    {
      logicalResourceId: 'SQSQueue',
      resourceType: 'AWS::SQS::Queue',
      action: 'DELETE',
      lineNumber: null,
      beforeContext: '{"Properties":{"QueueName":"CoolQueue"}}',
      afterContext: null
    },
    {
      logicalResourceId: 'NewSQSQueue',
      resourceType: 'AWS::SQS::Queue',
      action: 'CREATE',
      lineNumber: 14,
      beforeContext: null,
      afterContext: '{"Properties":{"QueueName":"NewCoolQueue"}}'
    },
    {
      logicalResourceId: 'DynamoDBTable',
      resourceType: 'AWS::DynamoDB::Table',
      action: 'UPDATE',
      lineNumber: 2,
      beforeContext: '{"Properties":{"BillingMode":"PAY_PER_REQUEST","AttributeDefinitions":[{"AttributeType":"S","AttributeName":"PK"}],"KeySchema":[{"KeyType":"HASH","AttributeName":"PK"}]}}',
      afterContext: '{"Properties":{"BillingMode":"PAY_PER_REQUEST","PointInTimeRecoverySpecification":{"PointInTimeRecoveryEnabled":"false"},"AttributeDefinitions":[{"AttributeType":"S","AttributeName":"PK"}],"KeySchema":[{"KeyType":"HASH","AttributeName":"PK"}]}}'
    }
  ]
}
```

### Esempio di funzione Lambda per le operazioni sui set di modifiche
<a name="lambda-hooks-create-lambda-function-change-set-example-function"></a>

L'esempio seguente è una semplice funzione che scarica il payload dell'operazione Change Set, esegue un ciclo su ogni modifica e quindi stampa le proprietà before e after prima di restituire a. `SUCCESS`

------
#### [ Node.js ]

```
export const handler = async (event, context) => {
    var payloadUrl = event?.requestData?.payload;    
    var response = {
        "hookStatus": "SUCCESS",
        "message": "Change set changes are compliant",
        "clientRequestToken": event.clientRequestToken
    };
    try {
        const changeSetHookPayloadRequest = await fetch(payloadUrl);
        const changeSetHookPayload = await changeSetHookPayloadRequest.json();
        const changes = changeSetHookPayload.changedResources || [];
        for(const change of changes) {
            var beforeContext = {};
            var afterContext = {};
            if(change.beforeContext) {
                beforeContext = JSON.parse(change.beforeContext);
            }
            if(change.afterContext) {
                afterContext = JSON.parse(change.afterContext);
            }
            console.log(beforeContext)
            console.log(afterContext)
            // Evaluate Change here
        }
    } catch (error) {
        console.log(error);
        response.hookStatus = "FAILED";
        response.message = "Failed to evaluate change set operation.";
        response.errorCode = "InternalFailure";
    }
    return response;
};
```

------
#### [ Python ]

Per usare Python, devi importare la `requests` libreria. A tale scopo, è necessario includere la libreria nel pacchetto di distribuzione durante la creazione della funzione Lambda. *Per ulteriori informazioni, consulta [Creazione di un pacchetto di distribuzione.zip con dipendenze](https://docs.aws.amazon.com/lambda/latest/dg/python-package.html#python-package-create-dependencies) nella Guida per gli AWS Lambda sviluppatori.*

```
import json
import requests

def lambda_handler(event, context):
    payload_url = event.get('requestData', {}).get('payload')
    response = {
        "hookStatus": "SUCCESS",
        "message": "Change set changes are compliant",
        "clientRequestToken": event.get('clientRequestToken')
    }

    try:
        change_set_hook_payload_request = requests.get(payload_url)
        change_set_hook_payload_request.raise_for_status()  # Raises an HTTPError for bad responses
        change_set_hook_payload = change_set_hook_payload_request.json()
        
        changes = change_set_hook_payload.get('changedResources', [])
        
        for change in changes:
            before_context = {}
            after_context = {}
            
            if change.get('beforeContext'):
                before_context = json.loads(change['beforeContext'])
            
            if change.get('afterContext'):
                after_context = json.loads(change['afterContext'])
            
            print(before_context)
            print(after_context)
            # Evaluate Change here

    except requests.RequestException as error:
        print(error)
        response['hookStatus'] = "FAILED"
        response['message'] = "Failed to evaluate change set operation."
        response['errorCode'] = "InternalFailure"
    except json.JSONDecodeError as error:
        print(error)
        response['hookStatus'] = "FAILED"
        response['message'] = "Failed to parse JSON payload."
        response['errorCode'] = "InternalFailure"

    return response
```

------