Invoca funzione AWS Lambda - Amazon Simple Storage Service

Invoca funzione AWS Lambda

È possibile utilizzare Operazioni in batch Amazon S3 per eseguire operazioni in batch su larga scala su oggetti Amazon S3. L'operazione Invoca funzione AWS Lambda di Operazioni in batch avvia le funzioni AWS Lambda per eseguire azioni personalizzate sugli oggetti elencati in un manifesto. Questa sezione descrive come creare una funzione Lambda da utilizzare con le operazioni in batch Amazon S3 e come creare un processo per richiamare la funzione. Il processo di S3 Batch Operations utilizza l'operazione LambdaInvoke per eseguire una funzione Lambda su ogni oggetto elencato in un manifest.

È possibile lavorare con Operazioni in batch S3 utilizzando la console Amazon S3, l'interfaccia AWS Command Line Interface (AWS CLI), gli SDK AWS o REST API di Amazon S3. Per ulteriori informazioni sull'utilizzo di Lambda, consulta Nozioni di base su AWS Lambda nella Guida per Developer di AWS Lambda.

Le sezioni seguenti spiegano come iniziare a utilizzare le operazioni in batch S3 con Lambda.

Utilizzo di Lambda con Operazioni in batch

Durante l'utilizzo delle operazioni in batch S3 con AWS Lambda, occorre creare nuove funzioni Lambda specifiche da utilizzare con le operazioni in batch S3. Non puoi riutilizzare funzioni basate su eventi Amazon S3 esistenti con le operazioni in batch S3. Le funzioni evento possono solo ricevere messaggi, non possono restituirli. Le funzioni Lambda utilizzate con le operazioni in batch S3 devono accettare e restituire messaggi. Per ulteriori informazioni sull'utilizzo di Lambda con eventi Amazon S3, consulta Utilizzo di AWS Lambda con Amazon S3 nella Guida per Developer AWS Lambda.

Devi creare un processo di operazioni in batch Amazon S3 che richiama la funzione Lambda. Il processo esegue la stessa funzione Lambda su tutti gli oggetti elencati nel manifest. Puoi controllare quali versioni della funzione Lambda utilizzare durante l'elaborazione degli oggetti nel manifest. Le operazioni in batch S3 supportano Amazon Resource Name (ARN) non qualificati, alias e versioni specifiche. Per ulteriori informazioni, consulta Introduzione al controllo delle versioni di AWS Lambda nella Guida per Developer di AWS Lambda.

Se fornisci il processo di operazioni in batch Amazon S3 con una funzione ARN che utilizza un alias o il qualificatore $LATEST e aggiorni la versione cui questi puntano, le operazioni in batch S3 iniziano a chiamare la nuova versione della funzione Lambda. Ciò può essere utile quando desideri aggiornare la parte di funzionalità durante un processo di grandi dimensioni. Se non si desidera che Operazioni in batch S3 modifichi la versione utilizzata, fornisci la versione specifica nel parametro FunctionARN quando crei il processo.

Un singolo processo AWS Lambda con Operazioni in batch S3 può supportare un manifesto con un massimo di 20 miliardi di oggetti.

Utilizzo di Lambda e Operazioni in batch con i bucket di directory

I bucket di directory sono un tipo di bucket Amazon S3 progettato per carichi di lavoro o applicazioni critiche dal punto di vista delle prestazioni che richiedono una latenza costante a una cifra al millisecondo. Per ulteriori informazioni, consulta Directory buckets.

Esistono requisiti speciali per l'uso di Operazioni in batch per invocare funzioni Lambda che agiscono sui bucket della directory. Ad esempio, è necessario strutturare la richiesta Lambda utilizzando uno schema JSON aggiornato e specificare InvocationSchemaVersion 2.0 (non 1.0) quando si crea il processo. Questo schema aggiornato consente di specificare coppie chiave-valore opzionali per UserArguments, che puoi utilizzare per modificare determinati parametri delle funzioni Lambda esistenti. Per ulteriori informazioni, consulta Automate object processing in Amazon S3 directory buckets with S3 Batch Operations and AWS Lambda in AWS Storage Blog.

Codici di risposta e dei risultati

Operazioni in batch S3 invoca la funzione Lambda con una o più chiavi, ognuna delle quali è associata a un TaskID. Operazioni in batch S3 si aspetta un codice risultato per chiave dalle funzioni Lambda. Tutti gli ID dei task inviati nella richiesta che non vengono restituiti con un codice di risultato per chiave riceveranno il codice di risultato dal campo treatMissingKeysAs. treatMissingKeysAs è un campo di richiesta opzionale e ha come valore predefinito TemporaryFailure. La tabella seguente contiene gli altri possibili codici di risultato e valori per il campo treatMissingKeysAs.

Codice di risposta Descrizione
Succeeded L'attività si è conclusa normalmente. Se hai richiesto un rapporto di completamento del processo, la stringa di risultato dell'attività viene inclusa nel rapporto.
TemporaryFailure Nell'attività si è verificato un errore temporaneo e verrà reindirizzata prima del completamento del processo. La stringa risultante viene ignorata. Se questo è l'ultimo reindirizzamento, il messaggio di errore viene incluso nel rapporto finale.
PermanentFailure Nell'attività si è verificato un errore permanente. Se hai richiesto un rapporto di completamento del processo, l'attività viene contrassegnata come Failed e include la stringa del messaggio di errore. Le stringhe risultanti da attività non riuscite vengono ignorate.

Creazione di una funzione Lambda da utilizzare con le operazioni in batch S3

In questa sezione sono fornite delle autorizzazioni AWS Identity and Access Management (IAM) di esempio da utilizzare con la funzione Lambda. Contiene anche una funzione Lambda di esempio da utilizzare con le operazioni in batch S3. Se non hai mai creato una funzione Lambda, consulta Tutorial: utilizzo di AWS Lambda con Amazon S3 nella Guida per Developer di AWS Lambda.

Devi creare funzioni Lambda specifiche da utilizzare con le operazioni in batch S3. Non è possibile riutilizzare le funzioni Lambda esistenti basate su eventi di Amazon S3, perché le funzioni Lambda utilizzate per Operazioni in batch S3 devono accettare e restituire campi di dati speciali.

Importante

Le funzioni AWS Lambda scritte in Java accettano le interfacce di gestione RequestHandler o RequestStreamHandler. Tuttavia, per supportare il formato di richiesta e risposta di operazioni in batch S3, AWS Lambda richiede l'interfaccia RequestStreamHandler per la serializzazione e la deserializzazione personalizzate di una richiesta e una risposta. Questa interfaccia permette a Lambda di passare oggetti InputStream e OutputStream al metodo Java handleRequest.

Assicurati di specificare l'interfaccia RequestStreamHandler quando utilizzi funzioni Lambda con le operazioni in batch S3. Se utilizzi un'interfaccia RequestHandler, il processo batch non riuscirà restituendo il messaggio "Invalid JSON returned in Lambda payload" (JSON non valido restituito nel payload Lambda) nel report di completamento.

Per ulteriori informazioni, consulta Interfacce Handler nella Guida per l'utente di AWS Lambda.

Autorizzazioni IAM di esempio

Di seguito sono riportati alcuni esempi delle autorizzazioni IAM necessarie per utilizzare una funzione Lambda con le operazioni in batch S3.

Esempio – Policy di trust delle operazioni in batch S3

Di seguito è riportato un esempio di policy di trust che puoi utilizzare per il ruolo IAM in Batch Operations. Questo ruolo IAM viene specificato quando crei il processo e concede a Batch Operations l'autorizzazione per assumere il ruolo IAM.

JSON
{ "Version":"2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "batchoperations.s3.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }
Esempio – Policy IAM Lambda

Di seguito è riportato un esempio di policy IAM che fornisce alle operazioni in batch S3 l'autorizzazione per richiamare la funzione Lambda e leggere il manifest di input.

JSON
{ "Version":"2012-10-17", "Statement": [ { "Sid": "BatchOperationsLambdaPolicy", "Effect": "Allow", "Action": [ "s3:GetObject", "s3:GetObjectVersion", "s3:PutObject", "lambda:InvokeFunction" ], "Resource": "*" } ] }

Richiesta e risposta di esempio

Questa sezione fornisce esempi di richiesta e risposta per la funzione Lambda.

Esempio Richiesta

Di seguito è riportato un esempio JSON di richiesta per la funzione Lambda.

{ "invocationSchemaVersion": "1.0", "invocationId": "YXNkbGZqYWRmaiBhc2RmdW9hZHNmZGpmaGFzbGtkaGZza2RmaAo", "job": { "id": "f3cc4f60-61f6-4a2b-8a21-d07600c373ce" }, "tasks": [ { "taskId": "dGFza2lkZ29lc2hlcmUK", "s3Key": "customerImage1.jpg", "s3VersionId": "1", "s3BucketArn": "arn:aws:s3:us-east-1:0123456788:amzn-s3-demo-bucket1" } ] }
Esempio Risposta

Di seguito è riportato un esempio JSON di risposta per la funzione Lambda.

{ "invocationSchemaVersion": "1.0", "treatMissingKeysAs" : "PermanentFailure", "invocationId" : "YXNkbGZqYWRmaiBhc2RmdW9hZHNmZGpmaGFzbGtkaGZza2RmaAo", "results": [ { "taskId": "dGFza2lkZ29lc2hlcmUK", "resultCode": "Succeeded", "resultString": "[\"Mary Major", \"John Stiles\"]" } ] }

Funzione Lambda di esempio per le operazioni in batch S3

Nell'esempio seguente Python Lambda rimuove un contrassegno di eliminazione da un oggetto con versione.

Come mostrato nell'esempio, le chiavi di operazioni in batch S3 sono codificate in formato URL. Per utilizzare Amazon S3 con altri servizi AWS, è importante che l'URL decodifichi la chiave che viene passata dalle operazioni in batch S3.

import logging from urllib import parse import boto3 from botocore.exceptions import ClientError logger = logging.getLogger(__name__) logger.setLevel("INFO") s3 = boto3.client("s3") def lambda_handler(event, context): """ Removes a delete marker from the specified versioned object. :param event: The S3 batch event that contains the ID of the delete marker to remove. :param context: Context about the event. :return: A result structure that Amazon S3 uses to interpret the result of the operation. When the result code is TemporaryFailure, S3 retries the operation. """ # Parse job parameters from Amazon S3 batch operations invocation_id = event["invocationId"] invocation_schema_version = event["invocationSchemaVersion"] results = [] result_code = None result_string = None task = event["tasks"][0] task_id = task["taskId"] try: obj_key = parse.unquote_plus(task["s3Key"], encoding="utf-8") obj_version_id = task["s3VersionId"] bucket_name = task["s3BucketArn"].split(":")[-1] logger.info( "Got task: remove delete marker %s from object %s.", obj_version_id, obj_key ) try: # If this call does not raise an error, the object version is not a delete # marker and should not be deleted. response = s3.head_object( Bucket=bucket_name, Key=obj_key, VersionId=obj_version_id ) result_code = "PermanentFailure" result_string = ( f"Object {obj_key}, ID {obj_version_id} is not " f"a delete marker." ) logger.debug(response) logger.warning(result_string) except ClientError as error: delete_marker = error.response["ResponseMetadata"]["HTTPHeaders"].get( "x-amz-delete-marker", "false" ) if delete_marker == "true": logger.info( "Object %s, version %s is a delete marker.", obj_key, obj_version_id ) try: s3.delete_object( Bucket=bucket_name, Key=obj_key, VersionId=obj_version_id ) result_code = "Succeeded" result_string = ( f"Successfully removed delete marker " f"{obj_version_id} from object {obj_key}." ) logger.info(result_string) except ClientError as error: # Mark request timeout as a temporary failure so it will be retried. if error.response["Error"]["Code"] == "RequestTimeout": result_code = "TemporaryFailure" result_string = ( f"Attempt to remove delete marker from " f"object {obj_key} timed out." ) logger.info(result_string) else: raise else: raise ValueError( f"The x-amz-delete-marker header is either not " f"present or is not 'true'." ) except Exception as error: # Mark all other exceptions as permanent failures. result_code = "PermanentFailure" result_string = str(error) logger.exception(error) finally: results.append( { "taskId": task_id, "resultCode": result_code, "resultString": result_string, } ) return { "invocationSchemaVersion": invocation_schema_version, "treatMissingKeysAs": "PermanentFailure", "invocationId": invocation_id, "results": results, }

Creazione di un processo di operazioni in batch Amazon S3 che richiama una funzione Lambda

Quando crei un processo di operazioni in batch Amazon S3 per richiamare una funzione Lambda, devi fornire gli elementi seguenti:

  • ARN della funzione Lambda, che può includere l'alias della funzione o un numero specifico di versione

  • Ruolo IAM con l'autorizzazione per richiamare la funzione

  • Il parametro dell'operazione LambdaInvokeFunction

Per ulteriori informazioni sulla creazione di un processo di operazioni in batch Amazon S3, consulta Creazione di un processo di operazioni in batch S3 e Operazioni supportate dalle operazioni in batch S3.

L'esempio seguente crea un processo di Operazioni in batch S3 che invoca una funzione Lambda utilizzando l'interfaccia AWS CLI. Per utilizzare questo esempio, sostituisci user input placeholders con le informazioni appropriate.

aws s3control create-job --account-id account-id --operation '{"LambdaInvoke": { "FunctionArn": "arn:aws:lambda:region:account-id:function:LambdaFunctionName" } }' --manifest '{"Spec":{"Format":"S3BatchOperations_CSV_20180820","Fields":["Bucket","Key"]},"Location":{"ObjectArn":"arn:aws:s3:::amzn-s3-demo-manifest-bucket","ETag":"ManifestETag"}}' --report '{"Bucket":"arn:aws:s3:::amzn-s3-demo-bucket","Format":"Report_CSV_20180820","Enabled":true,"Prefix":"ReportPrefix","ReportScope":"AllTasks"}' --priority 2 --role-arn arn:aws:iam::account-id:role/BatchOperationsRole --region region --description "Lambda Function"

Fornitura di informazioni a livello di task nei manifesti Lambda

Quando si utilizzano le funzioni AWS Lambda con Operazioni in batch S3, è possibile che si desiderino dati aggiuntivi per accompagnare ogni attività o chiave che viene gestita. Ad esempio, si potrebbe voler fornire sia una chiave dell'oggetto di origine che una chiave dell'oggetto nuovo. La funzione Lambda può quindi copiare la chiave di origine in un nuovo bucket S3 con un nuovo nome. Per impostazione predefinita, Operazioni in batch consente di specificare solo il bucket di destinazione e un elenco di chiavi di origine nel manifesto di input del processo. Gli esempi seguenti descrivono come includere dati aggiuntivi nel manifesto, in modo da poter eseguire funzioni Lambda più complesse.

Per specificare i parametri per chiave nel manifest delle operazioni in batch S3 da utilizzare nel codice della funzione Lambda, utilizza il formato JSON con codifica in formato URL seguente. Il campo key viene passato alla funzione Lambda come se fosse una chiave oggetto Amazon S3. Tuttavia, può essere interpretato dalla funzione Lambda per contenere altri valori o più chiavi, come mostrato negli esempi seguenti.

Nota

Il numero massimo di caratteri per il campo key nel manifest è 1.024.

Esempio - Manifesto che sostituisce le "chiavi Amazon S3" con stringhe JSON

Alle operazioni in batch S3 deve essere fornita la versione con codifica in formato URL.

amzn-s3-demo-bucket,{"origKey": "object1key", "newKey": "newObject1Key"} amzn-s3-demo-bucket,{"origKey": "object2key", "newKey": "newObject2Key"} amzn-s3-demo-bucket,{"origKey": "object3key", "newKey": "newObject3Key"}
Esempio - Manifesto codificato tramite URL

Alle operazioni in batch S3 deve essere fornita questa versione con codifica in formato URL. La versione senza codifica URL non funziona.

amzn-s3-demo-bucket,%7B%22origKey%22%3A%20%22object1key%22%2C%20%22newKey%22%3A%20%22newObject1Key%22%7D amzn-s3-demo-bucket,%7B%22origKey%22%3A%20%22object2key%22%2C%20%22newKey%22%3A%20%22newObject2Key%22%7D amzn-s3-demo-bucket,%7B%22origKey%22%3A%20%22object3key%22%2C%20%22newKey%22%3A%20%22newObject3Key%22%7D
Esempio – Funzione Lambda con formato manifest che scrive i risultati nel report del processo

Questo esempio di manifesto codificato dall'URL contiene chiavi di oggetti delimitate da pipe per l'analisi della seguente funzione Lambda.

amzn-s3-demo-bucket,object1key%7Clower amzn-s3-demo-bucket,object2key%7Cupper amzn-s3-demo-bucket,object3key%7Creverse amzn-s3-demo-bucket,object4key%7Cdelete

Questa funzione Lambda mostra come analizzare un'attività delimitata da barra verticale e codificata nel manifesto di Operazioni in batch S3. L'attività indica quale operazione di revisione viene applicata all'oggetto specificato.

import logging from urllib import parse import boto3 from botocore.exceptions import ClientError logger = logging.getLogger(__name__) logger.setLevel("INFO") s3 = boto3.resource("s3") def lambda_handler(event, context): """ Applies the specified revision to the specified object. :param event: The Amazon S3 batch event that contains the ID of the object to revise and the revision type to apply. :param context: Context about the event. :return: A result structure that Amazon S3 uses to interpret the result of the operation. """ # Parse job parameters from Amazon S3 batch operations invocation_id = event["invocationId"] invocation_schema_version = event["invocationSchemaVersion"] results = [] result_code = None result_string = None task = event["tasks"][0] task_id = task["taskId"] # The revision type is packed with the object key as a pipe-delimited string. obj_key, revision = parse.unquote_plus(task["s3Key"], encoding="utf-8").split("|") bucket_name = task["s3BucketArn"].split(":")[-1] logger.info("Got task: apply revision %s to %s.", revision, obj_key) try: stanza_obj = s3.Bucket(bucket_name).Object(obj_key) stanza = stanza_obj.get()["Body"].read().decode("utf-8") if revision == "lower": stanza = stanza.lower() elif revision == "upper": stanza = stanza.upper() elif revision == "reverse": stanza = stanza[::-1] elif revision == "delete": pass else: raise TypeError(f"Can't handle revision type '{revision}'.") if revision == "delete": stanza_obj.delete() result_string = f"Deleted stanza {stanza_obj.key}." else: stanza_obj.put(Body=bytes(stanza, "utf-8")) result_string = ( f"Applied revision type '{revision}' to " f"stanza {stanza_obj.key}." ) logger.info(result_string) result_code = "Succeeded" except ClientError as error: if error.response["Error"]["Code"] == "NoSuchKey": result_code = "Succeeded" result_string = ( f"Stanza {obj_key} not found, assuming it was deleted " f"in an earlier revision." ) logger.info(result_string) else: result_code = "PermanentFailure" result_string = ( f"Got exception when applying revision type '{revision}' " f"to {obj_key}: {error}." ) logger.exception(result_string) finally: results.append( { "taskId": task_id, "resultCode": result_code, "resultString": result_string, } ) return { "invocationSchemaVersion": invocation_schema_version, "treatMissingKeysAs": "PermanentFailure", "invocationId": invocation_id, "results": results, }

Tutorial su Operazioni in batch S3

I seguenti tutorial illustrano le procedure complete end-to-end per alcune operazioni in batch con Lambda. In questa esercitazione si apprende come impostare Operazioni in batch per invocare una funzione Lambda per la transcodifica in batch dei video memorizzati in un bucket di origine S3. La funzione Lambda chiama AWS Elemental MediaConvert per transcodificare i video.