

# Invocar Lambda con eventos de otros servicios de AWS
<a name="lambda-services"></a>

Algunos Servicios de AWS pueden invocar directamente las funciones de Lambda mediante *desencadenadores*. Estos servicios envían eventos a Lambda y la función se invoca inmediatamente cuando se produce el evento especificado. Los desencadenadores son adecuados para eventos discretos y para el procesamiento en tiempo real. Al [crear un desencadenador mediante la consola de Lambda](#lambda-invocation-trigger), esta interactúa con el servicio de AWS correspondiente para configurar la notificación de eventos en ese servicio. En realidad, el servicio que genera los eventos es el que almacena y administra el desencadenador, no Lambda.

Los eventos son datos estructurados en formato JSON. La estructura JSON varía según el servicio que la genera y el tipo de evento, pero todas contienen los datos que la función necesita para procesar el evento.

Una función puede tener varios desencadenadores. Cada desencadenador actúa como un cliente que invoca su función de manera independiente, y cada evento que Lambda envía a su función tiene datos de un solo desencadenador. Lambda convierte el documento de evento en un objeto y se lo pasa al controlador de la función.

La invocación basada en eventos puede ser [sinrónica](invocation-sync.md) o [asincrónic](invocation-async.md)a, en función del servicio.
+ Para la invocación síncrona, el servicio que genera el evento espera la respuesta de la función. Ese servicio define los datos que la función necesita devolver en la respuesta. El servicio controla la estrategia de error, como, por ejemplo, si se debe reintentar en caso de errores.
+ Para la invocación asíncrona, Lambda coloca el evento en la cola antes de pasárselo a la función. Cuando Lambda pone en cola el evento, envía inmediatamente una respuesta de operación correcta al servicio que lo generó. Después de que la función procese el evento, Lambda no devuelve una respuesta al servicio de generación de eventos.

## Creación de un desencadenador
<a name="lambda-invocation-trigger"></a>

La forma más sencilla de crear un desencadenador es utilizar la consola de Lambda. Al crear un desencadenador mediante la consola, Lambda agrega de forma automática los permisos necesarios a la [política basada en recursos](access-control-resource-based.md) de la función.

**Creación de un desencadenador mediante la consola de Lambda**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función para la que desee crear un desencadenador.

1. En el panel **Información general de la función**, elija **Agregar desencadenador**.

1. Seleccione el servicio de AWS en el que desee invocar su función.

1. Rellene las opciones del panel **Configuración del desencadenador** y seleccione **Agregar**. En función del Servicio de AWS que elija para invocar la función, las opciones de configuración del desencadenador serán diferentes.

## Servicios que pueden invocar funciones de Lambda
<a name="listing-of-services-and-links-to-more-information"></a>

En la siguiente tabla se enumeran los servicios que pueden invocar funciones de Lambda.


****  

| Servicio | Método de invocación | 
| --- | --- | 
|  [Transmisión gestionada de Amazon para Apache Kafka](with-msk.md)  |  [Asignación de orígenes de eventos](invocation-eventsourcemapping.md)  | 
|  [Apache Kafka autoadministrado](with-kafka.md)  |  [Asignación de orígenes de eventos](invocation-eventsourcemapping.md)  | 
|  [Amazon API Gateway](services-apigateway.md)  |  Invocación síncrona basada en eventos  | 
|  [AWS CloudFormation](services-cloudformation.md)  |  Invocación asíncrona basada en eventos  | 
|  [Registros de Amazon CloudWatch](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#LambdaFunctionExample)  |  Invocación asíncrona basada en eventos  | 
|  [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-notify-lambda-cc.html)  |  Invocación asíncrona basada en eventos  | 
|  [AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html)  |  Invocación asíncrona basada en eventos  | 
|  [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-events.html)  |  Invocación síncrona basada en eventos  | 
|  [AWS Config](governance-config.md)  |  Invocación asíncrona basada en eventos  | 
|  [Amazon Connect](https://docs.aws.amazon.com/connect/latest/adminguide/connect-lambda-functions.html)  |  Invocación sincrónica basada en eventos  | 
|  [Amazon DocumentDB](with-documentdb.md)  |  [Asignación de orígenes de eventos](invocation-eventsourcemapping.md)  | 
|  [Amazon DynamoDB](with-ddb.md)  |  [Asignación de orígenes de eventos](invocation-eventsourcemapping.md)  | 
|  [Elastic Load Balancing (Equilibrador de carga de aplicación)](services-alb.md)  |  Invocación sincrónica basada en eventos  | 
|  [Amazon EventBridge (CloudWatch Events)](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html)  |  Basado en eventos; invocación asíncrona (buses de eventos), invocación asíncrona o sincrónica (canalizaciones y planificaciones)  | 
|  [AWS IoT](services-iot.md)  |  Invocación asíncrona basada en eventos  | 
|  [Amazon Kinesis](with-kinesis.md)  |  [Asignación de orígenes de eventos](invocation-eventsourcemapping.md)  | 
|  [Amazon Data Firehose](https://docs.aws.amazon.com/firehose/latest/dev/data-transformation.html)  |  Invocación sincrónica basada en eventos  | 
|  [Amazon Lex](https://docs.aws.amazon.com/lexv2/latest/dg/lambda.html)  |  Invocación síncrona basada en eventos  | 
|  [Amazon MQ](with-mq.md)  |  [Asignación de orígenes de eventos](invocation-eventsourcemapping.md)  | 
|  [Amazon Simple Email Service](https://docs.aws.amazon.com/ses/latest/dg/receiving-email-action-lambda.html)  |  Invocación asíncrona basada en eventos  | 
|  [Amazon Simple Notification Service](with-sns.md)  |  Invocación asíncrona basada en eventos  | 
|  [Amazon Simple Queue Service](with-sqs.md)  |  [Asignación de orígenes de eventos](invocation-eventsourcemapping.md)  | 
|  [Amazon Simple Storage Service (Amazon S3)](with-s3.md)  |  Invocación asíncrona basada en eventos  | 
|  [Amazon Simple Storage Service Batch](services-s3-batch.md)  |  Invocación síncrona basada en eventos  | 
|  [Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotate-secrets_lambda.html)  |  Rotación de secretos  | 
|  [AWS Step Functions](https://docs.aws.amazon.com/step-functions/latest/dg/connect-lambda.html)  |  Invocación sincrónica o asíncrona basada en eventos  | 
|  [Amazon VPC Lattice](https://docs.aws.amazon.com/vpc-lattice/latest/ug/lambda-functions.html)  |  Invocación sincrónica basada en eventos  | 

# Uso de Lambda con Apache Kafka
<a name="with-kafka-esm"></a>

Lambda admite [Apache Kafka](https://kafka.apache.org/) como una [fuente del evento](invocation-eventsourcemapping.md). Apache Kafka es una plataforma de transmisión de eventos de código abierto diseñada para gestionar canalizaciones de datos y aplicaciones de transmisión de alto rendimiento y en tiempo real. Existen dos formas principales de utilizar Lambda con Apache Kafka:
+ [Uso de Lambda con Amazon MSK](with-msk.md): Amazon Managed Streaming para Apache Kafka (Amazon MSK) es un servicio totalmente administrado por AWS. Amazon MSK ayuda a automatizar la administración de la infraestructura de Kafka, lo que incluye el aprovisionamiento, la aplicación de parches y el escalado.
+ [Uso de Lambda con Apache Kafka autoadministrado](with-kafka.md): en la terminología de AWS, un clúster autoadministrado incluye clústeres de Kafka alojados que no son de AWS. Por ejemplo, puede seguir utilizando Lambda con un clúster de Kafka alojado en un proveedor de servicios en la nube que no sea AWS, como [Confluent Cloud](https://www.confluent.io/confluent-cloud/) o [Redpanda](https://www.redpanda.com/).

Al decidir entre Amazon MSK y Apache Kafka autoadministrado, tenga en cuenta sus necesidades operativas y requisitos de control. Amazon MSK es la mejor opción si quiere que AWS le ayude rápidamente a administrar una configuración de Kafka escalable y lista para producción con una sobrecarga operativa mínima. Simplifica la seguridad, la supervisión y la alta disponibilidad, lo que le ayuda a centrarse en el desarrollo de aplicaciones en lugar de la administración de la infraestructura. Por otro lado, Apache Kafka autoadministrado es más adecuado para los casos de uso que se ejecutan en entornos alojados que no son de AWS, lo que incluye los clústeres en las instalaciones.

**Topics**
+ [

# Uso de Lambda con Amazon MSK
](with-msk.md)
+ [

# Uso de Lambda con Apache Kafka autoadministrado
](with-kafka.md)
+ [

# Modos de escalado del sondeo de eventos de Apache Kafka en Lambda
](kafka-scaling-modes.md)
+ [

# Posiciones iniciales de flujos y sondeo de Apache Kafka en Lambda
](kafka-starting-positions.md)
+ [

# ID del grupo de consumidores personalizable en Lambda
](kafka-consumer-group-id.md)
+ [

# Filtrado de eventos de Amazon MSK y de fuentes de eventos autoadministrados de Apache Kafka
](kafka-filtering.md)
+ [

# Uso de registros de esquemas con orígenes de eventos de Kafka en Lambda
](services-consume-kafka-events.md)
+ [

# Procesamiento de baja latencia para orígenes de eventos de Kafka
](with-kafka-low-latency.md)
+ [

# Configuración de los controles de gestión de errores para orígenes de eventos de Kafka
](kafka-retry-configurations.md)
+ [

# Captura de lotes descartados para orígenes de eventos de Amazon MSK y Apache Kafka autoadministrado
](kafka-on-failure.md)
+ [

# Uso de un tema de Kafka como destino en caso de error
](kafka-on-failure-destination.md)
+ [

# Registro de asignación de orígenes de eventos de Kafka
](esm-logging.md)
+ [

# Solución de errores de asignación de orígenes de eventos de Kafka
](with-kafka-troubleshoot.md)

# Uso de Lambda con Amazon MSK
<a name="with-msk"></a>

[Amazon Managed Streaming para Apache Kafka (Amazon MSK)](https://docs.aws.amazon.com/msk/latest/developerguide/what-is-msk.html) es un servicio completamente administrado que le permite crear y ejecutar aplicaciones que utilizan Apache Kafka para procesar datos de transmisión. Amazon MSK simplifica la configuración, el escalado y la administración de clústeres de Kafka. Amazon MSK también facilita la configuración de la aplicación para varias zonas de disponibilidad y para la seguridad con AWS Identity and Access Management (IAM).

En este capítulo se explica cómo utilizar un clúster de Amazon MSK como origen de eventos para su función de Lambda. El proceso general de integración de Amazon MSK con Lambda implica los siguientes pasos:

1. **[Configuración del clúster y la red](with-msk-cluster-network.md)**: primero, configure su [clúster de Amazon MSK](https://docs.aws.amazon.com/msk/latest/developerguide/what-is-msk.html). Esto incluye la configuración de red correcta para permitir que Lambda acceda a su clúster.

1. **[Configuración de la asignación de orígenes de eventos](with-msk-configure.md)**: luego, cree el recurso de [asignación de orígenes de eventos](invocation-eventsourcemapping.md) que Lambda necesita para conectar de forma segura su clúster de Amazon MSK a su función.

1. **[Configuración de la función y los permisos](with-msk-permissions.md)**: por último, asegúrese de que su función esté configurada correctamente y de que cuente con los permisos necesarios en su [rol de ejecución](lambda-intro-execution-role.md).

**nota**  
Ahora puede crear y administrar las asignaciones de orígenes de eventos de Amazon MSK directamente desde la consola de Lambda o de Amazon MSK. Ambas consolas ofrecen la opción de gestionar automáticamente la configuración de los permisos del rol de ejecución de Lambda necesarios para agilizar el proceso de configuración.

Para ver ejemplos sobre cómo configurar una integración de Lambda con un clúster de Amazon MSK, consulte [Tutorial: Uso de una asignación de orígenes de eventos de Amazon MSK para invocar una función de Lambda](services-msk-tutorial.md), [Using Amazon MSK as an event source for AWS Lambda](https://aws.amazon.com/blogs/compute/using-amazon-msk-as-an-event-source-for-aws-lambda/) en AWS Compute Blog, y [ Amazon MSK Lambda Integration](https://amazonmsk-labs.workshop.aws/en/msklambda.html) en Amazon MSK Labs.

**Topics**
+ [

## Evento de ejemplo
](#msk-sample-event)
+ [

# Configuración del clúster de Amazon MSK y la red de Amazon VPC para Lambda
](with-msk-cluster-network.md)
+ [

# Cómo configurar permisos de Lambda para las asignaciones de orígenes de eventos
](with-msk-permissions.md)
+ [

# Configuración de orígenes de eventos de Amazon MSK para Lambda
](with-msk-configure.md)
+ [

# Tutorial: Uso de una asignación de orígenes de eventos de Amazon MSK para invocar una función de Lambda
](services-msk-tutorial.md)

## Evento de ejemplo
<a name="msk-sample-event"></a>

Lambda envía el lote de mensajes en el parámetro de evento cuando invoca su función. La carga de eventos contiene una matriz de mensajes. Cada elemento de matriz contiene detalles del tema y el identificador de partición de Amazon MSK, junto con una marca de hora y un mensaje codificado en base64.

```
{
   "eventSource":"aws:kafka",
   "eventSourceArn":"arn:aws:kafka:us-east-1:123456789012:cluster/vpc-2priv-2pub/751d2973-a626-431c-9d4e-d7975eb44dd7-2",
   "bootstrapServers":"b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092",
   "records":{
      "mytopic-0":[
         {
            "topic":"mytopic",
            "partition":0,
            "offset":15,
            "timestamp":1545084650987,
            "timestampType":"CREATE_TIME",
            "key":"abcDEFghiJKLmnoPQRstuVWXyz1234==",
            "value":"SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==",
            "headers":[
               {
                  "headerKey":[
                     104,
                     101,
                     97,
                     100,
                     101,
                     114,
                     86,
                     97,
                     108,
                     117,
                     101
                  ]
               }
            ]
         }
      ]
   }
}
```

# Configuración del clúster de Amazon MSK y la red de Amazon VPC para Lambda
<a name="with-msk-cluster-network"></a>

Para conectar la función de AWS Lambda al clúster de Amazon MSK, debe configurar correctamente tanto el clúster como la [Amazon Virtual Private Cloud (VPC)](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html) en la que se encuentra. En esta página se describe cómo configurar el clúster y la VPC. Si el clúster y la VPC ya están configurados correctamente, consulte [Configuración de orígenes de eventos de Amazon MSK para Lambda](with-msk-configure.md) para configurar la asignación de orígenes de eventos.

**Topics**
+ [

## Descripción general de los requisitos de configuración de red para las integraciones de Lambda y MSK
](#msk-network-requirements)
+ [

## Configuración de una puerta de enlace de NAT para un origen de eventos de MSK
](#msk-nat-gateway)
+ [

## Configuración de puntos de conexión de AWS PrivateLink para un origen de eventos de MSK
](#msk-vpc-privatelink)

## Descripción general de los requisitos de configuración de red para las integraciones de Lambda y MSK
<a name="msk-network-requirements"></a>

La configuración de red necesaria para la integración de Lambda y MSK depende de la arquitectura de red de su aplicación. Esta integración implica tres recursos principales: el clúster de Amazon MSK, la función de Lambda y la asignación de orígenes de eventos de Lambda. Cada uno de estos recursos se encuentra en una VPC diferente:
+ Su clúster de Amazon MSK suele residir en una subred privada de una VPC que administra.
+ Su función de Lambda reside en una VPC administrada por AWS propiedad de Lambda.
+ La asignación de orígenes de eventos de Lambda reside en otra VPC administrada por AWS que es propiedad de Lambda, independiente de la VPC que contiene su función.

La [asignación de orígenes de eventos](invocation-eventsourcemapping.md) es el recurso intermediario entre el clúster de MSK y la función de Lambda. La asignación de orígenes de eventos tiene dos funciones principales. En primer lugar, sondea su clúster de MSK en busca de mensajes nuevos. A continuación, invoca su función de Lambda con esos mensajes. Dado que estos tres recursos se encuentran en VPC diferentes, tanto las operaciones de sondeo como las de invocación requieren llamadas de red entre VPC.

Los requisitos de configuración de red para su asignación de orígenes de eventos dependen de si utiliza el [modo aprovisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode) o el modo bajo demanda, como se muestra en el siguiente diagrama:

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/MSK-esm-network-overview.png)


La forma en que la asignación de orígenes de eventos de Lambda sondea el clúster de MSK en busca de nuevos mensajes es la misma en ambos modos. Para establecer una conexión entre la asignación de orígenes de eventos y el clúster de MSK, Lambda crea una [ENI de hiperplano](configuration-vpc.md#configuration-vpc-enis) (o reutiliza una existente, si está disponible) en su subred privada para establecer una conexión segura. Como se muestra en el diagrama, esta ENI de hiperplano utiliza la configuración de subredes y grupos de seguridad del clúster de MSK, no la de su función de Lambda.

Tras sondear el mensaje del clúster, la forma en que Lambda invoca su función es diferente en cada modo:
+ En el modo aprovisionado, Lambda gestiona automáticamente la conexión entre la VPC de la asignación de orígenes de eventos y la VPC de la función. Por lo tanto, no necesita ningún componente de red adicional para invocar correctamente su función.
+ En el modo bajo demanda, su asignación de orígenes de eventos de Lambda invoca su función a través de una ruta en su VPC administrada por el cliente. Por ello, debe configurar una [puerta de enlace de NAT](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) en la subred pública de su VPC o puntos de conexión de [AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/what-is-privatelink.html) en la subred privada de la VPC que proporcionen acceso a Lambda, [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html) y, opcionalmente, [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). La configuración correcta de cualquiera de estas opciones permite establecer una conexión entre su VPC y la VPC de tiempo de ejecución administrada por Lambda, que es necesaria para invocar su función.

Una puerta de enlace de NAT permite a los recursos de su subred privada acceder a la Internet pública. El uso de esta configuración significa que el tráfico atraviesa Internet antes de invocar la función de Lambda. Los puntos de conexión de AWS PrivateLink permiten que las subredes privadas se conecten de forma segura a servicios de AWS u otros recursos de VPC privados sin atravesar la Internet pública. Consulte [Configuración de una puerta de enlace de NAT para un origen de eventos de MSK](#msk-nat-gateway) o [Configuración de puntos de conexión de AWS PrivateLink para un origen de eventos de MSK](#msk-vpc-privatelink) para obtener detalles sobre cómo configurar estos recursos.

Hasta ahora, asumimos que el clúster de MSK reside en una subred privada dentro de la VPC, que es el caso más común. Sin embargo, incluso si el clúster de MSK se encuentra en una subred pública dentro de la VPC, debe configurar los puntos de conexión de AWS PrivateLink para permitir una conexión segura. En la siguiente tabla se resumen los requisitos de configuración de red en función de cómo configure el clúster de MSK y la asignación de orígenes de eventos de Lambda:


| Ubicación del clúster de MSK (en una VPC administrada por el cliente) | Modo de escalado de la asignación de orígenes de eventos de Lambda | Configuración de red obligatoria | 
| --- | --- | --- | 
|  Subred privada  |  Modo bajo demanda  |  Puerta de enlace de NAT (en la subred pública de su VPC) o puntos de conexión de AWS PrivateLink (en la subred privada de su VPC) para permitir el acceso a Lambda, AWS STS y, opcionalmente, Secrets Manager.  | 
|  Public subnet  |  Modo bajo demanda  |  Puntos de conexión de AWS PrivateLink (en la subred pública de su VPC) para permitir el acceso a Lambda, AWS STS y, opcionalmente, Secrets Manager.  | 
|  Subred privada  |  Modo aprovisionado  |  Ninguno  | 
|  Public subnet  |  Modo aprovisionado  |  Ninguno  | 

Además, los grupos de seguridad asociados a su clúster de MSK deben permitir el tráfico a través de los puertos correctos. Asegúrese de tener configuradas las siguientes reglas de grupos de seguridad:
+ **Reglas de entrada**: permiten todo el tráfico en el puerto del agente predeterminado. El puerto que usa MSK depende del tipo de autenticación del clúster: `9098` para la autenticación de IAM, `9096` para SASL/SCRAM y `9094` para TLS. Como alternativa, puede usar una regla de grupo de seguridad con autorreferencia para permitir el acceso desde instancias que pertenecen al mismo grupo de seguridad.
+ **Reglas de salida**: permiten que todo el tráfico del puerto `443` vaya a destinos externos en caso de que su función necesite comunicarse con otros servicios de AWS. Como alternativa, puede usar una regla de grupo de seguridad con autorreferencia para limitar el acceso al agente en caso de que no necesite comunicarse con otros servicios de AWS.
+ **Reglas de entrada del punto de conexión de Amazon VPC**: si usa un punto de conexión de Amazon VPC, el grupo de seguridad asociado al punto de conexión debe permitir el tráfico entrante en el puerto `443` desde el grupo de seguridad del clúster.

## Configuración de una puerta de enlace de NAT para un origen de eventos de MSK
<a name="msk-nat-gateway"></a>

Puede configurar una puerta de enlace de NAT para permitir que la asignación de orígenes de eventos sondee los mensajes de su clúster e invoque la función a través de una ruta por su VPC. Esto solo es necesario si la asignación de orígenes de eventos utiliza el modo bajo demanda y el clúster reside en una subred privada de su VPC. Si el clúster reside en una subred pública de su VPC o si la asignación de orígenes de eventos utiliza el modo aprovisionado, no es necesario configurar una puerta de enlace de NAT.

Una [puerta de enlace de NAT](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) permite a los recursos de una subred privada acceder a la Internet pública. Si necesita conectividad privada con Lambda, consulte [Configuración de puntos de conexión de AWS PrivateLink para un origen de eventos de MSK](#msk-vpc-privatelink) como alternativa.

Después de configurar la puerta de enlace de NAT, debe configurar las tablas de enrutamiento adecuadas. Esto permite que el tráfico desde su subred privada se dirija a la Internet pública a través de la puerta de enlace de NAT.

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/MSK-NAT-Gateway.png)


Los pasos siguientes le guiarán a través de la configuración de una puerta de enlace de NAT con la consola. Repita estos pasos según sea necesario para cada zona de disponibilidad (AZ).

**Para configurar una puerta de enlace de NAT y un enrutamiento adecuado (consola)**

1. Siga los pasos que se indican en [Creación de una puerta de enlace de NAT](https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-working-with.html) y tenga en cuenta lo siguiente:
   + Las puertas de enlace de NAT siempre deben residir en una subred pública. Cree puertas de enlace de NAT con [conectividad pública](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html).
   + Si su clúster de MSK está replicado en varias zonas de disponibilidad, cree una puerta de enlace de NAT por AZ. Por ejemplo, en cada AZ, su VPC debe tener una subred privada que contenga su clúster y una subred pública que contenga su puerta de enlace de NAT. Para una configuración con tres AZ, tendrá tres subredes privadas, tres subredes públicas y tres puertas de enlace de NAT.

1. Tras crear la puerta de enlace de NAT, abra la [consola de Amazon VPC](https://console.aws.amazon.com/vpc/) y elija **Tablas de enrutamiento** en el menú de la izquierda.

1. Elija **Create Route Table (Crear tabla de enrutamiento)**.

1. Asocie esta tabla de enrutamiento con la VPC que contiene su clúster de MSK. Opcionalmente, ingrese un nombre para su tabla de enrutamiento.

1. Elija **Create Route Table (Crear tabla de enrutamiento)**.

1. Elija la tabla de enrutamiento que acaba de crear.

1. En la pestaña **Asociaciones de subredes**, elija **Editar asociaciones de subredes**.
   + Asocie esta tabla de enrutamiento con la subred privada que contiene su clúster de MSK.

1. Elija **Edit routes** (Editar rutas).

1. Elija **Agregar ruta**.

   1. Para **Destino**: elija `0.0.0.0/0`.

   1. En **Destino**, elija **Puerta de enlace de NAT**.

   1. En el cuadro de búsqueda, elija la puerta de enlace de NAT que ha creado en el paso 1. Esta debe ser la puerta de enlace de NAT en la misma AZ que la subred privada que contiene su clúster de MSK (la subred privada que asoció a esta tabla de enrutamiento en el paso 6).

1. Seleccione **Save changes (Guardar cambios)**.

## Configuración de puntos de conexión de AWS PrivateLink para un origen de eventos de MSK
<a name="msk-vpc-privatelink"></a>

Puede configurar los puntos de conexión de AWS PrivateLink para sondear los mensajes de su clúster e invocar la función a través de una ruta en su VPC. Estos puntos de conexión deberían permitir que su clúster de MSK acceda a lo siguiente:
+ El servicio de Lambda
+ [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html)
+ Opcionalmente, el servicio de [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). Esto es obligatorio si el secreto obligatorio para la autenticación del clúster se almacena en Secrets Manager.

La configuración de los puntos de conexión de PrivateLink solo es obligatoria si la asignación de orígenes de eventos utiliza el modo bajo demanda. Si la asignación de orígenes de eventos utiliza el modo aprovisionado, Lambda establece las conexiones que necesita.

Los puntos de conexión de PrivateLink permiten un acceso seguro y privado a los servicios de AWS a través de AWS PrivateLink. Como alternativa, para configurar una puerta de enlace de NAT que dé acceso a su clúster de MSK a la Internet pública, consulte [Configuración de una puerta de enlace de NAT para un origen de eventos de MSK](#msk-nat-gateway).

Tras configurar los puntos de conexión de VPC, el clúster de MSK debe tener acceso directo y privado a Lambda, STS y, opcionalmente, Secrets Manager.

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/MSK-PrivateLink-Endpoints.png)


Los pasos siguientes le guiarán a través de la configuración de un punto de conexión de PrivateLink con la consola. Repita estos pasos según sea necesario para cada punto de conexión (Lambda, STS, Secrets Manager).

**Configuración de un punto de conexión de VPC (consola)**

1. Abra la [consola de Amazon VPC](https://console.aws.amazon.com/vpc/) y elija **Puntos de conexión** en el menú de la izquierda.

1. Seleccione **Crear punto de conexión**.

1. Opcionalmente, ingrese un nombre para su punto de conexión.

1. En **Tipo**, elija **Servicios de AWS**.

1. En **Servicios**, comience a escribir el nombre del servicio. Por ejemplo, para crear un punto de conexión para conectarse a Lambda, escriba `lambda` en el cuadro de búsqueda.

1. En los resultados, debería ver el punto de conexión del servicio en la región actual. Por ejemplo, en la región Este de EE. UU. (Norte de Virginia), debería ver `com.amazonaws.us-east-2.lambda`. Seleccione este servicio.

1. En **Configuración de red**, seleccione la VPC que contiene su clúster de MSK.

1. En **Subredes**, seleccione las AZ en las que se encuentra su clúster de MSK.
   + Para cada AZ, en **ID de subred**, elija la subred privada que contiene su clúster de MSK.

1. En **Grupos de seguridad**, elija los grupos de seguridad asociados al clúster de base de datos de MSK.

1. Seleccione **Crear punto de conexión**.

De forma predeterminada, los puntos de conexión de VPC de Amazon tienen políticas de IAM abiertas que permiten un amplio acceso a los recursos. La práctica recomendada es restringir estas políticas para realizar las acciones necesarias mediante ese punto de conexión. Por ejemplo, para su punto de conexión de Secrets Manager, puede modificar su política de manera que solo permita que el rol de ejecución de su función acceda al secreto.

**Example Política de punto de conexión de VPC: punto de conexión de Secrets Manager**  

```
{
    "Statement": [
        {
            "Action": "secretsmanager:GetSecretValue",
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "arn:aws::iam::123456789012:role/my-role"
                ]
            },
            "Resource": "arn:aws::secretsmanager:us-west-2:123456789012:secret:my-secret"
        }
    ]
}
```

Para los puntos de conexión de AWS STS y Lambda, puede restringir la entidad principal de llamada a la entidad principal del servicio de Lambda. Sin embargo, asegúrese de utilizar `"Resource": "*"` en estas políticas.

**Example Política de punto de conexión de VPC: punto de conexión de AWS STS**  

```
{
    "Statement": [
        {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "lambda.amazonaws.com"
                ]
            },
            "Resource": "*"
        }
    ]
}
```

**Example Política de punto de conexión de VPC: punto de conexión de Lambda**  

```
{
    "Statement": [
        {
            "Action": "lambda:InvokeFunction",
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "lambda.amazonaws.com"
                ]
            },
            "Resource": "*"
        }
    ]
}
```

# Cómo configurar permisos de Lambda para las asignaciones de orígenes de eventos
<a name="with-msk-permissions"></a>

Para acceder al clúster de Amazon MSK, la función y la asignación de orígenes de eventos necesitan permisos para llevar a cabo varias acciones de la API de Amazon MSK. Todos estos permisos se agregan al [rol de ejecución](lambda-intro-execution-role.md) de la función. Si los usuarios necesitan acceso, agregue los permisos necesarios a la política de identidad para el usuario o rol.

La política administrada de [AWSLambdaMSKExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaMSKExecutionRole.html) contiene los permisos mínimos necesarios para las asignaciones de orígenes de eventos de Lambda en Amazon MSK. Para simplificar el proceso de permisos, pruebe lo siguiente:
+ Asocie la política administrada [AWSLambdaMSKExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaMSKExecutionRole.html) al rol de ejecución.
+ Deje que la consola de Lambda genere los permisos por usted. Cuando [crea una asignación de orígenes de eventos de Amazon MSK en la consola](msk-esm-create.md#msk-console), Lambda evalúa su rol de ejecución y le avisa si falta algún permiso. Elija **Generar permisos** para actualizar automáticamente su rol de ejecución. Esto no funciona si ha creado o modificado manualmente las políticas de los roles de ejecución, o si las políticas están asociadas a varios roles. Tenga en cuenta que es posible que su rol de ejecución siga necesitando permisos adicionales cuando utilice funciones avanzadas, como [destino en caso de error](kafka-on-failure.md) o [registro de esquemas de AWS Glue](services-consume-kafka-events.md).

**Topics**
+ [

## Permisos necesarios
](#msk-required-permissions)
+ [

## Permisos opcionales
](#msk-optional-permissions)

## Permisos necesarios
<a name="msk-required-permissions"></a>

El rol de ejecución de la función de Lambda debe tener los siguientes permisos necesarios para las asignaciones de orígenes de eventos de Amazon MSK. Estos permisos están incluidos en la política administrada de [AWSLambdaMSKExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaMSKExecutionRole.html).

### Permisos de Registros de CloudWatch
<a name="msk-basic-permissions"></a>

Los siguientes permisos autorizan a Lambda par que cree y almacene registros en Registros de Amazon CloudWatch.
+ [logs:CreateLogGroup](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html)
+ [logs:CreateLogStream](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogStream.html)
+ [logs:PutLogEvents](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html)

### Permisos de clústeres de MSK
<a name="msk-cluster-permissions"></a>

Los siguientes permisos permiten que Lambda acceda al clúster de Amazon MSK en su nombre:
+ [kafka:DescribeCluster](https://docs.aws.amazon.com/msk/1.0/apireference/clusters-clusterarn.html)
+ [kafka:DescribeClusterV2](https://docs.aws.amazon.com/MSK/2.0/APIReference/v2-clusters-clusterarn.html)
+ [kafka:GetBootstrapBrokers](https://docs.aws.amazon.com/msk/1.0/apireference/clusters-clusterarn-bootstrap-brokers.html)

Recomendamos utilizar [kafka:DescribeClusterV2](https://docs.aws.amazon.com/MSK/2.0/APIReference/v2-clusters-clusterarn.html) en lugar de [kafka:DescribeCluster](https://docs.aws.amazon.com/msk/1.0/apireference/clusters-clusterarn.html). El permiso v2 funciona con clústeres de Amazon MSK aprovisionados y sin servidor. Solo necesita uno de estos permisos en la política.

### Permisos de VPC
<a name="msk-vpc-permissions"></a>

Los siguientes permisos permiten que Lambda cree y administre interfaces de red al conectarse a su clúster de Amazon MSK:
+ [ec2:CreateNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateNetworkInterface.html)
+ [ec2:DescribeNetworkInterfaces](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeNetworkInterfaces.html)
+ [ec2:DescribeVpcs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpcs.html)
+ [ec2:DeleteNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteNetworkInterface.html)
+ [ec2:DescribeSubnets](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSubnets.html)
+ [ec2:DescribeSecurityGroups](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html)

## Permisos opcionales
<a name="msk-optional-permissions"></a>

 Es posible que la función de Lambda también necesite permisos para: 
+ Acceda a los clústeres de Amazon MSK entre cuentas. Para las asignaciones de orígenes de eventos entre cuentas, necesita [kafka:DescribeVpcConnection](https://docs.aws.amazon.com/msk/1.0/apireference/vpc-connection-arn.html) en el rol de ejecución. Una entidad principal de IAM que cree una asignación de orígenes de eventos entre cuentas necesita [kafka:ListVpcConnections](https://docs.aws.amazon.com/msk/1.0/apireference/vpc-connections.html).
+ Acceda a su secreto de SCRAM, si usa la [autenticación SASL/SCRAM](msk-cluster-auth.md#msk-sasl-scram). Esto permite que su función utilice un nombre de usuario y una contraseña para conectarse a Kafka.
+ Describa su secreto de Secrets Manager, si usa la autenticación SASL/SCRAM o [mTLS](msk-cluster-auth.md#msk-mtls). Esto permite que su función recupere las credenciales o los certificados necesarios para las conexiones seguras.
+ Acceda a su clave administrada de cliente de AWS KMS si su secreto de AWS Secrets Manager está cifrado con una clave administrada de cliente de AWS KMS.
+ Acceda a los secretos del registro de esquemas si utiliza un registro de esquemas con autenticación:
  + Para el registro de esquemas de AWS Glue: su función necesita permisos de `glue:GetRegistry` y `glue:GetSchemaVersion`. Esto le permite a la función buscar y utilizar las reglas de formato de mensajes almacenadas en AWS Glue.
  + Para el [registro de esquemas de Confluent](https://docs.confluent.io/platform/current/schema-registry/security/index.html) con `BASIC_AUTH` o `CLIENT_CERTIFICATE_TLS_AUTH`: su función necesita permiso de `secretsmanager:GetSecretValue` para el secreto que contiene las credenciales de autenticación. Esto le permite a la función recuperar el nombre de usuario y la contraseña o los certificados necesarios para acceder al registro de esquemas de Confluent.
  + Para los certificados de CA privados: su función necesita el permiso secretsmanager:GetSecretValue para el secreto que contiene el certificado. Esto permite a la función comprobar la identidad de los registros de esquemas que utilizan certificados personalizados.
+ Acceda a los grupos de consumidores de clúster de Kafka y sondee los mensajes del tema si utiliza la autenticación de IAM para la asignación de orígenes de eventos.

 Estos corresponden a los siguientes permisos necesarios: 
+ [kafka:ListScramSecrets](https://docs.aws.amazon.com/msk/1.0/apireference/clusters-clusterarn-scram-secrets.html): permite enumerar los secretos de SCRAM para la autenticación de Kafka
+ [secretsmanager:GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html): permite la recuperación de secretos de Secrets Manager
+ [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html): permite descifrar datos cifrados mediante AWS KMS
+ [glue:GetRegistry](https://docs.aws.amazon.com/glue/latest/webapi/API_GetRegistry.html): permite el acceso al registro de esquemas AWS Glue
+ [glue:GetSchemaVersion](https://docs.aws.amazon.com/glue/latest/webapi/API_GetSchemaVersion.html): permite recuperar versiones de esquemas específicas del registro de esquemas AWS Glue
+ [kafka-cluster:Connect](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): otorga permiso para conectarse al clúster y autenticarse en este.
+ [kafka-cluster:AlterGroup](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): otorga permiso para unirse a grupos en un clúster, equivalente a la ACL READ GROUP de Apache Kafka.
+ [kafka-cluster:DescribeGroup](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): otorga permiso para describir grupos en un clúster, equivalente a la ACL DESCRIBE GROUP de Apache Kafka.
+ [kafka-cluster:DescribeTopic](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): otorga permiso para describir temas en un clúster, equivalente a la ACL DESCRIBE TOPIC de Apache Kafka.
+ [kafka-cluster:ReadData](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): otorga permiso para leer datos de temas de un clúster, equivalente a la ACL READ TOPIC de Apache Kafka.

 Además, si desea enviar registros de invocaciones fallidas a un destino en caso de error, necesitará los siguientes permisos según el tipo de destino: 
+ Para destinos de Amazon SQS: [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html): permite enviar mensajes a una cola de Amazon SQS
+ Para destinos de Amazon SNS: [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html): permite publicar mensajes en un tema de Amazon SNS
+ Para destinos de bucket de Amazon S3: [s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) y [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucket.html): permite escribir y enumerar objetos en un bucket de Amazon S3

Para la solución de problemas de errores de autenticación y autorización, consulte [Solución de errores de asignación de orígenes de eventos de Kafka](with-kafka-troubleshoot.md).

# Configuración de orígenes de eventos de Amazon MSK para Lambda
<a name="with-msk-configure"></a>

Para usar un clúster de Amazon MSK como origen de eventos para su función de Lambda, cree una [asignación de orígenes de eventos](invocation-eventsourcemapping.md) que conecte los dos recursos. Esta página describe cómo crear una asignación de orígenes de eventos para Amazon MSK.

Esta página asume que ya ha configurado correctamente su clúster de MSK y la [Amazon Virtual Private Cloud (VPC)](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html) en la que reside. Si necesita configurar el clúster o la VPC, consulte [Configuración del clúster de Amazon MSK y la red de Amazon VPC para Lambda](with-msk-cluster-network.md). Para configurar el comportamiento de reintento para la gestión de errores, consulte [Configuración de los controles de gestión de errores para orígenes de eventos de Kafka](kafka-retry-configurations.md).

**Topics**
+ [

## Utilizar un clúster de Amazon MSK como origen de eventos
](#msk-esm-overview)
+ [

# Configuración de métodos de autenticación de clústeres de Amazon MSK en Lambda
](msk-cluster-auth.md)
+ [

# Creación de una asignación de orígenes de eventos de Lambda para un origen de eventos de Amazon MSK
](msk-esm-create.md)
+ [

# Creación de asignaciones de orígenes de eventos entre cuentas en Lambda
](msk-cross-account.md)
+ [

# Todos los parámetros de configuración de orígenes de eventos de Amazon MSK en Lambda
](msk-esm-parameters.md)

## Utilizar un clúster de Amazon MSK como origen de eventos
<a name="msk-esm-overview"></a>

Cuando agrega su clúster de Apache Kafka o Amazon MSK como desencadenador para su función de Lambda, el clúster se utiliza como [origen de eventos](invocation-eventsourcemapping.md).

Lambda lee los datos de eventos de los temas de Kafka que especifique como `Topics` en una solicitud de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html), en función de la [posición inicial](kafka-starting-positions.md) que especifique. Después de un procesamiento exitoso, su tema de Kafka se compromete a su clúster de Kafka.

Lambda lee los mensajes secuencialmente para cada partición de tema de Kafka. Una sola carga de Lambda puede contener mensajes de varias particiones. Cuando hay más registros disponibles, Lambda continúa procesando registros en lotes, en función del valor de BatchSize que especifique en una solicitud de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html), hasta que la función se ponga al día con el tema.

Después de que Lambda procese cada lote, confirma los desplazamientos de los mensajes en ese lote. Si su función devuelve un error para cualquiera de los mensajes de un lote, Lambda reintenta todo el lote de mensajes hasta que el procesamiento sea correcto o los mensajes caduquen. Puede enviar los registros con error en todos los reintentos a un destino en caso de error para su posterior procesamiento.

**nota**  
Si bien las funciones de Lambda suelen tener un límite de tiempo de espera máximo de 15 minutos, las asignaciones de orígenes de eventos para Amazon MSK, Apache Kafka autoadministrado, Amazon DocumentDB y Amazon MQ para ActiveMQ y RabbitMQ solo admiten funciones con límites de tiempo de espera máximos de 14 minutos.

# Configuración de métodos de autenticación de clústeres de Amazon MSK en Lambda
<a name="msk-cluster-auth"></a>

Lambda necesita permiso para acceder a su clúster de Amazon MSK, recuperar registros y llevar a cabo otras tareas. Amazon MSK admite varios métodos para autenticarse con su clúster de MSK.

**Topics**
+ [

## Acceso sin autenticar
](#msk-unauthenticated)
+ [

## Autenticación SASL/SCRAM
](#msk-sasl-scram)
+ [

## Autenticación TLS mutua
](#msk-mtls)
+ [

## Autenticación de IAM
](#msk-iam-auth)
+ [

## Cómo Lambda elige un agente de arranque
](#msk-bootstrap-brokers)

## Acceso sin autenticar
<a name="msk-unauthenticated"></a>

Si ningún cliente accede al clúster a través de Internet, puede utilizar el acceso no autenticado.

## Autenticación SASL/SCRAM
<a name="msk-sasl-scram"></a>

Lambda admite [autenticación simple y autenticación de capa de seguridad/mecanismo de autenticación de respuesta por desafío saltado (SASL/SCRAM)](https://docs.aws.amazon.com/msk/latest/developerguide/msk-password-tutorial.html), con cifrado de seguridad de la capa de transporte (TLS) y la función hash SHA-512. Para que Lambda se conecte al clúster, las credenciales de autenticación (nombre de usuario y contraseña) se almacenan en un secreto de Secrets Manager. Haga referencia a este secreto al configurar la asignación de orígenes de eventos.

Para obtener más información sobre Secrets Manager, consulte [Sign-in credentials authentication with Secrets Manager](https://docs.aws.amazon.com/msk/latest/developerguide/msk-password.html) en la *Guía para desarrolladores de Amazon Managed Streaming para Apache Kafka*.

**nota**  
Amazon MSK no admite la autenticación SASL/PLAIN.

## Autenticación TLS mutua
<a name="msk-mtls"></a>

TLS mutua (mTLS) proporciona autenticación bidireccional entre el cliente y el servidor. El cliente envía un certificado al servidor para que el servidor verifique el cliente. El servidor también envía un certificado al cliente para que el cliente verifique el servidor.

Para las integraciones de Amazon MSK con Lambda, el clúster de MSK actúa como servidor y Lambda actúa como cliente.
+ Para que Lambda verifique el clúster de MSK, configure un certificado de cliente como secreto en Secrets Manager y haga referencia a este certificado en la configuración de asignación de orígenes de eventos. El certificado de servidor debe estar firmado por una entidad de certificación que esté en el almacén de confianza del servidor.
+ El clúster de MSK también envía un certificado de servidor a Lambda. El certificado de servidor debe estar firmado por una entidad de certificación que esté en el almacén de confianza de AWS.

Amazon MSK no admite certificados de servidor autofirmados. Todos los agentes de Amazon MSK utilizan [certificados públicos](https://docs.aws.amazon.com/msk/latest/developerguide/msk-encryption.html) firmados por [CA de Amazon Trust Services](https://www.amazontrust.com/repository/), en los que Lambda confía de forma predeterminada.

### Configuración del secreto de mTLS
<a name="mtls-auth-secret"></a>

El secreto CLIENT\$1CERTIFICATE\$1TLS\$1AUTH requiere un campo de certificado y un campo de clave privada. Para una clave privada cifrada, el secreto requiere una contraseña de clave privada. El certificado y la clave privada deben estar en formato PEM.

**nota**  
Lambda admite los algoritmos de cifrado de claves privadas [PBES1](https://datatracker.ietf.org/doc/html/rfc2898/#section-6.1) (pero no PBES2).

El campo de certificado debe contener una lista de certificados y debe comenzar por el certificado de cliente, seguido de cualquier certificado intermedio, y finalizar con el certificado raíz. Cada certificado debe comenzar en una nueva línea con la siguiente estructura:

```
-----BEGIN CERTIFICATE-----  
        <certificate contents>
-----END CERTIFICATE-----
```

Secrets Manager admite secretos de hasta 65 536 bytes, que supone suficiente espacio para cadenas de certificados largas.

El formato de la clave privada debe ser [PKCS \$18](https://datatracker.ietf.org/doc/html/rfc5208), con la siguiente estructura:

```
-----BEGIN PRIVATE KEY-----  
         <private key contents>
-----END PRIVATE KEY-----
```

Para una clave privada cifrada, utilice la siguiente estructura:

```
-----BEGIN ENCRYPTED PRIVATE KEY-----  
          <private key contents>
-----END ENCRYPTED PRIVATE KEY-----
```

El siguiente ejemplo muestra el contenido de un secreto para la autenticación de mTLS mediante una clave privada cifrada. Para una clave privada cifrada, incluya la contraseña de la clave privada en el secreto.

```
{
 "privateKeyPassword": "testpassword",
 "certificate": "-----BEGIN CERTIFICATE-----
MIIE5DCCAsygAwIBAgIRAPJdwaFaNRrytHBto0j5BA0wDQYJKoZIhvcNAQELBQAw
...
j0Lh4/+1HfgyE2KlmII36dg4IMzNjAFEBZiCRoPimO40s1cRqtFHXoal0QQbIlxk
cmUuiAii9R0=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFgjCCA2qgAwIBAgIQdjNZd6uFf9hbNC5RdfmHrzANBgkqhkiG9w0BAQsFADBb
...
rQoiowbbk5wXCheYSANQIfTZ6weQTgiCHCCbuuMKNVS95FkXm0vqVD/YpXKwA/no
c8PH3PSoAaRwMMgOSA2ALJvbRz8mpg==
-----END CERTIFICATE-----",
 "privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFKzBVBgkqhkiG9w0BBQ0wSDAnBgkqhkiG9w0BBQwwGgQUiAFcK5hT/X7Kjmgp
...
QrSekqF+kWzmB6nAfSzgO9IaoAaytLvNgGTckWeUkWn/V0Ck+LdGUXzAC4RxZnoQ
zp2mwJn2NYB7AZ7+imp0azDZb+8YG2aUCiyqb6PnnA==
-----END ENCRYPTED PRIVATE KEY-----"
}
```

Para obtener más información sobre mTLS para Amazon MSK e instrucciones sobre cómo generar un certificado de cliente, consulte [Mutual TLS client authentication for Amazon MSK](https://docs.aws.amazon.com/msk/latest/developerguide/msk-authentication.html) en la *Guía para desarrolladores de Amazon Managed Streaming para Apache Kafka*.

## Autenticación de IAM
<a name="msk-iam-auth"></a>

Puede utilizar AWS Identity and Access Management (IAM) para autenticar la identidad de los clientes que se conectan al clúster de MSK. Con la autenticación de IAM, Lambda confía en los permisos del [rol de ejecución](lambda-intro-execution-role.md) de la función para conectarse al clúster, recuperar registros y llevar a cabo otras acciones necesarias. Para ver un ejemplo de política que contenga los permisos necesarios, consulte [Create authorization policies for the IAM role](https://docs.aws.amazon.com/msk/latest/developerguide/create-iam-access-control-policies.html) en la *Guía para desarrolladores de Amazon Managed Streaming para Apache Kafka*.

Si la autenticación de IAM está activa en el clúster de MSK y no proporciona ningún secreto, Lambda utilizará de forma automática la autenticación de IAM.

Para obtener más información acerca de la autenticación de IAM en Amazon MSK, consulte [IAM access control](https://docs.aws.amazon.com/msk/latest/developerguide/iam-access-control.html).

## Cómo Lambda elige un agente de arranque
<a name="msk-bootstrap-brokers"></a>

Lambda elige un [agente de arranque](https://docs.aws.amazon.com/msk/latest/developerguide/msk-get-bootstrap-brokers.html) en función de los métodos de autenticación disponibles en el clúster y de si proporciona un secreto para la autenticación. Si proporciona un secreto para mTLS o SASL/SCRAM, Lambda elige de forma automática ese método de autenticación. Si no proporciona ningún secreto, Lambda selecciona el método de autenticación más seguro que esté activo en el clúster. El siguiente es el orden de prioridad en el que Lambda selecciona un agente, de la autenticación más segura a la menos segura:
+ mTLS (secreto proporcionado para mTLS)
+ SASL/SCRAM (secreto proporcionado para SASL/SCRAM)
+ SASL IAM (no se proporciona secreto y la autenticación de IAM está activa)
+ TLS no autenticada (no se proporciona secreto y la autenticación de IAM no está activa)
+ Texto sin formato (no se proporciona secreto y tanto la autenticación de IAM como la TLS no autenticada no están activas)

**nota**  
Si Lambda no puede conectarse al tipo de agente más seguro, no intentará conectarse a un tipo de agente diferente (menos seguro). Si quiere que Lambda elija un tipo de agente más débil, desactive todos los métodos de autenticación más seguros del clúster.

# Creación de una asignación de orígenes de eventos de Lambda para un origen de eventos de Amazon MSK
<a name="msk-esm-create"></a>

Para crear una asignación de orígenes de eventos, puede usar la consola de Lambda, la [AWS Command Line Interface (CLI)](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) o un [AWS SDK](https://aws.amazon.com/getting-started/tools-sdks/).

**nota**  
Al crear la asignación de orígenes de eventos, Lambda crea una [ENI de hiperplano](configuration-vpc.md#configuration-vpc-enis) en la subred privada que contiene su clúster de MSK, lo que permite a Lambda establecer una conexión segura. Esta ENI de hiperplano utiliza la configuración de subredes y grupos de seguridad del clúster de MSK, no la de su función de Lambda.

Los siguientes pasos de la consola agregan un clúster de Amazon MSK como desencadenador para su función de Lambda. Internamente, esto crea un recurso de asignación de orígenes de eventos.

**Cómo agregar un desencadenador Amazon MSK a su función de Lambda (consola)**

1. Abra la [Página de función](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de la función de Lambda a la que desea agregar el desencadenador de Amazon MSK.

1. En **Descripción general de la función**, elija **Agregar desencadenador**.

1. En **Configuración del desencadenador**, elija **MSK**.

1. Para especificar los detalles de su clúster de Kafka, haga lo siguiente:

   1. Para **clúster de MSK**, seleccione su clúster.

   1. En **Nombre del tema**, ingrese el nombre del tema de Kafka del que se consumirán los mensajes.

   1. En **ID de grupo de consumidores**, ingrese el ID de un grupo de consumidores de Kafka al que unirse, si corresponde. Para obtener más información, consulte [ID del grupo de consumidores personalizable en Lambda](kafka-consumer-group-id.md).

1. En **Autenticación del clúster**, lleve a cabo las configuraciones necesarias. Para obtener más información acerca de la autenticación del clúster, consulte [Configuración de métodos de autenticación de clústeres de Amazon MSK en Lambda](msk-cluster-auth.md).
   + Active **Usar autenticación** si desea que Lambda lleve a cabo la autenticación con su clúster de MSK al establecer una conexión. Se recomienda la autenticación.
   + Si usa la autenticación, en **Método de autenticación**, elija el método de autenticación que desee utilizar.
   + Si utiliza autenticación, en **Clave de Secrets Manager**, elija la clave de Secrets Manager que contiene las credenciales de autenticación necesarias para acceder al clúster.

1. En **Configuración del sondeador de eventos**, lleve a cabo las configuraciones necesarias.
   + Elija **Activar desencadenador** para activar el desencadenador inmediatamente después de crearlo.
   + Elija si desea **configurar el modo aprovisionado** para su asignación de orígenes de eventos. Para obtener más información, consulte [Modos de escalado del sondeo de eventos de Apache Kafka en Lambda](kafka-scaling-modes.md).
     + Si configura el modo aprovisionado, ingrese un valor para **Sondeadores de eventos mínimos**, un valor para **Sondeadores de eventos máximos** y un valor opcional para PollerGroupName para especificar la agrupación de varias ESM dentro de la misma VPC de origen de eventos.
   + En **Posición inicial**, elija cómo quiere que Lambda comience a leer desde su flujo. Para obtener más información, consulte [Posiciones iniciales de flujos y sondeo de Apache Kafka en Lambda](kafka-starting-positions.md).

1. En **Procesamiento en lotes**, lleve a cabo las configuraciones necesarias. Para obtener más información acerca del procesamiento en lotes, consulte [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

   1. Para el **Tamaño del lote**, establezca el número máximo de mensajes para recibir un solo lote.

   1. En **Periodo del lote**, ingrese el número máximo de segundos que Lambda emplea a fin de recopilar registros antes de invocar la función.

1. En **Filtrado**, lleve a cabo las configuraciones necesarias. Para obtener más información sobre cómo filtrar, consulte [Filtrado de eventos de Amazon MSK y de fuentes de eventos autoadministrados de Apache Kafka](kafka-filtering.md).
   + En **Criterios de filtro**, agregue definiciones de criterios de filtro para determinar si se debe procesar o no un evento.

1. En **Gestión de fallos**, lleve a cabo las configuraciones necesarias. Para obtener más información sobre la gestión de fallos, consulte [Captura de lotes descartados para orígenes de eventos de Amazon MSK y Apache Kafka autoadministrado](kafka-on-failure.md).
   + En **Destino en caso de error**, especifique el ARN de su destino en caso de error.

1. En **Etiquetas**, ingrese las etiquetas que desee asociar a esta asignación de orígenes de eventos.

1. Para crear el desencadenador, elija **Add** (Añadir).

También puede crear la asignación de orígenes de eventos mediante la AWS CLI con el comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html). El siguiente ejemplo crea una asignación de orígenes de eventos para asignar la función de Lambda `my-msk-function` al tema `AWSKafkaTopic`, empezando por el mensaje `LATEST`. Este comando también usa el objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html) para indicar a Lambda que utilice la autenticación [SASL/SCRAM](msk-cluster-auth.md#msk-sasl-scram) al conectarse al clúster.

```
aws lambda create-event-source-mapping \
  --event-source-arn arn:aws:kafka:us-east-1:111122223333:cluster/my-cluster/fc2f5bdf-fd1b-45ad-85dd-15b4a5a6247e-2 \
  --topics AWSKafkaTopic \
  --starting-position LATEST \
  --function-name my-kafka-function
  --source-access-configurations '[{"Type": "SASL_SCRAM_512_AUTH","URI": "arn:aws:secretsmanager:us-east-1:111122223333:secret:my-secret"}]'
```

Si el clúster usa la [autenticación mTLS](msk-cluster-auth.md#msk-mtls), incluya un objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html) que especifique `CLIENT_CERTIFICATE_TLS_AUTH` y un ARN de clave de Secrets Manager. Esto se muestra en el siguiente comando:

```
aws lambda create-event-source-mapping \
  --event-source-arn arn:aws:kafka:us-east-1:111122223333:cluster/my-cluster/fc2f5bdf-fd1b-45ad-85dd-15b4a5a6247e-2 \
  --topics AWSKafkaTopic \
  --starting-position LATEST \
  --function-name my-kafka-function
  --source-access-configurations '[{"Type": "CLIENT_CERTIFICATE_TLS_AUTH","URI": "arn:aws:secretsmanager:us-east-1:111122223333:secret:my-secret"}]'
```

Cuando el clúster utiliza la [autenticación de IAM](msk-cluster-auth.md#msk-iam-auth), no necesita un objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html). Esto se muestra en el siguiente comando:

```
aws lambda create-event-source-mapping \
  --event-source-arn arn:aws:kafka:us-east-1:111122223333:cluster/my-cluster/fc2f5bdf-fd1b-45ad-85dd-15b4a5a6247e-2 \
  --topics AWSKafkaTopic \
  --starting-position LATEST \
  --function-name my-kafka-function
```

# Creación de asignaciones de orígenes de eventos entre cuentas en Lambda
<a name="msk-cross-account"></a>

Puede utilizar la [conectividad privada de varias VPC](https://docs.aws.amazon.com/msk/latest/developerguide/aws-access-mult-vpc.html) para conectar una función de Lambda a un clúster de MSK aprovisionado en otra Cuenta de AWS. La conectividad de varias VPC utiliza AWS PrivateLink, que mantiene todo el tráfico dentro de la red de AWS.

**nota**  
No puede crear asignaciones de orígenes de eventos entre cuentas para clústeres de MSK sin servidor.

Para crear una asignación de orígenes de eventos entre cuentas, primero debe [configurar la conectividad de múltiples VPC para el clúster de MSK](https://docs.aws.amazon.com/msk/latest/developerguide/aws-access-mult-vpc.html#mvpc-cluster-owner-action-turn-on). Al crear la asignación de orígenes de eventos, utilice el ARN de conexión de VPC administrada en lugar del ARN del clúster, como se muestra en los siguientes ejemplos. La operación [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) también varía según el tipo de autenticación que utilice el clúster de MSK.

**Example — Creación de una asignación de orígenes de eventos entre cuentas para un clúster que utilice la autenticación de IAM**  
Cuando el clúster utiliza la [autenticación basada en roles de IAM](msk-cluster-auth.md#msk-iam-auth), no se necesita un objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html). Ejemplo:  

```
aws lambda create-event-source-mapping \
  --event-source-arn arn:aws:kafka:us-east-1:111122223333:vpc-connection/444455556666/my-cluster-name/51jn98b4-0a61-46cc-b0a6-61g9a3d797d5-7 \
  --topics AWSKafkaTopic \
  --starting-position LATEST \
  --function-name my-kafka-function
```

**Example — Creación de una asignación de orígenes de eventos entre cuentas para un clúster que utilice la autenticación SASL/SCRAM**  
Si el clúster usa la [autenticación SASL/SCRAM](msk-cluster-auth.md#msk-sasl-scram), debe incluir un objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html) que especifique `SASL_SCRAM_512_AUTH` y un ARN secreto de Secrets Manager.  
Hay dos formas de utilizar los secretos para las asignaciones de orígenes de eventos entre cuentas de Amazon MSK con autenticación SASL/SCRAM:  
+ Cree un secreto en la cuenta de la función de Lambda y sincronícelo con el secreto del clúster. [Cree una rotación](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html) para mantener los dos secretos sincronizados. Esta opción le permite controlar el secreto desde la cuenta de la función.
+ Use el secreto asociado al clúster de MSK. Este secreto debe permitir el acceso entre cuentas a la cuenta de la función de Lambda. Para obtener más información, consulte [Permisos para secretos de AWS Secrets Manager para usuarios en una cuenta diferente](https://docs.aws.amazon.com/secretsmanager/latest/userguide/auth-and-access_examples_cross.html).

```
aws lambda create-event-source-mapping \
  --event-source-arn arn:aws:kafka:us-east-1:111122223333:vpc-connection/444455556666/my-cluster-name/51jn98b4-0a61-46cc-b0a6-61g9a3d797d5-7 \
  --topics AWSKafkaTopic \
  --starting-position LATEST \
  --function-name my-kafka-function \
  --source-access-configurations '[{"Type": "SASL_SCRAM_512_AUTH","URI": "arn:aws:secretsmanager:us-east-1:444455556666:secret:my-secret"}]'
```

**Example — Creación de una asignación de orígenes de eventos entre cuentas para un clúster que utilice la autenticación mTLS**  
Si el clúster usa la [autenticación mTLS](msk-cluster-auth.md#msk-mtls), debe incluir un objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html) que especifique `CLIENT_CERTIFICATE_TLS_AUTH` y un ARN secreto de Secrets Manager. El secreto se puede almacenar en la cuenta del clúster o en la cuenta de la función de Lambda.  

```
aws lambda create-event-source-mapping \
  --event-source-arn arn:aws:kafka:us-east-1:111122223333:vpc-connection/444455556666/my-cluster-name/51jn98b4-0a61-46cc-b0a6-61g9a3d797d5-7 \
  --topics AWSKafkaTopic \
  --starting-position LATEST \
  --function-name my-kafka-function \
  --source-access-configurations '[{"Type": "CLIENT_CERTIFICATE_TLS_AUTH","URI": "arn:aws:secretsmanager:us-east-1:444455556666:secret:my-secret"}]'
```

# Todos los parámetros de configuración de orígenes de eventos de Amazon MSK en Lambda
<a name="msk-esm-parameters"></a>

Todos los tipos de origen de eventos Lambda comparten las mismas operaciones [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) y [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) de la API. Sin embargo, solo algunos de los parámetros se aplican a Amazon MSK, como se muestra en la siguiente tabla.


| Parámetro | Obligatorio | Predeterminado | Notas | 
| --- | --- | --- | --- | 
|  AmazonManagedKafkaEventSourceConfig  |  N  |  Contiene el campo ConsumerGroupId, que se establece de forma predeterminada en un valor único.  |  Solo se puede establecer en Crear  | 
|  BatchSize  |  N  |  100  |  Máximo: 10 000  | 
|  DestinationConfig  |  N  |  N/A  |  [Captura de lotes descartados para orígenes de eventos de Amazon MSK y Apache Kafka autoadministrado](kafka-on-failure.md)  | 
|  Habilitado  |  N  |  True  |    | 
|  BisectBatchOnFunctionError  |  N  |  False  |  [Configuración de los controles de gestión de errores para orígenes de eventos de Kafka](kafka-retry-configurations.md)  | 
|  FunctionResponseTypes  |  N  |  N/A  |  [Configuración de los controles de gestión de errores para orígenes de eventos de Kafka](kafka-retry-configurations.md)  | 
|  MaximumRecordAgeInSeconds  |  N  |  -1 (infinito)  |  [Configuración de los controles de gestión de errores para orígenes de eventos de Kafka](kafka-retry-configurations.md)  | 
|  MaximumRetryAttempts  |  N  |  -1 (infinito)  |  [Configuración de los controles de gestión de errores para orígenes de eventos de Kafka](kafka-retry-configurations.md)  | 
|  EventSourceArn  |  S  | N/A |  Solo se puede establecer en Crear  | 
|  FilterCriteria  |  N  |  N/A  |  [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md)  | 
|  FunctionName  |  S  |  N/A  |    | 
|  KMSKeyArn  |  N  |  N/A  |  [Cifrado de los criterios de filtro](invocation-eventfiltering.md#filter-criteria-encryption)  | 
|  MaximumBatchingWindowInSeconds  |  N  |  500 ms  |  [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching)  | 
|  ProvisionedPollersConfig  |  N  |  `MinimumPollers`: si no se especifica, el valor predeterminado es 1. `MaximumPollers`: si no se especifica, el valor predeterminado es 200. `PollerGroupName`: N/A  |  [Modo aprovisionado](kafka-scaling-modes.md#kafka-provisioned-mode)  | 
|  SourceAccessConfigurations  |  N  |  Sin credenciales  |  Credenciales de autenticación de SASL/SCRAM o CLIENT\$1CERTIFICATE\$1TLS\$1AUTH (MutualTLS) para el origen de eventos  | 
|  StartingPosition  |  S  | N/A |  AT\$1TIMESTAMP, TRIM\$1HORIZON o LATEST Solo se puede establecer en Crear  | 
|  StartingPositionTimestamp  |  N  |  N/A  |  Obligatorio si StartingPosition se establece en AT\$1TIMESTAMP  | 
|  Etiquetas  |  N  |  N/A  |  [Uso de etiquetas en asignaciones de orígenes de eventos](tags-esm.md)  | 
|  Temas  |  S  | N/A |  Nombre del tema de Kafka Solo se puede establecer en Crear  | 

**nota**  
Cuando especifica un `PollerGroupName`, varias ESM de la misma Amazon VPC pueden compartir la capacidad de la unidad de sondeador de eventos (EPU). Puede utilizar esta opción para optimizar los costos del modo aprovisionado para sus ESM. Requisitos para la agrupación de ESM:  
Las ESM deben estar dentro de la misma Amazon VPC.
Máximo de 100 ESM por grupo de sondeadores
El número máximo total de sondeadores en todos las ESM de un grupo no puede superar los 2000.
Puede actualizar el `PollerGroupName` para mover una ESM a un grupo diferente o eliminar una ESM de un grupo; para ello, configure una string vacía («») en `PollerGroupName`:

# Tutorial: Uso de una asignación de orígenes de eventos de Amazon MSK para invocar una función de Lambda
<a name="services-msk-tutorial"></a>

En este tutorial, hará lo siguiente:
+ Creará una función de Lambda en la misma cuenta de AWS de un clúster existente de Amazon MSK.
+ Configurará las redes y la autenticación para que Lambda se comunique con Amazon MSK.
+ Configurará una asignación de orígenes de eventos de Amazon MSK de Lambda que ejecute la función de Lambda cuando los eventos aparezcan en el tema.

Una vez finalizados estos pasos, cuando los eventos se envíen a Amazon MSK, podrá configurar una función de Lambda para procesar dichos eventos automáticamente con su propio código de Lambda personalizado.

 **¿Qué puede hacer con esta característica?** 

**Ejemplo de solución: utilice una asignación de orígenes de eventos de MSK para ofrecer puntuaciones en directo a sus clientes.**

Considere el siguiente escenario: su empresa aloja una aplicación web en la que sus clientes pueden ver información sobre eventos en directo, como partidos deportivos. Las actualizaciones de información del juego se proporcionan a su equipo a través de un tema de Kafka en Amazon MSK. Desea diseñar una solución que utilice las actualizaciones del tema de MSK para ofrecer a los clientes una visión actualizada del evento en directo desde una aplicación que desarrolle. Ha optado por el siguiente enfoque de diseño: sus aplicaciones cliente se comunicarán con un backend sin servidor alojado en AWS. Los clientes se conectarán a través de sesiones de websocket mediante la API de WebSocket de Amazon API Gateway.

En esta solución, necesita un componente que lea los eventos de MSK, ejecute una lógica personalizada para preparar esos eventos para la capa de aplicación y, a continuación, reenvíe esa información a la API de API Gateway. Puede implementar este componente con AWS Lambda al proporcionar su lógica personalizada en una función de Lambda y luego llamarla con una asignación de orígenes de eventos de Amazon MSK de AWS Lambda.

Para obtener más información sobre la implementación de soluciones mediante la API de WebSocket de Amazon API Gateway, consulte los [tutoriales de la API de WebSocket](https://docs.aws.amazon.com/apigateway/latest/developerguide/websocket-api-chat-app.html) en la documentación de API Gateway.

## Requisitos previos
<a name="w2aad101c23c15c35c19"></a>

Una cuenta de AWS con los siguientes recursos preconfigurados:

**Para cumplir estos requisitos previos, le recomendamos que consulte la sección [Getting started using Amazon MSK](https://docs.aws.amazon.com//msk/latest/developerguide/getting-started.html) en la documentación de Amazon MSK.**
+ Un clúster de Amazon MSK Consulte [Create an Amazon MSK cluster](https://docs.aws.amazon.com//msk/latest/developerguide/create-cluster.html) en *Getting started using Amazon MSK*.
+ La siguiente configuración:
  + Asegúrese de que la **autenticación basada en roles de IAM** esté **habilitada** en la configuración de seguridad de su clúster. Esto mejora la seguridad al limitar la función de Lambda para que solo acceda a los recursos de Amazon MSK necesarios. Esto está habilitado de forma predeterminada en los nuevos clústeres de Amazon MSK.
  + Asegúrese de que el **acceso público** esté desactivado en la configuración de red del clúster. Restringir el acceso de su clúster de Amazon MSK a Internet mejora su seguridad al limitar el número de intermediarios que gestionan sus datos. Esto está habilitado de forma predeterminada en los nuevos clústeres de Amazon MSK.
+ Un tema de Kafka en su clúster de Amazon MSK para usarlo en esta solución. Consulte [Create a topic](https://docs.aws.amazon.com//msk/latest/developerguide/create-topic.html) en *Getting started using Amazon MSK*.
+ Un host de administración de Kafka configurado para recuperar información de su clúster de Kafka y enviar los eventos de Kafka a su tema para probarlos, como una instancia de Amazon EC2 con la CLI de administración de Kafka y la biblioteca de IAM de Amazon MSK instaladas. Consulte [Create an Amazon MSK cluster](https://docs.aws.amazon.com//msk/latest/developerguide/create-client-machine.html) en *Getting started using Amazon MSK*.

Una vez que haya configurado estos recursos, recopile la siguiente información de su cuenta de AWS para confirmar que puede continuar.
+ El nombre de su clúster de Amazon MSK. Puede encontrar esta información en la consola de Amazon MSK.
+ El UUID del clúster, que forma parte del ARN de su clúster de Amazon MSK, que puede encontrar en la consola de Amazon MSK. Siga los procedimientos que se indican en [Listing clusters](https://docs.aws.amazon.com/msk/latest/developerguide/msk-list-clusters.html) en la documentación de Amazon MSK para encontrar esta información.
+ Los grupos de seguridad asociados con su clúster de Amazon MSK. Puede encontrar esta información en la consola de Amazon MSK. En los siguientes pasos, se hará referencia a ellos como *clusterSecurityGroups*.
+ El identificador de la Amazon VPC que contiene su clúster de Amazon MSK. Para encontrar esta información, identifique las subredes asociadas a su clúster de Amazon MSK en la consola de Amazon MSK y, a continuación, identifique la Amazon VPC asociada a la subred en la consola de Amazon VPC.
+ El nombre del tema de Kafka utilizado en su solución. Puede encontrar esta información al llamar a su clúster de Amazon MSK con la CLI de `topics` de Kafka desde su host de administración de Kafka. Para obtener más información sobre la CLI de temas, consulte [Adding and removing topics](https://kafka.apache.org/documentation/#basic_ops_add_topic) en la documentación de Kafka.
+ El nombre de un grupo de consumidores para su tema de Kafka, adecuado para que lo utilice su función de Lambda. Lambda puede crear este grupo automáticamente, por lo que no es necesario crearlo con la CLI de Kafka. Si necesita administrar sus grupos de consumidores, para obtener más información sobre la CLI de grupos de consumidores, consulte [Managing Consumer Groups](https://kafka.apache.org/documentation/#basic_ops_consumer_group) en la documentación de Kafka.

Los siguientes permisos en su cuenta de AWS:
+ Permiso para crear y administrar una función de Lambda
+ Permiso para crear políticas de IAM y asociarlas a su función de Lambda.
+ Permiso para crear puntos de conexión de Amazon VPC y modificar la configuración de red en la Amazon VPC que aloja el clúster de Amazon MSK.

### Instala la AWS Command Line Interface
<a name="install_aws_cli"></a>

Si aún no ha instalado AWS Command Line Interface, siga los pasos que se indican en [Instalación o actualización de la versión más reciente de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalarlo.

El tutorial requiere un intérprete de comandos o un terminal de línea de comando para ejecutar los comandos. En Linux y macOS, use su administrador de intérprete de comandos y paquetes preferido.

**nota**  
En Windows, algunos comandos de la CLI de Bash que se utilizan habitualmente con Lambda (por ejemplo, `zip`) no son compatibles con los terminales integrados del sistema operativo. Para obtener una versión de Ubuntu y Bash integrada con Windows, [instale el subsistema de Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Configuración de la conectividad de red para que Lambda se comunique con Amazon MSK
<a name="w2aad101c23c15c35c21"></a>

 Use AWS PrivateLink para conectar Lambda y Amazon MSK. Para ello, puede crear puntos de conexión de Amazon VPC de interfaz en la consola de Amazon VPC. Para obtener más información acerca de la configuración de red, consulte [Configuración del clúster de Amazon MSK y la red de Amazon VPC para Lambda](with-msk-cluster-network.md). 

Cuando se ejecuta una asignación de orígenes de eventos de Amazon MSK en nombre de una función de Lambda, asume el rol de ejecución de la función de Lambda. Este rol de IAM autoriza la asignación para acceder a los recursos protegidos por IAM, como su clúster de Amazon MSK. Si bien los componentes comparten un rol de ejecución, la asignación de Amazon MSK y la función de Lambda tienen requisitos de conectividad distintos para sus respectivas tareas, como se muestra en el siguiente diagrama.

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/msk_tut_network.png)


La asignación de orígenes de eventos pertenece al grupo de seguridad de su clúster de Amazon MSK. En este paso de red, cree puntos de conexión de Amazon VPC a partir de la VPC de su clúster de Amazon MSK para conectar la asignación de orígenes de eventos a los servicios Lambda y STS. Proteja estos puntos de conexión para que acepten el tráfico del grupo de seguridad de su clúster de Amazon MSK. A continuación, ajuste los grupos de seguridad del clúster de Amazon MSK para permitir que la asignación de orígenes de eventos se comunique con el clúster de Amazon MSK.

 Puede configurar los siguientes pasos que mediante la Consola de administración de AWS.

**Cómo configurar los puntos de conexión de Amazon VPC de interfaz para conectar Lambda y Amazon MSK**

1. Cree un grupo de seguridad para los puntos de conexión de Amazon VPC de interfaz, *endpointSecurityGroup*, que permita el tráfico TCP entrante en 443 desde *clusterSecurityGroups*. Siga el procedimiento descrito en [Crear un grupo de seguridad](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/working-with-security-groups.html#creating-security-group) en la documentación de Amazon EC2 para crear un grupo de seguridad. A continuación, siga el procedimiento descrito en [Agregar reglas a un grupo de seguridad](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/working-with-security-groups.html#adding-security-group-rule) en la documentación de Amazon EC2 para agregar las reglas adecuadas. 

   **Cree un grupo de seguridad con la siguiente información:**

   Al agregar las reglas de entrada, cree una regla para cada grupo de seguridad de *clusterSecurityGroups*. Para cada regla:
   + En **Tipo**, seleccione **HTTPS**.
   + En **Origen**, seleccione uno de los *clusterSecurityGroups*.

1.  Cree un punto de conexión que conecte el servicio de Lambda a la Amazon VPC que contiene su clúster de Amazon MSK. Siga el procedimiento que se indica en [Crear un punto de conexión de interfaz](https://docs.aws.amazon.com//vpc/latest/privatelink/create-interface-endpoint.html).

   **Cree un punto de conexión de interfaz con la siguiente información:**
   + En **Nombre del servicio**, seleccione `com.amazonaws.regionName.lambda`, cuyo *RegionName* sea donde se aloja la función de Lambda.
   + Para **VPC**, seleccione la Amazon VPC que contiene el clúster de Amazon MSK.
   + Para **Grupos de seguridad**, seleccione *endpointSecurityGroup*, el cual creó anteriormente.
   + En **Subredes**, seleccione las subredes que alojan su clúster de Amazon MSK.
   + En **Política**, proporcione el siguiente documento de política, que protege el punto de conexión para que lo utilice la entidad principal del servicio de Lambda para la acción `lambda:InvokeFunction`.

     ```
     {
         "Statement": [
             {
                 "Action": "lambda:InvokeFunction",
                 "Effect": "Allow",
                 "Principal": {
                     "Service": [
                         "lambda.amazonaws.com"
                     ]
                 },
                 "Resource": "*"
             }
         ]
     }
     ```
   + Asegúrese de que **Habilitar nombre de DNS** permanezca establecido.

1.  Cree un punto de conexión que conecte el servicio AWS STS a la Amazon VPC que contiene su clúster de Amazon MSK. Siga el procedimiento que se indica en [Crear un punto de conexión de interfaz](https://docs.aws.amazon.com//vpc/latest/privatelink/create-interface-endpoint.html).

   **Cree un punto de conexión de interfaz con la siguiente información:**
   + En **Nombre de servicio**, seleccione AWS STS.
   + Para **VPC**, seleccione la Amazon VPC que contiene el clúster de Amazon MSK.
   + Para **Grupos de seguridad**, seleccione *endpointSecurityGroup*.
   + En **Subredes**, seleccione las subredes que alojan su clúster de Amazon MSK.
   + En **Política**, proporcione el siguiente documento de política, que protege el punto de conexión para que lo utilice la entidad principal del servicio de Lambda para la acción `sts:AssumeRole`.

     ```
     {
         "Statement": [
             {
                 "Action": "sts:AssumeRole",
                 "Effect": "Allow",
                 "Principal": {
                     "Service": [
                         "lambda.amazonaws.com"
                     ]
                 },
                 "Resource": "*"
             }
         ]
     }
     ```
   + Asegúrese de que **Habilitar nombre de DNS** permanezca establecido.

1. Para cada grupo de seguridad asociado a su clúster de Amazon MSK, es decir, en *clusterSecurityGroups*, permita lo siguiente:
   + Permita que todo el tráfico TCP entrante y saliente de 9098 llegue a todos los *clusterSecurityGroups*, incluso dentro del propio grupo.
   + Permita todo el tráfico TCP saliente en 443.

   Las reglas predeterminadas de los grupos de seguridad permiten parte de este tráfico, por lo que si el clúster está conectado a un único grupo de seguridad y ese grupo tiene reglas predeterminadas, no se necesitan reglas adicionales. Para ajustar las reglas de los grupos de seguridad, siga los procedimientos de [Agregar reglas a un grupo de seguridad](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/working-with-security-groups.html#adding-security-group-rule) en la documentación de Amazon EC2.

   **Agregue reglas a sus grupos de seguridad con la siguiente información:**
   + Para cada regla de entrada o de salida del puerto 9098, proporcione lo siguiente:
     + En **Type (Tipo)**, seleccione **Custom TCP (TCP personalizada)**.
     + Para **Intervalo de puertos**, proporcione 9098.
     + En **Origen**, proporcione uno de los *clusterSecurityGroups*.
   + Para cada regla de entrada del puerto 443, en **Tipo**, seleccione **HTTPS**.

## Creación de un rol de IAM para que Lambda lea un tema de Amazon MSK
<a name="w2aad101c23c15c35c23"></a>

Identifique los requisitos de autenticación que Lambda debe leer en su tema de Amazon MSK y, a continuación, defínalos en una política. Cree un rol, *lambdaAuthRole*, que autorice a Lambda a usar esos permisos. Autorice acciones en su clúster de Amazon MSK mediante las acciones de IAM `kafka-cluster`. A continuación, autorice a Lambda a realizar las acciones de Amazon MSK `kafka` y Amazon EC2 necesarias para descubrir el clúster de Amazon MSK y conectarse a él, así como las acciones de CloudWatch para que Lambda pueda registrar lo que ha hecho.

**Cómo describir los requisitos de autenticación para que Lambda lea desde Amazon MSK**

1. Redacte un documento de política de IAM (un documento JSON), *clusterAuthPolicy*, que permita a Lambda leer el tema de Kafka en su clúster de Amazon MSK mediante su grupo de consumidores de Kafka. Lambda requiere que se configure un grupo de consumidores de Kafka para la lectura.

   Modifique la siguiente plantilla para adaptarla a sus requisitos previos:

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "kafka-cluster:Connect",
                   "kafka-cluster:DescribeGroup",
                   "kafka-cluster:AlterGroup",
                   "kafka-cluster:DescribeTopic",
                   "kafka-cluster:ReadData",
                   "kafka-cluster:DescribeClusterDynamicConfiguration"
               ],
               "Resource": [
                   "arn:aws:kafka:us-east-1:111122223333:cluster/mskClusterName/cluster-uuid",
                   "arn:aws:kafka:us-east-1:111122223333:topic/mskClusterName/cluster-uuid/mskTopicName",
                   "arn:aws:kafka:us-east-1:111122223333:group/mskClusterName/cluster-uuid/mskGroupName"
               ]
           }
       ]
   }
   ```

------

   Para obtener más información, consulte [Cómo configurar permisos de Lambda para las asignaciones de orígenes de eventos](with-msk-permissions.md). Al redactar la política:
   + Sustituya *us-east-1* y *111122223333* por la Región de AWS y la Cuenta de AWS de su clúster de Amazon MSK.
   + Para *mskClusterName*, proporcione el nombre de su clúster de Amazon MSK.
   + Para *cluster-uuid*, proporcione el UUID del ARN de su clúster de Amazon MSK.
   + Para *mskTopicName*, proporcione el nombre del tema de Kafka.
   + Para *mskGroupName*, proporcione el nombre de su grupo de consumidores de Kafka.

1. Identifique los permisos de Amazon MSK, Amazon EC2 y CloudWatch necesarios para que Lambda detecte y conecte su clúster de Amazon MSK a fin de registrar esos eventos.

   La política administrada `AWSLambdaMSKExecutionRole` define de forma permisiva los permisos necesarios. Úsela en los siguientes pasos.

   En un entorno de producción, evalúe `AWSLambdaMSKExecutionRole` para restringir su política de rol de ejecución según el principio de privilegio mínimo y luego escriba una política para su rol que reemplace esta política administrada.

Para obtener más información sobre el lenguaje de políticas de IAM, consulte la [documentación de IAM](https://docs.aws.amazon.com//iam/).

Ahora que ha redactado su documento de política, cree una política de IAM para poder adjuntarla a su rol. Para ello, puede utilizar la consola de la siguiente manera.

**Cómo crear una política de IAM a partir de su documento de política**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de IAM en [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. En el panel de navegación de la izquierda, elija **Políticas**. 

1. Elija **Crear política**.

1. En la sección **Editor de políticas**, seleccione la opción **JSON**.

1. Pegue *clusterAuthPolicy*.

1. Cuando haya terminado de agregar permisos a la política, seleccione **Siguiente**.

1. En la página **Revisar y crear**, escriba el **Nombre de la política** y la **Descripción** (opcional) para la política que está creando. Revise los **Permisos definidos en esta política** para ver los permisos que concede la política.

1. Elija **Crear política** para guardar la nueva política.

Para obtener más información, consulte [Crear políticas de IAM](https://docs.aws.amazon.com//IAM/latest/UserGuide/access_policies_create.html) en la documentación de IAM.

Ahora que dispone de las políticas de IAM adecuadas, cree un rol y adjúnteselas. Para ello, puede utilizar la consola de la siguiente manera.

**Para crear un rol de ejecución en la consola de IAM**

1. Abra la [página Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Elija **Creación de rol**.

1. En **Tipo de entidad de confianza**, seleccione **Servicio de AWS**.

1. En **Use case** (Caso de uso), elija **Lambda**.

1. Elija **Siguiente**.

1. Seleccione las siguientes políticas:
   + *clusterAuthPolicy*
   + `AWSLambdaMSKExecutionRole`

1. Elija **Siguiente**.

1. En **Nombre de rol**, escriba *lambdaAuthRole* y luego elija **Crear rol**.

Para obtener más información, consulte [Definición de permisos de funciones de Lambda con un rol de ejecución](lambda-intro-execution-role.md).

## Creación de una función de Lambda para leer su tema de Amazon MSK
<a name="w2aad101c23c15c35c25"></a>

Cree una función de Lambda configurada para usar su rol de IAM. Puede crear la función de Lambda con la consola.

**Cómo crear una función de Lambda con su configuración de autenticación**

1.  Abra la consola de Lambda y seleccione **Crear función** en el encabezado. 

1. Seleccione **Crear desde cero**.

1. En **Nombre de la función**, introduzca el nombre apropiado de su elección.

1. En **Tiempo de ejecución**, elija la **última versión compatible** de `Node.js` para usar el código que se proporciona en este tutorial.

1. Elija **Cambiar el rol de ejecución predeterminado**.

1. Seleccione **Usar un rol existente**.

1. En **Rol existente**, seleccione *lambdaAuthRole*.

En un entorno de producción, normalmente es necesario agregar más políticas al rol de ejecución de la función de Lambda para procesar de forma significativa los eventos de Amazon MSK. Para obtener más información sobre cómo agregar políticas a su rol, consulte [Agregar o eliminar permisos de identidad](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html#add-policies-console) en la documentación de IAM.

## Creación de una asignación de orígenes de eventos para la función de Lambda
<a name="w2aad101c23c15c35c27"></a>

La asignación de orígenes de eventos de Amazon MSK proporciona al servicio Lambda la información necesaria para invocar una función de Lambda cuando se producen los eventos de Amazon MSK adecuados. Puede crear una asignación de Amazon MSK mediante la consola. Cree un desencadenador de Lambda y, a continuación, la asignación de orígenes de eventos se configurará automáticamente.

**Cómo crear un desencadenador de Lambda (y la asignación de orígenes de eventos)**

1. Navegue a la página de información general de la función de Lambda.

1. En la sección de información general de la función, seleccione **Agregar desencadenador** en la parte inferior izquierda.

1. En el menú desplegable **Seleccionar un origen**, seleccione **Amazon MSK**.

1. No configure la **autenticación**.

1. Para **Clúster de MSK**, seleccione el nombre de su clúster.

1. En **Tamaño del lote**, ingrese 1. Este paso hace que esta característica sea más fácil de probar, pero no es un valor ideal en producción.

1. Para **Nombre del tema**, escriba un nombre para el tema de Kafka.

1. Para **ID de grupo de consumidores**, indique el identificador de su grupo de consumidores de Kafka.

## Actualización de la función de Lambda para leer los datos de transmisión
<a name="w2aad101c23c15c35c29"></a>

 Lambda proporciona información sobre los eventos de Kafka a través del parámetro del método event. Para ver un ejemplo de estructura de un evento de Amazon MSK, consulte [Evento de ejemplo](with-msk.md#msk-sample-event). Una vez que sepa cómo interpretar los eventos de Amazon MSK reenviados por Lambda, puede modificar el código de la función de Lambda para utilizar la información que proporcionan. 

 Proporcione el siguiente código a la función de Lambda para registrar el contenido de un evento de Amazon MSK de Lambda con fines de prueba: 

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumo de un evento de Amazon MSK con Lambda mediante .NET.  

```
using System.Text;
using Amazon.Lambda.Core;
using Amazon.Lambda.KafkaEvents;


// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace MSKLambda;

public class Function
{
    
    
    /// <param name="input">The event for the Lambda function handler to process.</param>
    /// <param name="context">The ILambdaContext that provides methods for logging and describing the Lambda environment.</param>
    /// <returns></returns>
    public void FunctionHandler(KafkaEvent evnt, ILambdaContext context)
    {

        foreach (var record in evnt.Records)
        {
            Console.WriteLine("Key:" + record.Key); 
            foreach (var eventRecord in record.Value)
            {
                var valueBytes = eventRecord.Value.ToArray();    
                var valueText = Encoding.UTF8.GetString(valueBytes);
                
                Console.WriteLine("Message:" + valueText);
            }
        }
    }
    

}
```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumo de un evento de Amazon MSK con Lambda mediante Go.  

```
package main

import (
	"encoding/base64"
	"fmt"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handler(event events.KafkaEvent) {
	for key, records := range event.Records {
		fmt.Println("Key:", key)

		for _, record := range records {
			fmt.Println("Record:", record)

			decodedValue, _ := base64.StdEncoding.DecodeString(record.Value)
			message := string(decodedValue)
			fmt.Println("Message:", message)
		}
	}
}

func main() {
	lambda.Start(handler)
}
```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Uso de un evento de Amazon MSK con Lambda mediante Java.  

```
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.KafkaEvent;
import com.amazonaws.services.lambda.runtime.events.KafkaEvent.KafkaEventRecord;

import java.util.Base64;
import java.util.Map;

public class Example implements RequestHandler<KafkaEvent, Void> {

    @Override
    public Void handleRequest(KafkaEvent event, Context context) {
        for (Map.Entry<String, java.util.List<KafkaEventRecord>> entry : event.getRecords().entrySet()) {
            String key = entry.getKey();
            System.out.println("Key: " + key);

            for (KafkaEventRecord record : entry.getValue()) {
                System.out.println("Record: " + record);

                byte[] value = Base64.getDecoder().decode(record.getValue());
                String message = new String(value);
                System.out.println("Message: " + message);
            }
        }

        return null;
    }
}
```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Uso de un evento de Amazon MSK con Lambda mediante JavaScript.  

```
exports.handler = async (event) => {
    // Iterate through keys
    for (let key in event.records) {
      console.log('Key: ', key)
      // Iterate through records
      event.records[key].map((record) => {
        console.log('Record: ', record)
        // Decode base64
        const msg = Buffer.from(record.value, 'base64').toString()
        console.log('Message:', msg)
      }) 
    }
}
```
Consumo de un evento de Amazon MSK con Lambda mediante TypeScript.  

```
import { MSKEvent, Context } from "aws-lambda";
import { Buffer } from "buffer";
import { Logger } from "@aws-lambda-powertools/logger";

const logger = new Logger({
  logLevel: "INFO",
  serviceName: "msk-handler-sample",
});

export const handler = async (
  event: MSKEvent,
  context: Context
): Promise<void> => {
  for (const [topic, topicRecords] of Object.entries(event.records)) {
    logger.info(`Processing key: ${topic}`);

    // Process each record in the partition
    for (const record of topicRecords) {
      try {
        // Decode the message value from base64
        const decodedMessage = Buffer.from(record.value, 'base64').toString();

        logger.info({
          message: decodedMessage
        });
      }
      catch (error) {
        logger.error('Error processing event', { error });
        throw error;
      }
    };
  }
}
```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumo de un evento de Amazon MSK con Lambda mediante PHP.  

```
<?php
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

// using bref/bref and bref/logger for simplicity

use Bref\Context\Context;
use Bref\Event\Kafka\KafkaEvent;
use Bref\Event\Handler as StdHandler;
use Bref\Logger\StderrLogger;

require __DIR__ . '/vendor/autoload.php';

class Handler implements StdHandler
{
    private StderrLogger $logger;
    public function __construct(StderrLogger $logger)
    {
        $this->logger = $logger;
    }

    /**
     * @throws JsonException
     * @throws \Bref\Event\InvalidLambdaEvent
     */
    public function handle(mixed $event, Context $context): void
    {
        $kafkaEvent = new KafkaEvent($event);
        $this->logger->info("Processing records");
        $records = $kafkaEvent->getRecords();

        foreach ($records as $record) {
            try {
                $key = $record->getKey();
                $this->logger->info("Key: $key");

                $values = $record->getValue();
                $this->logger->info(json_encode($values));

                foreach ($values as $value) {
                    $this->logger->info("Value: $value");
                }
                
            } catch (Exception $e) {
                $this->logger->error($e->getMessage());
            }
        }
        $totalRecords = count($records);
        $this->logger->info("Successfully processed $totalRecords records");
    }
}

$logger = new StderrLogger();
return new Handler($logger);
```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumo de un evento de Amazon MSK con Lambda mediante Python.  

```
import base64

def lambda_handler(event, context):
    # Iterate through keys
    for key in event['records']:
        print('Key:', key)
        # Iterate through records
        for record in event['records'][key]:
            print('Record:', record)
            # Decode base64
            msg = base64.b64decode(record['value']).decode('utf-8')
            print('Message:', msg)
```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumo de un evento de Amazon MSK con Lambda mediante Ruby.  

```
require 'base64'

def lambda_handler(event:, context:)
  # Iterate through keys
  event['records'].each do |key, records|
    puts "Key: #{key}"

    # Iterate through records
    records.each do |record|
      puts "Record: #{record}"

      # Decode base64
      msg = Base64.decode64(record['value'])
      puts "Message: #{msg}"
    end
  end
end
```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumo de un evento de Amazon MSK con Lambda mediante Rust.  

```
use aws_lambda_events::event::kafka::KafkaEvent;
use lambda_runtime::{run, service_fn, tracing, Error, LambdaEvent};
use base64::prelude::*;
use serde_json::{Value};
use tracing::{info};

/// Pre-Requisites:
/// 1. Install Cargo Lambda - see https://www.cargo-lambda.info/guide/getting-started.html
/// 2. Add packages tracing, tracing-subscriber, serde_json, base64
///
/// This is the main body for the function.
/// Write your code inside it.
/// There are some code example in the following URLs:
/// - https://github.com/awslabs/aws-lambda-rust-runtime/tree/main/examples
/// - https://github.com/aws-samples/serverless-rust-demo/

async fn function_handler(event: LambdaEvent<KafkaEvent>) -> Result<Value, Error> {

    let payload = event.payload.records;

    for (_name, records) in payload.iter() {

        for record in records {

         let record_text = record.value.as_ref().ok_or("Value is None")?;
         info!("Record: {}", &record_text);

         // perform Base64 decoding
         let record_bytes = BASE64_STANDARD.decode(record_text)?;
         let message = std::str::from_utf8(&record_bytes)?;
         
         info!("Message: {}", message);
        }

    }

    Ok(().into())
}

#[tokio::main]
async fn main() -> Result<(), Error> {

    // required to enable CloudWatch error logging by the runtime
    tracing::init_default_subscriber();
    info!("Setup CW subscriber!");

    run(service_fn(function_handler)).await
}
```

------

Puede proporcionar un código de función de Lambda con la consola.

**Para actualizar el código de función mediante el editor de código de la consola**

1. Abra la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) de la consola de Lambda y seleccione su función.

1. Seleccione la pestaña **Código**.

1. En el panel **Código fuente**, seleccione su archivo de código fuente y edítelo en el editor de código integrado.

1. En la sección **IMPLEMENTAR** elija **Implementar** para actualizar el código de la función:  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

## Prueba de la función de Lambda para comprobar que está conectada al tema de Amazon MSK
<a name="w2aad101c23c15c35c31"></a>

Ahora puede comprobar si el origen de eventos está invocando o no su función de Lambda mediante la inspección de los registros de eventos de CloudWatch.

**Cómo comprobar si se está invocando la función de Lambda**

1. Utilice su host de administración de Kafka para generar eventos de Kafka mediante la CLI `kafka-console-producer`. Para obtener más información, consulte [Write some events into the topic](https://kafka.apache.org/documentation/#quickstart_send) en la documentación de Kafka. Envíe suficientes eventos a fin de llenar el lote definido en el tamaño del lote para la asignación de orígenes de eventos especificada en el paso anterior. Si no lo hace, Lambda esperará a que se invoque más información.

1. Si la función se ejecuta, Lambda escribe lo ocurrido en CloudWatch. En la consola, navegue hasta la página de detalles de su función de Lambda.

1. Seleccione la pestaña **Configuración**.

1. En la barra lateral, seleccione **Herramientas de monitoreo y operaciones**.

1. Identifique el **grupo de registro de CloudWatch** en **Configuración de registro**. El grupo de registro debe empezar con `/aws/lambda`. Elija el enlace del grupo de registro.

1. En la consola de CloudWatch, inspeccione los **eventos de registro** para ver los eventos de registro que Lambda ha enviado al flujo de registro. Identifique si hay eventos de registro que contengan el mensaje de su evento de Kafka, como se muestra en la siguiente imagen. Si los hay, significa que ha conectado correctamente una función de Lambda a Amazon MSK con una asignación de orígenes de eventos de Lambda.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/msk_tut_log.png)

# Uso de Lambda con Apache Kafka autoadministrado
<a name="with-kafka"></a>

En este tema se describe cómo utilizar Lambda con un clúster de Kafka autoadministrado. En la terminología de AWS, un clúster autoadministrado incluye clústeres Kafka alojados que no son de AWS. Por ejemplo, puede alojar su clúster de Kafka con un proveedor de servicios en la nube, como [Confluent Cloud](https://www.confluent.io/confluent-cloud/) o [Redpanda](https://www.redpanda.com/).

En este capítulo se explica cómo utilizar un clúster de Apache Kafka autoadministrado como origen de eventos para su función de Lambda. El proceso general de integración de Apache Kafka autoadministrado con Lambda implica los siguientes pasos:

1. **[Configuración de clúster y red](with-kafka-cluster-network.md)**: primero, configure su clúster Apache Kafka autoadministrado con la configuración de red correcta para permitir que Lambda acceda a su clúster.

1. **[Configuración de la asignación de orígenes de eventos](with-kafka-configure.md)**: luego, cree el recurso de [asignación de orígenes de eventos](invocation-eventsourcemapping.md) que Lambda necesita para conectar de forma segura su clúster de Apache Kafka a su función.

1. **[Configuración de la función y los permisos](with-kafka-permissions.md)**: por último, asegúrese de que su función esté configurada correctamente y de que cuente con los permisos necesarios en su [rol de ejecución](lambda-intro-execution-role.md).

Apache Kafka como origen de eventos funciona de manera similar a utilizar Amazon Simple Queue Service (Amazon SQS) o Amazon Kinesis. Lambda sondea internamente nuevos mensajes del origen de eventos y luego invoca sincrónicamente la función de Lambda objetivo. Lambda lee los mensajes en lotes y los proporciona a su función como carga de eventos. El tamaño máximo del lote se puede configurar (el valor predeterminado son 100 mensajes). Para obtener más información, consulte [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

Para optimizar el rendimiento de la asignación de orígenes de eventos de Apache Kafka autoadministrado, configure el modo aprovisionado. En el modo aprovisionado, puede definir el número mínimo y máximo de sondeos de eventos asignados a su asignación de orígenes de eventos. Esto puede mejorar la capacidad de la asignación de orígenes de eventos para manejar picos de mensajes inesperados. Para obtener más información, consulte [Modo aprovisionado](kafka-scaling-modes.md#kafka-provisioned-mode).

**aviso**  
Las asignaciones de orígenes de eventos de Lambda procesan cada evento al menos una vez, y puede producirse un procesamiento duplicado de registros. Para evitar posibles problemas relacionados con la duplicación de eventos, le recomendamos encarecidamente que haga que el código de la función sea idempotente. Para obtener más información, consulte [¿Cómo puedo hacer que mi función de Lambda sea idempotente?](https://repost.aws/knowledge-center/lambda-function-idempotent) en el Centro de conocimientos de AWS.

Para los orígenes de eventos basados en Kafka, Lambda admite parámetros de control de procesamiento, como los plazos de procesamiento por lotes y el tamaño del lote. Para obtener más información, consulte [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

Para ver un ejemplo de cómo utilizar Kafka autoadministrado como origen de eventos, consulte [Uso de Apache Kafka autoalojado como origen de eventos para AWS Lambda](https://aws.amazon.com/blogs/compute/using-self-hosted-apache-kafka-as-an-event-source-for-aws-lambda/) en el blog de informática de AWS.

**Topics**
+ [

## Evento de ejemplo
](#smaa-sample-event)
+ [

# Configuración del clúster Apache Kafka autoadministrado y de la red para Lambda
](with-kafka-cluster-network.md)
+ [

# Configuración de permisos del rol de ejecución de Lambda
](with-kafka-permissions.md)
+ [

# Configuración de Apache Kafka autoadministrado como origen de eventos para Lambda
](with-kafka-configure.md)

## Evento de ejemplo
<a name="smaa-sample-event"></a>

Lambda envía el lote de mensajes en el parámetro de evento cuando invoca su función de Lambda. La carga de eventos contiene una matriz de mensajes. Cada elemento de la matriz contiene detalles del tema Kafka y el identificador de partición Kafka, junto con una marca de tiempo y un mensaje codificado en base64.

```
{
   "eventSource": "SelfManagedKafka",
   "bootstrapServers":"b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092",
   "records":{
      "mytopic-0":[
         {
            "topic":"mytopic",
            "partition":0,
            "offset":15,
            "timestamp":1545084650987,
            "timestampType":"CREATE_TIME",
            "key":"abcDEFghiJKLmnoPQRstuVWXyz1234==",
            "value":"SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==",
            "headers":[
               {
                  "headerKey":[
                     104,
                     101,
                     97,
                     100,
                     101,
                     114,
                     86,
                     97,
                     108,
                     117,
                     101
                  ]
               }
            ]
         }
      ]
   }
}
```

# Configuración del clúster Apache Kafka autoadministrado y de la red para Lambda
<a name="with-kafka-cluster-network"></a>

Para conectar la función de Lambda al clúster de Apache Kafka autoagestionado, debe configurar correctamente tanto el clúster como la red en la que reside. En esta página se describe cómo configurar el clúster y la red. Si el clúster y la red ya están configurados correctamente, consulte [Configuración de Apache Kafka autoadministrado como origen de eventos para Lambda](with-kafka-configure.md) para configurar la asignación de orígenes de eventos.

**Topics**
+ [

## Configuración de clúster de Apache Kafka autoadministrado.
](#kafka-cluster-setup)
+ [

## Configuración de la seguridad de la red
](#services-kafka-vpc-config)

## Configuración de clúster de Apache Kafka autoadministrado.
<a name="kafka-cluster-setup"></a>

Puede alojar su clúster Apache Kafka autoadministrado con proveedores de nube como [Confluent Cloud](https://www.confluent.io/confluent-cloud/) o [Redpanda](https://www.redpanda.com/), o ejecutarlo en su propia infraestructura. Asegúrese de que el clúster esté correctamente configurado y sea accesible desde la red a la que se conectará la asignación de origen de eventos de Lambda.

## Configuración de la seguridad de la red
<a name="services-kafka-vpc-config"></a>

Para que Lambda tenga acceso completo a Apache Kafka autoadministrado a través de su asignación de orígenes de eventos, debe proporcionar acceso a la instancia de Amazon VPC en la que creó el clúster o este debe utilizar un punto de conexión público (dirección IP pública).

Cuando utilice Apache Kafka autoadministrado con Lambda, recomendamos que cree [puntos de conexión de VPC AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html) que proporcionen a su función acceso a los recursos de su Amazon VPC.

**nota**  
Los puntos de conexión de VPC de AWS PrivateLink son necesarios para las funciones con asignaciones de orígenes de eventos que utilizan el modo predeterminado (bajo demanda) para los sondeos de eventos. Si la asignación de orígenes de eventos utiliza el [modo aprovisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode), no es necesario configurar los puntos de conexión de VPC de AWS PrivateLink.

Cree un punto de conexión para proporcionar acceso a los siguientes recursos:
+  Lambda: cree un punto de conexión para la entidad principal del servicio de Lambda. 
+  AWS STS: cree un punto de conexión para AWS STS con el objetivo de que la entidad principal del servicio asuma un rol en su nombre. 
+  Secrets Manager: si el clúster usa Secrets Manager para almacenar las credenciales, cree un punto de conexión para Secrets Manager. 

Como alternativa, configure una puerta de enlace de NAT en cada subred pública de la Amazon VPC. Para obtener más información, consulte [Habilitación del acceso a Internet para funciones de Lambda conectadas a VPC](configuration-vpc-internet.md).

Al crear una asignación de orígenes de eventos para Apache Kafka autoadministrado, Lambda comprueba si las interfaces de red elásticas (ENI) ya están presentes en las subredes y los grupos de seguridad configurados para la Amazon VPC. Si Lambda encuentra ENI existentes, intenta reutilizarlos. De lo contrario, Lambda crea nuevos ENI para conectarse al origen de eventos e invocar la función.

**nota**  
Las funciones de Lambda siempre se ejecutan dentro de VPC propiedad del servicio de Lambda. La configuración de VPC de la función no afecta la asignación de orígenes de eventos. Solo la configuración de red del origen de eventos determina cómo se conecta Lambda al origen de eventos.

Configure los grupos de seguridad para la Amazon VPC que contiene el clúster. De forma predeterminada, Apache Kafka autoadministrado utiliza los siguientes puertos: `9092`.
+ Reglas de entrada: permiten todo el tráfico en el puerto del agente predeterminado para el grupo de seguridad asociado al origen de eventos. Como alternativa, puede usar una regla de grupo de seguridad con autorreferencia para permitir el acceso desde instancias que pertenecen al mismo grupo de seguridad.
+ Reglas de salida: permiten que todo el tráfico en el puerto `443` vaya a destinos externos en caso de que su función necesite comunicarse con servicios de AWS. Como alternativa, también puede usar una regla de grupo de seguridad con autorreferencia para limitar el acceso al agente en caso de que no necesite comunicarse con otros servicios de AWS.
+ Reglas de entrada del punto de conexión de Amazon VPC: si usa un punto de conexión de Amazon VPC, el grupo de seguridad asociado al punto de conexión de Amazon VPC debe permitir el tráfico entrante en el puerto `443` desde el grupo de seguridad del clúster.

Si el clúster utiliza la autenticación, también puede restringir la política del punto de conexión para el punto de conexión de Secrets Manager. Para llamar a la API de Secrets Manager, Lambda usa su rol de función, no la entidad principal de servicio de Lambda.

**Example Política de punto de conexión de VPC: punto de conexión de Secrets Manager**  

```
{
      "Statement": [
          {
              "Action": "secretsmanager:GetSecretValue",
              "Effect": "Allow",
              "Principal": {
                  "AWS": [
                      "arn:aws::iam::123456789012:role/my-role"
                  ]
              },
              "Resource": "arn:aws::secretsmanager:us-west-2:123456789012:secret:my-secret"
          }
      ]
  }
```

Cuando utiliza los puntos de conexión de VPC de Amazon, AWS enruta las llamadas a la API para invocar una función mediante la interfaz de red elástica (ENI) del punto de conexión. La entidad principal del servicio de Lambda debe llamar a `lambda:InvokeFunction` en cualquier rol y función que utilicen esas ENI.

De forma predeterminada, los puntos de conexión de VPC de Amazon tienen políticas de IAM abiertas que permiten un amplio acceso a los recursos. La práctica recomendada es restringir estas políticas para realizar las acciones necesarias mediante ese punto de conexión. Para garantizar que la asignación de orígenes de eventos pueda invocar la función de Lambda, la política de punto de conexión de VPC debe permitir que la entidad principal del servicio de Lambda llame a `sts:AssumeRole` y `lambda:InvokeFunction`. Restringir las políticas de punto de conexión de VPC para permitir únicamente las llamadas a la API que se originen en su organización impide que la asignación de orígenes de eventos funcione correctamente, por lo que en estas políticas es necesario `"Resource": "*"`.

En el siguiente ejemplo de políticas de puntos de conexión de VPC, se muestra cómo conceder el acceso necesario a las entidades principales del servicio de Lambda para AWS STS y los puntos de conexión de Lambda.

**Example Política de punto de conexión de VPC: punto de conexión de AWS STS**  

```
{
      "Statement": [
          {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                  "Service": [
                      "lambda.amazonaws.com"
                  ]
              },
              "Resource": "*"
          }
      ]
    }
```

**Example Política de punto de conexión de VPC: punto de conexión de Lambda**  

```
{
      "Statement": [
          {
              "Action": "lambda:InvokeFunction",
              "Effect": "Allow",
              "Principal": {
                  "Service": [
                      "lambda.amazonaws.com"
                  ]
              },
              "Resource": "*"
          }
      ]
  }
```

# Configuración de permisos del rol de ejecución de Lambda
<a name="with-kafka-permissions"></a>

Además de [acceder al clúster de Kafka autoadministrado](kafka-cluster-auth.md), la función de Lambda necesita permisos para llevar a cabo varias acciones de la API. Los permisos se agregan al [rol de ejecución](lambda-intro-execution-role.md) de la función. Si los usuarios tienen que acceder a cualquier acción de la API, agregue los permisos necesarios a la política de identidad para el usuario o rol de AWS Identity and Access Management (IAM).

**Topics**
+ [

## Permisos de función de Lambda necesarios
](#smaa-api-actions-required)
+ [

## Permisos de función de Lambda opcionales
](#smaa-api-actions-optional)
+ [

## Adición de permisos a su rol de ejecución
](#smaa-permissions-add-policy)
+ [

## Concesión de acceso a los usuarios con una política de IAM
](#smaa-permissions-add-users)

## Permisos de función de Lambda necesarios
<a name="smaa-api-actions-required"></a>

Para crear y almacenar registros en un grupo de registros en Registros de Amazon CloudWatch, la función de Lambda debe tener los siguientes permisos en su rol de ejecución:
+ [logs:CreateLogGroup](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html)
+ [logs:CreateLogStream](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogStream.html)
+ [logs:PutLogEvents](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html)

## Permisos de función de Lambda opcionales
<a name="smaa-api-actions-optional"></a>

Es posible que la función de Lambda también necesite permisos para:
+ Describir el secreto de Secrets Manager.
+ Acceder a su clave administrada por el cliente de AWS Key Management Service (AWS KMS).
+ Acceder a su Amazon VPC.
+ Envíe los registros de las invocaciones fallidas a un destino.

### Secrets Manager y permisos de AWS KMS
<a name="smaa-api-actions-secrets"></a>

En función del tipo de control de acceso que configure para los agentes de Kafka, es posible que la función de Lambda necesite permiso para acceder a su secreto de Secrets Manager o para descifrar su clave administrada por el cliente de AWS KMS. Para acceder a estos recursos, el rol de ejecución de la función debe tener los siguientes permisos:
+ [secretsmanager:GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html)
+ [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html)

### Permisos de VPC
<a name="smaa-api-actions-vpc"></a>

Si solo los usuarios de una VPC pueden acceder a su clúster de Apache Kafka autoadministrado, su función de Lambda debe tener permiso para acceder a sus recursos de Amazon VPC. Estos recursos incluyen su VPC, subredes, grupos de seguridad e interfaces de red. Para acceder a estos recursos, el rol de ejecución de la función debe tener los siguientes permisos:
+ [ec2:CreateNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateNetworkInterface.html)
+ [ec2:DescribeNetworkInterfaces](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeNetworkInterfaces.html)
+ [ec2:DescribeVpcs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpcs.html)
+ [ec2:DeleteNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteNetworkInterface.html)
+ [ec2:DescribeSubnets](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSubnets.html)
+ [ec2:DescribeSecurityGroups](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html)

## Adición de permisos a su rol de ejecución
<a name="smaa-permissions-add-policy"></a>

Para tener acceso a otros servicios de AWS que su clúster Apache Kafka autoadministrado utiliza, Lambda utiliza las políticas de permisos que defina en el [rol de ejecución](lambda-intro-execution-role.md) de la función de Lambda.

De forma predeterminada, Lambda no está permitido realizar las acciones necesarias u opcionales para un clúster Apache Kafka autoadministrado. Debe crear y definir estas acciones en una [política de confianza de IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-trust-policy.html) para su rol de ejecución. En este ejemplo se muestra cómo puede crear una política que permita a Lambda tener acceso a los recursos de Amazon VPC.

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

****  

```
{
        "Version":"2012-10-17",		 	 	 
        "Statement":[
           {
              "Effect":"Allow",
              "Action":[
                 "ec2:CreateNetworkInterface",
                 "ec2:DescribeNetworkInterfaces",
                 "ec2:DescribeVpcs",
                 "ec2:DeleteNetworkInterface",
                 "ec2:DescribeSubnets",
                 "ec2:DescribeSecurityGroups"
              ],
              "Resource":"*"
           }
        ]
     }
```

------

## Concesión de acceso a los usuarios con una política de IAM
<a name="smaa-permissions-add-users"></a>

De forma predeterminada, los usuarios y roles no tienen permiso para llevar a cabo [operaciones de API de origen de eventos](invocation-eventsourcemapping.md#event-source-mapping-api). Para conceder acceso a los usuarios de su organización o cuenta, cree o actualice la política basada en identidades. Para obtener más información, consulte [Control del acceso a los recursos de AWS mediante políticas](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_controlling.html) en la *Guía del usuario de IAM*.

Para la solución de problemas de errores de autenticación y autorización, consulte [Solución de errores de asignación de orígenes de eventos de Kafka](with-kafka-troubleshoot.md).

# Configuración de Apache Kafka autoadministrado como origen de eventos para Lambda
<a name="with-kafka-configure"></a>

Para usar un clúster de Apache Kafka autoadministrado como origen de eventos para su función de Lambda, cree una [asignación de orígenes de eventos](invocation-eventsourcemapping.md) que conecte los dos recursos. Esta página describe cómo crear una asignación de orígenes de eventos para Apache Kafka autoadministrado.

Esta página asume que ya ha configurado correctamente su clúster de Kafka y la red en la que reside. Si necesita configurar el clúster o la red, consulte [Configuración del clúster Apache Kafka autoadministrado y de la red para Lambda](with-kafka-cluster-network.md).

**Topics**
+ [

## Uso de un clúster de Apache Kafka autoadministrado como origen de eventos.
](#kafka-esm-overview)
+ [

# Configuración de métodos de autenticación de clústeres en Lambda
](kafka-cluster-auth.md)
+ [

# Creación de una asignación de orígenes de eventos de Lambda para un origen de eventos de Apache Kafka autoadministrado
](kafka-esm-create.md)
+ [

# Todos los parámetros de configuración de orígenes de eventos de Apache Kafka autoadministrado en Lambda
](kafka-esm-parameters.md)

## Uso de un clúster de Apache Kafka autoadministrado como origen de eventos.
<a name="kafka-esm-overview"></a>

Cuando agrega su clúster de Apache Kafka o Amazon MSK como desencadenador para su función de Lambda, el clúster se utiliza como [origen de eventos](invocation-eventsourcemapping.md).

Lambda lee los datos de eventos de los temas de Kafka que especifique como `Topics` en una solicitud de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html), en función de la [posición inicial](kafka-starting-positions.md) que especifique. Después de un procesamiento exitoso, su tema de Kafka se compromete a su clúster de Kafka.

Lambda lee los mensajes secuencialmente para cada partición de tema de Kafka. Una sola carga de Lambda puede contener mensajes de varias particiones. Cuando hay más registros disponibles, Lambda continúa procesando registros en lotes, en función del valor de BatchSize que especifique en una solicitud de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html), hasta que la función se ponga al día con el tema.

Después de que Lambda procese cada lote, confirma los desplazamientos de los mensajes en ese lote. Si su función devuelve un error para cualquiera de los mensajes de un lote, Lambda reintenta todo el lote de mensajes hasta que el procesamiento sea correcto o los mensajes caduquen. Puede enviar los registros con error en todos los reintentos a un destino en caso de error para su posterior procesamiento.

**nota**  
Si bien las funciones de Lambda suelen tener un límite de tiempo de espera máximo de 15 minutos, las asignaciones de orígenes de eventos para Amazon MSK, Apache Kafka autoadministrado, Amazon DocumentDB y Amazon MQ para ActiveMQ y RabbitMQ solo admiten funciones con límites de tiempo de espera máximos de 14 minutos.

# Configuración de métodos de autenticación de clústeres en Lambda
<a name="kafka-cluster-auth"></a>

Lambda admite varios métodos para autenticarse con su clúster de Apache Kafka autoadministrado. Asegúrese de configurar el clúster de Kafka para que utilice uno de estos métodos de autenticación admitidos: Para obtener más información acerca de la seguridad de Kafka, consulte la sección [Security](http://kafka.apache.org/documentation.html#security) (Seguridad) de la documentación de Kafka.

## Autenticación SASL/SCRAM
<a name="smaa-auth-sasl"></a>

Lambda es compatible con la autenticación simple y la autenticación de capa de seguridad/mecanismo de autenticación de respuesta por desafío saltado (SASL/SCRAM) con cifrado de seguridad de la capa de transporte (TLS) (`SASL_SSL`). Lambda envía las credenciales cifradas para autenticarse con el clúster. Lambda no es compatible con SASL/SCRAM con texto simple (`SASL_PLAINTEXT`). Para obtener más información acerca de la autenticación SASL/SCRAM, consulte [RFC 5802](https://tools.ietf.org/html/rfc5802).

Lambda también admite la autenticación SASL/PLAIN. Dado que este mecanismo utiliza credenciales en texto claro, la conexión con el servidor debe utilizar cifrado TLS para garantizar la protección de las credenciales.

Para la autenticación SASL, almacene las credenciales de inicio de sesión como secreto en AWS Secrets Manager. Para obtener más información acerca de cómo utilizar Secrets Manager, consulte [Creación de un secreto de AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html) en la *Guía del usuario de AWS Secrets Manager*.

**importante**  
Para utilizar Secrets Manager para la autenticación, los secretos deben almacenarse en la misma región de AWS que la función de Lambda.

## Autenticación TLS mutua
<a name="smaa-auth-mtls"></a>

TLS mutua (mTLS) proporciona autenticación bidireccional entre el cliente y el servidor. El cliente envía un certificado al servidor para que el servidor verifique el cliente, mientras que el servidor envía un certificado al cliente para que el cliente verifique el servidor. 

En Apache Kafka autoadministrado, Lambda actúa como cliente. Puede configurar un certificado de cliente (como secreto en Secrets Manager) para autenticar a Lambda con los agentes de Kafka. El certificado de cliente debe estar firmado por una entidad de certificación en el almacén de confianza del servidor.

El clúster de Kafka envía un certificado de servidor a Lambda para autenticar a los agentes de Kafka con Lambda. El certificado de servidor puede ser un certificado de entidad de certificación pública o un certificado autofirmado o de entidad de certificación privada. El certificado de entidad de certificación pública debe estar firmado por una entidad de certificación que esté en el almacén de confianza de Lambda. Para un certificado autofirmado o de entidad de certificación privada, configure el certificado de entidad de certificación raíz del servidor (como secreto en Secrets Manager). Lambda utiliza el certificado raíz para verificar los agentes de Kafka.

Para obtener más información acerca de mTLS, consulte [Introducing mutual TLS authentication for Amazon MSK as an event source](https://aws.amazon.com/blogs/compute/introducing-mutual-tls-authentication-for-amazon-msk-as-an-event-source) (Presentación de la autenticación de TLS mutua para Amazon MSK como origen de eventos).

## Configuración del secreto de certificado de cliente
<a name="smaa-auth-secret"></a>

El secreto CLIENT\$1CERTIFICATE\$1TLS\$1AUTH requiere un campo de certificado y un campo de clave privada. Para una clave privada cifrada, el secreto requiere una contraseña de clave privada. El certificado y la clave privada deben estar en formato PEM.

**nota**  
Lambda admite los algoritmos de cifrado de claves privadas [PBES1](https://datatracker.ietf.org/doc/html/rfc2898/#section-6.1) (pero no PBES2).

El campo de certificado debe contener una lista de certificados y debe comenzar por el certificado de cliente, seguido de cualquier certificado intermedio, y finalizar con el certificado raíz. Cada certificado debe comenzar en una nueva línea con la siguiente estructura:

```
-----BEGIN CERTIFICATE-----  
            <certificate contents>
-----END CERTIFICATE-----
```

Secrets Manager admite secretos de hasta 65 536 bytes, que supone suficiente espacio para cadenas de certificados largas.

El formato de la clave privada debe ser [PKCS \$18](https://datatracker.ietf.org/doc/html/rfc5208), con la siguiente estructura:

```
-----BEGIN PRIVATE KEY-----  
             <private key contents>
-----END PRIVATE KEY-----
```

Para una clave privada cifrada, utilice la siguiente estructura:

```
-----BEGIN ENCRYPTED PRIVATE KEY-----  
              <private key contents>
-----END ENCRYPTED PRIVATE KEY-----
```

El siguiente ejemplo muestra el contenido de un secreto para la autenticación de mTLS mediante una clave privada cifrada. Para una clave privada cifrada, incluya la contraseña de la clave privada en el secreto.

```
{"privateKeyPassword":"testpassword",
"certificate":"-----BEGIN CERTIFICATE-----
MIIE5DCCAsygAwIBAgIRAPJdwaFaNRrytHBto0j5BA0wDQYJKoZIhvcNAQELBQAw
...
j0Lh4/+1HfgyE2KlmII36dg4IMzNjAFEBZiCRoPimO40s1cRqtFHXoal0QQbIlxk
cmUuiAii9R0=
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIFgjCCA2qgAwIBAgIQdjNZd6uFf9hbNC5RdfmHrzANBgkqhkiG9w0BAQsFADBb
...
rQoiowbbk5wXCheYSANQIfTZ6weQTgiCHCCbuuMKNVS95FkXm0vqVD/YpXKwA/no
c8PH3PSoAaRwMMgOSA2ALJvbRz8mpg==
-----END CERTIFICATE-----",
"privateKey":"-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFKzBVBgkqhkiG9w0BBQ0wSDAnBgkqhkiG9w0BBQwwGgQUiAFcK5hT/X7Kjmgp
...
QrSekqF+kWzmB6nAfSzgO9IaoAaytLvNgGTckWeUkWn/V0Ck+LdGUXzAC4RxZnoQ
zp2mwJn2NYB7AZ7+imp0azDZb+8YG2aUCiyqb6PnnA==
-----END ENCRYPTED PRIVATE KEY-----"
}
```

## Configuración del secreto de certificado de entidad de certificación raíz del servidor
<a name="smaa-auth-ca-cert"></a>

Cree este secreto si sus agentes de Kafka utilizan cifrado TLS con certificados firmados por una entidad de certificación privada. Puede utilizar el cifrado TLS para autenticación VPC, SASL/SCRAM, SASL/PLAIN o mTLS.

El secreto de certificado de entidad de certificación raíz del servidor requiere un campo que contenga el certificado de entidad de certificación raíz del agente de Kafka en formato PEM. La estructura del secreto se muestra en el ejemplo siguiente.

```
{"certificate":"-----BEGIN CERTIFICATE-----
MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dG...
-----END CERTIFICATE-----"
}
```

# Creación de una asignación de orígenes de eventos de Lambda para un origen de eventos de Apache Kafka autoadministrado
<a name="kafka-esm-create"></a>

Para crear una asignación de orígenes de eventos, puede usar la consola de Lambda, la [AWS Command Line Interface (CLI)](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) o un [AWS SDK](https://aws.amazon.com/getting-started/tools-sdks/).

Los siguientes pasos de la consola agregan un clúster de Apache Kafka autoadministrado como desencadenador para su función de Lambda. Internamente, esto crea un recurso de asignación de orígenes de eventos.

## Requisitos previos
<a name="kafka-esm-prereqs"></a>
+ Un clúster de Apache Kafka autoadministrado. Lambda es compatible con Apache Kafka 0.10.1.0 y versiones posteriores.
+ Un [rol de ejecución](lambda-intro-execution-role.md) con permiso para acceder a los recursos de AWS que utiliza el clúster de Kafka autoadministrado.

## Agregar un clúster de Kafka autoadministrado (consola)
<a name="kafka-esm-console"></a>

Siga estos pasos para agregar su clúster Apache Kafka autoadministrado y un tema Kafka como desencadenador de su función de Lambda.

**Para agregar un desencadenador de Apache Kafka a su función de Lambda (consola)**

1. .Abra la página de [Functions (Funciones)](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de su función de Lambda.

1. En **Descripción general de la función**, elija **Agregar desencadenador**.

1. En **Configuración del desencadenador**, haga lo siguiente:

   1. Elija el tipo de desencadenador **Apache Kafka**.

   1. Para los **servidores de Bootstrap**, ingrese la dirección de host y par de puertos de un broker de Kafka en su clúster y, a continuación, elija **Add (Agregar)**. Repita para cada broker de Kafka en el clúster.

   1. Para el **nombre del tema**, escriba el nombre del tema Kafka utilizado para almacenar registros en el clúster.

   1. Si configura el modo aprovisionado, ingrese un valor para **Sondeadores de eventos mínimos**, un valor para **Sondeadores de eventos máximos** y un valor opcional para PollerGroupName para especificar la agrupación de varias ESM dentro de la misma VPC de origen de eventos.

   1. (Opcional) Para **Tamaño del lote**, introduzca el número máximo de registros que se recibirán en un solo lote.

   1. Para el **periodo de lotes**, ingrese la cantidad máxima de segundos que Lambda emplea a fin de recopilar registros antes de invocar la función.

   1. (Opcional) Para el **ID del grupo de consumidores**, ingrese el ID de un grupo de consumidores de Kafka al que unirse.

   1. (Opcional) En **Posición inicial**, elija **Última** para empezar a leer el flujo desde el registro más reciente, **Horizonte de supresión** para comenzar por el registro más antiguo disponible o **En la marca de tiempo** para especificar una marca de tiempo desde la cual comenzar a leer.

   1. (Opcional) Para **VPC**, elija Amazon VPC para su clúster de Kafka. A continuación, elija **VPC subnets** (Subredes de VPC) y **VPC security groups** (Grupos de seguridad de VPC).

      Esta configuración es obligatoria si solo los usuarios de la VPC acceden a los agentes.

      

   1. (Opcional) Para **Authentication** (Autenticación), elija **Add** (Agregar) y, a continuación, haga lo siguiente:

      1. Elija el protocolo de acceso o autenticación de los agentes de Kafka en su clúster.
         + Si su agente de Kafka utiliza autenticación SASL/PLAIN, elija **BASIC\$1AUTH**.
         + Si su agente utiliza autenticación de SASL/SCRAM, elija uno de los protocolos de **SASL\$1SCRAM**.
         + Si configura la autenticación de mTLS, elija el protocolo **CLIENT\$1CERTIFICATE\$1TLS\$1AUTH**.

      1. Para la autenticación de SASL/SCRAM o mTLS, elija la clave secreta de Secrets Manager que contiene las credenciales del clúster de Kafka.

   1. (Opcional) Para **Encryption** (Cifrado), elija el secreto de Secrets Manager que contiene el certificado de entidad de certificación raíz que los agentes de Kafka utilizan para el cifrado con TLS, si los agentes de Kafka utilizan certificados firmados por una entidad de certificación privada.

      Esta configuración se aplica al cifrado con TLS para SASL/SCRAM o SASL/PLAIN y a la autenticación con mTLS.

   1. Para crear el desencadenador en un estado deshabilitado para la prueba (recomendado), desactive **Activar desencadenador**. O bien, para habilitar el desencadenador de inmediato, seleccione**Activar desencadenador**.

1. Para crear el desencadenador, elija **Add** (Añadir).

## Agregar un clúster Kafka autoadministrado (AWS CLI)
<a name="kafka-esm-cli"></a>

Utilice los siguientes AWS CLI comandos de ejemplo para crear y ver un desencadenador Apache Kafka autoadminstrado para su función de Lambda.

### Uso de SASL/SCRAM
<a name="kafka-esm-cli-create"></a>

Si los usuarios de Kafka acceden a los agentes de Kafka a través de Internet, especifique el secreto de Secrets Manager que creó para la autenticación con SASL/SCRAM. En el siguiente ejemplo se utiliza el comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) de la AWS CLI para asignar una función de Lambda llamada `my-kafka-function` a un tema de Kafka llamado `AWSKafkaTopic`.

```
aws lambda create-event-source-mapping \ 
  --topics AWSKafkaTopic \
  --source-access-configuration Type=SASL_SCRAM_512_AUTH,URI=arn:aws:secretsmanager:us-east-1:111122223333:secret:MyBrokerSecretName \
  --function-name arn:aws:lambda:us-east-1:111122223333:function:my-kafka-function \
  --self-managed-event-source '{"Endpoints":{"KAFKA_BOOTSTRAP_SERVERS":["abc3.xyz.com:9092", "abc2.xyz.com:9092"]}}'
```

### Uso de una VPC
<a name="kafka-esm-cli-create-vpc"></a>

Si solo los usuarios de Kafka de su VPC acceden a sus agentes de Kafka, debe especificar su VPC, subredes y grupo de seguridad de VPC. En el siguiente ejemplo se utiliza el comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) de la AWS CLI para asignar una función de Lambda llamada `my-kafka-function` a un tema de Kafka llamado `AWSKafkaTopic`.

```
aws lambda create-event-source-mapping \ 
  --topics AWSKafkaTopic \
  --source-access-configuration '[{"Type": "VPC_SUBNET", "URI": "subnet:subnet-0011001100"}, {"Type": "VPC_SUBNET", "URI": "subnet:subnet-0022002200"}, {"Type": "VPC_SECURITY_GROUP", "URI": "security_group:sg-0123456789"}]' \
  --function-name arn:aws:lambda:us-east-1:111122223333:function:my-kafka-function \
  --self-managed-event-source '{"Endpoints":{"KAFKA_BOOTSTRAP_SERVERS":["abc3.xyz.com:9092", "abc2.xyz.com:9092"]}}'
```

### Visualización del estado mediante la AWS CLI
<a name="kafka-esm-cli-view"></a>

En el siguiente ejemplo se utiliza el comando [get-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-event-source-mapping.html) de la AWS CLI para describir el estado de la asignación de orígenes de eventos que ha creado.

```
aws lambda get-event-source-mapping
              --uuid dh38738e-992b-343a-1077-3478934hjkfd7
```

# Todos los parámetros de configuración de orígenes de eventos de Apache Kafka autoadministrado en Lambda
<a name="kafka-esm-parameters"></a>

Todos los tipos de origen de eventos Lambda comparten las mismas operaciones [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) y [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) de la API. Sin embargo, solo algunos de los parámetros se aplican a Apache Kafka, como se muestra en la siguiente tabla.


| Parámetro | Obligatorio | Predeterminado | Notas | 
| --- | --- | --- | --- | 
|  BatchSize  |  N  |  100  |  Máximo: 10 000  | 
|  DestinationConfig  |  N  |  N/A  |  [Captura de lotes descartados para orígenes de eventos de Amazon MSK y Apache Kafka autoadministrado](kafka-on-failure.md)  | 
|  Habilitado  |  N  |  True  |  | 
|  FilterCriteria  |  N  |  N/A  |  [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md)  | 
|  FunctionName  |  S  |  N/A  |    | 
|  KMSKeyArn  |  N  |  N/A  |  [Cifrado de los criterios de filtro](invocation-eventfiltering.md#filter-criteria-encryption)  | 
|  MaximumBatchingWindowInSeconds  |  N  |  500 ms  |  [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching)  | 
|  ProvisionedPollersConfig  |  N  |  `MinimumPollers`: si no se especifica, el valor predeterminado es 1. `MaximumPollers`: si no se especifica, el valor predeterminado es 200. `PollerGroupName`: N/A  |  [Modo aprovisionado](kafka-scaling-modes.md#kafka-provisioned-mode)  | 
|  SelfManagedEventSource  |  S  | N/A |  Lista de agentes de Kafka. Solo se puede establecer en Crear  | 
|  SelfManagedKafkaEventSourceConfig  |  N  |  Contiene el campo ConsumerGroupId, que se establece de forma predeterminada en un valor único.  |  Solo se puede establecer en Crear  | 
|  SourceAccessConfigurations  |  N  |  Sin credenciales  |  Información de VPC o credenciales de autenticación para el clúster   Para SASL\$1PLAIN, establezca en BASIC\$1AUTH  | 
|  StartingPosition  |  S  |  N/A  |  AT\$1TIMESTAMP, TRIM\$1HORIZON o LATEST Solo se puede establecer en Crear  | 
|  StartingPositionTimestamp  |  N  |  N/A  |  Obligatorio si StartingPosition se establece en AT\$1TIMESTAMP  | 
|  Etiquetas  |  N  |  N/A  |  [Uso de etiquetas en asignaciones de orígenes de eventos](tags-esm.md)  | 
|  Temas  |  S  |  N/A  |  Nombre del tema Solo se puede establecer en Crear  | 

**nota**  
Cuando especifica un `PollerGroupName`, varias ESM de la misma Amazon VPC pueden compartir la capacidad de la unidad de sondeador de eventos (EPU). Puede utilizar esta opción para optimizar los costos del modo aprovisionado para sus ESM. Requisitos para la agrupación de ESM:  
Las ESM deben estar dentro de la misma Amazon VPC.
Máximo de 100 ESM por grupo de sondeadores
El número máximo total de sondeadores en todos las ESM de un grupo no puede superar los 2000.
Puede actualizar el `PollerGroupName` para mover una ESM a un grupo diferente o eliminar una ESM de un grupo; para ello, configure una string vacía («») en `PollerGroupName`:

# Modos de escalado del sondeo de eventos de Apache Kafka en Lambda
<a name="kafka-scaling-modes"></a>

Puede elegir entre dos modos de escalado del sondeo de eventos para las asignaciones de orígenes de eventos de Amazon MSK y Apache Kafka autoadministrado:
+ [Modo bajo demanda (predeterminado)](#kafka-default-mode)
+ [Modo aprovisionado](#kafka-provisioned-mode)

## Modo bajo demanda (predeterminado)
<a name="kafka-default-mode"></a>

Cuando crea inicialmente un origen de eventos de Kafka, Lambda asigna una cantidad predeterminada de sondeos de eventos para procesar todas las particiones en el tema de Kafka. Lambda reduce o escala verticalmente de forma automática el número de [sondeos de eventos](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode) en función de la carga de mensajes.

En intervalos de un minuto, Lambda evalúa el retraso de inicio de todas las particiones del tema. Si el retraso es demasiado alto, la partición recibe mensajes más rápido de lo que Lambda puede procesarlos. Si es necesario, Lambda agrega o elimina a los sondeos de eventos del tema. Este proceso de escalado automático para agregar o eliminar sondeos de eventos se produce dentro de los tres minutos posteriores a la evaluación.

Si su función de Lambda de destino está limitada, Lambda reduce la cantidad de sondeos de eventos. Esta acción reduce la carga de trabajo de la función al reducir el número de mensajes que los sondeos de eventos pueden recuperar y enviar a la función.

## Modo aprovisionado
<a name="kafka-provisioned-mode"></a>

Para las cargas de trabajo en las que necesite afinar el rendimiento de su asignación de orígenes de eventos, puede utilizar el modo aprovisionado. En el modo aprovisionado, usted define los límites mínimos y máximos para la cantidad de sondeos de eventos aprovisionados. Estos sondeos de eventos aprovisionados están dedicados a la asignación de orígenes de eventos y pueden gestionar los picos de mensajes inesperados mediante un ajuste de escalado automático adaptable. Recomendamos que utilice el modo aprovisionado para las cargas de trabajo de Kafka que tengan requisitos de rendimiento estrictos.

En Lambda, un sondeador de eventos es una unidad de cómputo con capacidades de rendimiento que varían según el tipo de origen del evento. En el caso de Amazon MSK y Apache Kafka autoadministrado, cada sondeador de eventos puede gestionar hasta 5 MB/s de rendimiento o hasta 5 invocaciones simultáneas. Por ejemplo, si el origen de eventos produce una carga útil media de 1 MB y la duración media de la función es de 1 segundo, un único sondeador de eventos de Kafka puede admitir un rendimiento de 5 MB/s y 5 invocaciones simultáneas de Lambda (si se supone que no haya transformación de la carga útil). En el caso de Amazon SQS, cada sondeador de eventos puede gestionar hasta 1 MB/s de rendimiento o hasta 10 invocaciones simultáneas. El uso del modo aprovisionado incurre en costos adicionales en función del uso de sondeadores de eventos. Para obtener más información sobre precios, consulta [precios de AWS Lambda](https://aws.amazon.com/lambda/pricing/).

**nota**  
Al utilizar el modo aprovisionado, no es necesario crear puntos de conexión de VPC de PrivateLink de AWS ni conceder los permisos asociados como parte de la configuración de la red.

En el modo aprovisionado, el rango de valores aceptados para el número mínimo de sondeos de eventos (`MinimumPollers`) oscila entre 1 y 200, inclusive. El rango de valores aceptados para el número máximo de sondeos de eventos (`MaximumPollers`) está comprendido entre 1 y 2000, inclusive. `MaximumPollers` debe ser mayor o igual que `MinimumPollers`. Además, para mantener el procesamiento ordenado dentro de las particiones, Lambda limita el número de `MaximumPollers` al número de particiones del tema.

Para obtener más información sobre cómo elegir los valores de sondeos de eventos mínimos y máximos adecuados, consulte [Prácticas recomendadas](#kafka-provisioned-mode-bp).

Puede configurar el modo aprovisionado para la asignación de orígenes de eventos de Kafka mediante la consola o la API de Lambda.

**Cómo configurar el modo aprovisionado para una asignación de orígenes de eventos existente (consola)**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija la función para la asignación de orígenes de eventos para la que desee configurar el modo aprovisionado.

1. Elija **Configuración** y, a continuación, seleccione **Desencadenadores**.

1. Elija la asignación de orígenes de eventos para la que desee configurar el modo aprovisionado y, a continuación, seleccione **Editar**.

1. En el **modo aprovisionado**, seleccione **Configurar**.
   + En **Número mínimo de sondeos de eventos**, introduzca un valor entre 1 y 200. Si no especifica un valor, Lambda asigna el valor predeterminado de 1.
   + En **Número máximo de sondeos de eventos**, introduzca un valor entre 1 y 2000. Este valor debe ser mayor o igual que su valor para **Número mínimo de sondeos de eventos**. Si no especifica un valor, Lambda asigna el valor predeterminado de 200.

1. Seleccione **Save**.

Puede configurar el modo aprovisionado por programación mediante el objeto [ProvisionedPollerConfig](https://docs.aws.amazon.com/lambda/latest/api/API_ProvisionedPollerConfig.html) de su [EventSourceMappingConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_EventSourceMappingConfiguration.html). Por ejemplo, el siguiente comando de la CLI [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) configura un valor `MinimumPollers` de 5 y un valor `MaximumPollers` de 100.

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --provisioned-poller-config '{"MinimumPollers": 5, "MaximumPollers": 100}'
```

Tras configurar el modo aprovisionado, puede observar el uso de los sondeos de eventos para su carga de trabajo supervisando la métrica `ProvisionedPollers`. Para obtener más información, consulte [Métricas de asignación de orígenes de eventos](monitoring-metrics-types.md#event-source-mapping-metrics).

Para deshabilitar el modo aprovisionado y volver al modo predeterminado (bajo demanda), puede usar el siguiente comando de la CLI [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html):

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --provisioned-poller-config '{}'
```

## Gestión avanzada de errores y características de rendimiento
<a name="services-kafka-advanced-features"></a>

En el caso de las asignaciones de orígenes de eventos de Kafka con el modo aprovisionado habilitado, puede configurar características adicionales para mejorar la gestión de errores y el rendimiento:
+ [Configuraciones de reintentos](kafka-retry-configurations.md): controle la forma en que Lambda gestiona los registros fallidos con el máximo de reintentos, los límites de antigüedad de los registros, la división por lotes y las respuestas por lotes parciales.
+ [Destinos en caso de error de Kafka](kafka-on-failure-destination.md): envíe los registros fallidos a un tema de Kafka para su posterior procesamiento o análisis.

## Prácticas recomendadas y consideraciones al usar el modo aprovisionado
<a name="kafka-provisioned-mode-bp"></a>

La configuración óptima de los sondeos de eventos mínimos y máximos para la asignación de orígenes de eventos depende de los requisitos de rendimiento de la aplicación. Recomendamos que lea los sondeos de eventos mínimos predeterminados para establecer una línea de base del perfil de rendimiento. Ajuste la configuración en función de los patrones de procesamiento de mensajes observados y del perfil de rendimiento deseado.

En el caso de cargas de trabajo con un tráfico intenso y necesidades de rendimiento estrictas, aumente el número mínimo de sondeos de eventos para administrar los picos repentinos de mensajes. Para determinar los sondeos de eventos mínimos necesarios, tenga en cuenta los mensajes de su carga de trabajo por segundo y el tamaño medio de la carga útil y utilice la capacidad de rendimiento de un único sondeo de eventos (hasta 5 MBps) como referencia.

Para mantener el procesamiento ordenado dentro de una partición, Lambda limita el número máximo de sondeos de eventos al número de particiones del tema. Además, el número máximo de sondeos de eventos a los que se puede escalar la asignación de orígenes de eventos depende de la configuración de simultaneidad de la función.

Al activar el modo aprovisionado, actualiza la configuración de la red para eliminar los puntos de conexión de VPC AWS PrivateLink y los permisos asociados.

## Optimización de costos para el modo aprovisionado
<a name="kafka-cost-optimization"></a>

### Precios del modo aprovisionado
<a name="kafka-provisioned-pricing"></a>

El modo aprovisionado se cobra en función del mínimo de sondeadores de eventos aprovisionados y de los sondeadores de eventos consumidos durante el escalado automático. Los cargos se calculan mediante una unidad de facturación denominada unidad de sondeador de eventos (EPU). Usted paga por la cantidad y la duración de las EPU utilizadas, medidas en horas-por-unidad-de-sondeador-de-eventos. Puede utilizar el modo aprovisionado con una sola ESM para aplicaciones sensibles al rendimiento o puede agrupar varias ESM en la misma VPC para compartir la capacidad y los costos de la EPU. Analizaremos en profundidad dos capacidades que lo ayudarán a optimizar los costos del modo aprovisionado. Para obtener más información sobre los precios, consulte [Precios de AWS Lambda](https://aws.amazon.com/lambda/pricing/).

### Utilización mejorada de la EPU
<a name="kafka-enhanced-epu-utilization"></a>

Cada EPU admite una capacidad de rendimiento de hasta 20 MB/s para el sondeo de eventos y admite un valor predeterminado de 10 sondeadores de eventos. Cuando crea un modo aprovisionado para la ESM de Kafka mediante el establecimiento de un número mínimo y máximo de sondeadores, se utiliza un número mínimo de sondeadores para aprovisionar las EPU, según el valor predeterminado de 10 sondeadores de eventos por EPU. Sin embargo, cada sondeador de eventos se puede escalar de forma independiente para admitir una capacidad de rendimiento de hasta 5 MB/s, lo que puede requerir una menor densidad de sondeadores de eventos en una EPU específica y desencadenar el escalado de las EPU. El número de sondeadores de eventos asignados a una EPU depende de la capacidad de cómputo que consuma cada sondeador de eventos. Este enfoque de utilización mejorada de la EPU permite que los sondeadores de eventos con diferentes requisitos de rendimiento utilicen la capacidad de la EPU de forma eficaz, lo que reduce los costos de todas las ESM.

### Agrupación de ESM
<a name="kafka-esm-grouping-cost"></a>

Para optimizar aún más los costos del modo aprovisionado, puede agrupar varias ESM de Kafka para compartir la capacidad de la EPU. Con la agrupación de ESM y el uso mejorado de la EPU, puede reducir los costos del modo aprovisionado hasta un 90 % para las cargas de trabajo de bajo rendimiento en comparación con el uso de un solo modo de ESM. Todas las ESM que requieran una capacidad inferior a 1 EPU se beneficiarán de la agrupación de ESM. Estas ESM suelen requerir unos pocos sondeadores de eventos como mínimo para satisfacer sus necesidades de rendimiento. Esta capacidad le permitirá adoptar el modo aprovisionado para todas sus cargas de trabajo de Kafka y beneficiarse de funciones como la validación de esquemas, el filtrado de eventos de Avro/Protobuf, las invocaciones de baja latencia y la mejora de la gestión de errores, que solo están disponibles en el modo aprovisionado.

Cuando configura el parámetro `PollerGroupName` con el mismo valor para varias ESM dentro de la misma Amazon VPC, esas ESM comparten los recursos de la EPU en lugar de que cada una requiera una capacidad de EPU dedicada. Puede agrupar hasta 100 ESM por grupo de sondeadores y, en total, el número máximo de sondeadores de todas las ESM de un grupo no puede superar las 2000.

#### Cómo configurar la agrupación de ESM (consola)
<a name="kafka-esm-grouping-console-cost"></a>

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija su función.

1. Elija **Configuración** y, a continuación, seleccione **Desencadenadores**.

1. Cuando crea una nueva asignación de orígenes de eventos de Kafka o edita una existente, seleccione **Configurar** en **Modo aprovisionado**.

1. En **Número mínimo de sondeos de eventos**, introduzca un valor entre 1 y 200.

1. En **Número máximo de sondeos de eventos**, introduzca un valor entre 1 y 2000.

1. En **Nombre de grupo de sondeadores**, escriba un identificador del grupo. Use el mismo nombre para las demás ESM que desee agrupar.

1. Seleccione **Save**.

#### Cómo configurar la agrupación de ESM (CLI de AWS)
<a name="kafka-esm-grouping-cli-cost"></a>

Con el siguiente ejemplo se crea una ESM con un grupo de sondeadores denominado `production-app-group`:

```
aws lambda create-event-source-mapping \
  --function-name myFunction1 \
  --event-source-arn arn:aws:kafka:us-east-1:123456789012:cluster/MyCluster/abcd1234 \
  --topics topic1 \
  --starting-position LATEST \
  --provisioned-poller-config '{
    "MinimumPollers": 1, 
    "MaximumPollers": 10, 
    "PollerGroupName": "production-app-group"
  }'
```

Para añadir otra ESM al mismo grupo (que comparta la capacidad de la EPU), utilice el mismo PollerGroupName:

```
aws lambda create-event-source-mapping \
  --function-name myFunction2 \
  --event-source-arn arn:aws:kafka:us-east-1:123456789012:cluster/MyCluster/abcd1234 \
  --topics topic2 \
  --starting-position LATEST \
  --provisioned-poller-config '{
    "MinimumPollers": 1, 
    "MaximumPollers": 10, 
    "PollerGroupName": "production-app-group"
  }'
```

**nota**  
Puede actualizar el `PollerGroupName` para mover una ESM a un grupo diferente o eliminar una ESM de un grupo; para ello, pase una string vacía («») en `PollerGroupName`:

```
# Move ESM to a different group
aws lambda update-event-source-mapping \
  --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
  --provisioned-poller-config '{
    "MinimumPollers": 1, 
    "MaximumPollers": 10, 
    "PollerGroupName": "new-group-name"
  }'

# Remove ESM from group (use dedicated resources)
aws lambda update-event-source-mapping \
  --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
  --provisioned-poller-config '{
    "MinimumPollers": 1, 
    "MaximumPollers": 10, 
    "PollerGroupName": ""
  }'
```

#### Consideraciones relativas a la estrategia de agrupación
<a name="kafka-grouping-strategy-considerations"></a>
+ **Límite de aplicación**: agrupe las ESM que pertenecen a las mismas aplicaciones o servicios para una mejor asignación y administración de los costos. Considere utilizar convenciones de nomenclatura como `app-name-environment` (p. ej.,`order-processor-prod`).
+ **Patrón de tráfico**: evite agrupar las ESM con un rendimiento elevado y un patrón de tráfico intenso, ya que esto podría provocar una escasez de recursos.
+ **Radio de acción**: considere el impacto en caso de que la infraestructura compartida presente problemas. Todas las ESM del mismo grupo se ven afectadas por las limitaciones de los recursos compartidos. Para las cargas de trabajo de misión crítica, es posible que desee utilizar grupos separados o ESM dedicadas.

#### Ejemplo de optimización de costos
<a name="kafka-cost-optimization-example"></a>

Considere un escenario en el que tiene 10 ESM, cada una configurada con un sondeador de eventos y un rendimiento inferior a 2 MB/s:

**Sin agrupamiento:**
+ Cada ESM requiere su propia EPU.
+ Total de EPU necesarias: 10
+ Costo por EPU: 0,185 USD/hora en el Este de EE. UU. (Norte de Virginia)
+ Costo mensual de la EPU (720 horas): 10 × 720 × 0,185 USD = 1332 USD

**Con agrupamiento:**
+ Las 10 ESM comparten la capacidad de la EPU.
+ 10 sondeadores de eventos caben en 1 EPU (con el nuevo soporte para 10 sondeadores nuevo por EPU)
+ Total de EPU necesarias: 1
+ Costo mensual de la EPU (720 horas): 1 × 720 × 0,185 USD = 133,20 USD
+ **Ahorro de costos: 90 %** (ahorro de 1198,80 USD al mes)

# Posiciones iniciales de flujos y sondeo de Apache Kafka en Lambda
<a name="kafka-starting-positions"></a>

El [parámetro StartingPosition](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-StartingPosition) indica a Lambda cuándo debe empezar a leer los mensajes del flujo de Amazon MSK o de Apache Kafka autoadministrado. Existen tres opciones entre las que elegir:
+ **Más reciente**: Lambda comienza a leer justo después del registro más reciente del tema de Kafka.
+ **Recortar horizonte**: Lambda comienza a leer a partir del último registro sin recortar en el tema de Kafka. Este también es el registro más antiguo del tema.
+ **En la marca de tiempo**: Lambda comienza a leer a partir de una posición definida por una marca de tiempo, en segundos de tiempo Unix. Use el [parámetro StartingPositionTimestamp](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-StartingPositionTimestamp) para especificar la marca de tiempo.

El sondeo de flujos durante la creación y la actualización de la asignación de orígenes de eventos es, en última instancia, coherente:
+ Durante la creación de la asignación de orígenes de eventos, es posible que se demore varios minutos en iniciar el sondeo de los eventos del flujo.
+ Durante las actualizaciones de la asignación de orígenes de eventos, es posible que se demore hasta 90 segundos en detener y reiniciar el sondeo de los eventos del flujo.

Este comportamiento significa que, si especifica `LATEST` como posición inicial del flujo, la asignación de orígenes de eventos podría omitir eventos durante una creación o actualización. Para asegurarse de que no se omita ningún evento, especifique `TRIM_HORIZON` o `AT_TIMESTAMP`.

# ID del grupo de consumidores personalizable en Lambda
<a name="kafka-consumer-group-id"></a>

Al configurar Amazon MSK o Apache Kafka autogesionado como origen de eventos, puede especificar un ID de [grupo de consumidores](https://developer.confluent.io/learn-more/kafka-on-the-go/consumer-groups/). Este ID de grupo de consumidores es un identificador existente para el grupo de consumidores de Kafka al que desea que se una la función de Lambda. Puede utilizar esta característica para migrar sin problemas cualquier configuración de procesamiento de registro de Kafka en curso de otros consumidores a Lambda.

Kafka distribuye mensajes entre todos los consumidores de un grupo de consumidores. Si especifica un ID de grupo de consumidores que tenga otros consumidores activos, Lambda recibirá solo una parte de los mensajes del tema de Kafka. Si desea que Lambda gestione todos los mensajes del tema, desactive los demás consumidores de ese grupo de consumidores.

Además, si especifica un ID de grupo de consumidores y Kafka encuentra un grupo de consumidores existente válido con el mismo ID, Lambda ignora el parámetro [StartingPosition](kafka-starting-positions.md) para la asignación de orígenes de eventos. En cambio, Lambda comienza a procesar los registros de acuerdo con la compensación comprometida del grupo de consumidores. Si especifica un ID de grupo de consumidores y Kafka no puede encontrar un grupo de consumidores existente, Lambda configura el origen de eventos con el especificado `StartingPosition`.

El ID del grupo de consumidores que especifique debe ser único entre todos los orígenes de eventos de Kafka. Tras crear una asignación de orígenes de eventos de Kafka con el ID de grupo de consumidores especificado, no puede actualizar este valor.

# Filtrado de eventos de Amazon MSK y de fuentes de eventos autoadministrados de Apache Kafka
<a name="kafka-filtering"></a>

Puede utilizar el filtrado de eventos para controlar qué registros de un flujo o una cola envía Lambda a su función. Para obtener información general sobre cómo funciona el filtrado de eventos, consulte [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md).

**nota**  
Las asignaciones de orígenes de eventos de Amazon MSK y Apache Kafka autogestionadas solo admiten el filtrado en la clave `value`.

**Topics**
+ [

## Conceptos básicos del filtrado de eventos de Kafka
](#filtering-kafka)

## Conceptos básicos del filtrado de eventos de Kafka
<a name="filtering-kafka"></a>

Supongamos que un productor escribe mensajes a un tema de su clúster de Kafka, ya sea en formato JSON válido o como cadenas simples. Un registro de ejemplo tendría el siguiente aspecto, con el mensaje convertido en una cadena codificada en Base64 en el campo `value`.

```
{
    "mytopic-0":[
        {
            "topic":"mytopic",
            "partition":0,
            "offset":15,
            "timestamp":1545084650987,
            "timestampType":"CREATE_TIME",
            "value":"SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==",
            "headers":[]
        }
    ]
}
```

Supongamos que su productor de Apache Kafka escribe mensajes a su tema en el siguiente formato JSON.

```
{
    "device_ID": "AB1234",
    "session":{
        "start_time": "yyyy-mm-ddThh:mm:ss",
        "duration": 162
    }
}
```

Puede utilizar la clave `value` para filtrar registros. Supongamos que desea filtrar solo los registros en los que `device_ID` comience con las letras AB. El objeto `FilterCriteria` sería el siguiente.

```
{
    "Filters": [
        {
            "Pattern": "{ \"value\" : { \"device_ID\" : [ { \"prefix\": \"AB\" } ] } }"
        }
    ]
}
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado.

```
{
    "value": {
        "device_ID": [ { "prefix": "AB" } ]
      }
}
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "value" : { "device_ID" : [ { "prefix":  "AB" } ] } }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:kafka:us-east-2:123456789012:cluster/my-cluster/b-8ac7cc01-5898-482d-be2f-a6b596050ea8 \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"value\" : { \"device_ID\" : [ { \"prefix\":  \"AB\" } ] } }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"value\" : { \"device_ID\" : [ { \"prefix\":  \"AB\" } ] } }"}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "value" : { "device_ID" : [ { "prefix":  "AB" } ] } }'
```

------

Con Kafka, también puede filtrar los registros en los que el mensaje sea una cadena simple. Supongamos que desea ignorar los mensajes en los que la cadena es “error”. El objeto `FilterCriteria` tendría el siguiente aspecto.

```
{
    "Filters": [
        {
            "Pattern": "{ \"value\" : [ { \"anything-but\": [ \"error\" ] } ] }"
        }
    ]
}
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado.

```
{
    "value": [
        {
        "anything-but": [ "error" ]
        }
    ]
}
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "value" : [ { "anything-but": [ "error" ] } ] }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:kafka:us-east-2:123456789012:cluster/my-cluster/b-8ac7cc01-5898-482d-be2f-a6b596050ea8 \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"value\" : [ { \"anything-but\": [ \"error\" ] } ] }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"value\" : [ { \"anything-but\": [ \"error\" ] } ] }"}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "value" : [ { "anything-but": [ "error" ] } ] }'
```

------

Los mensajes de Kafka deben ser cadenas codificadas en UTF-8, cadenas simples o en formato JSON. Esto se debe a que Lambda decodifica las matrices de bytes de Kafka en UTF-8 antes de aplicar los criterios de filtrado. Si los mensajes utilizan otra codificación, como UTF-16 o ASCII, o el formato del mensaje no coincide con el formato de `FilterCriteria`, Lambda solo procesa los filtros de metadatos. En la siguiente tabla se resume el comportamiento específico:


| Formato del mensaje entrante | Formato del patrón de filtro para las propiedades del mensaje | Acción resultante | 
| --- | --- | --- | 
|  Cadena sin formato  |  Cadena sin formato  |  Lambda filtra en función de los criterios de filtro.  | 
|  Cadena sin formato  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  Cadena sin formato  |  JSON válido  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  JSON válido  |  Cadena sin formato  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  JSON válido  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  JSON válido  |  JSON válido  |  Lambda filtra en función de los criterios de filtro.  | 
|  Cadena no codificada con UTF-8  |  JSON, cadena sin formato o sin patrón  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 

# Uso de registros de esquemas con orígenes de eventos de Kafka en Lambda
<a name="services-consume-kafka-events"></a>

 Los registros de esquemas ayudan a definir y administrar los esquemas de flujo de datos. Un esquema define la estructura y el formato de un registro de datos. En el contexto de las asignaciones de orígenes de eventos de Kafka, puede configurar un registro de esquemas para validar la estructura y el formato de los mensajes de Kafka comparándolos con esquemas predefinidos antes de que lleguen a su función de Lambda. Esto agrega una capa de gobernanza de datos a su aplicación y le permite administrar los formatos de datos de forma eficiente, garantizar el cumplimiento del esquema y optimizar los costos mediante el filtrado de eventos. 

 Esta característica funciona con todos los lenguajes de programación, pero debe tener en cuenta estos puntos importantes: 
+ Powertools para Lambda proporciona soporte específico para Java, Python y TypeScript, mantiene la coherencia con los patrones de desarrollo de Kafka existentes y permite el acceso directo a los objetos de negocio sin necesidad de un código de deserialización personalizado.
+ Esta característica solo está disponible para asignaciones de orígenes de eventos con modo aprovisionado. El registro de esquemas no admite asignaciones de orígenes de eventos en el modo bajo demanda. Si utiliza el modo aprovisionado y tiene un registro de esquemas configurado, no podrá cambiar al modo bajo demanda a menos que elimine primero la configuración del registro de esquemas. Para obtener más información, consulte [Modo aprovisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode)
+ Solo puede configurar un registro de esquemas por asignación de orígenes de eventos (ESM). El uso de un registro de esquemas con los orígenes de eventos de Kafka puede aumentar el uso de la unidad Lambda Event Poller Unit (EPU), que es una dimensión de precios para el modo aprovisionado. 

**Topics**
+ [

## Opciones del registro de esquemas
](#services-consume-kafka-events-options)
+ [

## Cómo Lambda valida el esquema de los mensajes de Kafka
](#services-consume-kafka-events-how)
+ [

## Configuración de un registro de esquemas de Kafka
](#services-consume-kafka-events-config)
+ [

## Filtrado para Avro y Protobuf
](#services-consume-kafka-events-filtering)
+ [

## Formatos de carga útil y comportamiento de deserialización
](#services-consume-kafka-events-payload)
+ [

## Trabajar con datos deserializados en funciones de Lambda
](#services-consume-kafka-events-payload-examples)
+ [

## Métodos de autenticación para el registro de esquemas
](#services-consume-kafka-events-auth)
+ [

## Gestión de errores y solución de problemas relacionados con el registro de esquemas
](#services-consume-kafka-events-troubleshooting)

## Opciones del registro de esquemas
<a name="services-consume-kafka-events-options"></a>

 Lambda es compatible con las siguientes opciones de registro de esquemas: 
+ [AWS Glue Registro de esquemas](https://docs.aws.amazon.com/glue/latest/dg/schema-registry.html)
+ [Registro de esquemas de Confluent Cloud](https://docs.confluent.io/platform/current/schema-registry/index.html)
+ [Registro de esquemas de Confluent de administración automática](https://docs.confluent.io/platform/current/schema-registry/index.html)

 El registro de esquemas es compatible con la validación de mensajes en los siguientes formatos de datos: 
+ Apache Avro
+ Búferes de protocolo (Protobuf)
+ Esquema JSON (JSON-SE)

 Para usar un registro de esquemas, primero asegúrese de que la asignación de orígenes de eventos esté en modo aprovisionado. Cuando se utiliza un registro de esquemas, Lambda agrega metadatos sobre el esquema a la carga útil. Para obtener más información, consulte [Formatos de carga útil y comportamiento de deserialización](#services-consume-kafka-events-payload). 

## Cómo Lambda valida el esquema de los mensajes de Kafka
<a name="services-consume-kafka-events-how"></a>

 Al configurar un registro de esquemas, Lambda realiza los siguientes pasos para cada mensaje de Kafka: 

1. Lambda sondea el registro de Kafka de su clúster.

1. Lambda valida los atributos de los mensajes seleccionados en el registro en relación con un esquema específico en su registro de esquemas.
   + Si el esquema asociado al mensaje no se encuentra en el registro, Lambda envía el mensaje a un DLQ con el código de motivo `SCHEMA_NOT_FOUND`.

1. Lambda deserializa el mensaje de acuerdo con la configuración del registro de esquemas para validar el mensaje. Si está configurado el filtrado de eventos, Lambda lo realiza en función de los criterios de filtro configurados.
   + Si se produce un error en la deserialización, Lambda envía el mensaje a un DLQ con el código de motivo `DESERIALIZATION_ERROR`. Si no se configura ningún DLQ, Lambda descarta el mensaje.

1. Si el mensaje es validado por el registro del esquema y no se filtra según sus criterios de filtro, Lambda invoca su función con el mensaje.

 Esta característica está destinada a validar los mensajes que ya se han producido con clientes de Kafka integrados con un registro de esquemas. Recomendamos que configure sus productores de Kafka para que funcionen con el registro de esquemas a fin de crear mensajes con el formato adecuado. 

## Configuración de un registro de esquemas de Kafka
<a name="services-consume-kafka-events-config"></a>

 Los siguientes pasos de la consola añaden una configuración de registro del esquema de Kafka a la asignación de orígenes de eventos. 

**Cómo agregar una configuración de registro de esquema de Kafka a la asignación de orígenes de eventos (consola)**

1. Abra la [Página de función](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija **Configuración**.

1. Elija **Añadir desencadenador**.

1. Seleccione la asignación de orígenes de eventos de Kafka que desea configurar para un registro de esquemas y elija **Editar**.

1. En **Configuración del sondeo de eventos**, elija **Configurar registro de esquemas**. Su asignación de orígenes de eventos debe estar en modo aprovisionado para ver esta opción.

1. Para el **URI del registro de esquemas**, ingrese el ARN de su registro de esquemas de AWS Glue o la URL HTTPS de su registro de esquemas de Confluent Cloud o registro de esquemas de Confluent de administración automática.

1. Los siguientes pasos de configuración indican a Lambda cómo acceder al registro de esquemas. Para obtener más información, consulte [Métodos de autenticación para el registro de esquemas](#services-consume-kafka-events-auth).
   + En el **tipo de configuración de acceso**, elija el tipo de autenticación que Lambda utiliza para acceder al registro de esquemas.
   + En el **URI de configuración de acceso**, introduzca el ARN del secreto de Secrets Manager para autenticarse con el registro de esquemas, si corresponde. Asegúrese de que el rol de [ejecución de su función](with-msk-permissions.md) contenga los permisos correctos.

1. El campo **Cifrado** solo se aplica si el registro del esquema está firmado por una entidad de certificación (CA) privada o una entidad de certificación (CA) que no se encuentra en el almacén de confianza de Lambda. Si corresponde, proporcione la clave secreta que contiene el certificado de CA privado que utiliza el registro de esquemas para el cifrado TLS.

1. En **Formato de registro de eventos**, elija cómo desea que Lambda entregue los registros a su función después de la validación del esquema. Para obtener más información, consulte [Ejemplos de formato de carga útil](#services-consume-kafka-events-payload).
   + Si elige **JSON**, Lambda entrega los atributos que selecciona en el atributo de validación de esquema que aparece a continuación en formato JSON estándar. En el caso de los atributos que no seleccione, Lambda los entrega tal cual.
   + Si elige **SOURCE**, Lambda entrega los atributos que selecciona en el atributo de validación de esquema que aparece a continuación en formato original.

1. En **Atributo de validación de esquema**, seleccione los atributos de mensaje que desea que Lambda valide y deserialice mediante el registro de esquemas. Debe seleccionar al menos uno de los siguientes: **KEY** o **VALUE**. Si eligió JSON como formato de registro de eventos, Lambda también deserializa los atributos de mensaje seleccionados antes de enviarlos a su función. Para obtener más información, consulte [Formatos de carga útil y comportamiento de deserialización](#services-consume-kafka-events-payload).

1. Seleccione **Save**.

 También puede usar la API de Lambda para crear o actualizar la asignación de orígenes de eventos con una configuración de registro de esquemas. Los siguientes ejemplos muestran cómo configurar un registro de esquema de AWS Glue o de Confluent mediante el AWS CLI, que corresponde a las operaciones de la API de [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) y de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) en la *Referencia de la API de AWS Lambda* : 

**importante**  
Si está actualizando un campo de configuración del registro de esquemas mediante la API de AWS CLI o la API de `update-event-source-mapping`, debe actualizar todos los campos de la configuración del registro de esquemas.

------
#### [ Create Event Source Mapping ]

```
aws lambda create-event-source-mapping \
  --function-name my-schema-validator-function \
  --event-source-arn arn:aws:kafka:us-east-1:123456789012:cluster/my-cluster/a1b2c3d4-5678-90ab-cdef-11111EXAMPLE \
  --topics my-kafka-topic \
  --provisioned-poller-config MinimumPollers=1,MaximumPollers=1 \
  --amazon-managed-kafka-event-source-mapping '{
      "SchemaRegistryConfig" : {
          "SchemaRegistryURI": "https://abcd-ef123.us-west-2.aws.confluent.cloud",
          "AccessConfigs": [{
              "Type": "BASIC_AUTH", 
              "URI": "arn:aws:secretsmanager:us-east-1:123456789012:secret:secretName"
          }],
          "EventRecordFormat": "JSON",
          "SchemaValidationConfigs": [
          { 
              "Attribute": "KEY" 
          },
          { 
              "Attribute": "VALUE" 
          }]
      }
  }'
```

------
#### [ Update AWS Glue Schema Registry ]

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --amazon-managed-kafka-event-source-mapping '{
        "SchemaRegistryConfig" : {
            "SchemaRegistryURI": "arn:aws:glue:us-east-1:123456789012:registry/registryName",
            "EventRecordFormat": "JSON",
            "SchemaValidationConfigs": [
            { 
                "Attribute": "KEY" 
            },
            { 
                "Attribute": "VALUE" 
            }]
        }
    }'
```

------
#### [ Update Confluent Schema Registry with Authentication ]

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --amazon-managed-kafka-event-source-mapping '{
        "SchemaRegistryConfig" : {
            "SchemaRegistryURI": "https://abcd-ef123.us-west-2.aws.confluent.cloud",
            "AccessConfigs": [{
                "Type": "BASIC_AUTH", 
                "URI": "arn:aws:secretsmanager:us-east-1:123456789012:secret:secretName"
            }],
            "EventRecordFormat": "JSON",
            "SchemaValidationConfigs": [
            { 
                "Attribute": "KEY" 
            },
            { 
                "Attribute": "VALUE" 
            }]
        }
    }'
```

------
#### [ Update Confluent Schema Registry without Authentication ]

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --amazon-managed-kafka-event-source-mapping '{
        "SchemaRegistryConfig" : {
            "SchemaRegistryURI": "https://abcd-ef123.us-west-2.aws.confluent.cloud",
            "EventRecordFormat": "JSON",
            "SchemaValidationConfigs": [
            { 
                "Attribute": "KEY" 
            },
            { 
                "Attribute": "VALUE" 
            }]
        }
    }'
```

------
#### [ Remove Schema Registry Configuration ]

Para eliminar una configuración de registro de esquemas de la asignación de orígenes de eventos, puede usar el comando de CLI [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) en la *Referencia de la API de AWS Lambda * .

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --amazon-managed-kafka-event-source-mapping '{
        "SchemaRegistryConfig" : {}
    }'
```

------

## Filtrado para Avro y Protobuf
<a name="services-consume-kafka-events-filtering"></a>

 Si utiliza los formatos Avro o Protobuf con un registro de esquemas, puede aplicar el filtrado de eventos a la función de Lambda. Los patrones de filtro se aplican a la representación JSON clásica deserializada de sus datos después de la validación del esquema. Por ejemplo, con un esquema Avro que defina los detalles del producto, incluido el precio, puede filtrar los mensajes en función del valor del precio: 

**nota**  
 Cuando se deserializa, Avro se convierte en formato JSON estándar, lo que significa que no se puede volver a convertir directamente en un objeto Avro. Si necesita convertirlo en un objeto Avro, utilice el formato SOURCE.   
 Para la deserialización de Protobuf, los nombres de campo del JSON resultante coinciden con los que están definidos en el esquema, en lugar de convertirse en estilo camel case como suele hacer Protobuf. Tenga esto en cuenta durante la creación de patrones de filtrado. 

```
aws lambda create-event-source-mapping \
    --function-name myAvroFunction \
    --topics myAvroTopic \
    --starting-position TRIM_HORIZON \
    --kafka-bootstrap-servers '["broker1:9092", "broker2:9092"]' \
    --schema-registry-config '{
        "SchemaRegistryURI": "arn:aws:glue:us-east-1:123456789012:registry/myAvroRegistry",
        "EventRecordFormat": "JSON",
        "SchemaValidationConfigs": [
            { 
                "Attribute": "VALUE" 
            }
        ]
    }' \
    --filter-criteria '{
        "Filters": [
            {
                "Pattern": "{ \"value\" : { \"field_1\" : [\"value1\"], \"field_2\" : [\"value2\"] } }"
            }
        ]
    }'
```

 En este ejemplo, el patrón de filtro analiza el objeto `value` y hace coincidir los mensajes `field_1` con `"value1"` y `field_2` con `"value2"`. Los criterios del filtro se comparan con los datos deserializados, después de que Lambda convierte el mensaje del formato Avro l formato JSON. 

 Para obtener más información respecto del filtrado de eventos, consulte [Filtrado de eventos de Lambda](invocation-eventfiltering.md). 

## Formatos de carga útil y comportamiento de deserialización
<a name="services-consume-kafka-events-payload"></a>

 Cuando se utiliza un registro de esquemas, Lambda entrega la carga útil final a la función en un formato similar al de la [carga útil de evento regular](with-msk.md#msk-sample-event), con campos adicionales. Los campos adicionales dependen del parámetro `SchemaValidationConfigs`. Para cada atributo que seleccione para la validación (clave o valor), Lambda añade los metadatos del esquema correspondientes a la carga útil. 

**nota**  
Debe actualizar su [aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events) a la versión 3.16.0 o una superior para utilizar los campos de metadatos del esquema.

 Por ejemplo, si valida el campo `value`, Lambda añade un campo llamado `valueSchemaMetadata` a su carga útil. Del mismo modo, para el campo `key`, Lambda agrega un campo llamado `keySchemaMetadata`. Estos metadatos contienen información sobre el formato de los datos y el ID del esquema utilizados para la validación: 

```
"valueSchemaMetadata": {
    "dataFormat": "AVRO",
    "schemaId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"
}
```

 El parámetro `EventRecordFormat` se puede establecer en `JSON` o `SOURCE`, lo que determina cómo Lambda gestiona los datos validados por el esquema antes de entregarlos a la función. Cada opción ofrece distintas capacidades de procesamiento: 
+ `JSON`: Lambda deserializa los atributos validados en formato JSON estándar, lo que permite que los datos estén listos para uso directo en lenguajes compatibles con JSON nativo. Este formato es ideal cuando no se necesita conservar el formato binario original ni trabajar con las clases generadas.
+ `SOURCE`: Lambda conserva el formato binario original de los datos como una cadena de codificación Base64, lo que permite la conversión directa a objetos Avro o Protobuf. Este formato es esencial cuando se trabaja con lenguajes fuertemente tipados o cuando se necesitan mantener todas las capacidades de los esquemas de Avro o Protobuf.

En función de estas características del formato y de las consideraciones específicas del lenguaje, recomendamos los siguientes formatos:


**Formatos recomendados según el lenguaje de programación**  

| Idioma | Avro | Protobuf | JSON | 
| --- | --- | --- | --- | 
| Java | SOURCE | SOURCE | SOURCE | 
| Python | JSON | JSON | JSON | 
| NodeJS | JSON | JSON | JSON | 
| .NET | SOURCE | SOURCE | SOURCE | 
| Otros | JSON | JSON | JSON | 

En las siguientes secciones se describen estos formatos en detalle y se proporcionan ejemplos de cargas útiles para cada uno de ellos.

### Formato JSON
<a name="services-consume-kafka-events-payload-json"></a>

 Si elige `JSON` como el `EventRecordFormat`, Lambda valida y deserializa los atributos del mensaje que ha seleccionado en el campo `SchemaValidationConfigs` (los atributos `key` o `value`). Lambda entrega estos atributos seleccionados como cadenas de codificación base64 de su representación JSON estándar en su función. 

**nota**  
 Cuando se deserializa, Avro se convierte en formato JSON estándar, lo que significa que no se puede volver a convertir directamente en un objeto Avro. Si necesita convertirlo en un objeto Avro, utilice el formato SOURCE.   
 Para la deserialización de Protobuf, los nombres de campo del JSON resultante coinciden con los que están definidos en el esquema, en lugar de convertirse en estilo camel case como suele hacer Protobuf. Tenga esto en cuenta durante la creación de patrones de filtrado. 

 A continuación se muestra un ejemplo de carga útil, sobre la suposición de que elige `JSON` como `EventRecordFormat`, y ambos atributos `key` y `value` como `SchemaValidationConfigs`: 

```
{
   "eventSource":"aws:kafka",
   "eventSourceArn":"arn:aws:kafka:us-east-1:123456789012:cluster/vpc-2priv-2pub/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111-1",
   "bootstrapServers":"b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092",
   "records":{
      "mytopic-0":[
         {
            "topic":"mytopic",
            "partition":0,
            "offset":15,
            "timestamp":1545084650987,
            "timestampType":"CREATE_TIME",
            "key":"abcDEFghiJKLmnoPQRstuVWXyz1234==", //Base64 encoded string of JSON
            "keySchemaMetadata": {
                "dataFormat": "AVRO",
                "schemaId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"
            },
            "value":"abcDEFghiJKLmnoPQRstuVWXyz1234", //Base64 encoded string of JSON
            "valueSchemaMetadata": {
                "dataFormat": "AVRO",
                "schemaId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"
            },
            "headers":[
               {
                  "headerKey":[
                     104,
                     101,
                     97,
                     100,
                     101,
                     114,
                     86,
                     97,
                     108,
                     117,
                     101
                  ]
               }
            ]
         }
      ]
   }
}
```

 En este ejemplo: 
+ Ambos `key` y `value` son cadenas de codificación base64 de su representación JSON después de la deserialización.
+ Lambda incluye metadatos de esquema para ambos atributos en `keySchemaMetadata` y `valueSchemaMetadata`.
+ La función puede decodificar las cadenas `key` y `value` para acceder a los datos JSON deserializados.

 Se recomienda el formato JSON para los lenguajes que no están fuertemente tipados, como Python o Node.js. Estos lenguajes cuentan con soporte nativo para convertir el formato JSON en objetos. 

### Formato de origen
<a name="services-consume-kafka-events-payload-source"></a>

 Si elige `SOURCE` como `EventRecordFormat`, Lambda igual valida el registro con respecto al registro del esquema, pero entrega los datos binarios originales a la función sin deserialización. Estos datos binarios se entregan como una cadena de codificación Base64 de los datos de bytes originales, sin incluir los metadatos agregados por el productor. Como resultado, puede convertir directamente los datos binarios sin procesar en objetos Avro y Protobuf dentro del código de función. Se recomienda que utilice Powertools para AWS Lambda, que deserializará los datos binarios sin procesar y proporcionará directamente los objetos Avro y Protobuf. 

 Por ejemplo, si configura Lambda para validar los atributos `key` y `value`, pero utiliza el formato `SOURCE`, la función recibe una carga útil como la siguiente: 

```
{
    "eventSource": "aws:kafka",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/vpc-2priv-2pub/a1b2c3d4-5678-90ab-cdef-EXAMPLE11111-1",
    "bootstrapServers": "b-2.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092,b-1.demo-cluster-1.a1bcde.c1.kafka.us-east-1.amazonaws.com:9092",
    "records": {
        "mytopic-0": [
            {
                "topic": "mytopic",
                "partition": 0,
                "offset": 15,
                "timestamp": 1545084650987,
                "timestampType": "CREATE_TIME",
                "key": "abcDEFghiJKLmnoPQRstuVWXyz1234==", // Base64 encoded string of Original byte data, producer-appended metadata removed
                "keySchemaMetadata": {
                    "dataFormat": "AVRO",
                    "schemaId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"
                },
                "value": "abcDEFghiJKLmnoPQRstuVWXyz1234==", // Base64 encoded string of Original byte data, producer-appended metadata removed
                "valueSchemaMetadata": {
                    "dataFormat": "AVRO",
                    "schemaId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111"
                },
                "headers": [
                    {
                        "headerKey": [
                            104,
                            101,
                            97,
                            100,
                            101,
                            114,
                            86,
                            97,
                            108,
                            117,
                            101
                        ]
                    }
                ]
            }
        ]
    }
}
```

 En este ejemplo: 
+ Ambos `key` y `value` contienen los datos binarios originales en forma de cadenas de codificación Base64.
+ Su función debe gestionar la deserialización con las bibliotecas adecuadas.

 Se recomienda elegir `SOURCE` para `EventRecordFormat` si utiliza objetos generados por Avro o Protobuf, especialmente con funciones de Java. Esto se debe a que Java está fuertemente tipado y requiere deserializadores específicos para los formatos Avro y Protobuf. En el código de la función, puede usar la biblioteca Avro o Protobuf de su preferencia para deserializar los datos. 

## Trabajar con datos deserializados en funciones de Lambda
<a name="services-consume-kafka-events-payload-examples"></a>

Powertools para AWS Lambda ayuda a deserializar los registros de Kafka en el código de su función según el formato que utilice. Esta utilidad simplifica el trabajo con los registros de Kafka al gestionar la conversión de datos y proporcionar objetos listos para usar.

 Si desea usar Powertools para AWS Lambda en su función, debe agregar Powertools para AWS Lambda como una capa o incluirlo como una dependencia al crear su función de Lambda. Para obtener instrucciones de configuración y más información, consulte la documentación de Powertools para AWS Lambda para su lenguaje preferido: 
+ [Powertools para AWS Lambda (Java)](https://docs.powertools.aws.dev/lambda/java/latest/utilities/kafka/)
+ [Powertools para AWS Lambda (Python)](https://docs.powertools.aws.dev/lambda/python/latest/utilities/kafka/)
+ [Powertools para AWS Lambda (TypeScript)](https://docs.powertools.aws.dev/lambda/typescript/latest/features/kafka/)
+ [Powertools para AWS Lambda (.NET)](https://docs.powertools.aws.dev/lambda/dotnet/utilities/kafka/)

**nota**  
Al trabajar con la integración del registro de esquemas, puede elegir el formato `SOURCE` o `JSON`. Cada opción admite diferentes formatos de serialización, como se muestra a continuación:  


| Formato | Admite | 
| --- | --- | 
|  SOURCE  |  Avro y Protobuf (mediante la integración del registro de esquema de Lambda)  | 
|  JSON  |  Datos JSON  | 

 Al usar el formato `SOURCE` o `JSON`, puede utilizar Powertools para AWS a fin de ayudar a deserializar los datos en el código de la función. Estos son algunos ejemplos de cómo manejar los diferentes formatos de datos: 

------
#### [ AVRO ]

Ejemplo de Java:

```
package org.demo.kafka;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.demo.kafka.avro.AvroProduct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.lambda.powertools.kafka.Deserialization;
import software.amazon.lambda.powertools.kafka.DeserializationType;
import software.amazon.lambda.powertools.logging.Logging;

public class AvroDeserializationFunction implements RequestHandler<ConsumerRecords<String, AvroProduct>, String> {

    private static final Logger LOGGER = LoggerFactory.getLogger(AvroDeserializationFunction.class);

    @Override
    @Logging
    @Deserialization(type = DeserializationType.KAFKA_AVRO)
    public String handleRequest(ConsumerRecords<String, AvroProduct> records, Context context) {
        for (ConsumerRecord<String, AvroProduct> consumerRecord : records) {
            LOGGER.info("ConsumerRecord: {}", consumerRecord);

            AvroProduct product = consumerRecord.value();
            LOGGER.info("AvroProduct: {}", product);

            String key = consumerRecord.key();
            LOGGER.info("Key: {}", key);
        }

        return "OK";
    }

}
```

Ejemplo de Python:

```
from aws_lambda_powertools.utilities.kafka_consumer.kafka_consumer import kafka_consumer
from aws_lambda_powertools.utilities.kafka_consumer.schema_config import SchemaConfig
from aws_lambda_powertools.utilities.kafka_consumer.consumer_records import ConsumerRecords

from aws_lambda_powertools.utilities.typing import LambdaContext
from aws_lambda_powertools import Logger

logger = Logger(service="kafkaConsumerPowertools")

value_schema_str = open("customer_profile.avsc", "r").read()

schema_config = SchemaConfig(
value_schema_type="AVRO",
value_schema=value_schema_str)

@kafka_consumer(schema_config=schema_config)
def lambda_handler(event: ConsumerRecords, context:LambdaContext):

  for record in event.records:
      value = record.value
      logger.info(f"Received value: {value}")
```

Muestra de TypeScript:

```
import { kafkaConsumer } from '@aws-lambda-powertools/kafka';

import type { ConsumerRecords } from '@aws-lambda-powertools/kafka/types';
import { Logger } from '@aws-lambda-powertools/logger';
import type { Context } from 'aws-lambda';

const logger = new Logger();

type Value = {
    id: number;
    name: string;
    price: number;
};

const schema = '{   
    "type": "record",   
    "name": "Product",   
    "fields": [     
        { "name": "id", "type": "int" },     
        { "name": "name", "type": "string" },     
        { "name": "price", "type": "double" }   
    ] 
}';

export const handler = kafkaConsumer<string, Value>(
    (event: ConsumerRecords<string, Value>, _context: Context) => {
        for (const record of event.records) {
            logger.info(Processing record with key: ${record.key});
            logger.info(Record value: ${JSON.stringify(record.value)});
            // You can add more processing logic here
        }
    },
    {
        value: {
            type: 'avro',
            schema: schema,
        },
    }
);
```

Ejemplo de .NET:

```
using Amazon.Lambda.Core;
using AWS.Lambda.Powertools.Kafka;
using AWS.Lambda.Powertools.Kafka.Avro;
using AWS.Lambda.Powertools.Logging;
using Com.Example;

// Assembly attribute to enable the Lambda function's Kafka event to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(PowertoolsKafkaAvroSerializer))]

namespace ProtoBufClassLibrary;

public class Function
{
    public string FunctionHandler(ConsumerRecords<string, CustomerProfile> records, ILambdaContext context)
    {
        foreach (var record in records)
        {
            Logger.LogInformation("Processing messagem from topic: {topic}", record.Topic);
            Logger.LogInformation("Partition: {partition}, Offset: {offset}", record.Partition, record.Offset);
            Logger.LogInformation("Produced at: {timestamp}", record.Timestamp);
            
            foreach (var header in record.Headers.DecodedValues())
            {
                Logger.LogInformation($"{header.Key}: {header.Value}");
            }
            
            Logger.LogInformation("Processing order for: {fullName}", record.Value.FullName);
        }
    
        return "Processed " + records.Count() + " records";
    }
}
```

------
#### [ PROTOBUF ]

Ejemplo de Java:

```
package org.demo.kafka;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.demo.kafka.protobuf.ProtobufProduct;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.lambda.powertools.kafka.Deserialization;
import software.amazon.lambda.powertools.kafka.DeserializationType;
import software.amazon.lambda.powertools.logging.Logging;

public class ProtobufDeserializationFunction
        implements RequestHandler<ConsumerRecords<String, ProtobufProduct>, String> {

    private static final Logger LOGGER = LoggerFactory.getLogger(ProtobufDeserializationFunction.class);

    @Override
    @Logging
    @Deserialization(type = DeserializationType.KAFKA_PROTOBUF)
    public String handleRequest(ConsumerRecords<String, ProtobufProduct> records, Context context) {
        for (ConsumerRecord<String, ProtobufProduct> consumerRecord : records) {
            LOGGER.info("ConsumerRecord: {}", consumerRecord);

            ProtobufProduct product = consumerRecord.value();
            LOGGER.info("ProtobufProduct: {}", product);

            String key = consumerRecord.key();
            LOGGER.info("Key: {}", key);
        }

        return "OK";
    }

}
```

Ejemplo de Python:

```
from aws_lambda_powertools.utilities.kafka_consumer.kafka_consumer import kafka_consumer

from aws_lambda_powertools.utilities.kafka_consumer.schema_config import SchemaConfig
from aws_lambda_powertools.utilities.kafka_consumer.consumer_records import ConsumerRecords

from aws_lambda_powertools.utilities.typing import LambdaContext
from aws_lambda_powertools import Logger

from user_pb2 import User # protobuf generated class

logger = Logger(service="kafkaConsumerPowertools")

schema_config = SchemaConfig(
value_schema_type="PROTOBUF",
value_schema=User)

@kafka_consumer(schema_config=schema_config)
def lambda_handler(event: ConsumerRecords, context:LambdaContext):

  for record in event.records:
      value = record.value
      logger.info(f"Received value: {value}")
```

Muestra de TypeScript:

```
import { kafkaConsumer } from '@aws-lambda-powertools/kafka';
import type { ConsumerRecords } from '@aws-lambda-powertools/kafka/types';
import { Logger } from '@aws-lambda-powertools/logger';
import type { Context } from 'aws-lambda';
import { Product } from './product.generated.js';

const logger = new Logger();

type Value = {
    id: number;
    name: string;
    price: number;
};

export const handler = kafkaConsumer<string, Value>(
    (event: ConsumerRecords<string, Value>, _context: Context) => {
        for (const record of event.records) {
            logger.info(Processing record with key: ${record.key});
            logger.info(Record value: ${JSON.stringify(record.value)});
        }
    },
    {
        value: {
            type: 'protobuf',
            schema: Product,
        },
    }
);
```

Ejemplo de .NET:

```
using Amazon.Lambda.Core;
using AWS.Lambda.Powertools.Kafka;
using AWS.Lambda.Powertools.Kafka.Protobuf;
using AWS.Lambda.Powertools.Logging;
using Com.Example;

// Assembly attribute to enable the Lambda function's Kafka event to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(PowertoolsKafkaProtobufSerializer))]

namespace ProtoBufClassLibrary;

public class Function
{
    public string FunctionHandler(ConsumerRecords<string, CustomerProfile> records, ILambdaContext context)
    {
        foreach (var record in records)
        {
            Logger.LogInformation("Processing messagem from topic: {topic}", record.Topic);
            Logger.LogInformation("Partition: {partition}, Offset: {offset}", record.Partition, record.Offset);
            Logger.LogInformation("Produced at: {timestamp}", record.Timestamp);
            
            foreach (var header in record.Headers.DecodedValues())
            {
                Logger.LogInformation($"{header.Key}: {header.Value}");
            }
            
            Logger.LogInformation("Processing order for: {fullName}", record.Value.FullName);
        }
    
        return "Processed " + records.Count() + " records";
    }
}
```

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

Ejemplo de Java:

```
package org.demo.kafka;

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

import software.amazon.lambda.powertools.kafka.Deserialization;
import software.amazon.lambda.powertools.kafka.DeserializationType;
import software.amazon.lambda.powertools.logging.Logging;

public class JsonDeserializationFunction implements RequestHandler<ConsumerRecords<String, Product>, String> {

    private static final Logger LOGGER = LoggerFactory.getLogger(JsonDeserializationFunction.class);

    @Override
    @Logging
    @Deserialization(type = DeserializationType.KAFKA_JSON)
    public String handleRequest(ConsumerRecords<String, Product> consumerRecords, Context context) {
        for (ConsumerRecord<String, Product> consumerRecord : consumerRecords) {
            LOGGER.info("ConsumerRecord: {}", consumerRecord);

            Product product = consumerRecord.value();
            LOGGER.info("Product: {}", product);

            String key = consumerRecord.key();
            LOGGER.info("Key: {}", key);
        }

        return "OK";
    }
}
```

Ejemplo de Python:

```
from aws_lambda_powertools.utilities.kafka_consumer.kafka_consumer import kafka_consumer

from aws_lambda_powertools.utilities.kafka_consumer.schema_config import SchemaConfig
from aws_lambda_powertools.utilities.kafka_consumer.consumer_records import ConsumerRecords

from aws_lambda_powertools.utilities.typing import LambdaContext
from aws_lambda_powertools import Logger

logger = Logger(service="kafkaConsumerPowertools")

schema_config = SchemaConfig(value_schema_type="JSON")

@kafka_consumer(schema_config=schema_config)
def lambda_handler(event: ConsumerRecords, context:LambdaContext):

  for record in event.records:
      value = record.value
      logger.info(f"Received value: {value}")
```

Muestra de TypeScript:

```
import { kafkaConsumer } from '@aws-lambda-powertools/kafka';
import type { ConsumerRecords } from '@aws-lambda-powertools/kafka/types';
import { Logger } from '@aws-lambda-powertools/logger';
import type { Context } from 'aws-lambda';

const logger = new Logger();

type Value = {
    id: number;
    name: string;
    price: number;
};

export const handler = kafkaConsumer<string, Value>(
    (event: ConsumerRecords<string, Value>, _context: Context) => {
        for (const record of event.records) {
            logger.info(Processing record with key: ${record.key});
            logger.info(Record value: ${JSON.stringify(record.value)});
            // You can add more processing logic here
        }
    },
    {
        value: {
            type: 'json',
        },
    }
);
```

Ejemplo de .NET:

```
using Amazon.Lambda.Core;
using AWS.Lambda.Powertools.Kafka;
using AWS.Lambda.Powertools.Kafka.Json;
using AWS.Lambda.Powertools.Logging;
using Com.Example;

// Assembly attribute to enable the Lambda function's Kafka event to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(PowertoolsKafkaJsonSerializer))]

namespace JsonClassLibrary;

public class Function
{
    public string FunctionHandler(ConsumerRecords<string, CustomerProfile> records, ILambdaContext context)
    {
        foreach (var record in records)
        {
            Logger.LogInformation("Processing messagem from topic: {topic}", record.Topic);
            Logger.LogInformation("Partition: {partition}, Offset: {offset}", record.Partition, record.Offset);
            Logger.LogInformation("Produced at: {timestamp}", record.Timestamp);
            
            foreach (var header in record.Headers.DecodedValues())
            {
                Logger.LogInformation($"{header.Key}: {header.Value}");
            }
            
            Logger.LogInformation("Processing order for: {fullName}", record.Value.FullName);
        }
    
        return "Processed " + records.Count() + " records";
    }
}
```

------

## Métodos de autenticación para el registro de esquemas
<a name="services-consume-kafka-events-auth"></a>

 Para utilizar un registro de esquemas, Lambda debe poder acceder a este de forma segura. Si trabaja con un registro de esquemas de AWS Glue, Lambda se basa en la autenticación de IAM. Esto significa que el [rol de ejecución](lambda-intro-execution-role.md) de su función debe tener los siguientes permisos para acceder al registro AWS Glue: 
+ [GetRegistry](https://docs.aws.amazon.com/glue/latest/webapi/API_GetRegistry.html) en la *referencia de la API web de AWS Glue*
+ [GetSchemaVersion](https://docs.aws.amazon.com/glue/latest/webapi/API_GetSchemaVersion.html) en la *referencia de la API web de AWS Glue*

Ejemplo de la política de IAM requerida: 

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "glue:GetRegistry",
                "glue:GetSchemaVersion"
            ],
            "Resource": [
                "*"
            ]
        }
    ]
}
```

------

**nota**  
 Para los registros de esquemas de AWS Glue, si proporciona `AccessConfigs` para un registro AWS Glue, Lambda devolverá una excepción de validación. 

Si trabaja con un registro de esquemas de Confluent, puede elegir uno de los tres métodos de autenticación compatibles para el parámetro `Type` de su objeto [KafkaSchemaRegistryAccessConfig](https://docs.aws.amazon.com/lambda/latest/api/API_KafkaSchemaRegistryAccessConfig):
+ **BASIC\$1AUTH**: Lambda utiliza la autenticación de nombre de usuario y contraseña o clave de API y secreto de API para acceder al registro. Si elige esta opción, proporcione el ARN de Secrets Manager que contiene sus credenciales en el campo URI.
+ **CLIENT\$1CERTIFICATE\$1TLS\$1AUTH**: Lambda utiliza la autenticación TLS mutua con los certificados de cliente. Lambda necesita acceder tanto al certificado como a la clave privada para usar esta opción. Proporcione el ARN de Secrets Manager que contiene estas credenciales en el campo URI.
+ **NO\$1AUTH**: El certificado de entidad de certificación pública debe estar firmado por una entidad de certificación que esté en el almacén de confianza de Lambda. Para un certificado autofirmado o de entidad de certificación privada, configure el certificado de entidad de certificación raíz del servidor. Para usar esta opción, se debe omitir el parámetro `AccessConfigs`.

 Además, si Lambda necesita acceder a un certificado de CA privado para verificar el certificado TLS del registro de esquemas, seleccione `SERVER_ROOT_CA_CERT` como `Type` y proporcione el ARN de Secrets Manager al certificado en el campo URI. 

**nota**  
 Para configurar la opción `SERVER_ROOT_CA_CERT` en la consola, proporcione el ARN secreto que contiene el certificado en el campo **Cifrado**. 

 La configuración de autenticación del registro de esquemas es independiente de cualquier autenticación que haya configurado para el clúster de Kafka. Debe configurar ambas por separado, incluso si utilizan métodos de autenticación que son similares. 

## Gestión de errores y solución de problemas relacionados con el registro de esquemas
<a name="services-consume-kafka-events-troubleshooting"></a>

Al utilizar un registro de esquemas con los orígenes de eventos de Amazon MSK, es posible que se produzcan varios errores. En esta sección se proporciona orientación sobre los problemas habituales y cómo resolverlos.

### Errores de configuración
<a name="consume-kafka-events-troubleshooting-configuration-errors"></a>

Estos errores se producen al configurar el registro de esquemas.

Se requiere el modo aprovisionado  
**Mensaje de error:** `SchemaRegistryConfig is only available for Provisioned Mode. To configure Schema Registry, please enable Provisioned Mode by specifying MinimumPollers in ProvisionedPollerConfig.`  
**Solución:** habilite el modo aprovisionado para la asignación de orígenes de eventos mediante la configuración del parámetro `MinimumPollers` en `ProvisionedPollerConfig`. 

URL del registro de esquemas no válida  
**Mensaje de error:** `Malformed SchemaRegistryURI provided. Please provide a valid URI or ARN. For example, https://schema-registry.example.com:8081 or arn:aws:glue:us-east-1:123456789012:registry/ExampleRegistry.`  
**Solución:** proporcione una URL HTTPS válida para el registro de esquemas de Confluent o un ARN válido para el registro de esquemas de AWS Glue.

Falta el formato de registro de eventos o este no es válido  
**Mensaje de error:** `EventRecordFormat is a required field for SchemaRegistryConfig. Please provide one of supported format types: SOURCE, JSON.`  
**Solución:** especifique SOURCE o JSON como EventRecordFormat en la configuración del registro de esquemas.

Atributos de validación duplicados  
**Mensaje de error:** `Duplicate KEY/VALUE Attribute in SchemaValidationConfigs. SchemaValidationConfigs must contain at most one KEY/VALUE Attribute.`  
**Solución:** elimine los atributos KEY o VALUE duplicados de sus SchemaValidationConfigs. Cada tipo de atributo solo puede aparecer una vez.

Falta la configuración de validación  
**Mensaje de error:** `SchemaValidationConfigs is a required field for SchemaRegistryConfig.`  
**Solución:** Añada SchemaValidationConfigs a su configuración y especifique al menos un atributo de validación (CLAVE o VALOR).

### Accesos y errores de permisos
<a name="consume-kafka-events-troubleshooting-access-errors"></a>

Estos errores ocurren cuando Lambda no puede acceder al registro de esquemas debido a problemas de permisos o autenticación.

Acceso denegado al registro de esquemas de AWS Glue  
**Mensaje de error:** `Cannot access Glue Schema with provided role. Please ensure the provided role can perform the GetRegistry and GetSchemaVersion Actions on your schema.`  
**Solución:** Agregue una política con los permisos necesarios (`glue:GetRegistry` y `glue:GetSchemaVersion`) al rol de ejecución de la función.

Acceso denegado al registro de esquemas de Confluent  
**Mensaje de error:** `Cannot access Confluent Schema with the provided access configuration.`  
**Solución:** Verifique que sus credenciales de autenticación (almacenadas en Secrets Manager) sean correctas y tengan los permisos necesarios para acceder al registro de esquemas.

Registro de esquemas de AWS Glue entre cuentas  
**Mensaje de error:** `Cross-account Glue Schema Registry ARN not supported.`  
**Solución:** Utilice un registro de esquemas de AWS Glue que esté en la misma cuenta de AWS que su función de Lambda.

Registro de esquemasAWS Glue entre regiones  
**Mensaje de error:** `Cross-region Glue Schema Registry ARN not supported.`  
**Solución:** Utilice un registro de esquemas que esté en la misma región que su función de Lambda.AWS Glue

Problemas de acceso a secretos  
**Mensaje de error:** `Lambda received InvalidRequestException from Secrets Manager.`  
**Solución:** Verifique que el rol de ejecución de su función tenga permiso para acceder al secreto y que este no esté cifrado con una clave AWS KMS predeterminada si accede desde una cuenta diferente.

### Errores de conexión
<a name="consume-kafka-events-troubleshooting-connection-errors"></a>

Estos errores ocurren cuando Lambda no puede establecer una conexión con el registro de esquemas.

Problemas de conectividad de VPC  
**Mensaje de error:** `Cannot connect to your Schema Registry. Your Kafka cluster's VPC must be able to connect to the schema registry. You can provide access by configuring AWS PrivateLink or a NAT Gateway or VPC Peering between Kafka Cluster VPC and the schema registry VPC.`  
**Solución:** Configure la red de VPC para permitir conexiones al registro de esquemas mediante AWS PrivateLink, una puerta de enlace NAT o un emparejamiento de VPC.

Error de protocolo de enlace TLS  
**Mensaje de error:** `Unable to establish TLS handshake with the schema registry. Please provide correct CA-certificate or client certificate using Secrets Manager to access your schema registry.`  
**Solución:** Verifique que sus certificados de CA y de cliente (para mTLS) sean correctos y estén correctamente configurados en Secrets Manager.

Limitación  
**Mensaje de error:** `Receiving throttling errors when accessing the schema registry. Please increase API TPS limits for your schema registry.`  
**Solución:** Aumente los límites de tasa de API para el registro de esquemas o reduzca la tasa de las solicitudes de su aplicación.

Errores de registro de esquemas de administración automática  
**Mensaje de error:** `Lambda received an internal server an unexpected error from the provided self-managed schema registry.`  
**Solución:** Verifique el estado y la configuración de su servidor de registro de esquemas de administración automática.

# Procesamiento de baja latencia para orígenes de eventos de Kafka
<a name="with-kafka-low-latency"></a>

AWS Lambda admite de forma nativa el procesamiento de eventos de baja latencia para aplicaciones que requieren latencias constantes de extremo a extremo de menos de 100 milisegundos. Esta página brinda detalles de configuración y recomendaciones para habilitar los flujos de trabajo de baja latencia.

## Habilitación del procesamiento de baja latencia
<a name="enable-low-latency"></a>

Para habilitar el procesamiento de baja latencia en una asignación de orígenes de eventos de Kafka, se requiere la siguiente configuración básica: 
+ Habilite el modo aprovisionado. Para obtener más información, consulte [Modo aprovisionado](kafka-scaling-modes.md#kafka-provisioned-mode).
+ Establezca el parámetro `MaximumBatchingWindowInSeconds` de la asignación de orígenes de eventos en 0. Para obtener más información, consulte [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

## Ajuste de su ESM de Kafka de baja latencia
<a name="recommendations-low-latency"></a>

Tenga en cuenta las siguientes recomendaciones para optimizar su asignación de orígenes de eventos de Kafka para lograr una baja latencia:

### Configuración del modo aprovisionado
<a name="recommendations-pollers"></a>

En el modo aprovisionado para la asignación de orígenes de eventos de Kafka, Lambda permite afinar el rendimiento de la asignación de orígenes de eventos al configurar una cantidad mínima y máxima de recursos llamados **sondeos de eventos**. Un sondeo de eventos (o **un sondeo**) representa un recurso informático que sustenta una asignación de orígenes de eventos en el modo aprovisionado y asigna un rendimiento de hasta 5 MB/s. Cada sondeo de eventos admite hasta 5 invocaciones de Lambda simultáneas.

Para determinar la configuración de sondeo óptima para su aplicación, tenga en cuenta la tasa máxima de ingesta y los requisitos de procesamiento. Veamos un ejemplo simplificado:

Con un tamaño de lote de 20 registros y una duración media de la función de destino de 50 ms, cada sondeo puede procesar 2000 registros por segundo con un límite de 5 MB/s. Esto se calcula como: (20 registros × 1000 ms / 50 ms) × 5 invocaciones de Lambda simultáneas. Por lo tanto, si la tasa máxima de ingesta deseada es de 20 000 registros por segundo, necesitará al menos 10 sondeos de eventos.

**nota**  
Recomendamos disponer de sondeos de eventos adicionales como búfer para evitar que operen de forma constante a su máxima capacidad.

El modo aprovisionado escala automáticamente los sondeos de eventos en función de los patrones de tráfico dentro de los **sondeos de eventos** mínimos y máximos configurados, lo que puede provocar un reequilibrio y, por lo tanto, presentar una latencia adicional. Puede deshabilitar el escalado automático al configurar el mismo valor para el **sondeo de eventos** mínimo y máximo.

### Consideraciones adicionales
<a name="additional-considerations-low-latency"></a>

Algunas de las consideraciones adicionales incluyen:
+ Los arranques en frío a partir de la invocación de la función de destino de Lambda pueden aumentar la latencia de extremo a extremo. Para reducir este riesgo, considere habilitar la [simultaneidad aprovisionada](provisioned-concurrency.md) o [SnapStart](snapstart.md) en la función de destino de la asignación de orígenes de eventos. Además, optimice la asignación de memoria de su función para garantizar ejecuciones uniformes y óptimas.
+ Cuando `MaximumBatchingWindowInSeconds` se establece en 0, Lambda procesará inmediatamente todos los registros disponibles sin esperar a llenar el tamaño del lote por completo. Por ejemplo, si el tamaño del lote está establecido en 1000 registros pero solo hay 100 registros disponibles, Lambda procesará esos 100 registros inmediatamente en lugar de esperar a que se acumulen los 1000 registros completos.

**importante**  
La configuración óptima para el procesamiento de baja latencia varía considerablemente en función de la carga de trabajo específica. Recomendamos encarecidamente probar diferentes configuraciones con su carga de trabajo real para determinar la mejor configuración para su caso de uso. 

# Configuración de los controles de gestión de errores para orígenes de eventos de Kafka
<a name="kafka-retry-configurations"></a>

Puede configurar la forma en que Lambda administra los errores y los reintentos de las asignaciones de orígenes de eventos de Kafka. Estas configuraciones lo ayudan a controlar la forma en que Lambda procesa los registros fallidos y administra el comportamiento de los reintentos.

## Configuraciones de reintento disponibles
<a name="kafka-retry-options"></a>

Las siguientes configuraciones de reintento están disponibles para orígenes de eventos de Amazon MSK y autoadministrados de Kafka:
+ **Número máximo de reintentos**: número máximo de reintentos que Lambda realiza cuando la función devuelve un error. Esto no cuenta el intento de invocación inicial. El valor predeterminado es -1 (infinito). Al configurar un número reintentos infinitos como un [destino en caso de error](kafka-on-failure-destination.md), Lambda aplica automáticamente un máximo de 10 acciones de reintento.
+ **Antigüedad máxima de registro**: antigüedad máxima de un registro que Lambda envía a su función. El valor predeterminado es -1 (infinito).
+ **División del lote en caso de error**: cuando la función devuelve un error, divida el lote en dos lotes más pequeños y reintente cada uno por separado. Esto ayuda a aislar los registros problemáticos.
+ **Respuesta de lote parcial**: permita que la función devuelva información sobre los registros de un lote que no se procesaron correctamente, de modo que Lambda solo pueda reintentar los registros con errores.

## Configuración de los controles de gestión de errores (consola)
<a name="kafka-retry-console"></a>

Puede configurar el comportamiento de reintento cuando crea o actualiza una asignación de orígenes de eventos de Kafka en la consola de Lambda.

**Cómo configurar el comportamiento de reintento de un origen de eventos de Kafka (consola)**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de su función.

1. Realice una de las siguientes acciones:
   + Para añadir un nuevo desencadenador de Kafka, en **Descripción general de la función**, seleccione **Añadir desencadenador**.
   + Para modificar un desencadenador de Kafka existente, selecciónelo y, a continuación, elija **Editar**.

1. En **Configuración del sondeador de eventos**, seleccione el modo aprovisionado para configurar los controles de gestión de errores:

   1. En **Reintentos**, introduzca el número máximo de reintentos (0-10000 o -1 para infinito).

   1. En **Antigüedad máxima registrada**, introduzca la antigüedad máxima en segundos (60-604 800 o -1 para infinito).

   1. Para habilitar la división por lotes cuando se produzcan errores, seleccione **Dividir lote en caso de error**.

   1. Para habilitar la respuesta parcial por lotes, seleccione **ReportBatchItemFailures**.

1. Elija **Añadir** o **Guardar**.

## Cómo configurar el comportamiento de reintento (AWS CLI)
<a name="kafka-retry-cli"></a>

Utilice los siguientes comandos de la AWS CLI para configurar el comportamiento de los reintentos en las asignaciones de orígenes de eventos de Kafka.

### Creación de una asignación de orígenes de eventos con configuraciones de reintento
<a name="kafka-retry-cli-create"></a>

En el siguiente ejemplo, se crea una asignación de orígenes de eventos de Kafka autoadministrado con controles de gestión de errores:

```
aws lambda create-event-source-mapping \
  --function-name my-kafka-function \
  --topics my-kafka-topic \
  --source-access-configuration Type=SASL_SCRAM_512_AUTH,URI=arn:aws:secretsmanager:us-east-1:111122223333:secret:MyBrokerSecretName \
  --self-managed-event-source '{"Endpoints":{"KAFKA_BOOTSTRAP_SERVERS":["abc.xyz.com:9092"]}}' \
  --starting-position LATEST \
  --provisioned-poller-config MinimumPollers=1,MaximumPollers=1 \
  --maximum-retry-attempts 3 \
  --maximum-record-age-in-seconds 3600 \
  --bisect-batch-on-function-error \
  --function-response-types "ReportBatchItemFailures"
```

En el caso de orígenes de eventos de Amazon MSK:

```
aws lambda create-event-source-mapping \
  --event-source-arn arn:aws:kafka:us-east-1:111122223333:cluster/my-cluster/fc2f5bdf-fd1b-45ad-85dd-15b4a5a6247e-2 \
  --topics AWSMSKKafkaTopic \
  --starting-position LATEST \
  --function-name my-kafka-function \
  --source-access-configurations '[{"Type": "SASL_SCRAM_512_AUTH","URI": "arn:aws:secretsmanager:us-east-1:111122223333:secret:my-secret"}]' \
  --provisioned-poller-config MinimumPollers=1,MaximumPollers=1 \
  --maximum-retry-attempts 3 \
  --maximum-record-age-in-seconds 3600 \
  --bisect-batch-on-function-error \
  --function-response-types "ReportBatchItemFailures"
```

### Actualización de las configuraciones de reintento
<a name="kafka-retry-cli-update"></a>

Utilice el comando `update-event-source-mapping` para modificar las configuraciones de reintentos de una asignación de orígenes de eventos existente:

```
aws lambda update-event-source-mapping \
  --uuid 12345678-1234-1234-1234-123456789012 \
  --maximum-retry-attempts 5 \
  --maximum-record-age-in-seconds 7200 \
  --bisect-batch-on-function-error \
  --function-response-types "ReportBatchItemFailures"
```

## PartialBatchResponse
<a name="kafka-partial-batch-response"></a>

La respuesta parcial por lotes, también conocida como ReportBatchItemFailures, es una característica clave para la gestión de errores en la integración de Lambda con los orígenes de Kafka. Sin esta característica, cuando se produce un error en uno de los elementos de un lote, se vuelven a procesar todos los mensajes de ese lote. Con la respuesta parcial por lotes habilitada e implementada, el controlador devuelve los identificadores solo de los mensajes fallidos, lo que permite que Lambda reintente solo esos elementos específicos. Esto proporciona un mayor control sobre cómo se procesan los lotes que contienen mensajes fallidos.

Para informar los errores de lote, utilizará este esquema JSON:

```
{
  "batchItemFailures": [
    {
      "itemIdentifier": {
        "partition": "topic-partition_number",
        "offset": 100
      }
    },
    ...
  ]
}
```

**importante**  
Si devuelve una JSON válida vacía o nula, la asignación de orígenes de eventos considerará que el lote se ha procesado correctamente. Cualquier topic-partition\$1number o desplazamiento inválido devuelto que no estuviera presente en el evento invocado se considerará un error, y se reintentará procesar todo el lote.

Los siguientes ejemplos de código muestran cómo implementar una respuesta parcial por lotes para las funciones de Lambda que reciben eventos de orígenes de Kafka. La función informa los errores de los elementos del lote en la respuesta y le indica a Lambda que vuelva a intentar esos mensajes más adelante.

Esta es una implementación del controlador de Lambda de Python que muestra este enfoque:

```
import base64
from typing import Any, Dict, List

def lambda_handler(event: Dict[str, Any], context: Any) -> Dict[str, List[Dict[str, Dict[str, Any]]]]:
    failures: List[Dict[str, Dict[str, Any]]] = []
    records_dict = event.get("records", {})
    
    for topic_partition, records_list in records_dict.items():
        for record in records_list:
            topic = record.get("topic")
            partition = record.get("partition")
            offset = record.get("offset")
            value_b64 = record.get("value")
            
            try:
                data = base64.b64decode(value_b64).decode("utf-8")
                process_message(data)
            except Exception as exc:
                print(f"Failed to process record topic={topic} partition={partition} offset={offset}: {exc}")
                item_identifier: Dict[str, Any] = {
                    "partition": f"{topic}-{partition}",
                    "offset": int(offset) if offset is not None else None,
                }
                failures.append({"itemIdentifier": item_identifier})
    
    return {"batchItemFailures": failures}

def process_message(data: str) -> None:
    # Your business logic for a single message
    pass
```

Esta es una versión de Node.js:

```
const { Buffer } = require("buffer");

const handler = async (event) => {
  const failures = [];
  
  for (let topicPartition in event.records) {
    const records = event.records[topicPartition];
    
    for (const record of records) {
      const topic = record.topic;
      const partition = record.partition;
      const offset = record.offset;
      const valueBase64 = record.value;
      const data = Buffer.from(valueBase64, "base64").toString("utf8");
      
      try {
        await processMessage(data);
      } catch (error) {
        console.error("Failed to process record", { topic, partition, offset, error });
        const itemIdentifier = {
          "partition": `${topic}-${partition}`,
          "offset": Number(offset),
        };
        failures.push({ itemIdentifier });
      }
    }
  }
  
  return { batchItemFailures: failures };
};

async function processMessage(payload) {
  // Your business logic for a single message
}

module.exports = { handler };
```

# Captura de lotes descartados para orígenes de eventos de Amazon MSK y Apache Kafka autoadministrado
<a name="kafka-on-failure"></a>

Para retener los registros de las invocaciones de asignación de orígenes de eventos fallidos, agregue un destino a la asignación de orígenes de eventos de su función. Cada registro enviado al destino es un documento JSON que contiene metadatos sobre la invocación fallida. Para los destinos de Amazon S3, Lambda envía también todo el registro de invocación junto con los metadatos. Puede configurar cualquier tema de Amazon SNS, cola de Amazon SQS, bucket de Amazon S3 o Kafka como destino.

Con los destinos de Amazon S3, puede utilizar la característica de [notificaciones de eventos de Amazon S3](https://docs.aws.amazon.com/) para recibir notificaciones cuando se carguen objetos en el bucket de S3 de destino. También puede configurar las notificaciones de eventos de S3 para que invoquen otra función de Lambda para realizar el procesamiento automatizado de los lotes fallidos.

Su rol de ejecución debe tener permisos para el destino:
+ **En el caso de un destino de SQS:** [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)
+ **En el caso de un destino de SNS:** [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)
+ **En el caso de un destino de S3:** [ s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) y [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/ListObjectsV2.html)
+ **Para un destino de Kafka:** [kafka-cluster:WriteData](https://docs.aws.amazon.com/msk/latest/developerguide/kafka-actions.html)

Puede configurar un tema de Kafka como destino en caso de error para las asignaciones de orígenes de eventos de Kafka. Cuando Lambda no puede procesar los registros tras agotar los reintentos o cuando los registros superan la antigüedad máxima, Lambda envía los registros fallidos al tema de Kafka especificado para su posterior procesamiento. Consulte [Uso de un tema de Kafka como destino en caso de error](kafka-on-failure-destination.md).

Debe implementar un punto de conexión de VPC para el servicio de destino en caso de error en la VPC de su clúster de Kafka.

Además, si configuró una clave de KMS en su destino, Lambda necesita los siguientes permisos según el tipo de destino:
+ Si tiene activado el cifrado con su propia clave de KMS para un destino de S3, necesitará [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html). Si la clave de KMS y el destino del bucket de S3 están en una cuenta diferente a la de su función de Lambda y rol de ejecución, configure la clave de KMS para que confíe en el rol de ejecución y permita kms:GenerateDataKey.
+ Si tiene activado el cifrado con su propia clave de KMS para un destino de SQS, necesitará [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) y [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html). Si la clave de KMS y el destino de la cola de SQS están en una cuenta diferente a la de su función de Lambda y rol de ejecución, configure la clave de KMS para que confíe en el rol de ejecución y permita kms:Decrypt, kms:GenerateDataKey, [kms:DescribeKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_DescribeKey.html) y [kms:ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html).
+ Si tiene activado el cifrado con su propia clave de KMS para un destino de SNS, necesitará [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) y [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html). Si la clave de KMS y el destino del tema de SNS están en una cuenta diferente a la de su función de Lambda y rol de ejecución, configure la clave de KMS para que confíe en el rol de ejecución y permita kms:Decrypt, kms:GenerateDataKey, [kms:DescribeKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_DescribeKey.html) y [kms:ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html).

## Configuración de destinos en caso de error para la asignación de orígenes de eventos de Kafka
<a name="kafka-onfailure-destination"></a>

Para configurar un destino en caso de error mediante la consola, siga estos pasos:

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija una función.

1. En **Descripción general de la función**, elija **Agregar destino**.

1. En **Origen**, elija **Invocación de asignación de orígenes de eventos**.

1. Para la **Asignación de orígenes de eventos**, elija un origen de eventos que esté configurado para esta función.

1. En **Condición**, seleccione **En caso de error**. Para las invocaciones de asignación de orígenes de eventos, esta es la única condición aceptada.

1. En **Tipo de destino**, elija el tipo de destino al que Lambda envía los registros de invocación.

1. En **Destino**, elija un recurso.

1. Seleccione **Save**.

También puede configurar un destino en caso de error mediante la AWS CLI. Por ejemplo, el siguiente comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) agrega una asignación de orígenes de eventos con un destino de SQS en caso de error a `MyFunction`:

```
aws lambda create-event-source-mapping \
--function-name "MyFunction" \
--event-source-arn arn:aws:kafka:us-east-1:123456789012:cluster/vpc-2priv-2pub/751d2973-a626-431c-9d4e-d7975eb44dd7-2 \
--destination-config '{"OnFailure": {"Destination": "arn:aws:sqs:us-east-1:123456789012:dest-queue"}}'
```

El siguiente comando [UpdateEventSourceMapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) agrega un destino S3 en caso de error al origen de eventos asociado a la entrada `uuid`:

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--destination-config '{"OnFailure": {"Destination": "arn:aws:s3:::dest-bucket"}}'
```

Para eliminar un destino, introduzca una cadena vacía como argumento del parámetro `destination-config`:

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--destination-config '{"OnFailure": {"Destination": ""}}'
```

### Prácticas recomendadas de seguridad para destinos de Amazon S3
<a name="kafka-s3-destination-security"></a>

Eliminar un bucket de S3 que está configurado como destino sin eliminar el destino de la configuración de la función puede suponer un riesgo de seguridad. Si otro usuario conoce el nombre del bucket de destino, puede volver a crear el bucket en su Cuenta de AWS. Los registros de las invocaciones fallidas se enviarán a su bucket, lo que podría exponer los datos de su función.

**aviso**  
Para asegurarse de que los registros de invocación de su función no se puedan enviar a un bucket de S3 de otra Cuenta de AWS, agregue una condición al rol de ejecución de la función que limite los permisos `s3:PutObject` a los buckets de su cuenta. 

En el siguiente ejemplo, se muestra una política de IAM que limita los permisos `s3:PutObject` de la función a los buckets de la cuenta. Esta política también otorga a Lambda el permiso `s3:ListBucket` que necesita para usar un bucket de S3 como destino.

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "S3BucketResourceAccountWrite",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::*/*",
                "arn:aws:s3:::*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:ResourceAccount": "111122223333"
                }
            }
        }
    ]
}
```

Para agregar una política de permisos al rol de ejecución de su función mediante la Consola de administración de AWS o la AWS CLI, consulte las instrucciones de los siguientes procedimientos:

------
#### [ Console ]

**Cómo agregar una política de permisos al rol de ejecución de la función (consola)**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función de Lambda cuyo rol de ejecución desee modificar.

1. En la pestaña **Configuración**, elija **Permisos**.

1. En la pestaña **Rol de ejecución**, seleccione el **nombre del rol** de la función para abrir la página de la consola de IAM del rol.

1. Agregue una política de permisos al rol de la siguiente manera:

   1. En el panel **Política de permisos**, elija **Agregar permisos** y seleccione **Crear política insertada**.

   1. En el **editor de políticas**, seleccione **JSON**.

   1. Pegue la política que desee agregar en el editor (sustituyendo el JSON existente) y, a continuación, seleccione **Siguiente**.

   1. En **Detalles de política**, ingrese un **Nombre de política**.

   1. Seleccione **Crear política**.

------
#### [ AWS CLI ]

**Cómo agregar una política de permisos al rol de ejecución de la función (CLI)**

1. Cree un documento de política de JSON con los permisos necesarios y guárdelo en un directorio local.

1. Utilice el comando de la CLI de IAM `put-role-policy` para agregar permisos al rol de ejecución de la función. Ejecute el siguiente comando desde el directorio en el que guardó el documento de política JSON y sustituya el nombre del rol, el nombre de la política y el documento de política por sus propios valores.

   ```
   aws iam put-role-policy \
   --role-name my_lambda_role \
   --policy-name LambdaS3DestinationPolicy \
   --policy-document file://my_policy.json
   ```

------

### Ejemplo de registro de invocación SNS y SQS
<a name="kafka-sns-sqs-destinations"></a>

El siguiente ejemplo muestra lo que Lambda envía a un destino de tema de SNS o cola de SQS cuando se produce un error en la invocación de un origen de eventos de Kafka. Cada una de las claves en `recordsInfo` contiene el tema y la partición de Kafka, separados por un guion. Por ejemplo, para la clave `"Topic-0"`, `Topic` es el tema de Kafka, y `0` es la partición. Para cada tema y partición, puede usar los desplazamientos y los datos de las marcas de tiempo para buscar los registros de invocación originales.

```
{
    "requestContext": {
        "requestId": "316aa6d0-8154-xmpl-9af7-85d5f4a6bc81",
        "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:myfunction",
        "condition": "RetryAttemptsExhausted" | "MaximumPayloadSizeExceeded",
        "approximateInvokeCount": 1
    },
    "responseContext": { // null if record is MaximumPayloadSizeExceeded
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "version": "1.0",
    "timestamp": "2019-11-14T00:38:06.021Z",
    "KafkaBatchInfo": {
        "batchSize": 500,
        "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/vpc-2priv-2pub/751d2973-a626-431c-9d4e-d7975eb44dd7-2",
        "bootstrapServers": "...",
        "payloadSize": 2039086, // In bytes
        "recordsInfo": {
            "Topic-0": {
                "firstRecordOffset": "49601189658422359378836298521827638475320189012309704722",
                "lastRecordOffset": "49601189658422359378836298522902373528957594348623495186",
                "firstRecordTimestamp": "2019-11-14T00:38:04.835Z",
                "lastRecordTimestamp": "2019-11-14T00:38:05.580Z",
            },
            "Topic-1": {
                "firstRecordOffset": "49601189658422359378836298521827638475320189012309704722",
                "lastRecordOffset": "49601189658422359378836298522902373528957594348623495186",
                "firstRecordTimestamp": "2019-11-14T00:38:04.835Z",
                "lastRecordTimestamp": "2019-11-14T00:38:05.580Z",
            }
        }
    }
}
```

### Ejemplo de registro de invocación de un destino S3
<a name="kafka-s3-destinations"></a>

Para los destinos de S3, Lambda envía todo el registro de invocación junto con los metadatos al destino. El siguiente ejemplo muestra lo que Lambda envía a un bucket de S3 de destino cuando se produce un error en la invocación de un origen de evento de Kafka. Además de todos los campos del ejemplo anterior para los destinos de SQS y SNS, el campo `payload` contiene el registro de invocación original en forma de cadena JSON de escape.

```
{
    "requestContext": {
        "requestId": "316aa6d0-8154-xmpl-9af7-85d5f4a6bc81",
        "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:myfunction",
        "condition": "RetryAttemptsExhausted" | "MaximumPayloadSizeExceeded",
        "approximateInvokeCount": 1
    },
    "responseContext": { // null if record is MaximumPayloadSizeExceeded
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "version": "1.0",
    "timestamp": "2019-11-14T00:38:06.021Z",
    "KafkaBatchInfo": {
        "batchSize": 500,
        "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/vpc-2priv-2pub/751d2973-a626-431c-9d4e-d7975eb44dd7-2",
        "bootstrapServers": "...",
        "payloadSize": 2039086, // In bytes
        "recordsInfo": {
            "Topic-0": {
                "firstRecordOffset": "49601189658422359378836298521827638475320189012309704722",
                "lastRecordOffset": "49601189658422359378836298522902373528957594348623495186",
                "firstRecordTimestamp": "2019-11-14T00:38:04.835Z",
                "lastRecordTimestamp": "2019-11-14T00:38:05.580Z",
            },
            "Topic-1": {
                "firstRecordOffset": "49601189658422359378836298521827638475320189012309704722",
                "lastRecordOffset": "49601189658422359378836298522902373528957594348623495186",
                "firstRecordTimestamp": "2019-11-14T00:38:04.835Z",
                "lastRecordTimestamp": "2019-11-14T00:38:05.580Z",
            }
        }
    },
    "payload": "<Whole Event>" // Only available in S3
}
```

**sugerencia**  
También se recomienda habilitar el control de versiones de S3 en el bucket de destino.

# Uso de un tema de Kafka como destino en caso de error
<a name="kafka-on-failure-destination"></a>

Puede configurar un tema de Kafka como destino en caso de error para las asignaciones de orígenes de eventos de Kafka. Cuando Lambda no puede procesar los registros tras agotar los reintentos o cuando los registros superan la antigüedad máxima, Lambda envía los registros fallidos al tema de Kafka especificado para su posterior procesamiento. Al configurar un número [reintentos infinitos](kafka-retry-configurations.md) como un destino en caso de error, Lambda aplica automáticamente un máximo de 10 acciones de reintento.

## Cómo funciona un destino en caso de error de Kafka
<a name="kafka-ofd-overview"></a>

Cuando configura un tema de Kafka como destino en caso de error, Lambda actúa como productor de Kafka y escribe los registros fallidos en el tema de destino. Esto crea un patrón de temas de mensajes fallidos (DLT) en su infraestructura de Kafka.
+ **Mismo requisito de clúster**: el tema de destino debe estar en el mismo clúster de Kafka que los temas de origen.
+ **Contenido real del registro**: los destinos de Kafka reciben los registros fallidos reales junto con los metadatos del error.
+ **Prevención de recursión**: Lambda evita los bucles infinitos porque bloquea las configuraciones en las que los temas de origen y destino son los mismos.

## Configuración de un destino en caso de error de Kafka
<a name="kafka-ofd-configure"></a>

Puede configurar un tema de Kafka como un destino en caso de error al crear o actualizar una asignación de orígenes de eventos de Kafka.

### Configuración de un destino de Kafka (consola)
<a name="kafka-ofd-console"></a>

**Cómo configurar un tema de Kafka como destino en caso de error (consola)**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de su función.

1. Realice una de las siguientes acciones:
   + Para añadir un nuevo desencadenador de Kafka, en **Descripción general de la función**, seleccione **Añadir desencadenador**.
   + Para modificar un desencadenador de Kafka existente, selecciónelo y, a continuación, elija **Editar**.

1. En **Configuración adicional**, en **Destino en caso de error**, elija **Tema de Kafka**.

1. En **Nombre del tema**, escriba el nombre del tema de Kafka al que quiere enviar los registros fallidos.

1. Elija **Añadir** o **Guardar**.

### Configuración de un destino de Kafka (AWS CLI)
<a name="kafka-ofd-cli"></a>

Utilice el prefijo `kafka://` para especificar un tema de Kafka como destino en caso de error.

#### Creación de una asignación de orígenes de eventos con el destino de Kafka
<a name="kafka-ofd-cli-create"></a>

En el siguiente ejemplo, se crea una asignación de orígenes de eventos de Amazon MSK con un tema de Kafka como destino en caso de error:

```
aws lambda create-event-source-mapping \
  --function-name my-kafka-function \
  --topics AWSKafkaTopic \
  --event-source-arn arn:aws:kafka:us-east-1:123456789012:cluster/my-cluster/abc123 \
  --starting-position LATEST \
  --provisioned-poller-config MinimumPollers=1,MaximumPollers=3 \
  --destination-config '{"OnFailure":{"Destination":"kafka://failed-records-topic"}}'
```

En el caso de Kafka autoadministrado, utilice la misma sintaxis:

```
aws lambda create-event-source-mapping \
  --function-name my-kafka-function \
  --topics AWSKafkaTopic \
  --self-managed-event-source '{"Endpoints":{"KAFKA_BOOTSTRAP_SERVERS":["abc.xyz.com:9092"]}}' \
  --starting-position LATEST \
  --provisioned-poller-config MinimumPollers=1,MaximumPollers=3 \
  --destination-config '{"OnFailure":{"Destination":"kafka://failed-records-topic"}}'
```

#### Actualización de un destino de Kafka
<a name="kafka-ofd-cli-update"></a>

Utilice el comando `update-event-source-mapping` para añadir o modificar un destino de Kafka:

```
aws lambda update-event-source-mapping \
  --uuid 12345678-1234-1234-1234-123456789012 \
  --destination-config '{"OnFailure":{"Destination":"kafka://failed-records-topic"}}'
```

## Formato de registro para un destino de Kafka
<a name="kafka-ofd-record-format"></a>

Cuando Lambda envía registros fallidos a un tema de Kafka, cada mensaje contiene metadatos sobre el error y el contenido real del registro.

### Metadatos de error
<a name="kafka-ofd-metadata"></a>

Los metadatos incluyen información sobre el motivo por el que se produjo un error en el registro y detalles sobre el lote original:

```
{
  "requestContext": {
    "requestId": "e4b46cbf-b738-xmpl-8880-a18cdf61200e",
    "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function:$LATEST",
    "condition": "RetriesExhausted",
    "approximateInvokeCount": 3
  },
  "responseContext": {
    "statusCode": 200,
    "executedVersion": "$LATEST",
    "functionError": "Unhandled"
  },
  "version": "1.0",
  "timestamp": "2019-11-14T18:16:05.568Z",
  "KafkaBatchInfo": {
    "batchSize": 1,
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/my-cluster/abc123",
    "bootstrapServers": "b-1.mycluster.abc123.kafka.us-east-1.amazonaws.com:9098",
    "payloadSize": 1162,
    "recordInfo": {
      "offset": "49601189658422359378836298521827638475320189012309704722",
      "timestamp": "2019-11-14T18:16:04.835Z"
    }
  },
  "payload": {
    "bootstrapServers": "b-1.mycluster.abc123.kafka.us-east-1.amazonaws.com:9098",
    "eventSource": "aws:kafka",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/my-cluster/abc123",
    "records": {
      "my-topic-0": [
        {
          "headers": [],
          "key": "dGVzdC1rZXk=",
          "offset": 100,
          "partition": 0,
          "timestamp": 1749116692330,
          "timestampType": "CREATE_TIME",
          "topic": "my-topic",
          "value": "dGVzdC12YWx1ZQ=="
        }
      ]
    }
  }
}
```

### Comportamiento de claves de partición
<a name="kafka-ofd-partitioning"></a>

Lambda usa la misma clave de partición del registro original cuando produce para el tema de destino. Si el registro original no tenía ninguna clave, Lambda utiliza la partición por turnos predeterminada de Kafka en todas las particiones disponibles en el tema de destino.

## Requisitos y limitaciones
<a name="kafka-ofd-requirements"></a>
+ **Se requiere el modo aprovisionado**: un destino en caso de error de Kafka solo está disponible para las asignaciones de orígenes de eventos con el modo aprovisionado habilitado.
+ **Solo el mismo clúster**: el tema de destino debe estar en el mismo clúster de Kafka que los temas de origen.
+ **Permisos de tema**: la asignación de orígenes de eventos debe tener permisos de escritura en el tema de destino. Ejemplo:

  ```
  {
      "Version": "2012-10-17",		 	 	 
      "Statement": [
          {
              "Sid": "ClusterPermissions",
              "Effect": "Allow",
              "Action": [
                  "kafka-cluster:Connect",
                  "kafka-cluster:DescribeCluster",
                  "kafka-cluster:DescribeTopic",
                  "kafka-cluster:WriteData",
                  "kafka-cluster:ReadData"
              ],
              "Resource": [
                  "arn:aws:kafka:*:*:cluster/*"
              ]
          },
          {
              "Sid": "TopicPermissions",
              "Effect": "Allow",
              "Action": [
                  "kafka-cluster:DescribeTopic",
                  "kafka-cluster:WriteData",
                  "kafka-cluster:ReadData"
              ],
              "Resource": [
                  "arn:aws:kafka:*:*:topic/*/*"
              ]
          },
          {
              "Effect": "Allow",
              "Action": [
                  "kafka:DescribeCluster",
                  "kafka:GetBootstrapBrokers",
                  "kafka:Produce"
              ],
              "Resource": "arn:aws:kafka:*:*:cluster/*"
          },
          {
              "Effect": "Allow",
              "Action": [
                  "ec2:CreateNetworkInterface",
                  "ec2:DescribeNetworkInterfaces",
                  "ec2:DeleteNetworkInterface",
                  "ec2:DescribeSubnets",
                  "ec2:DescribeSecurityGroups"
              ],
              "Resource": "*"
          }
      ]
  }
  ```
+ **Sin recursión**: el nombre del tema de destino no puede coincidir con ninguno de los nombres del tema de origen.

# Registro de asignación de orígenes de eventos de Kafka
<a name="esm-logging"></a>

Puede configurar el registro a nivel del sistema para las asignaciones de orígenes de eventos de Kafka para habilitar y filtrar los registros del sistema que los sondeadores de eventos de Lambda envían a CloudWatch. 

Esta característica solo está disponible para asignaciones de orígenes de eventos de Kafka y con el [modo aprovisionado](https://docs.aws.amazon.com/lambda/latest/dg/kafka-scaling-modes.html#kafka-provisioned-mode).

Para la asignación de orígenes de eventos con configuración de registro, ahora también puede consultar los registros del sistema a partir de consultas de registro prediseñadas en la pestaña **Supervisar** desde la página de la consola **Lambda** > **Recursos adicionales** > **asignación de orígenes de eventos**.

## Cómo funciona el proceso de registro
<a name="esm-logging-overview"></a>

Cuando establece la configuración de registro con el nivel de registro en su asignación de orígenes de eventos, el sondeador de eventos de Lambda envía los registros correspondientes (registros del sistema de asignación de orígenes de eventos).

La asignación de orígenes de eventos reutiliza el mismo [destino de registro](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-logs.html#configuring-log-destinations) con la función de Lambda. Asegúrese de que el rol de ejecución de la función de Lambda tenga los permisos de registro necesarios.

La asignación de orígenes de eventos tendrá su propio flujo de registro, cuyo nombre estará compuesto por la fecha y el UUID de la asignación de orígenes de eventos, por ejemplo, `2020/01/01/12345678-1234-1234-1234-12345678901`.

Para los registros del sistema de la asignación de orígenes de eventos, puede elegir entre los siguientes niveles de registro.


| Nivel de registro | Uso | 
| --- | --- | 
| DEBUG (más detallado) | Información detallada sobre el progreso del procesamiento del origen de eventos | 
| INFO | Mensajes sobre el funcionamiento normal de la asignación de orígenes de eventos | 
| WARN (menos detallado) | Mensajes sobre posibles advertencias y errores que pueden provocar un comportamiento inesperado | 

Al seleccionar un nivel de registro, el sondeador de eventos de Lambda envía los registros a ese nivel y a niveles inferiores. Por ejemplo, si establece el nivel de registro del sistema de asignación de orígenes de eventos en INFO, el sondeador de eventos no envía las salidas de registro en el nivel DEBUG.

## Configuración del registro
<a name="esm-logging-configure"></a>

Puede establecer la configuración de registro cuando crea o actualiza una asignación de orígenes de eventos de Kafka.

### Configuración de registro (consola)
<a name="esm-logging-console"></a>

**Cómo configurar el proceso de registro (consola)**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de su función.

1. Realice una de las siguientes acciones:
   + Para añadir un nuevo desencadenador de Kafka, en **Descripción general de la función**, seleccione **Añadir desencadenador**.
   + Para modificar un desencadenador de Kafka existente, selecciónelo y, a continuación, elija **Editar**.

1. En la sección **Configuración del sondeador de eventos**, para el **Modo aprovisionado**, habilite la casilla **Configurar**. Aparecerá la configuración del **Nivel de registro**.

1.  Haga clic en la lista desplegable de **Nivel de registro** y seleccione un nivel para la asignación de orígenes de eventos.

1. Seleccione **Añadir** o **Guardar** en la parte inferior para crear o actualizar la asignación de orígenes de eventos.

### Configuración de registros (AWS CLI)
<a name="esm-logging-cli"></a>

#### Creación de una asignación de orígenes de eventos con registro
<a name="esm-logging-cli-create"></a>

En el siguiente ejemplo, se crea una asignación de orígenes de eventos de Amazon MSK con configuración de registro:

```
aws lambda create-event-source-mapping \
  --function-name my-kafka-function \
  --topics AWSKafkaTopic \
  --event-source-arn arn:aws:kafka:us-east-1:123456789012:cluster/my-cluster/abc123 \
  --starting-position LATEST \
  --provisioned-poller-config MinimumPollers=1,MaximumPollers=3 \
  --logging-config '{"SystemLogLevel":"DEBUG"}'
```

En el caso de Kafka autoadministrado, utilice la misma sintaxis:

```
aws lambda create-event-source-mapping \
  --function-name my-kafka-function \
  --topics AWSKafkaTopic \
  --self-managed-event-source '{"Endpoints":{"KAFKA_BOOTSTRAP_SERVERS":["abc.xyz.com:9092"]}}' \
  --starting-position LATEST \
  --provisioned-poller-config MinimumPollers=1,MaximumPollers=3 \
  --logging-config '{"SystemLogLevel":"DEBUG"}'
```

#### Actualización de la configuración de registro
<a name="esm-logging-cli-update"></a>

Use el comando `update-event-source-mapping` para añadir o modificar la configuración de registro:

```
aws lambda update-event-source-mapping \
  --uuid 12345678-1234-1234-1234-123456789012 \
  --logging-config '{"SystemLogLevel":"WARN"}'
```

## Formato del registro del sistema de una asignación de orígenes de eventos de Kafka
<a name="esm-logging-record-format"></a>

Cuando el sondeador de eventos de Lambda envía el registro, cada entrada del registro contiene metadatos generales de la asignación de orígenes de eventos y también contenido específico del evento.

### Registro WARN
<a name="esm-logging-warn-record"></a>

El registro WARN contiene errores o advertencias del sondeador de eventos y se emite cuando ocurre el evento. Por ejemplo:

```
{
    "eventType": "ESM_PROCESSING_EVENT",
    "timestamp": 1546347650000,
    "resourceArn": "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:12345678-1234-1234-1234-123456789012",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/tests-cluster/87654321-4321-4321-4321-876543221-s1",
    "eventProcessorId": "12345678-1234-1234-1234-123456789012/0",
    "logLevel": "WARN",
    "error": {
        "errorMessage": "Timeout expired while fetching topic metadata",
        "errorCode": "org.apache.kafka.common.errors.TimeoutException"
    }
}
```

### Registro INFO
<a name="esm-logging-info-record"></a>

El registro INFO contiene las configuraciones de los clientes consumidores de Kafka en cada sondeador de eventos y se emite en caso de que se cree o modifique un consumidor. Por ejemplo:

```
{
    "eventType": "POLLER_STATUS_EVENT",
    "timestamp": 1546347660000,
    "resourceArn": "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:12345678-1234-1234-1234-123456789012",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/tests-cluster/87654321-4321-4321-4321-876543221-s1",
    "eventProcessorId": "12345678-1234-1234-1234-123456789012/0",
    "logLevel": "INFO",
    "kafkaEventSourceConnection": {
        "brokerEndpoints": "boot-abcd1234.c2.kafka-serverless.us-east-1.amazonaws.com:9098",
        "consumerId": "12345678-1234-1234-1234-123456789012-0",
        "topics": [
            "test"
        ],
        "consumerGroupId": "12345678-1234-1234-1234-123456789012",
        "securityProtocol": "SASL_SSL",
        "saslMechanism": "AWS_MSK_IAM",
        "totalPartitionCount": 2,
        "assignedPartitionCount": 2,
        "partitionsAssignmentGeneration": 5,
        "assignedPartitions": [
            "test-0",
            "test-1"
        ],
        "networkConfig": {
            "ipAddresses": [
                "10.100.141.1"
            ],
            "subnetCidrBlock": "10.100.128.0/20",
            "securityGroups": [
                "sg-abcdefabcdefabcdef"
            ]
        }
    }
}
```

### Registro DEBUG
<a name="esm-logging-debug-record"></a>

El registro DEBUG contiene la información relacionada con los desplazamientos de Kafka en el procesamiento de la asignación de orígenes de eventos, y la información de desplazamiento se emite por minuto. Por ejemplo:

```
{
    "eventType": "KAFKA_STATUS_EVENT",
    "timestamp": 1546347670000,
    "resourceArn": "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:12345678-1234-1234-1234-123456789012",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/tests-cluster/87654321-4321-4321-4321-876543221-s1",
    "eventProcessorId": "12345678-1234-1234-1234-123456789012/0",
    "logLevel": "DEBUG",
    "kafkaPartitionOffsets": {
        "partition": "test-1",
        "endOffset": 5004,
        "consumedOffset": 5003,
        "processedOffset": 5003,
        "committedOffset": 5004
    }
}
```

# Solución de errores de asignación de orígenes de eventos de Kafka
<a name="with-kafka-troubleshoot"></a>

En los siguientes temas se proporcionan consejos para solucionar errores y problemas que puedan surgir cuando utilice Amazon MSK o Apache Kafka autoadministrado con Lambda.

Para obtener más ayuda con la solución de problemas, visite el [Centro de conocimiento de AWS](https://repost.aws/knowledge-center#AWS_Lambda).

## Errores de autenticación y autorización
<a name="kafka-permissions-errors"></a>

Si falta alguno de los permisos necesarios para consumir datos del clúster de Kafka, Lambda muestra uno de los siguientes mensajes de error en la asignación de orígenes de eventos en **LastProcessingResult**.

**Topics**
+ [

### Error de autorización del clúster a Lambda
](#kafka-authorize-errors)
+ [

### Error de autenticación de SASL
](#kafka-sasl-errors)
+ [

### El servidor no pudo autenticar Lambda
](#kafka-mtls-errors-server)
+ [

### Lambda no ha podido autenticar el servidor
](#kafka-mtls-errors-lambda)
+ [

### El certificado o la clave privada proporcionados no son válidos
](#kafka-key-errors)

### Error de autorización del clúster a Lambda
<a name="kafka-authorize-errors"></a>

Para SASL/SCRAM o mTLS, este error indica que el usuario proporcionado no tiene todos los permisos de lista de control de acceso (ACL) de Kafka necesarios que se indican a continuación:
+ Clúster DescribeConfigs
+ Descripción del grupo
+ Grupo de lectura
+ Descripción del tema
+ Tema de lectura

Cuando crea las ACL de Kafka con los permisos de `kafka-cluster` necesarios, debe especificar el tema y el grupo como recursos. El nombre del tema debe coincidir con el tema de la asignación de origen de eventos. El nombre del grupo debe coincidir con el UUID de la asignación de origen de eventos.

Después de agregar los permisos necesarios al rol de ejecución, pueden pasar varios minutos hasta que los cambios surtan efecto.

El siguiente es un ejemplo de registro a nivel del sistema de la ESM después de habilitar la [Configuración de registro](esm-logging.md) para este problema:

```
{
    "eventType": "ESM_PROCESSING_EVENT",
    "timestamp": 1734567890123,
    "resourceArn": "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:a1b2c3d4-5678-90ab-cdef-EXAMPLE11111",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/my-kafka-cluster/12345678-abcd-1234-efgh-EXAMPLE11111-1",
    "eventProcessorId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE11111/0",
    "logLevel": "WARN",
    "error": {
        "errorMessage": "Not authorized to access topics: [my-topic]",
        "errorCode": "org.apache.kafka.common.errors.TopicAuthorizationException"
    }
}
```

### Error de autenticación de SASL
<a name="kafka-sasl-errors"></a>

Para SASL/SCRAM o SASL/PLAIN, este error indica que las credenciales de inicio de sesión proporcionadas no son válidas.

Para el control de acceso de IAM, falta el permiso `kafka-cluster:Connect` para el clúster en el rol de ejecución. Agregue este permiso al rol y especifique el nombre de recurso de Amazon (ARN) del clúster como recurso.

Es posible que vea que este error se produce de forma intermitente. El clúster rechaza las conexiones después de que el número de conexiones TCP supere la Service Quotas. Lambda retrocede y vuelve a intentarlo hasta que una conexión tenga éxito. Después de que Lambda se conecte al clúster y sondee los registros, el último resultado de procesamiento cambia a `OK`.

El siguiente es un ejemplo de registro a nivel del sistema de la ESM después de habilitar la [Configuración de registro](esm-logging.md) para este problema cuando se utiliza la autenticación de IAM:

```
{
    "eventType": "ESM_PROCESSING_EVENT",
    "timestamp": 1734567890456,
    "resourceArn": "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:a1b2c3d4-5678-90ab-cdef-EXAMPLE22222",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/my-kafka-cluster/12345678-abcd-1234-efgh-EXAMPLE22222-1",
    "eventProcessorId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE22222/0",
    "logLevel": "WARN",
    "error": {
        "errorMessage": "[a1b2c3d4-5678-90ab-cdef-EXAMPLE22222]: Access denied",
        "errorCode": "org.apache.kafka.common.errors.SaslAuthenticationException"
    }
}
```

### El servidor no pudo autenticar Lambda
<a name="kafka-mtls-errors-server"></a>

Este error indica que el agente de Kafka no ha podido autenticar Lambda. Este error puede producirse por cualquiera de las razones siguientes:
+ No proporcionó ningún certificado de cliente para la autenticación de mTLS.
+ Proporcionó un certificado de cliente, pero los agentes de Kafka no están configurados para utilizar la autenticación de mTLS.
+ Los agentes de Kafka no confían en el certificado de cliente.

### Lambda no ha podido autenticar el servidor
<a name="kafka-mtls-errors-lambda"></a>

Este error indica que Lambda no ha podido autenticar el agente de Kafka. Este error puede producirse por cualquiera de las razones siguientes:
+ En el caso de Apache Kafka autoadministrado: los agentes de Kafka utilizan certificados autofirmados o una entidad de certificación privada, pero no proporcionaron el certificado CA raíz del servidor.
+ En el caso de Apache Kafka autoadministrado: el certificado CA raíz del servidor no coincide con la CA raíz que firmó el certificado del agente.
+ No se pudo validar el nombre de host porque el certificado del agente no contiene el nombre DNS ni la dirección IP del agente como nombre alternativo de sujeto.

### El certificado o la clave privada proporcionados no son válidos
<a name="kafka-key-errors"></a>

Este error indica que el consumidor de Kafka no ha podido utilizar la clave privada ni el certificado proporcionados. Asegúrese de que el formato del certificado y la clave sea PEM, y de que el cifrado de clave privada utilice un algoritmo PBES1.

El siguiente es un ejemplo de registro a nivel del sistema de la ESM después de habilitar la [Configuración de registro](esm-logging.md) para este problema:

```
{
    "eventType": "ESM_PROCESSING_EVENT",
    "timestamp": 1734567891234,
    "resourceArn": "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:a1b2c3d4-5678-90ab-cdef-EXAMPLE44444",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/my-kafka-cluster/12345678-abcd-1234-efgh-EXAMPLE44444-1",
    "eventProcessorId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE44444/0",
    "logLevel": "WARN",
    "error": {
        "errorMessage": "Invalid PEM keystore configs",
        "errorCode": "org.apache.kafka.common.errors.InvalidConfigurationException"
    }
}
```

## Errores de red y conectividad
<a name="kafka-network-errors"></a>

Los problemas de configuración de la red pueden impedir que Lambda se conecte al clúster de Kafka. En los temas siguientes se describen los errores comunes relacionados con la red.

**Topics**
+ [

### Tiempo de espera de conexión agotado debido a la configuración del grupo de seguridad
](#kafka-security-group-errors)
+ [

### Los puntos de conexión del agente de Kafka no se pueden resolver
](#kafka-cluster-deleted-errors)

### Tiempo de espera de conexión agotado debido a la configuración del grupo de seguridad
<a name="kafka-security-group-errors"></a>

Si el grupo de seguridad asociado al clúster de Kafka no permite el tráfico entrante procedente de sí mismo, Lambda no podrá conectarse al clúster. Asegúrese de que las reglas de entrada del grupo de seguridad permitan el tráfico procedente del propio grupo de seguridad en los puertos del agente de Kafka.

El siguiente es un ejemplo de registro a nivel del sistema de la ESM después de habilitar la [Configuración de registro](esm-logging.md) para este problema:

```
{
    "eventType": "ESM_PROCESSING_EVENT",
    "timestamp": 1734567892345,
    "resourceArn": "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:a1b2c3d4-5678-90ab-cdef-EXAMPLE55555",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/my-kafka-cluster/12345678-abcd-1234-efgh-EXAMPLE55555-1",
    "eventProcessorId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE55555/0",
    "logLevel": "WARN",
    "error": {
        "errorMessage": "Timeout expired while fetching topic metadata",
        "errorCode": "org.apache.kafka.common.errors.TimeoutException"
    }
}
```

También puede consultar el registro de información para consumidores de Kafka para verificar la conexión y la configuración de la red. En el campo `brokerEndpoints` se muestran las direcciones de los agentes de Kafka; en el `securityProtocol` y `saslMechanism`, si corresponde, se muestra el método de autenticación; y en el campo `networkConfig` se muestran las direcciones IP, el bloque de CIDR de la subred y los grupos de seguridad utilizados en la asignación de orígenes de eventos. Verifique que los grupos de seguridad de la lista permitan el tráfico entrante necesario:

```
{
    "eventType": "POLLER_STATUS_EVENT",
    "timestamp": 1734567892456,
    "resourceArn": "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:a1b2c3d4-5678-90ab-cdef-11111EXAMPLE",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/my-kafka-cluster/a1b2c3d4-5678-90ab-cdef-11111EXAMPLE-1",
    "eventProcessorId": "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE/0",
    "logLevel": "INFO",
    "kafkaEventSourceConnection": {
        "brokerEndpoints": "boot-abcd1234.c2.kafka-serverless.us-east-1.amazonaws.com:9098",
        "consumerId": "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE-0",
        "topics": [
            "my-topic"
        ],
        "consumerGroupId": "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE",
        "securityProtocol": "SASL_SSL",
        "saslMechanism": "AWS_MSK_IAM",
        "totalPartitionCount": 2,
        "assignedPartitionCount": 2,
        "partitionsAssignmentGeneration": 1,
        "assignedPartitions": [
            "my-topic-0",
            "my-topic-1"
        ],
        "networkConfig": {
            "ipAddresses": [
                "10.0.0.37"
            ],
            "subnetCidrBlock": "10.0.0.32/28",
            "securityGroups": [
                "sg-0123456789abcdef0"
            ]
        }
    }
}
```

### Los puntos de conexión del agente de Kafka no se pueden resolver
<a name="kafka-cluster-deleted-errors"></a>

Este error indica que el clúster de Kafka no existe o se ha eliminado. Verifique que el clúster especificado en la asignación de orígenes de eventos existe y se encuentra en un estado activo.

El siguiente es un ejemplo de registro a nivel del sistema de la ESM después de habilitar la [Configuración de registro](esm-logging.md) para este problema:

```
{
    "eventType": "ESM_PROCESSING_EVENT",
    "timestamp": 1734567893456,
    "resourceArn": "arn:aws:lambda:us-east-1:123456789012:event-source-mapping:a1b2c3d4-5678-90ab-cdef-EXAMPLE66666",
    "eventSourceArn": "arn:aws:kafka:us-east-1:123456789012:cluster/my-kafka-cluster/12345678-abcd-1234-efgh-EXAMPLE66666-1",
    "eventProcessorId": "a1b2c3d4-5678-90ab-cdef-EXAMPLE66666/0",
    "logLevel": "WARN",
    "error": {
        "errorMessage": "No resolvable bootstrap urls given in bootstrap.servers",
        "errorCode": "org.apache.kafka.common.config.ConfigException"
    }
}
```

## Errores de asignación de orígenes de eventos
<a name="services-event-errors"></a>

Cuando agrega el clúster de Apache Kafka como un [origen de eventos](invocation-eventsourcemapping.md) para su función de Lambda, si su función encuentra un error, su consumidor de Kafka deja de procesar registros. Los consumidores de una partición de tema son aquellos que se suscriben, leen y procesan sus registros. Sus otros consumidores de Kafka pueden continuar procesando registros, siempre que no encuentren el mismo error.

Para determinar la causa de un consumidor detenido, compruebe el `StateTransitionReason` campo en la respuesta de `EventSourceMapping`. En la siguiente lista se describen los errores de origen de eventos que puede recibir:

**`ESM_CONFIG_NOT_VALID`**  
La configuración de asignación de orígenes de eventos no es válida.

**`EVENT_SOURCE_AUTHN_ERROR`**  
Lambda no pudo autenticar el origen de eventos.

**`EVENT_SOURCE_AUTHZ_ERROR`**  
Lambda no tiene los permisos necesarios para acceder al origen de eventos.

**`FUNCTION_CONFIG_NOT_VALID`**  
La configuración de la función no es válida.

**nota**  
Si los registros de eventos de Lambda superan el límite de tamaño permitido de 6 MB, pueden no procesarse.

# Invocación de una función de Lambda mediante un punto de conexión de Amazon API Gateway
<a name="services-apigateway"></a>

Puede crear una API web con un punto de enlace HTTP para la función Lambda utilizando Amazon API Gateway. API Gateway dispone de herramientas para crear y documentar API web que enrutan solicitudes HTTP a funciones de Lambda. Puede proteger el acceso a la API con controles de autenticación y autorización. Las API pueden atender el tráfico a través de Internet o estar accesibles exclusivamente en la VPC.

**sugerencia**  
Lambda ofrece dos formas de invocar la función a través de un punto de conexión HTTP: API Gateway y URL de función de Lambda. Si no está seguro de cuál es el mejor método para el caso, consulte [Selección de un método para invocar una función de Lambda mediante una solicitud HTTP](apig-http-invoke-decision.md).

Los recursos de la API definen uno o varios métodos, como GET o POST. Los métodos tienen una integración que enruta las solicitudes a una función Lambda o a otro tipo de integración. Puede definir cada recurso y cada método de manera individual, o utilizar tipos de recursos y métodos especiales para que coincidan con todas las solicitudes que se ajustan a un patrón. Un [recurso proxy](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html) captura todas las rutas que hay debajo de un recurso. El método `ANY` captura todos los métodos HTTP.

**Topics**
+ [

## Elegir un tipo de API
](#services-apigateway-apitypes)
+ [

## Adición de un punto de conexión a la función de Lambda
](#apigateway-add)
+ [

## Integración de proxy
](#apigateway-proxy)
+ [

## Formato de eventos
](#apigateway-example-event)
+ [

## Formato de respuesta
](#apigateway-types-transforms)
+ [

## Permisos
](#apigateway-permissions)
+ [

## Aplicación de muestra
](#services-apigateway-samples)
+ [

## Controlador de eventos de Powertools para AWS Lambda
](#services-apigateway-powertools)
+ [

# Tutorial: Uso de Lambda con API Gateway
](services-apigateway-tutorial.md)
+ [

# Manejo de los errores en Lambda con una API de API Gateway
](services-apigateway-errors.md)
+ [

# Selección de un método para invocar una función de Lambda mediante una solicitud HTTP
](apig-http-invoke-decision.md)

## Elegir un tipo de API
<a name="services-apigateway-apitypes"></a>

API Gateway admite tres tipos de API que invocan funciones de Lambda:
+ [API HTTP](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html): una API de RESTful ligera de baja latencia.
+ [API de REST](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html): una API de RESTful personalizable con gran variedad de características.
+ [API de WebSocket](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html): una API web que mantiene conexiones persistentes con clientes para una comunicación dúplex completa.

Las API HTTP y REST son API RESTful que procesan solicitudes HTTP y devuelven respuestas. Las API HTTP son más recientes y se construyen con la API de la versión 2 de API Gateway. Las siguientes características son nuevas en las API HTTP:

**Características de las API HTTP**
+ **Implementaciones automáticas**: cuando se modifican rutas o integraciones, los cambios se implementan automáticamente en etapas que tienen habilitada la implementación automática.
+ **Etapa predeterminada**: puede crear una etapa predeterminada (`$default`) para atender las solicitudes en la ruta raíz de la URL de la API. En las etapas con nombre asignado, debe incluir el nombre de la etapa al principio de la ruta.
+ **Configuración CORS**: puede configurar la API para agregar encabezados CORS a las respuestas salientes, en lugar de agregarlos en forma manual en el código de función.

Las API REST son las API RESTful clásicas que API Gateway admite desde su lanzamiento. En la actualidad, las API REST tienen más características de personalización, integración y administración.

**Características de las API REST**
+ **Tipos de integración**: las API REST son compatibles con las integraciones de Lambda personalizadas. Con una integración personalizada, puede enviar solo el cuerpo de la solicitud a la función o aplicar una plantilla de transformación al cuerpo de la solicitud antes de enviarla a la función.
+ **Control de acceso**: las API REST admiten más opciones de autenticación y autorización.
+ **Monitoreo y seguimiento**: la API REST admiten el seguimiento de AWS X-Ray y otras opciones de registro.

Para ver una comparativa detallada, consulte [Elección entre las API de REST y las API de HTTP](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-vs-rest.html) en la *Guía para desarrolladores de API Gateway*.

Las API de WebSocket también usan la API de la versión 2 de API Gateway y admiten un conjunto de características similares. Utilice una API de WebSocket para las aplicaciones que se benefician de una conexión persistente entre el cliente y la API. Las API de WebSocket proporcionan comunicación dúplex completa, lo que significa que tanto el cliente como la API pueden enviar mensajes continuamente sin esperar una respuesta.

Las API HTTP admiten un formato de evento simplificado (versión 2.0). Para ver un ejemplo de un evento de una API de HTTP, consulte [Creación de integraciones proxy de AWS Lambda para la API de HTTP en API Gateway](https://docs.aws.amazon.com//apigateway/latest/developerguide/http-api-develop-integrations-lambda.html).

Para obtener más información, consulte [Creación de integraciones de proxy de AWS Lambda Lambda para las API de HTTP en API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html).

## Adición de un punto de conexión a la función de Lambda
<a name="apigateway-add"></a>

**Para agregar un punto de enlace público a la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija una función.

1. En **Descripción general de la función**, elija **Agregar desencadenador**.

1. Seleccione **API Gateway**.

1. Seleccione **Create an API** (Crear una API) o **Use an existing API** (Usar una API existente).

   1. **Nueva API:** Para **API type** (Tipo de API), elija **HTTP API** (API HTTP). Para obtener más información, consulte [Elegir un tipo de API](#services-apigateway-apitypes).

   1. **API existente:** seleccione la API en la lista desplegable o ingrese el ID de API (p. ej., r3pmxmplak).

1. En **Security (Seguridad)**, elija **Open (Abrir)**.

1. Elija **Añadir**.

## Integración de proxy
<a name="apigateway-proxy"></a>

Las API de API Gateway se componen de etapas, recursos, métodos e integraciones. La etapa y el recurso determinan la ruta del punto de enlace:

**Formato de la ruta de las API**
+ `/prod/`: etapa `prod` y recurso raíz.
+ `/prod/user`: etapa `prod` y recurso `user`.
+ `/dev/{proxy+}`: cualquier ruta de la etapa `dev`.
+ `/`: (API HTTP) etapa predeterminada y recurso raíz.

La integración de Lambda asigna una combinación de ruta y método HTTP a una función de Lambda. Puede configurar API Gateway para pasar el cuerpo de la solicitud HTTP tal cual (integración personalizada) o para encapsular el cuerpo de la solicitud en un documento que incluya toda la información de la solicitud, incluidos los encabezados, los recursos, la ruta y el método.

Para obtener más información, consulte [Integraciones de proxy de Lambda en API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html).

## Formato de eventos
<a name="apigateway-example-event"></a>

Amazon API Gateway invoca la función [sincrónicamente](invocation-sync.md) con un evento que contiene una representación JSON de la solicitud HTTP. En las integraciones personalizadas, el evento es el cuerpo de la solicitud. En las integraciones de proxy, el evento tiene una estructura definida. Para ver un ejemplo de un evento de proxy de una API de REST de API Gateway, consulte [Formato de entrada de una función de Lambda para la integración de proxy](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format) en la *Guía para desarrolladores de API Gateway*.

## Formato de respuesta
<a name="apigateway-types-transforms"></a>

API Gateway espera una respuesta de la función y transmite el resultado a la persona que llama. En las integraciones personalizadas, debe definir una respuesta de integración y una respuesta de método para convertir la salida de la función en una respuesta HTTP. En las integraciones de proxy, la función debe responder con una representación de la respuesta en un formato específico.

En el ejemplo siguiente, se muestra un objeto response de una función Node.js. El objeto response representa una respuesta HTTP correcta que contiene un documento JSON.

**Example index.mjs: objeto de respuesta de integración de proxy (Node.js).**  

```
var response = {
      "statusCode": 200,
      "headers": {
        "Content-Type": "application/json"
      },
      "isBase64Encoded": false,
      "multiValueHeaders": { 
        "X-Custom-Header": ["My value", "My other value"],
      },
      "body": "{\n  \"TotalCodeSize\": 104330022,\n  \"FunctionCount\": 26\n}"
    }
```

El tiempo de ejecución de Lambda serializa el objeto response en un archivo JSON y lo envía a la API. La API analiza la respuesta y la utiliza para crear una respuesta HTTP, que luego envía al cliente que realizó la solicitud original.

**Example Respuesta HTTP**  

```
< HTTP/1.1 200 OK
  < Content-Type: application/json
  < Content-Length: 55
  < Connection: keep-alive
  < x-amzn-RequestId: 32998fea-xmpl-4268-8c72-16138d629356
  < X-Custom-Header: My value
  < X-Custom-Header: My other value
  < X-Amzn-Trace-Id: Root=1-5e6aa925-ccecxmplbae116148e52f036
  <
  {
    "TotalCodeSize": 104330022,
    "FunctionCount": 26
  }
```

## Permisos
<a name="apigateway-permissions"></a>

Amazon API Gateway necesita permiso para invocar la función desde la [política basada en recursos](access-control-resource-based.md) de la función. Puede conceder permiso de invocación a toda una API o conceder acceso limitado a una etapa, un recurso o un método.

Cuando agrega una API a la función utilizando la consola de Lambda, la consola de API Gateway o una plantilla de AWS SAM, la política basada en recursos de la función se actualiza automáticamente. A continuación se muestra una política de función de ejemplo.

**Example política de funciones**    
****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Id": "default",
  "Statement": [
    {
      "Sid": "nodejs-apig-functiongetEndpointPermissionProd-BWDBXMPLXE2F",
      "Effect": "Allow",
      "Principal": {
        "Service": "apigateway.amazonaws.com"
      },
      "Action": "lambda:InvokeFunction",
      "Resource": "arn:aws:lambda:us-east-2:111122223333:function:nodejs-apig-function-1G3MXMPLXVXYI",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "111122223333"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:execute-api:us-east-2:111122223333:ktyvxmpls1/*/GET/"
        }
      }
    }
  ]
}
```

Puede administrar manualmente los permisos de las políticas de funciones con las siguientes operaciones de API:
+ [AddPermission](https://docs.aws.amazon.com/lambda/latest/api/API_AddPermission.html)
+ [RemovePermission](https://docs.aws.amazon.com/lambda/latest/api/API_RemovePermission.html)
+ [GetPolicy](https://docs.aws.amazon.com/lambda/latest/api/API_GetPolicy.html)

Para conceder permiso de invocación a una API existente, utilice el comando `add-permission`. Ejemplo:

```
aws lambda add-permission \
  --function-name my-function \
  --statement-id apigateway-get --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:us-east-2:123456789012:mnh1xmpli7/default/GET/"
```

Debería ver los siguientes datos de salida:

```
{
    "Statement": "{\"Sid\":\"apigateway-test-2\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"apigateway.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-2:123456789012:function:my-function\",\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":\"arn:aws:execute-api:us-east-2:123456789012:mnh1xmpli7/default/GET\"}}}"
}
```

**nota**  
Si la función y la API se encuentran en Regiones de AWS diferentes, el identificador de región en el ARN del origen debe coincidir con la región de la función, no la región de la API. Cuando API Gateway invoca una función, utiliza el ARN de un recurso que se basa en el ARN de la API, pero que se ha modificado para que coincida con la región de la función.

El ARN de origen de este ejemplo concede permiso a una integración del método GET del recurso raíz en la etapa predeterminada de una API, con el ID `mnh1xmpli7`. Puede utilizar un asterisco en el ARN de origen para conceder permisos a varias etapas, métodos o recursos.

**Patrones de recursos**
+ `mnh1xmpli7/*/GET/*`: método GET de todos los recursos en todas las etapas.
+ `mnh1xmpli7/prod/ANY/user`: método ANY del recurso `user` en la etapa `prod`.
+ `mnh1xmpli7/*/*/*`: cualquier método de todos los recursos en todas las etapas.

Para obtener información detallada acerca de cómo ver la política y quitar instrucciones, consulte [Ver políticas de IAM basadas en recursos en Lambda](access-control-resource-based.md).

## Aplicación de muestra
<a name="services-apigateway-samples"></a>

La aplicación de muestra [API Gateway con Node.js](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/nodejs-apig) incluye una función con una plantilla de SAM AWS SAM que crea una API de REST que tiene el seguimiento de AWS X-Ray habilitado. También incluye scripts para implementar, invocar la función, probar la API y limpiar.

## Controlador de eventos de Powertools para AWS Lambda
<a name="services-apigateway-powertools"></a>

El controlador de eventos del kit de herramientas de Powertools para AWS Lambda proporciona enrutamiento, middleware, configuración CORS, generación de especificaciones de OpenAPI, validación de solicitudes, manejo de errores y otras características útiles durante la escritura de funciones de Lambda invocadas por un punto de conexión de una API Gateway (HTTP o REST). La utilidad de controlador de eventos está disponible para Python y TypeScript/JavaScript. Para obtener más información, consulte la [API de REST del controlador de eventos](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/) en la documentación de *Powertools para AWS Lambda (Python)* y la [API de HTTP del controlador de eventos](https://docs.aws.amazon.com/powertools/typescript/latest/features/event-handler/http/) en la documentación de *Powertools para AWS Lambda* (TypeScript).

### Python
<a name="services-apigateway-powertools-python"></a>

```
from aws_lambda_powertools import Logger
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing.lambda_context import LambdaContext

app = APIGatewayRestResolver()
logger = Logger()

@app.get("/healthz")
def ping():
    return {"message": "health status ok"}

@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)  
def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)
```

### Typescript
<a name="services-apigateway-powertools-typescript"></a>

```
import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest';
import { Logger } from '@aws-lambda-powertools/logger';
import {
  correlationPaths,
  search,
} from '@aws-lambda-powertools/logger/correlationId';
import type { Context } from 'aws-lambda/handler';

const logger = new Logger({
  correlationIdSearchFn: search,
});

const app = new Router({ logger });

app.get("/healthz", async () => {
  return { message: "health status ok" };
});

export const handler = async (event: unknown, context: Context) => {
  // You can continue using other utilities just as before
  logger.addContext(context);
  logger.setCorrelationId(event, correlationPaths.API_GATEWAY_REST);
  return app.resolve(event, context);
};
```

# Tutorial: Uso de Lambda con API Gateway
<a name="services-apigateway-tutorial"></a>

En este tutorial, se crea una API de REST a través la cual invoca una función de Lambda mediante una solicitud HTTP. Su función de Lambda realizará operaciones de creación, lectura, actualización y eliminación (CRUD) en una tabla de DynamoDB. Se proporciona esta función a modo de demostración, pero aprenderá a configurar una API de REST de API Gateway que pueda invocar cualquier función de Lambda.

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/APIG_tut_resources.png)


El uso de API Gateway proporciona a los usuarios un punto de conexión seguro en HTTP para invocar la función de Lambda y puede ayudar a gestionar grandes volúmenes de llamadas a su función al limitar el tráfico, validar y autorizar automáticamente las llamadas a la API. API Gateway también proporciona controles de seguridad flexibles mediante AWS Identity and Access Management (IAM) y Amazon Cognito. Esto resulta útil para los casos de uso en los que se requiere una autorización previa para las llamadas a la aplicación.

**sugerencia**  
Lambda ofrece dos formas de invocar la función a través de un punto de conexión HTTP: API Gateway y URL de función de Lambda. Si no está seguro de cuál es el mejor método para el caso, consulte [Selección de un método para invocar una función de Lambda mediante una solicitud HTTP](apig-http-invoke-decision.md).

Para completar este tutorial, pasará por las siguientes etapas:

1. Cree y configure una función de Lambda en Python o Node.js para realizar operaciones en una tabla de DynamoDB.

1. Cree una API de REST en API Gateway para conectarse a la función de Lambda.

1. Cree una tabla de DynamoDB y pruébela con la función de Lambda en la consola.

1. Despliegue su API y pruebe la configuración completa con curl en una terminal.

Al completar estas etapas, aprenderá a utilizar API Gateway para crear un punto de conexión en HTTP que pueda invocar de forma segura una función de Lambda a cualquier escala. También aprenderá a implementar su API, a probarla en la consola y a enviar una solicitud HTTP mediante una terminal.

## Creación de una política de permisos
<a name="services-apigateway-tutorial-policy"></a>

Para poder crear un [rol de ejecución](lambda-intro-execution-role.md) para la función de Lambda, primero debe crear una política de permisos que permita a la función acceder a los recursos de AWS necesarios. Para este tutorial, la política le permite a Lambda realizar operaciones de CRUD en una tabla de DynamoDB y escribir en Registros de Amazon CloudWatch.

**Para crear la política de**

1. Abra la página de [Policies (Políticas)](https://console.aws.amazon.com/iam/home#/policies) de la consola de IAM.

1. Seleccione **Crear política**.

1. Elija la pestaña **JSON** y pegue la siguiente política personalizada en el editor JSON.

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

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Sid": "Stmt1428341300017",
         "Action": [
           "dynamodb:DeleteItem",
           "dynamodb:GetItem",
           "dynamodb:PutItem",
           "dynamodb:Query",
           "dynamodb:Scan",
           "dynamodb:UpdateItem"
         ],
         "Effect": "Allow",
         "Resource": "*"
       },
       {
         "Sid": "",
         "Resource": "*",
         "Action": [
           "logs:CreateLogGroup",
           "logs:CreateLogStream",
           "logs:PutLogEvents"
         ],
         "Effect": "Allow"
       }
     ]
   }
   ```

------

1. Elija **Siguiente: Etiquetas**.

1. Elija **Siguiente: Revisar**.

1. En **Review policy (Revisar política)**, para el **Name (Nombre)** de la política, ingrese **lambda-apigateway-policy**.

1. Elija **Crear política**.

## Creación de un rol de ejecución
<a name="services-apigateway-tutorial-role"></a>

Un [rol de ejecución](lambda-intro-execution-role.md) es un rol de AWS Identity and Access Management (IAM) que concede a la función de Lambda permiso para acceder a recursos y Servicios de AWS. Para permitir que la función realice operaciones en una tabla de DynamoDB, adjuntará la política de permisos que creó en el paso anterior.

**Para crear una función de ejecución y adjuntar su política de permisos personalizada**

1. Abra la [página Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Elija **Creación de rol**.

1. Para el tipo de entidad de confianza, seleccione **Servicio de AWS** y, para el caso de uso, elija **Lambda**.

1. Elija **Siguiente**.

1. En el cuadro de búsqueda de políticas, escriba **lambda-apigateway-policy**.

1. En los resultados de búsqueda, seleccione la política que ha creado (`lambda-apigateway-policy`), y luego **Next** (Siguiente).

1. En **Role details** (Detalles del rol), introduzca **lambda-apigateway-role** en **Role name** (Nombre del rol) y, luego, elija **Create role** (Crear rol).

## Crear la función de Lambda
<a name="services-apigateway-tutorial-function"></a>

1. Abra la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) de la consola de Lambda y elija **Crear función**.

1. Elija **Crear desde cero**.

1. En **Nombre de la función**, introduzca `LambdaFunctionOverHttps`.

1. En **tiempo de ejecución**, elija el tiempo de ejecución de Node.js o Python más reciente.

1. En **Permissions** (Permisos), expanda **Change default execution role**(Cambiar rol de ejecución predeterminado).

1. Elija **Usar un rol existente** y, a continuación, seleccione el rol **lambda-apigateway-role** que creó antes.

1. Seleccione **Creación de función**.

1. En el panel **Código de fuente**, sustituya el código predeterminado por el siguiente código de Node.js o Python.

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

   La configuración de la `region` debe coincidir con la Región de AWS en la que se implementa la función y se [crea la tabla de DynamoDB](#services-apigateway-tutorial-table).

**Example index.mjs**  

   ```
   import { DynamoDBDocumentClient, PutCommand, GetCommand, 
            UpdateCommand, DeleteCommand} from "@aws-sdk/lib-dynamodb";
   import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
   
   const ddbClient = new DynamoDBClient({ region: "us-east-2" });
   const ddbDocClient = DynamoDBDocumentClient.from(ddbClient);
   
   // Define the name of the DDB table to perform the CRUD operations on
   const tablename = "lambda-apigateway";
   
   /**
    * Provide an event that contains the following keys:
    *
    *   - operation: one of 'create,' 'read,' 'update,' 'delete,' or 'echo'
    *   - payload: a JSON object containing the parameters for the table item
    *     to perform the operation on
    */
   export const handler = async (event, context) => {
      
        const operation = event.operation;
      
        if (operation == 'echo'){
             return(event.payload);
        }
        
       else { 
           event.payload.TableName = tablename;
           let response;
           
           switch (operation) {
             case 'create':
                  response = await ddbDocClient.send(new PutCommand(event.payload));
                  break;
             case 'read':
                  response = await ddbDocClient.send(new GetCommand(event.payload));
                  break;
             case 'update':
                  response = ddbDocClient.send(new UpdateCommand(event.payload));
                  break;
             case 'delete':
                  response = ddbDocClient.send(new DeleteCommand(event.payload));
                  break;
             default:
               response = 'Unknown operation: ${operation}';
             }
           console.log(response);
           return response;
       }
   };
   ```

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

**Example lambda\$1function.py**  

   ```
   import boto3
   
   # Define the DynamoDB table that Lambda will connect to
   table_name = "lambda-apigateway"
   
   # Create the DynamoDB resource
   dynamo = boto3.resource('dynamodb').Table(table_name)
   
   # Define some functions to perform the CRUD operations
   def create(payload):
       return dynamo.put_item(Item=payload['Item'])
   
   def read(payload):
       return dynamo.get_item(Key=payload['Key'])
   
   def update(payload):
       return dynamo.update_item(**{k: payload[k] for k in ['Key', 'UpdateExpression', 
       'ExpressionAttributeNames', 'ExpressionAttributeValues'] if k in payload})
   
   def delete(payload):
       return dynamo.delete_item(Key=payload['Key'])
   
   def echo(payload):
       return payload
   
   operations = {
       'create': create,
       'read': read,
       'update': update,
       'delete': delete,
       'echo': echo,
   }
   
   def lambda_handler(event, context):
       '''Provide an event that contains the following keys:
         - operation: one of the operations in the operations dict below
         - payload: a JSON object containing parameters to pass to the 
           operation being performed
       '''
       
       operation = event['operation']
       payload = event['payload']
       
       if operation in operations:
           return operations[operation](payload)
           
       else:
           raise ValueError(f'Unrecognized operation "{operation}"')
   ```

------
**nota**  
En este ejemplo, el nombre de la tabla de DynamoDB se define como una variable en el código de la función. En la aplicación real, la mejor práctica es pasar este parámetro como variable de entorno y evitar codificar el nombre de la tabla. Para obtener más información, consulte [Uso de variables de entorno de AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html).

1. En la sección **IMPLEMENTAR** elija **Implementar** para actualizar el código de la función:  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

## Prueba de la función
<a name="services-apigateway-tutorial-test-function"></a>

Antes de integrar la función con API Gateway, confirme que la ha implementado de forma correcta. Utilice la consola de Lambda para enviar un evento de prueba a su función.

1. En la página de la consola de Lambda para su función, seleccione la pestaña **Prueba**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/test-tab.png)

1. Desplácese a la sección **Evento JSON** y sustituya el evento predeterminado con el siguiente. Este evento coincide con la estructura esperada por la función de Lambda.

   ```
   {
       "operation": "echo",
       "payload": {
           "somekey1": "somevalue1",
           "somekey2": "somevalue2"
       }
   }
   ```

1. Seleccione **Probar**

1. En **Ejecutar la función: se realizó correctamente**, expanda **Detalles**. Debería ver la siguiente respuesta:

   ```
   {
     "somekey1": "somevalue1",
     "somekey2": "somevalue2"
   }
   ```

## Creación de una API REST mediante API Gateway
<a name="services-apigateway-tutorial-api"></a>

En este paso, crea la API de REST de API Gateway que utilizará para invocar la función de Lambda.

**Para crear la API**

1. Abra la [consola de API Gateway](https://console.aws.amazon.com/apigateway).

1. Seleccione **Create API (Crear API)**.

1. En el cuadro **REST API (API de REST)**, elija **Build (Crear)**.

1. En **Detalles de la API**, deje seleccionada la opción **Nueva API** y, en **Nombre de la API**, ingrese **DynamoDBOperations**.

1. Seleccione **Create API** (Crear API).

## Creación de un recurso en su API de REST.
<a name="services-apigateway-tutorial-resource"></a>

Para agregar un método HTTP a su API, primero debe crear un recurso para que funcione ese método. Aquí, se crea el recurso para administrar la tabla de DynamoDB.

**Para crear el recurso**

1. En la [consola de puerta de enlace de la API](https://console.aws.amazon.com/apigateway), en la página **Recursos** de su API, seleccione **Crear recurso**.

1. En **Detalles del recurso**, ingrese el **nombre del recurso****DynamoDBManager**.

1. Elija **Create Resource (Crear recurso)**.

## Creación de un método HTTP POST.
<a name="services-apigateway-tutorial-method"></a>

En este paso, creará un método (`POST`) para su recurso `DynamoDBManager`. Debe vincular este método `POST` a la función de Lambda para que cuando el método reciba una solicitud HTTP, API Gateway invoca la función de Lambda.

**nota**  
 A los efectos de este tutorial, se utiliza un método HTTP (`POST`) para invocar una única función de Lambda que lleva a cabo todas las operaciones de la tabla de DynamoDB. En una aplicación real, la práctica recomendada es utilizar una función de Lambda y un método HTTP diferente para cada operación. Para obtener más información, consulte [The Lambda monolith](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/monolith) en Serverless Land. 

**Para crear el método POST**

1. En la página **Recursos** de su API, asegúrese de que el recurso `/DynamoDBManager` esté resaltado. A continuación, en el panel **Métodos**, seleccione **Crear método**.

1. En **Tipo de método**, elija **POST**.

1. En **Tipo de integración**, seleccione **función de Lambda**.

1. Para la **función de Lambda**, elija el nombre de recurso de Amazon (ARN) para la función (`LambdaFunctionOverHttps`).

1. Elija **Crear método**.

## Creación de una tabla de DynamoDB
<a name="services-apigateway-tutorial-table"></a>

Cree una tabla de DynamoDB vacía en la que la función de Lambda realizará operaciones CRUD.

**Creación de la tabla de DynamoDB**

1. Abra la [página Tables (Tablas) en la consola de DynamoDB](https://console.aws.amazon.com/dynamodbv2#tables).

1. Seleccione **Create table (Creación de tabla)**.

1. En **Table details (Detalles de la tabla)**, haga lo siguiente:

   1. En **Nombre de la tabla**, introduzca **lambda-apigateway**.

   1. En **Partition key (Clave de partición)**, ingrese **id** y mantenga el tipo de datos establecido como **String (Cadena)**.

1. En **Settings** (Configuración), mantenga los valores predeterminados en **Default settings** (Configuración predeterminada).

1. Seleccione **Create table (Creación de tabla)**.

## Pruebe la integración de API Gateway, Lambda y DynamoDB.
<a name="services-apigateway-tutorial-test-setup"></a>

Ya está listo para probar la integración del método de API de API Gateway con la función de Lambda y la tabla de DynamoDB. Con la consola de API Gateway, envíe las solicitudes directamente a su método `POST` mediante la función de prueba de la consola. En este paso, primero use una operación `create` para agregar un nuevo elemento a la tabla de DynamoDB y, a continuación, use una operación `update` para modificar el elemento.

**Prueba 1: Crear un nuevo elemento en la tabla de DynamoDB**

1. En la [consola de API Gateway](https://console.aws.amazon.com/apigateway), elija su API (`DynamoDBOperations`).

1. Elija el método **POST** debajo del recurso `DynamoDBManager`.

1. Elija la pestaña **Prueba**. Puede que tenga que elegir el botón de flecha hacia la derecha para mostrar la pestaña.

1. En **Método de prueba**, deje vacías **las cadenas de consulta** y **los encabezados**. En **Cuerpo de la solicitud**, pegue el siguiente JSON:

   ```
   {
     "operation": "create",
     "payload": {
       "Item": {
         "id": "1234ABCD",
         "number": 5
       }
     }
   }
   ```

1. Seleccione **Probar**

   Los resultados que se muestran al finalizar la prueba deben mostrar el estado `200`. Este código de estado indica que la operación `create` se ha realizado correctamente.

    Para confirmarlo, verifique que ahora su tabla de DynamoDB contenga un nuevo elemento.

1. Abra la página [Tables](https://console.aws.amazon.com/dynamodbv2#tables) (Tablas) en la consola de DynamoDB y elija la tabla `lambda-apigateway`.

1. Elija **Explore table items** (Explorar elementos de la tabla). En el panel **Items returned** (Devolución de elementos), debería ver un elemento con el **id**`1234ABCD` y el **número** de `5`. Ejemplo:  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/items-returned.png)

**Prueba 2: Actualización del elemento de la tabla de DynamoDB**

1. En la [consola de la puerta de enlace de API](https://console.aws.amazon.com/apigateway), vuelva a la pestaña **Prueba** del método POST.

1. En **Método de prueba**, deje vacías **las cadenas de consulta** y **los encabezados**. En **Cuerpo de la solicitud**, pegue el siguiente JSON:

   ```
   {
       "operation": "update",
       "payload": {
           "Key": {
               "id": "1234ABCD"
           },
           "UpdateExpression": "SET #num = :newNum",
           "ExpressionAttributeNames": {
               "#num": "number"
           },
           "ExpressionAttributeValues": {
               ":newNum": 10
           }
       }
   }
   ```

1. Seleccione **Probar**

   Los resultados que se muestran cuando finaliza la prueba deben mostrar el estado `200`. Este código de estado indica que la operación de `update` se ha realizado correctamente.

    Para confirmarlo, compruebe que el elemento de la tabla de DynamoDB se haya modificado.

1. Abra la página [Tables](https://console.aws.amazon.com/dynamodbv2#tables) (Tablas) en la consola de DynamoDB y elija la tabla `lambda-apigateway`.

1. Elija **Explore table items** (Explorar elementos de la tabla). En el panel **Items returned** (Devolución de elementos), debería ver un elemento con el **id**`1234ABCD` y el **número** de `10`.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/items-returned-2.png)

## Implemente la API.
<a name="services-apigateway-tutorial-deploy-api"></a>

Para que un cliente llame a la API, debe crear una implementación y una etapa asociada. La etapa representa una imagen instantánea de su API, incluidos sus métodos e integraciones.

**Para implementar la API**

1. Abra la página **API** de la [consola de API Gateway](https://console.aws.amazon.com/apigateway) y seleccione la API de `DynamoDBOperations`.

1. En la página **Recursos** de su API, seleccione **Implementar la API**.

1. Para la **Etapa de implementación**, seleccione **\$1Nueva etapa\$1** y, en **Nombre de etapa**, introduzca **test**.

1. Elija **Implementar**.

1. En el panel **Editor de etapas de prueba**, copie la **URL de invocación**. Lo utilizará en el siguiente paso para invocar su función mediante una solicitud HTTP.

## Utilice curl para invocar tu función mediante solicitudes HTTP.
<a name="services-apigateway-tutorial-invoke-function"></a>

Ahora puede invocar la función de Lambda al emitir una solicitud HTTP a la API. En este paso, creará un elemento nuevo en la tabla de DynamoDB y, a continuación, lo someterá a operaciones de lectura, actualización y eliminación.

**Para crear un elemento en la tabla de DynamoDB con curl**

1. Abra una petición de comando o un terminal en su máquina local y ejecute el siguiente comando `curl` por medio de la URL de invocación que copió en el paso anterior. Este comando utiliza las siguientes opciones:
   + `-H`: añada un encabezado personalizado a la solicitud. Aquí, se especifica el tipo de contenido como JSON.
   + `-d`: envía los datos en el cuerpo de la solicitud. Esta opción usa un método HTTP POST de forma predeterminada.

------
#### [ Linux/macOS ]

   ```
   curl https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager \
   -H "Content-Type: application/json" \
   -d '{"operation": "create", "payload": {"Item": {"id": "5678EFGH", "number": 15}}}'
   ```

------
#### [ PowerShell ]

   ```
   curl.exe 'https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager' -H 'Content-Type: application/json' -d '{\"operation\": \"create\", \"payload\": {\"Item\": {\"id\": \"5678EFGH\", \"number\": 15}}}'
   ```

------

   Si la operación se realizó correctamente, debería ver una respuesta con el código de estado HTTP 200.

1. También puede utilizar la consola de DynamoDB para comprobar que el nuevo elemento esté en la tabla con las siguientes acciones:

   1. Abra la página [Tables](https://console.aws.amazon.com/dynamodbv2#tables) (Tablas) en la consola de DynamoDB y elija la tabla `lambda-apigateway`.

   1. Elija **Explore table items** (Explorar elementos de la tabla). En el panel **Items returned** (Devolución de elementos), debería ver un elemento con el **id**`5678EFGH` y el **número**`15`.

**Para leer el elemento en la tabla de DynamoDB con curl**
+ En la petición de comando o en el terminal, ejecute el siguiente comando `curl` para leer el valor del elemento que acaba de crear. Utilice su propia URL de invocación.

------
#### [ Linux/macOS ]

  ```
  curl https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager \
  -H "Content-Type: application/json" \
  -d '{"operation": "read", "payload": {"Key": {"id": "5678EFGH"}}}'
  ```

------
#### [ PowerShell ]

  ```
  curl.exe 'https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager' -H 'Content-Type: application/json' -d '{\"operation\": \"read\", \"payload\": {\"Key\": {\"id\": \"5678EFGH\"}}}'
  ```

------

  Debería ver uno de los siguientes resultados dependiendo de si eligió el código de función Node.js o Python:

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

  ```
  {"$metadata":{"httpStatusCode":200,"requestId":"7BP3G5Q0C0O1E50FBQI9NS099JVV4KQNSO5AEMVJF66Q9ASUAAJG",
  "attempts":1,"totalRetryDelay":0},"Item":{"id":"5678EFGH","number":15}}
  ```

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

  ```
  {"Item":{"id":"5678EFGH","number":15},"ResponseMetadata":{"RequestId":"QNDJICE52E86B82VETR6RKBE5BVV4KQNSO5AEMVJF66Q9ASUAAJG",
  "HTTPStatusCode":200,"HTTPHeaders":{"server":"Server","date":"Wed, 31 Jul 2024 00:37:01 GMT","content-type":"application/x-amz-json-1.0",
  "content-length":"52","connection":"keep-alive","x-amzn-requestid":"QNDJICE52E86B82VETR6RKBE5BVV4KQNSO5AEMVJF66Q9ASUAAJG","x-amz-crc32":"2589610852"},
  "RetryAttempts":0}}
  ```

------

**Para actualizar el elemento en la tabla de DynamoDB con curl**

1. En la petición de comando o en el terminal, ejecute el siguiente comando `curl` para actualizar el elemento que acaba de crear cambiando el valor `number`. Utilice su propia URL de invocación.

------
#### [ Linux/macOS ]

   ```
   curl https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager \
   -H "Content-Type: application/json" \
   -d '{"operation": "update", "payload": {"Key": {"id": "5678EFGH"}, "UpdateExpression": "SET #num = :new_value", "ExpressionAttributeNames": {"#num": "number"}, "ExpressionAttributeValues": {":new_value": 42}}}'
   ```

------
#### [ PowerShell ]

   ```
   curl.exe 'https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager' -H 'Content-Type: application/json' -d '{\"operation\": \"update\", \"payload\": {\"Key\": {\"id\": \"5678EFGH\"}, \"UpdateExpression\": \"SET #num = :new_value\", \"ExpressionAttributeNames\": {\"#num\": \"number\"}, \"ExpressionAttributeValues\": {\":new_value\": 42}}}'
   ```

------

1. Para confirmar que se ha actualizado el valor de `number` correspondiente al elemento, ejecute otro comando de lectura:

------
#### [ Linux/macOS ]

   ```
   curl https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager \
   -H "Content-Type: application/json" \
   -d '{"operation": "read", "payload": {"Key": {"id": "5678EFGH"}}}'
   ```

------
#### [ PowerShell ]

   ```
   curl.exe 'https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager' -H 'Content-Type: application/json' -d '{\"operation\": \"read\", \"payload\": {\"Key\": {\"id\": \"5678EFGH\"}}}'
   ```

------

**Para eliminar el elemento en la tabla de DynamoDB con curl**

1. En la petición de comando o en el terminal, ejecute el siguiente comando `curl` para eliminar el elemento que ha creado. Utilice su propia URL de invocación.

------
#### [ Linux/macOS ]

   ```
   curl https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager \
   -H "Content-Type: application/json" \
   -d '{"operation": "delete", "payload": {"Key": {"id": "5678EFGH"}}}'
   ```

------
#### [ PowerShell ]

   ```
   curl.exe 'https://l8togsqxd8.execute-api.us-east-2.amazonaws.com/test/DynamoDBManager' -H 'Content-Type: application/json' -d '{\"operation\": \"delete\", \"payload\": {\"Key\": {\"id\": \"5678EFGH\"}}}'
   ```

------

1. Confirme que la operación de eliminación se ha realizado correctamente. En el panel **Elementos devueltos** de la página **Explorar elementos** de la consola de DynamoDB, verifique que el elemento con **id** `5678EFGH` ya no se encuentre en la tabla.

## Elimine sus recursos (opcional)
<a name="cleanup"></a>

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

**Cómo eliminar la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que ha creado.

1. Elija **Acciones**, **Eliminar**.

1. Escriba **confirm** en el campo de entrada de texto y elija **Delete**(Eliminar).

**Cómo eliminar el rol de ejecución**

1. Abra la página [Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione el rol de ejecución que creó.

1. Elija **Eliminar**.

1. Si desea continuar, escriba el nombre del rol en el campo de entrada de texto y elija **Delete** (Eliminar).

**Para eliminar la API**

1. Abra la [página API](https://console.aws.amazon.com/apigateway/main/apis) de la consola de API Gateway.

1. Seleccione la API que ha creado.

1. Elija **Actions** (Acciones), **Delete** (Eliminar).

1. Elija **Eliminar**.

**Para eliminar una tabla de DynamoDB**

1. Abra la página [Tables (Tablas)](https://console.aws.amazon.com//dynamodb/home#tables:) en la consola de DynamoDB.

1. Seleccione la tabla que ha creado.

1. Elija **Eliminar**.

1. Escriba **delete** en el cuadro de texto.

1. Elija **Delete table (Eliminar tabla)**.

# Manejo de los errores en Lambda con una API de API Gateway
<a name="services-apigateway-errors"></a>

API Gateway trata todos los errores de las invocaciones y las funciones como errores internos. Si la API de Lambda rechaza la solicitud de invocación, API Gateway devuelve un código de error 500. Si la función se ejecuta pero devuelve un error o devuelve una respuesta con un formato incorrecto, API Gateway muestra un 502. En ambos casos, el cuerpo de la respuesta de API Gateway es `{"message": "Internal server error"}`.

**nota**  
API Gateway no vuelve a intentar ninguna invocación de Lambda. Si Lambda devuelve un error, API Gateway devuelve una respuesta de error al cliente.

En el ejemplo siguiente, se muestra un mapa de seguimiento de X-Ray de una solicitud que generó un error de función y un error 502 de API Gateway. El cliente recibirá el mensaje de error genérico.

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/tracemap-apig-502.png)


Para personalizar la respuesta del error, debe detectar errores en el código y elaborar una respuesta en el formato que desee.

**Example [index.mjs](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/nodejs-apig/function/index.mjs): error de formato.**  

```
var formatError = function(error){
  var response = {
    "statusCode": error.statusCode,
    "headers": {
      "Content-Type": "text/plain",
      "x-amzn-ErrorType": error.code
    },
    "isBase64Encoded": false,
    "body": error.code + ": " + error.message
  }
  return response
}
```

API Gateway convierte esta respuesta en un error HTTP con un código de estado y un cuerpo personalizados. En el mapa de seguimiento, el nodo de la función es verde porque el error se administró correctamente.

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/tracemap-apig-404.png)


# Selección de un método para invocar una función de Lambda mediante una solicitud HTTP
<a name="apig-http-invoke-decision"></a>

En muchos casos de uso habituales de Lambda, se debe invocar una función mediante una solicitud HTTP. Por ejemplo, tal vez desee que una aplicación web invoque su función mediante una solicitud del navegador. Las funciones de Lambda también se pueden utilizar para crear API de REST completas, gestionar las interacciones de los usuarios de las aplicaciones móviles, procesar datos de servicios externos mediante llamadas HTTP o crear webhooks personalizados.

En las siguientes secciones, se explican cuáles son sus opciones para invocar a Lambda a través de HTTP y se proporciona información que ayudará a que tome la decisión correcta para su caso de uso concreto.

## ¿Cuáles son sus opciones a la hora de seleccionar un método para invocar una HTTP?
<a name="w2aad101c29c46b9"></a>

Lambda ofrece dos métodos principales para invocar una función mediante una solicitud HTTP: las [URL de función](urls-configuration.md) y [API Gateway](services-apigateway.md). Las diferencias clave entre estas dos opciones son las siguientes:
+ **Las URL de función de Lambda** proporcionan un punto de conexión HTTP simple y directo para una función de Lambda. Están optimizadas para ofrecer simplicidad y rentabilidad y ofrecen la ruta más rápida para exponer una función de Lambda a través de HTTP.
+ **API Gateway** es un servicio más avanzado para crear una API con todas las características. API Gateway está optimizado para crear y administrar una API de producción a escala y ofrece herramientas integrales para la seguridad, el monitoreo y la administración del tráfico.

## Recomendaciones si ya conoce sus requisitos
<a name="w2aad101c29c46c11"></a>

Si ya tiene claros sus requisitos, estas son nuestras recomendaciones básicas:

Recomendamos las **[URL de función](urls-configuration.md)** para aplicaciones sencillas o para la creación de prototipos cuando solo necesite métodos básicos de autenticación y gestión de solicitudes y respuestas y siempre que desee reducir al mínimo los costos y la complejidad.

**[API Gateway](services-apigateway.md)** es una mejor opción para aplicaciones de producción a gran escala o para los casos en los que se necesitan características más avanzadas, como la compatibilidad con la [descripción de OpenAPI](https://www.openapis.org/), una variedad de opciones de autenticación, nombres de dominio personalizados o una gestión rica de solicitudes y respuestas, que incluye la limitación, el almacenamiento en caché y la transformación de solicitudes y respuestas.

## Aspectos que deben tenerse en cuenta al seleccionar un método para invocar una función de Lambda
<a name="w2aad101c29c46c13"></a>

Al seleccionar entre las URL de función y API Gateway, deben tener en cuenta los siguientes factores:
+ Sus necesidades de autenticación, por ejemplo, si necesita OAuth o Amazon Cognito para autenticar a los usuarios
+ Sus requisitos de escalado y la complejidad de la API que desea implementar
+ Si necesita características avanzadas, como la validación de solicitudes y el formato de las solicitudes o respuestas
+ Sus requisitos de monitoreo
+ Sus objetivos de costos

Al comprender estos factores, puede seleccionar la opción que mejor equilibre sus requisitos de seguridad, complejidad y costo.

En la siguiente información, se comparan las principales diferencias entre las dos opciones.

### Autenticación
<a name="w2aad101c29c46c13c11b1"></a>
+ **Las URL de función** proporcionan opciones de autenticación básicas mediante AWS Identity and Access Management (IAM). Puede configurar sus puntos de conexión para que sean públicos (sin autenticación) o para que requieran la autenticación de IAM. Con la autenticación de IAM, puede utilizar credenciales de AWS estándar o roles de IAM para controlar el acceso. Si bien es fácil de configurar, este enfoque ofrece opciones limitadas en comparación con otros métodos de autenticación.
+ **API Gateway** proporciona acceso a una gama más completa de opciones de autenticación. Además de la autenticación de IAM, puede utilizar [autorizadores de Lambda](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) (lógica de autenticación personalizada), grupos de usuarios de [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html) y flujos de OAuth2.0. Esta flexibilidad permite implementar esquemas de autenticación complejos, que incluyen proveedores de autenticación de terceros, autenticación basada en tokens y autenticación multifactorial.

### Gestión de solicitudes y respuestas
<a name="w2aad101c29c46c13c11b3"></a>
+ **Las URL de función** proporcionan una gestión básica de solicitudes y respuestas HTTP. Son compatibles con los métodos HTTP estándar e incluyen soporte integrado de uso compartido de recursos entre orígenes (CORS). Si bien pueden gestionar las cargas útiles de JSON y los parámetros de consulta de forma natural, no ofrecen capacidades de transformación o validación de solicitudes. La gestión de las respuestas es igual de sencillo: el cliente recibe la respuesta de la función de Lambda exactamente como Lambda la devuelve.
+ **API Gateway** ofrece capacidades sofisticadas de gestión de solicitudes y respuestas. Puede definir validadores de solicitudes, transformar las solicitudes y las respuestas mediante la asignación de plantillas, la configuración de encabezados de solicitudes y respuestas y la implementación el almacenamiento en caché de las respuestas. API Gateway también es compatible con las cargas útiles binarias y los nombres de dominio personalizados y puede modificar las respuestas antes de que lleguen al cliente. Puede configurar modelos para la validación y transformación de solicitudes y respuestas mediante el esquema JSON.

### Escalado
<a name="w2aad101c29c46c13c11b5"></a>
+ **Las URL de función** se escalan directamente con los límites de simultaneidad de la función de Lambda y gestionan los picos de tráfico al escalar la función hasta el límite máximo de simultaneidad configurado. Una vez alcanzado ese límite, Lambda responde a las solicitudes adicionales con respuestas HTTP 429. No hay un mecanismo de colas integrado, por lo que la gestión del escalado depende totalmente de la configuración de la función de Lambda. De forma predeterminada, las funciones de Lambda tienen un límite de 1000 ejecuciones simultáneas por Región de AWS.
+ **API Gateway** proporciona capacidades de escalado adicionales además del escalado propio de Lambda. Incluye controles integrados de limitación y cola de solicitudes, lo que permite administrar los picos de tráfico con mayor facilidad. De forma predeterminada, API Gateway puede gestionar hasta 10 000 solicitudes por segundo por región, con una capacidad de ampliación de 5000 solicitudes por segundo. También proporciona herramientas para limitar las solicitudes en diferentes niveles (API, fase o método) a fin de proteger el backend.

### Supervisión
<a name="w2aad101c29c46c13c11b7"></a>
+ **Las URL de función** ofrecen un monitoreo básico a través de las métricas de Amazon CloudWatch, que incluyen el recuento de solicitudes, la latencia y las tasas de error. Obtiene acceso a métricas y registros estándar de Lambda, que muestran las solicitudes sin procesar que llegan a su función. Si bien esto proporciona una visibilidad operativa esencial, las métricas se centran principalmente en la ejecución de las funciones.
+ **API Gateway** proporciona capacidades de monitoreo integrales que incluyen métricas detalladas, registro y opciones de rastreo. Puede supervisar las llamadas a la API, la latencia, las tasas de error y las tasas de aciertos y errores de la caché a través de CloudWatch. API Gateway también se integra con AWS X-Ray para el rastreo distribuido y proporciona formatos de registro personalizables.

### Coste
<a name="w2aad101c29c46c13c11b9"></a>
+ **Las URL de función** siguen el modelo de precios estándar de Lambda: solo paga por las invocaciones de funciones y el tiempo de cálculo. No hay recargos adicionales para el punto de conexión URL en sí. Esto lo convierte en una opción rentable para API simples o aplicaciones de bajo tráfico si no necesita las características adicionales de la API Gateway.
+ **API Gateway** ofrece un [nivel gratuito](https://aws.amazon.com/api-gateway/pricing/#Free_Tier) que incluye un millón de llamadas a la API recibidas para las API de REST y un millón de llamadas a la API recibidas para las API de HTTP. Después de esto, API Gateway cobra por las llamadas a la API, la transferencia de datos y el almacenamiento en caché (si están habilitados). Consulte la [página de precios](https://aws.amazon.com/api-gateway/pricing/) de API Gateway para conocer los costos de su propio caso práctico.

### Otras características
<a name="w2aad101c29c46c13c11c11"></a>
+ **Las URL de función** están diseñadas para ofrecer simplicidad e integración directa con Lambda. Son compatibles con los puntos de conexión HTTP y HTTPS, ofrecen soporte CORS integrado y proporcionan puntos de conexión de doble pila (IPv4 e IPv6). Si bien carecen de características avanzadas, destacan en situaciones en las que se necesita una forma rápida y sencilla de exponer las funciones de Lambda a través de HTTP.
+ **API Gateway** incluye numerosas características adicionales, como el control de versiones de las API, la administración de etapas, las claves de API para los planes de uso, la documentación de las API a través de Swagger/OpenAPI, las API de WebSocket, las API privadas dentro de una VPC y la integración de WAF para mayor seguridad. También es compatible con las implementaciones canarias, las integraciones simuladas para pruebas y la integración con otros Servicios de AWS más allá de Lambda.

## Selección de un método para invocar una función de Lambda
<a name="w2aad101c29c46c15"></a>

Ahora que ha leído los criterios para seleccionar entre las URL de función de Lambda y API Gateway y las principales diferencias entre ellas, puede seleccionar la opción que mejor se adapte a sus necesidades y utilizar los siguientes recursos para empezar a utilizarla.

------
#### [ Function URLs ]

**Comience a utilizar las URL de función con los siguientes recursos**
+ Siga el tutorial [Crear de una función de Lambda con una URL de función](urls-webhook-tutorial.md)
+ Obtenga más información sobre las URL de función en el capítulo [Creación y administración de URL de funciones de Lambda](urls-configuration.md) de esta guía
+ Pruebe el tutorial guiado integrado en la consola: **Crear una aplicación web sencilla** de la siguiente manera:

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Abra el panel de ayuda al elegir el icono de la esquina superior derecha de la pantalla.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/console_help_screenshot.png)

1. Seleccione **Tutoriales**.

1. En **Crear una aplicación web sencilla**, seleccione **Iniciar el tutorial**.

------
#### [ API Gateway ]

**Comience a utilizar Lambda y API Gateway con los siguientes recursos**
+ Siga el tutorial [Uso de Lambda con API Gateway](services-apigateway-tutorial.md) para crear una API de REST integrada con una función de Lambda de backend.
+ Obtenga más información sobre los distintos tipos de API que ofrece API Gateway en las siguientes secciones de la *guía para desarrolladores de Amazon API Gateway*:
  + [API de REST de API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html)
  + [API de HTTP de API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html)
  + [API de WebSocket de API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html)
+ Pruebe uno o varios de los ejemplos de la sección de [tutoriales y talleres](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-tutorials.html) de la *Guía para desarrolladores de Amazon API Gateway*.

------

# Uso de AWS Lambda con AWS Infrastructure Composer
<a name="services-appcomposer"></a>

AWS Infrastructure Composer es un generador visual para diseñar aplicaciones modernas en AWS. Diseñe la arquitectura de la aplicación arrastrando, agrupando y conectando Servicios de AWS en un lienzo visual. Infrastructure Composer crea plantillas de infraestructura como código (IaC) a partir de su diseño que puede implementar mediante [AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) o [CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html).

## Exportación de una función de Lambda a Infrastructure Composer
<a name="services-appcomposer-export"></a>

Para empezar a utilizar Infrastructure Composer, cree un nuevo proyecto basado en la configuración de una función de Lambda existente mediante la consola de Lambda. Haga lo siguiente para exportar la configuración y el código de la función a Infrastructure Composer para crear un nuevo proyecto:

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que desee utilizar como base para su proyecto de Infrastructure Composer.

1. En el panel **Información general de la función**, elija **Export to Infrastructure Composer**.

   Para exportar la configuración y el código de la función a Infrastructure Composer, Lambda crea un bucket de Amazon S3 en su cuenta para almacenar estos datos temporalmente.

1. En el cuadro de diálogo, seleccione **Confirmar y crear el proyecto** para aceptar el nombre predeterminado de este bucket y exportar la configuración y el código de la función a Infrastructure Composer.

1. (Opcional) Para elegir otro nombre para el bucket de Amazon S3 que Lambda crea, introduzca un nombre nuevo y elija **Confirmar y crear proyecto**. Los nombres de los buckets de Amazon S3 no pueden repetirse en ningún lado y deben seguir las [reglas de nomenclatura de buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html).

1. Para guardar los archivos de funciones y proyectos en Infrastructure Composer, active el [modo de sincronización local](https://docs.aws.amazon.com/application-composer/latest/dg/reference-features-local-sync.html).

**nota**  
Si ya ha utilizado la característica **Exportar a Application Composer** y ha creado un bucket de Amazon S3 con el nombre predeterminado, Lambda puede volver a utilizar este bucket si aún existe. Acepte el nombre del bucket predeterminado en el cuadro de diálogo para volver a utilizar el bucket existente.

### Configuración del bucket de transferencia de Amazon S3
<a name="services-appcomposer-bucket-info"></a>

El bucket de Amazon S3 que Lambda crea para transferir la configuración de la función cifra automáticamente los objetos mediante el estándar de cifrado AES 256. Lambda también configura el bucket para que utilice la [condición de propietario del bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-owner-condition.html) para garantizar que solo su Cuenta de AWS pueda agregar objetos al bucket.

Lambda configura el bucket para eliminar automáticamente los objetos 10 días después de su carga. Sin embargo, Lambda no elimina automáticamente el bucket en sí. Para eliminar el bucket de su Cuenta de AWS, siga las instrucciones que se indican en [Eliminar un bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html). El nombre predeterminado del bucket usa el prefijo `lambdasam`, una cadena alfanumérica de 10 dígitos y el Región de AWS en la que creó la función:

```
lambdasam-06f22da95b-us-east-1
```

Para evitar que se le agreguen cargos adicionales a su Cuenta de AWS, le recomendamos que elimine el bucket de Amazon S3 en cuanto termine de exportar su función a Infrastructure Composer.

Se aplican los [precios estándar de Amazon S3](https://aws.amazon.com/s3/pricing/).

### Permisos necesarios
<a name="services-appcomposer-permissions"></a>

A fin de usar la característica de integración de Lambda con Infrastructure Composer, necesita ciertos permisos para descargar una plantilla de AWS SAM y escribir la configuración de la función en Amazon S3.

Si quiere descargar una plantilla AWS SAM, debe tener permiso para utilizar las siguientes acciones de la API:
+ [GetPolicy](https://docs.aws.amazon.com/lambda/latest/api/API_GetPolicy.html)
+ [iam:GetPolicyVersion](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetPolicyVersion.html)
+ [iam:GetRole](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetRole.html)
+ [iam:GetRolePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetRolePolicy.html)
+ [iam:ListAttachedRolePolicies](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListAttachedRolePolicies.html)
+ [iam:ListRolePolicies](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListRolePolicies.html)
+ [iam:ListRoles](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListRoles.html)

Puede otorgar permisos para utilizar todas estas acciones si agrega la política [https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambda_ReadOnlyAccess.html](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambda_ReadOnlyAccess.html) administrada por AWS a su rol de usuario de IAM.

Para que Lambda escriba la configuración de su función en Amazon S3, debe tener permiso para usar las siguientes acciones de la API:
+ [S3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html)
+ [S3:CreateBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateBucket.html)
+ [S3:PutBucketEncryption](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketEncryption.html)
+ [S3:PutBucketLifecycleConfiguration](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutBucketLifecycleConfiguration.html)

Si no puede exportar su configuración de la función a Infrastructure Composer, compruebe que su cuenta tenga los permisos necesarios para estas operaciones. Si tiene los permisos necesarios, pero aún no puede exportar la configuración de su función, compruebe si hay [Políticas basadas en recursos](access-control-resource-based.md) que podrían limitar el acceso a Amazon S3.

## Otros recursos
<a name="w2aad101c33b7"></a>

Para obtener un tutorial más detallado sobre cómo diseñar una aplicación sin servidor en Infrastructure Composer basada en una función de Lambda existente, consulte [Uso de Lambda con la infraestructura como código (IaC)](foundation-iac.md).

Para utilizar Infrastructure Composer y AWS SAM para diseñar e implementar una aplicación sin servidor completa con Lambda, también puede seguir el [Tutorial de AWS Infrastructure Composer](https://catalog.workshops.aws/serverless-patterns/en-US/dive-deeper/module1a) en el [Taller de patrones sin servidor de AWS](https://catalog.workshops.aws/serverless-patterns/en-US).

# Uso de AWS Lambda con CloudFormation
<a name="services-cloudformation"></a>

En una plantilla de AWS CloudFormation puede especificar una función de Lambda como destino de un recurso personalizado. Utilice los recursos personalizados para procesar parámetros, recuperar valores de configuración o llamar a otros Servicios de AWS durante los eventos del ciclo de vida de la pila.

El ejemplo siguiente invoca una función definida en otra parte de la plantilla.

**Example - Definición de recurso personalizado**  

```
Resources:
  primerinvoke:
    Type: [AWS::CloudFormation::CustomResource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cfn-customresource.html)
    Version: "1.0"
    Properties:
      ServiceToken: !GetAtt primer.Arn
      FunctionName: !Ref randomerror
```

El token de servicio es el Nombre de recurso de Amazon (ARN) de la función que CloudFormation invoca al crear, actualizar o eliminar la pila. También puede incluir propiedades adicionales como `FunctionName`, que CloudFormation pasa a su función tal cual.

CloudFormation invoca la función de Lambda de forma [asíncrona](invocation-async.md) con un evento que incluye una URL de devolución de llamada.

**Example -CloudFormation Evento de mensaje de**  

```
{
    "RequestType": "Create",
    "ServiceToken": "arn:aws:lambda:us-east-1:123456789012:function:lambda-error-processor-primer-14ROR2T3JKU66",
    "ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3-us-east-1.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A123456789012%3Astack/lambda-error-processor/1134083a-2608-1e91-9897-022501a2c456%7Cprimerinvoke%7C5d478078-13e9-baf0-464a-7ef285ecc786?AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE&Expires=1555451971&Signature=28UijZePE5I4dvukKQqM%2F9Rf1o4%3D",
    "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/lambda-error-processor/1134083a-2608-1e91-9897-022501a2c456",
    "RequestId": "5d478078-13e9-baf0-464a-7ef285ecc786",
    "LogicalResourceId": "primerinvoke",
    "ResourceType": "AWS::CloudFormation::CustomResource",
    "ResourceProperties": {
        "ServiceToken": "arn:aws:lambda:us-east-1:123456789012:function:lambda-error-processor-primer-14ROR2T3JKU66",
        "FunctionName": "lambda-error-processor-randomerror-ZWUC391MQAJK"
    }
}
```

La función es responsable de devolver una respuesta a la URL de devolución de llamada que indica el éxito o el error de la operación. Para ver la sintaxis de respuesta completa, consulte [Objetos de respuesta de recursos personalizados](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html).

**Example -CloudFormation Respuesta de recursos personalizados de**  

```
{
    "Status": "SUCCESS",
    "PhysicalResourceId": "2019/04/18/[$LATEST]b3d1bfc65f19ec610654e4d9b9de47a0",
    "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/lambda-error-processor/1134083a-2608-1e91-9897-022501a2c456",
    "RequestId": "5d478078-13e9-baf0-464a-7ef285ecc786",
    "LogicalResourceId": "primerinvoke"
}
```

CloudFormation proporciona una biblioteca llamada `cfn-response` que controla el envío de la respuesta. Si define su función dentro de una plantilla, puede solicitar la biblioteca por nombre. A continuación, CloudFormation añade la biblioteca al paquete de implementación que crea para la función.

Si la función que utiliza un recurso personalizado tiene asociada una [interfaz de red elástica](configuration-vpc.md#configuration-vpc-enis), agregue los siguientes recursos a la política de VPC, donde **region** es la región en la que se encuentra la función, sin guiones. Por ejemplo, `us-east-1` es `useast1`. Esto permitirá que el recurso personalizado responda a la URL de devolución de llamada que envía una señal de vuelta a la pila de CloudFormation.

```
arn:aws:s3:::cloudformation-custom-resource-response-region",
"arn:aws:s3:::cloudformation-custom-resource-response-region/*",
```

La función de ejemplo siguiente invoca una segunda función. Si la llamada se realiza sin error, la función envía una respuesta de operación correcta a CloudFormation y la actualización de la pila continúa. La plantilla utiliza el tipo de recurso [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html) proporcionado por AWS Serverless Application Model.

**Example -Función de recursos personalizados**  

```
Transform: 'AWS::Serverless-2016-10-31'
Resources:
  primer:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      Handler: index.handler
      Runtime: nodejs16.x
      InlineCode: |
        var aws = require('aws-sdk');
        var response = require('cfn-response');
        exports.handler = function(event, context) {
            // For Delete requests, immediately send a SUCCESS response.
            if (event.RequestType == "Delete") {
                response.send(event, context, "SUCCESS");
                return;
            }
            var responseStatus = "FAILED";
            var responseData = {};
            var functionName = event.ResourceProperties.FunctionName
            var lambda = new aws.Lambda();
            lambda.invoke({ FunctionName: functionName }, function(err, invokeResult) {
                if (err) {
                    responseData = {Error: "Invoke call failed"};
                    console.log(responseData.Error + ":\n", err);
                }
                else responseStatus = "SUCCESS";
                response.send(event, context, responseStatus, responseData);
            });
        };
      Description: Invoke a function to create a log stream.
      MemorySize: 128
      Timeout: 8
      Role: !GetAtt role.Arn
      Tracing: Active
```

Si la función que el recurso personalizado invoca no está definida en una plantilla, puede obtener el código fuente de `cfn-response` desde el [módulo cfn-response](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html) en la Guía del usuario de AWS CloudFormation.

Para obtener más información sobre los recursos personalizados, consulte [Recursos personalizados](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html) en la *Guía del usuario de AWS CloudFormation*.

# Procese eventos de Amazon DocumentDB con Lambda
<a name="with-documentdb"></a>

Puede utilizar una función de Lambda para procesar eventos en un [flujo de cambios de Amazon DocumentDB (con compatibilidad con MongoDB)](https://docs.aws.amazon.com/documentdb/latest/developerguide/change_streams.html) si configura un clúster de Amazon DocumentDB como origen de eventos. A continuación, puede automatizar las cargas de trabajo basadas en eventos al invocar la función de Lambda cada vez que los datos cambien en su clúster de Amazon DocumentDB.

**nota**  
Lambda solo es compatible con la versión 4.0 y 5.0 de Amazon DocumentDB. Lambda no es compatible con la versión 3.6.  
Asimismo, en el caso de las asignaciones de orígenes de eventos, Lambda solo es compatible con clústeres basados en instancias y clústeres regionales. Lambda no admite [clústeres elásticos](https://docs.aws.amazon.com/documentdb/latest/developerguide/docdb-using-elastic-clusters.html) ni [clústeres globales](https://docs.aws.amazon.com/documentdb/latest/developerguide/global-clusters.html). Esta limitación no se aplica cuando se utiliza Lambda como cliente para conectarse a Amazon DocumentDB. Lambda puede conectarse a todos los tipos de clústeres para realizar operaciones CRUD.

Lambda procesa los eventos de los flujos de cambios de Amazon DocumentDB de forma secuencial en el orden en que llegan. Por este motivo, la función solo puede gestionar una invocación simultánea desde Amazon DocumentDB a la vez. Para monitorear su función, puede realizar un seguimiento de sus [métricas de simultaneidad](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-concurrency.html).

**aviso**  
Las asignaciones de orígenes de eventos de Lambda procesan cada evento al menos una vez, y puede producirse un procesamiento duplicado de registros. Para evitar posibles problemas relacionados con la duplicación de eventos, le recomendamos encarecidamente que haga que el código de la función sea idempotente. Para obtener más información, consulte [¿Cómo puedo hacer que mi función de Lambda sea idempotente?](https://repost.aws/knowledge-center/lambda-function-idempotent) en el Centro de conocimientos de AWS.

**Topics**
+ [

## Ejemplo de evento de Amazon DocumentDB
](#docdb-sample-event)
+ [

## Requisitos previos y permisos
](#docdb-prereqs)
+ [

## Configuración de la seguridad de la red
](#docdb-network)
+ [

## Creación de una asignación de orígenes de eventos de Amazon DocumentDB (consola)
](#docdb-configuration)
+ [

## Creación de una asignación de orígenes de eventos de Amazon DocumentDB (SDK o CLI)
](#docdb-api)
+ [

## Posiciones iniciales de flujos y sondeo
](#docdb-stream-polling)
+ [

## Monitoreo del origen de eventos de Amazon DocumentDB
](#docdb-monitoring)
+ [

# Tutorial: Uso de AWS Lambda con Amazon DocumentDB Streams
](with-documentdb-tutorial.md)

## Ejemplo de evento de Amazon DocumentDB
<a name="docdb-sample-event"></a>

```
{
    "eventSourceArn": "arn:aws:rds:us-east-1:123456789012:cluster:canaryclusterb2a659a2-qo5tcmqkcl03",
    "events": [
        {
            "event": {
                "_id": {
                    "_data": "0163eeb6e7000000090100000009000041e1"
                },
                "clusterTime": {
                    "$timestamp": {
                        "t": 1676588775,
                        "i": 9
                    }
                },
                "documentKey": {
                    "_id": {
                        "$oid": "63eeb6e7d418cd98afb1c1d7"
                    }
                },
                "fullDocument": {
                    "_id": {
                        "$oid": "63eeb6e7d418cd98afb1c1d7"
                    },
                    "anyField": "sampleValue"
                },
                "ns": {
                    "db": "test_database",
                    "coll": "test_collection"
                },
                "operationType": "insert"
            }
        }
    ],
    "eventSource": "aws:docdb"
}
```

Para obtener más información sobre los eventos de este ejemplo y sus formas, consulte [Eventos de cambio](https://www.mongodb.com/docs/manual/reference/change-events/) en el sitio web de la documentación de MongoDB.

## Requisitos previos y permisos
<a name="docdb-prereqs"></a>

Antes de utilizar Amazon DocumentDB como un origen de eventos para su función de Lambda, tenga en cuenta los siguientes requisitos previos. Debe hacer lo siguiente:
+ **Tener un clúster de Amazon DocumentDB existente en la misma Cuenta de AWS y Región de AWS que su función.** Si no dispone de un clúster existente, puede crearlo mediante los pasos de [Introducción a Amazon DocumentDB](https://docs.aws.amazon.com/documentdb/latest/developerguide/get-started-guide.html) en la *Guía para desarrolladores de Amazon DocumentDB*. Como alternativa, el primer conjunto de pasos de [Tutorial: Uso de AWS Lambda con Amazon DocumentDB Streams](with-documentdb-tutorial.md) lo guiará para crear un clúster de Amazon DocumentDB con todos los requisitos previos necesarios.
+ **Permitir que Lambda tenga acceso a los recursos de Amazon Virtual Private Cloud (Amazon VPC) asociados a su clúster de Amazon DocumentDB.** Para obtener más información, consulte [Configuración de la seguridad de la red](#docdb-network).
+ **Habilitar TLS en su clúster de Amazon DocumentDB.** Este es el valor predeterminado. Si deshabilita TLS, Lambda no podrá comunicarse con el clúster.
+ **Activar los flujos de cambios en su clúster de Amazon DocumentDB.** Para obtener más información, consulte [Uso de flujos de cambios de Amazon DocumentDB](https://docs.aws.amazon.com/documentdb/latest/developerguide/change_streams.html) en la *Guía para desarrolladores de Amazon DocumentDB*.
+ **Proporcionar a Lambda las credenciales para acceder a su clúster de Amazon DocumentDB.** Al configurar el origen de eventos, proporcione la clave de [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) que contiene los detalles de autenticación (nombre de usuario y contraseña) necesarios para acceder al clúster. Para proporcionar esta clave durante la configuración, puede realizar uno de los siguientes procedimientos:
  + Si está utilizando la consola de Lambda para la configuración, proporcione la clave en el campo **Clave del administrador de secretos**.
  + Si está utilizando la AWS Command Line Interface (AWS CLI), introduzca esta clave en la opción `source-access-configurations`. Puede incluir esta opción con los comandos [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) o [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html). Por ejemplo:

    ```
    aws lambda create-event-source-mapping \
        ...
        --source-access-configurations  '[{"Type":"BASIC_AUTH","URI":"arn:aws:secretsmanager:us-west-2:123456789012:secret:DocDBSecret-AbC4E6"}]' \
        ...
    ```
+ **Conceder permisos a Lambda para administrar los recursos relacionados con el flujo de Amazon DocumentDB.** Agregue los siguientes permisos de forma manual al [rol de ejecución](lambda-intro-execution-role.md) de su función:
  + [rds:DescribeDBClusters](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBClusters.html)
  + [rds:DescribeDBClusterParameters](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBClusterParameters.html)
  + [rds:DescribeDBSubnetGroups](https://docs.aws.amazon.com/AmazonRDS/latest/APIReference/API_DescribeDBSubnetGroups.html)
  + [ec2:CreateNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateNetworkInterface.html)
  + [ec2:DescribeNetworkInterfaces](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeNetworkInterfaces.html)
  + [ec2:DescribeVpcs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpcs.html)
  + [ec2:DeleteNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteNetworkInterface.html)
  + [ec2:DescribeSubnets](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSubnets.html)
  + [ec2:DescribeSecurityGroups](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html)
  + [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html)
  + [secretsmanager:GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html)
+ **Mantener el tamaño de los eventos del flujo de cambios de Amazon DocumentDB que envíe a Lambda por debajo de 6 MB.** Lambda admite tamaños de carga de hasta 6 MB. Si el flujo de cambios intenta enviar a Lambda un evento de más de 6 MB, Lambda elimina el mensaje y emite la métrica `OversizedRecordCount`. Lambda emite todas las métricas dentro de lo posible.

**nota**  
Si bien las funciones de Lambda suelen tener un límite de tiempo de espera máximo de 15 minutos, las asignaciones de orígenes de eventos para Amazon MSK, Apache Kafka autoadministrado, Amazon DocumentDB y Amazon MQ para ActiveMQ y RabbitMQ solo admiten funciones con límites de tiempo de espera máximos de 14 minutos. Esta restricción garantiza que la asignación de orígenes de eventos pueda gestionar correctamente los errores y reintentos de las funciones.

## Configuración de la seguridad de la red
<a name="docdb-network"></a>

Para que Lambda tenga acceso completo a Amazon DocumentDB a través de su asignación de orígenes de eventos, debe proporcionar acceso a la instancia de Amazon VPC en la que creó el clúster o este debe utilizar un punto de conexión público (dirección IP pública).

Cuando utilice Amazon DocumentDB con Lambda, cree [puntos de conexión de VPC de AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html) que brinden a su función acceso a los recursos de su Amazon VPC.

**nota**  
Los puntos de conexión de VPC de AWS PrivateLink son necesarios para las funciones con asignaciones de orígenes de eventos que utilizan el modo predeterminado (bajo demanda) para los sondeos de eventos. Si la asignación de orígenes de eventos utiliza el [modo aprovisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode), no es necesario configurar los puntos de conexión de VPC de AWS PrivateLink.

Cree un punto de conexión para proporcionar acceso a los siguientes recursos:
+  Lambda: cree un punto de conexión para la entidad principal del servicio de Lambda. 
+  AWS STS: cree un punto de conexión para AWS STS con el objetivo de que la entidad principal del servicio asuma un rol en su nombre. 
+  Secrets Manager: si el clúster usa Secrets Manager para almacenar las credenciales, cree un punto de conexión para Secrets Manager. 

Como alternativa, configure una puerta de enlace de NAT en cada subred pública de la Amazon VPC. Para obtener más información, consulte [Habilitación del acceso a Internet para funciones de Lambda conectadas a VPC](configuration-vpc-internet.md).

Al crear una asignación de orígenes de eventos para Amazon DocumentDB, Lambda comprueba si las interfaces de red elásticas (ENI) ya están presentes en las subredes y los grupos de seguridad configurados para la Amazon VPC. Si Lambda encuentra ENI existentes, intenta reutilizarlos. De lo contrario, Lambda crea nuevos ENI para conectarse al origen de eventos e invocar la función.

**nota**  
Las funciones de Lambda siempre se ejecutan dentro de VPC propiedad del servicio de Lambda. La configuración de VPC de la función no afecta la asignación de orígenes de eventos. Solo la configuración de red del origen de eventos determina cómo se conecta Lambda al origen de eventos.

Configure los grupos de seguridad para la Amazon VPC que contiene el clúster. De forma predeterminada, Amazon DocumentDB utiliza los siguientes puertos: `27017`.
+ Reglas de entrada: permiten todo el tráfico en el puerto del agente predeterminado para el grupo de seguridad asociado al origen de eventos. Como alternativa, puede usar una regla de grupo de seguridad con autorreferencia para permitir el acceso desde instancias que pertenecen al mismo grupo de seguridad.
+ Reglas de salida: permiten que todo el tráfico en el puerto `443` vaya a destinos externos en caso de que su función necesite comunicarse con servicios de AWS. Como alternativa, también puede usar una regla de grupo de seguridad con autorreferencia para limitar el acceso al agente en caso de que no necesite comunicarse con otros servicios de AWS.
+ Reglas de entrada del punto de conexión de Amazon VPC: si usa un punto de conexión de Amazon VPC, el grupo de seguridad asociado al punto de conexión de Amazon VPC debe permitir el tráfico entrante en el puerto `443` desde el grupo de seguridad del clúster.

Si el clúster utiliza la autenticación, también puede restringir la política del punto de conexión para el punto de conexión de Secrets Manager. Para llamar a la API de Secrets Manager, Lambda usa su rol de función, no la entidad principal de servicio de Lambda.

**Example Política de punto de conexión de VPC: punto de conexión de Secrets Manager**  

```
{
      "Statement": [
          {
              "Action": "secretsmanager:GetSecretValue",
              "Effect": "Allow",
              "Principal": {
                  "AWS": [
                      "arn:aws::iam::123456789012:role/my-role"
                  ]
              },
              "Resource": "arn:aws::secretsmanager:us-west-2:123456789012:secret:my-secret"
          }
      ]
  }
```

Cuando utiliza los puntos de conexión de VPC de Amazon, AWS enruta las llamadas a la API para invocar una función mediante la interfaz de red elástica (ENI) del punto de conexión. La entidad principal del servicio de Lambda debe llamar a `lambda:InvokeFunction` en cualquier rol y función que utilicen esas ENI.

De forma predeterminada, los puntos de conexión de VPC de Amazon tienen políticas de IAM abiertas que permiten un amplio acceso a los recursos. La práctica recomendada es restringir estas políticas para realizar las acciones necesarias mediante ese punto de conexión. Para garantizar que la asignación de orígenes de eventos pueda invocar la función de Lambda, la política de punto de conexión de VPC debe permitir que la entidad principal del servicio de Lambda llame a `sts:AssumeRole` y `lambda:InvokeFunction`. Restringir las políticas de punto de conexión de VPC para permitir únicamente las llamadas a la API que se originen en su organización impide que la asignación de orígenes de eventos funcione correctamente, por lo que en estas políticas es necesario `"Resource": "*"`.

En el siguiente ejemplo de políticas de puntos de conexión de VPC, se muestra cómo conceder el acceso necesario a las entidades principales del servicio de Lambda para AWS STS y los puntos de conexión de Lambda.

**Example Política de punto de conexión de VPC: punto de conexión de AWS STS**  

```
{
      "Statement": [
          {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                  "Service": [
                      "lambda.amazonaws.com"
                  ]
              },
              "Resource": "*"
          }
      ]
    }
```

**Example Política de punto de conexión de VPC: punto de conexión de Lambda**  

```
{
      "Statement": [
          {
              "Action": "lambda:InvokeFunction",
              "Effect": "Allow",
              "Principal": {
                  "Service": [
                      "lambda.amazonaws.com"
                  ]
              },
              "Resource": "*"
          }
      ]
  }
```

## Creación de una asignación de orígenes de eventos de Amazon DocumentDB (consola)
<a name="docdb-configuration"></a>

Para configurar una función de Lambda que lea desde un flujo de cambios de un clúster de Amazon DocumentDB, cree una [asignación de orígenes de eventos](invocation-eventsourcemapping.md). En esta sección, se describe cómo hacer esto desde la consola. Para obtener las instrucciones de AWS SDK y la AWS CLI, consulte [Creación de una asignación de orígenes de eventos de Amazon DocumentDB (SDK o CLI)](#docdb-api).

**Para crear una asignación de orígenes de eventos de Amazon DocumentDB (consola)**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de una función.

1. En **Descripción general de la función**, elija **Agregar desencadenador**.

1. En **Configuración del desencadenador**, seleccione **DocumentDB** de la lista desplegable.

1. Configure las opciones requeridas y luego elija **Agregar**.

Lambda admite las siguientes opciones para los orígenes de eventos de Amazon DocumentDB:
+ **Clúster de DocumentDB**: seleccione un clúster de Amazon DocumentDB.
+ **Activar el desencadenador**: elija si desea activar el desencadenador de forma inmediata. Si marca esta casilla, la función comenzará a recibir tráfico de forma inmediata del flujo de cambios de Amazon DocumentDB que se especificó al crear la asignación de orígenes de eventos. Recomendamos desmarcar la casilla para crear la asignación de orígenes de eventos en un estado desactivado para realizar pruebas. Tras la creación, puede activar la asignación de orígenes de eventos en cualquier momento.
+ **Nombre de base de datos:** introduzca el nombre de una base de datos dentro del clúster a consumir.
+ (Opcional) **Nombre de la colección**: ingrese el nombre de la colección dentro de la base de datos que se va a consumir. Si no especifica una colección, Lambda escucha todos los eventos de cada colección en la base de datos.
+ **Tamaño del lote:** establezca el número máximo de mensajes que se recuperarán en un solo lote, con un máximo de 10 000. El tamaño predeterminado del lote es de 100.
+ **Posición inicial:** elija la posición en el flujo desde la que desea comenzar a leer los registros.
  + **Más recientes:** procesa solo los registros nuevos que se agreguen al flujo principal. La función comienza a procesar registros solo después de que Lambda termina de crear el origen de eventos. Esto significa que es posible que se eliminen algunos registros hasta que el origen de eventos se haya creado correctamente.
  + **Horizonte de supresión**: procesar todos los registros del flujo. Lambda utiliza la duración de retención de registros de su clúster para determinar desde dónde comenzar a leer los eventos. En concreto, Lambda comienza a leer desde `current_time - log_retention_duration`. Su flujo de cambios ya debe estar activo antes de esta marca de tiempo para que Lambda lea de forma correcta todos los eventos.
  + **En marca temporal**: procesar los registros comenzando a partir de un momento determinado. Su flujo de cambios ya debe estar activo antes de la marca de tiempo especificada para que Lambda lea de forma correcta todos los eventos.
+ **Autenticación:** elija el método de autenticación para acceder a los agentes en su clúster.
  + **BASIC\$1AUTH:** con la autenticación básica, debe proporcionar la clave de Secrets Manager que contiene las credenciales para acceder al clúster.
+ **Clave de Secrets Manager**: elija la clave de Secrets Manager que contiene los detalles de autenticación (nombre de usuario y contraseña) necesarios para acceder al clúster de Amazon DocumentDB.
+ (Opcional) **Intervalo de lote**: la cantidad de tiempo máxima para recopilar registros antes de invocar la función, arriba de 300.
+ (Opcional) **Configuración completa del documento**: para las operaciones de actualización de los documentos, elija lo que desea enviar al flujo. El valor predeterminado es `Default`, lo que significa que, para cada evento de flujo de cambios, Amazon DocumentDB envía solo un delta que describe los cambios realizados. Para obtener más información sobre este campo, consulte [FullDocument](https://mongodb.github.io/mongo-java-driver/3.9/javadoc/com/mongodb/client/model/changestream/FullDocument.html#DEFAULT) en la documentación de la API de Javadocs para MongoDB.
  + **Predeterminado:** Lambda envía solo un documento parcial que describe los cambios realizados.
  + **UpdateLookup:** Lambda envía un delta que describe los cambios, junto con una copia del documento completo.

## Creación de una asignación de orígenes de eventos de Amazon DocumentDB (SDK o CLI)
<a name="docdb-api"></a>

Para crear o administrar una asignación de orígenes de eventos de Amazon DocumentDB con [AWS SDK](https://aws.amazon.com/developer/tools/), puede utilizar las siguientes operaciones de la API:
+ [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html)
+ [ListEventSourceMappings](https://docs.aws.amazon.com/lambda/latest/api/API_ListEventSourceMappings.html)
+ [GetEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_GetEventSourceMapping.html)
+ [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html)
+ [DeleteEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteEventSourceMapping.html)

Para crear la asignación de orígenes de eventos con la AWS CLI, use el comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html). En el siguiente ejemplo, se utiliza este comando para asignar una función denominada `my-function` a un flujo de cambios de Amazon DocumentDB. El origen del evento se especifica mediante un nombre de recurso de Amazon (ARN) con un tamaño de lote de 500, que comienza desde una marca temporal en tiempo Unix. El comando también especifica la clave de Secrets Manager que Lambda utiliza para conectarse a Amazon DocumentDB. Además, incluye parámetros `document-db-event-source-config` que especifican la base de datos y la colección desde la que se va a leer.

```
aws lambda create-event-source-mapping --function-name my-function \
    --event-source-arn arn:aws:rds:us-west-2:123456789012:cluster:privatecluster7de2-epzcyvu4pjoy
    --batch-size 500 \
    --starting-position AT_TIMESTAMP \
    --starting-position-timestamp 1541139109 \
    --source-access-configurations '[{"Type":"BASIC_AUTH","URI":"arn:aws:secretsmanager:us-east-1:123456789012:secret:DocDBSecret-BAtjxi"}]' \
    --document-db-event-source-config '{"DatabaseName":"test_database", "CollectionName": "test_collection"}' \
```

Debería ver un resultado con un aspecto similar al siguiente:

```
{
    "UUID": "2b733gdc-8ac3-cdf5-af3a-1827b3b11284",
    "BatchSize": 500,
    "DocumentDBEventSourceConfig": {
        "CollectionName": "test_collection",
        "DatabaseName": "test_database",
        "FullDocument": "Default"
    },
    "MaximumBatchingWindowInSeconds": 0,
    "EventSourceArn": "arn:aws:rds:us-west-2:123456789012:cluster:privatecluster7de2-epzcyvu4pjoy",
    "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
    "LastModified": 1541348195.412,
    "LastProcessingResult": "No records processed",
    "State": "Creating",
    "StateTransitionReason": "User action"
}
```

Tras la creación, puede utilizar el comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) para actualizar la configuración relacionada con el origen de eventos de Amazon DocumentDB. El siguiente comando actualiza el tamaño del lote a 1000 y el intervalo del lote a 10 segundos. Para este comando, necesita el UUID de la asignación de orígenes de eventos, que puede recuperar mediante el comando `list-event-source-mapping` o desde la consola de Lambda.

```
aws lambda update-event-source-mapping --function-name my-function \
    --uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
    --batch-size 1000 \
    --batch-window 10
```

Debería ver esta salida con un aspecto similar al siguiente:

```
{
    "UUID": "2b733gdc-8ac3-cdf5-af3a-1827b3b11284",
    "BatchSize": 500,
    "DocumentDBEventSourceConfig": {
        "CollectionName": "test_collection",
        "DatabaseName": "test_database",
        "FullDocument": "Default"
    },
    "MaximumBatchingWindowInSeconds": 0,
    "EventSourceArn": "arn:aws:rds:us-west-2:123456789012:cluster:privatecluster7de2-epzcyvu4pjoy",
    "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
    "LastModified": 1541359182.919,
    "LastProcessingResult": "OK",
    "State": "Updating",
    "StateTransitionReason": "User action"
}
```

Lambda actualiza la configuración de forma asíncrona, por lo que es posible que no vea estos cambios en la salida hasta que se complete el proceso. Para ver la configuración actual de la asignación de orígenes de eventos, utilice el comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-event-source-mapping.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-event-source-mapping.html).

```
aws lambda get-event-source-mapping --uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b
```

Debería ver esta salida con un aspecto similar al siguiente:

```
{
    "UUID": "2b733gdc-8ac3-cdf5-af3a-1827b3b11284",
    "DocumentDBEventSourceConfig": {
        "CollectionName": "test_collection",
        "DatabaseName": "test_database",
        "FullDocument": "Default"
    },
    "BatchSize": 1000,
    "MaximumBatchingWindowInSeconds": 10,
    "EventSourceArn": "arn:aws:rds:us-west-2:123456789012:cluster:privatecluster7de2-epzcyvu4pjoy",
    "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:my-function",
    "LastModified": 1541359182.919,
    "LastProcessingResult": "OK",
    "State": "Enabled",
    "StateTransitionReason": "User action"
}
```

Para eliminar la asignación de orígenes de eventos de Amazon DocumentDB, utilice el comando [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/delete-event-source-mapping.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/delete-event-source-mapping.html).

```
aws lambda delete-event-source-mapping \
    --uuid 2b733gdc-8ac3-cdf5-af3a-1827b3b11284
```

## Posiciones iniciales de flujos y sondeo
<a name="docdb-stream-polling"></a>

Tenga en cuenta que el sondeo de flujos durante la creación y las actualizaciones de la asignación de orígenes de eventos es, en última instancia, coherente.
+ Durante la creación de la asignación de orígenes de eventos, es posible que se demore varios minutos en iniciar el sondeo de los eventos del flujo.
+ Durante las actualizaciones de la asignación de orígenes de eventos, es posible que se demore varios minutos en detener y reiniciar el sondeo de los eventos del flujo.

Este comportamiento significa que, si especifica `LATEST` como posición inicial del flujo, la asignación de orígenes de eventos podría omitir eventos durante la creación o las actualizaciones. Para garantizar que no se pierda ningún evento, especifique la posición inicial del flujo como `TRIM_HORIZON` o `AT_TIMESTAMP`.

## Monitoreo del origen de eventos de Amazon DocumentDB
<a name="docdb-monitoring"></a>

Para ayudarlo a monitorear el origen de eventos de Amazon DocumentDB, Lambda emite la métrica `IteratorAge` cuando su función termina de procesar un lote de registros. La *antigüedad del iterador* es la diferencia entre la marca de tiempo del evento más reciente y la marca de tiempo actual. En esencia, la métrica `IteratorAge` indica la antigüedad del último registro procesado del lote. Si la función está procesando nuevos eventos en este momento, puede utilizar la antigüedad del iterador para estimar la latencia entre cuando un registro se agrega y cuando la función lo procesa. Una tendencia ascendente en `IteratorAge` puede indicar problemas con la función. Para obtener más información, consulte [Uso de métricas de CloudWatch con Lambda](monitoring-metrics.md).

Los flujos de cambios de Amazon DocumentDB no están optimizados para gestionar grandes intervalos de tiempo entre eventos. Si su origen de eventos de Amazon DocumentDB no recibe ningún evento durante un periodo prolongado, Lambda puede deshabilitar la asignación de orígenes de eventos. La duración de este periodo puede variar de unas semanas a unos meses, según el tamaño del clúster y otras cargas de trabajo.

Lambda admite cargas de hasta 6 MB. Sin embargo, los eventos del flujo de cambios de Amazon DocumentDB pueden tener un tamaño de hasta 16 MB. Si el flujo de cambios intenta enviar a Lambda un evento de flujo de cambios de más de 6 MB, Lambda elimina el mensaje y emite la métrica `OversizedRecordCount`. Lambda emite todas las métricas dentro de lo posible.

# Tutorial: Uso de AWS Lambda con Amazon DocumentDB Streams
<a name="with-documentdb-tutorial"></a>

 En este tutorial, creará una función de Lambda básica que consuma eventos de un flujo de cambios de Amazon DocumentDB (con compatibilidad con MongoDB). Para completar este tutorial, pasará por las siguientes etapas: 
+ Configure su clúster de Amazon DocumentDB, conéctese a él y active los flujos de cambios en él.
+ Cree la función de Lambda y configure el clúster de Amazon DocumentDB como origen de eventos para su función.
+ Para probar la configuración, inserte elementos en la base de datos de Amazon DocumentDB.

## Creación de un clúster de Amazon DocumentDB
<a name="docdb-documentdb-cluster"></a>

1. Abra la [consola de Amazon DocumentDB](https://console.aws.amazon.com/docdb/home#). En **Clústeres**, elija **Crear**.

1. Cree un clúster con la siguiente configuración:
   + En **Tipo de clúster**, elija **Clúster basado en instancias**. Esta es la opción predeterminada.
   + En **Configuración del clúster**, asegúrese de haber seleccionado la **Versión del motor** 5.0.0. Esta es la opción predeterminada.
   + En **Configuración de la instancia**:
     + En **Clase de la instancia de base de datos**, seleccione **Clases optimizadas para memoria**. Esta es la opción predeterminada.
     + En **Número de instancias de réplicas regulares**, elija 1.
     + En **Clase de instancia**, use la selección predeterminada.
   + En **Autenticación**, ingrese un nombre de usuario para el usuario principal y, a continuación, elija **Autoadministrado**. Ingrese una contraseña y, a continuación, confírmela.
   + Conserve todas las otras opciones de configuración predeterminadas.

1. Elija **Create cluster**.

## Crear un secreto en Secrets Manager
<a name="docdb-secret-in-secrets-manager"></a>

Mientras Amazon DocumentDB crea el clúster, cree un secreto de AWS Secrets Manager para almacenar las credenciales de la base de datos. Proporcionará este secreto cuando cree la asignación de orígenes de eventos de Lambda en un paso posterior.

**Para crear un secreto en Secrets Manager**

1. Abra la consola de [Secrets Manager](https://console.aws.amazon.com/secretsmanager/home#) y elija **Almacenar un nuevo secreto**.

1. En **Elegir tipo de secreto**, elija las siguientes opciones:
   + En **Detalles básicos**:
     + **Tipo de secreto**: credenciales para la base de datos de Amazon DocumentDB
     + En **Credenciales**, ingrese el mismo nombre de usuario y la contraseña que usó para crear el clúster de Amazon DocumentDB.
     + **Base de datos**: elija su clúster de Amazon DocumentDB.
     + Elija **Siguiente**.

1. En **Configurar secreto**, elija las siguientes opciones:
   + **Nombre del secreto**: `DocumentDBSecret`
   + Elija **Siguiente**.

1. Elija **Siguiente**.

1. Elija **Almacenar**.

1. Actualice la consola para comprobar que ha guardado correctamente el secreto `DocumentDBSecret`.

Anote el **ARN del secreto**. Lo necesitará en un paso posterior.

## Conexión al clúster
<a name="docdb-connect-to-cluster"></a>

**Conexión al clúster de Amazon DocumentDB con AWS CloudShell**

1. En la consola de administración de Amazon DocumentDB, en **Clústeres**, localice el clúster que ha creado. Para elegir el clúster, haga clic en la casilla de verificación situada junto a él.

1. Elija **Conectarse al clúster**. Aparece la pantalla **Ejecutar comando** de CloudShell.

1. En el campo **Nombre del nuevo entorno**, ingrese un nombre único, como “prueba” y elija **Crear y ejecutar**.

1. Escriba la contraseña cuando se le solicite. Cuando la petición se convierte en `rs0 [direct: primary] <env-name>>`, significa que se ha conectado correctamente al clúster de Amazon DocumentDB.

## Activar flujos de cambios
<a name="docdb-activate-change-streams"></a>

En este tutorial, hará un seguimiento de los cambios en la colección `products` de la base de datos `docdbdemo` en el clúster de Amazon DocumentDB. Para ello, active los [flujos de cambios](https://docs.aws.amazon.com/documentdb/latest/developerguide/change_streams.html).

**Para crear una nueva base de datos dentro del clúster**

1. Ejecute el siguiente comando para crear una nueva base de datos denominada `docdbdemo`:

   ```
   use docdbdemo
   ```

1. En la ventana del terminal, use el siguiente comando para insertar un registro en `docdbdemo`:

   ```
   db.products.insertOne({"hello":"world"})
   ```

   Debería ver una salida similar a esta:

   ```
   {
     acknowledged: true,
     insertedId: ObjectId('67f85066ca526410fd531d59')
   }
   ```

1. A continuación, active los flujos de cambios en la colección `products` de la base de datos `docdbdemo` con el siguiente comando:

   ```
   db.adminCommand({modifyChangeStreams: 1,
       database: "docdbdemo",
       collection: "products", 
       enable: true});
   ```

    Debería ver un resultado con un aspecto similar al siguiente: 

   ```
   { "ok" : 1, "operationTime" : Timestamp(1680126165, 1) }
   ```

## Creación de puntos de conexión de VPC de interfaz
<a name="docdb-create-interface-vpc-endpoints"></a>

A continuación, cree [puntos de conexión de VPC de interfaz](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html#create-interface-endpoint-aws) para garantizar que Lambda y Secrets Manager (que se utilizarán más adelante para almacenar nuestras credenciales de acceso al clúster) puedan conectarse a su VPC predeterminada.

**Cómo crear puntos de conexión de VPC de interfaz**

1. Abra la [consola de VPC](https://console.aws.amazon.com/vpc/home#). En el menú de la izquierda, en **Nube privada virtual**, seleccione **Puntos de conexión**.

1. Seleccione **Crear punto de conexión**. Cree un punto de conexión con la siguiente configuración:
   + En **Etiqueta de nombre**, ingrese `lambda-default-vpc`.
   + En **Categoría de servicios**, elija Servicios de AWS.
   + En **Servicios**, ingrese `lambda` en el cuadro de búsqueda. Elija el servicio con formato `com.amazonaws.<region>.lambda`.
   + En **VPC**, elija la VPC en la que se encuentra su clúster de Amazon DocumentDB. Suele ser la [VPC predeterminada](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html).
   + En **Subredes**, marque las casillas situadas junto a cada zona de disponibilidad. Elija el ID de subred correcto para cada zona de disponibilidad.
   + En **Tipo de dirección IP**, seleccione IPv4.
   + En **Grupos de seguridad**, elija el grupo de seguridad que utiliza su clúster de Amazon DocumentDB. Suele ser el grupo de seguridad `default`.
   + Conserve todas las otras opciones de configuración predeterminadas.
   + Seleccione **Crear punto de conexión**.

1. Elija nuevamente **Crear punto de conexión**. Cree un punto de conexión con la siguiente configuración:
   + En **Etiqueta de nombre**, ingrese `secretsmanager-default-vpc`.
   + En **Categoría de servicios**, elija Servicios de AWS.
   + En **Servicios**, ingrese `secretsmanager` en el cuadro de búsqueda. Elija el servicio con formato `com.amazonaws.<region>.secretsmanager`.
   + En **VPC**, elija la VPC en la que se encuentra su clúster de Amazon DocumentDB. Suele ser la [VPC predeterminada](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html).
   + En **Subredes**, marque las casillas situadas junto a cada zona de disponibilidad. Elija el ID de subred correcto para cada zona de disponibilidad.
   + En **Tipo de dirección IP**, seleccione IPv4.
   + En **Grupos de seguridad**, elija el grupo de seguridad que utiliza su clúster de Amazon DocumentDB. Suele ser el grupo de seguridad `default`.
   + Conserve todas las otras opciones de configuración predeterminadas.
   + Seleccione **Crear punto de conexión**.

 Esto completa la parte de configuración del clúster de este tutorial. 

## Creación del rol de ejecución
<a name="docdb-create-the-execution-role"></a>

 En la siguiente serie de pasos, creará la función de Lambda. Primero, debe crear el rol de ejecución que concederá a su función permiso para acceder al clúster. Para ello, primero creará una política de IAM y luego asociará esta política a un rol de IAM. 

**Para crear una política de IAM**

1. En la consola de IAM, abra la [página Políticas](https://console.aws.amazon.com/iam/home#/policies), y, a continuación, elija **Crear política**.

1. Seleccione la pestaña **JSON**. En la siguiente política, sustituya el ARN del recurso de Secrets Manager en la última línea de la instrucción por el ARN secreto anterior y copie la política en el editor.

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "LambdaESMNetworkingAccess",
               "Effect": "Allow",
               "Action": [
                   "ec2:CreateNetworkInterface",
                   "ec2:DescribeNetworkInterfaces",
                   "ec2:DescribeVpcs",
                   "ec2:DeleteNetworkInterface",
                   "ec2:DescribeSubnets",
                   "ec2:DescribeSecurityGroups",
                   "kms:Decrypt"
               ],
               "Resource": "*"
           },
           {
               "Sid": "LambdaDocDBESMAccess",
               "Effect": "Allow",
               "Action": [
                   "rds:DescribeDBClusters",
                   "rds:DescribeDBClusterParameters",
                   "rds:DescribeDBSubnetGroups"
               ],
               "Resource": "*"
           },
           {
               "Sid": "LambdaDocDBESMGetSecretValueAccess",
               "Effect": "Allow",
               "Action": [
                   "secretsmanager:GetSecretValue"
               ],
               "Resource": "arn:aws:secretsmanager:us-east-1:123456789012:secret:DocumentDBSecret"
           }
       ]
   }
   ```

------

1. Elija **Siguiente: Etiquetas** y, a continuación, seleccione **Siguiente: Revisar**.

1. En **Name** (Nombre), ingrese `AWSDocumentDBLambdaPolicy`.

1. Elija **Crear política**.

**Creación del rol de IAM**

1. Abra la [página Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM y elija **Crear rol**.

1. En **Seleccionar entidad de confianza**, elija las siguientes opciones:
   + **Tipo de entidad de confianza**: servicio de AWS
   + **Servicio o caso de uso**: Lambda
   + Elija **Siguiente**.

1. En **Agregar permisos**, elija la política `AWSDocumentDBLambdaPolicy` que acaba de crear y también `AWSLambdaBasicExecutionRole` para conceder a su función permisos para escribir en los Registros de Amazon CloudWatch.

1. Elija **Siguiente**.

1. En **Role name (Nombre del rol)**, introduzca `AWSDocumentDBLambdaExecutionRole`.

1. Elija **Create role** (Crear rol).

## Crear la función de Lambda
<a name="docdb-create-the-lambda-function"></a>

En este tutorial, se utiliza el tiempo de ejecución de Python 3.14, pero también proporcionamos archivos de código de ejemplo para otros tiempos de ejecución. Puede seleccionar la pestaña del siguiente cuadro para ver el código del tiempo de ejecución que le interesa.

El código recibe un evento de Amazon DocumentDB como entrada y procesa el mensaje que contiene.

**Para crear la función de Lambda**

1. Abra la página de [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funciones) en la consola de Lambda.

1. Seleccione **Creación de función**.

1. Elija **Crear desde cero**.

1. Bajo **Información básica**, haga lo siguiente:

   1. En **Nombre de la función**, ingrese `ProcessDocumentDBRecords`.

   1. En **Tiempo de ejecución**, seleccione **Python 3.14**.

   1. En **Arquitectura**, elija **x86\$164**.

1. En la pestaña **Cambiar rol de ejecución predeterminado**, haga lo siguiente:

   1. Amplíe la pestaña y, a continuación, elija **Utilizar un rol existente**.

   1. Seleccione el `AWSDocumentDBLambdaExecutionRole` que creó anteriormente.

1. Seleccione **Creación de función**.

**Para implementar el código de la función**

1. Seleccione la pestaña **Python** en el siguiente cuadro y copie el código.

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumo de un evento de Amazon DocumentDB con Lambda mediante .NET.  

   ```
   using Amazon.Lambda.Core;
   using System.Text.Json;
   using System;
   using System.Collections.Generic;
   using System.Text.Json.Serialization;
   //Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
   [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
   
   namespace LambdaDocDb;
   
   public class Function
   {
       
        /// <summary>
       /// Lambda function entry point to process Amazon DocumentDB events.
       /// </summary>
       /// <param name="event">The Amazon DocumentDB event.</param>
       /// <param name="context">The Lambda context object.</param>
       /// <returns>A string to indicate successful processing.</returns>
       public string FunctionHandler(Event evnt, ILambdaContext context)
       {
           
           foreach (var record in evnt.Events)
           {
               ProcessDocumentDBEvent(record, context);
           }
   
           return "OK";
       }
   
        private void ProcessDocumentDBEvent(DocumentDBEventRecord record, ILambdaContext context)
       {
           
           var eventData = record.Event;
           var operationType = eventData.OperationType;
           var databaseName = eventData.Ns.Db;
           var collectionName = eventData.Ns.Coll;
           var fullDocument = JsonSerializer.Serialize(eventData.FullDocument, new JsonSerializerOptions { WriteIndented = true });
   
           context.Logger.LogLine($"Operation type: {operationType}");
           context.Logger.LogLine($"Database: {databaseName}");
           context.Logger.LogLine($"Collection: {collectionName}");
           context.Logger.LogLine($"Full document:\n{fullDocument}");
       }
   
   
   
       public class Event
       {
           [JsonPropertyName("eventSourceArn")]
           public string EventSourceArn { get; set; }
   
           [JsonPropertyName("events")]
           public List<DocumentDBEventRecord> Events { get; set; }
   
           [JsonPropertyName("eventSource")]
           public string EventSource { get; set; }
       }
   
       public class DocumentDBEventRecord
       {
           [JsonPropertyName("event")]
           public EventData Event { get; set; }
       }
   
       public class EventData
       {
           [JsonPropertyName("_id")]
           public IdData Id { get; set; }
   
           [JsonPropertyName("clusterTime")]
           public ClusterTime ClusterTime { get; set; }
   
           [JsonPropertyName("documentKey")]
           public DocumentKey DocumentKey { get; set; }
   
           [JsonPropertyName("fullDocument")]
           public Dictionary<string, object> FullDocument { get; set; }
   
           [JsonPropertyName("ns")]
           public Namespace Ns { get; set; }
   
           [JsonPropertyName("operationType")]
           public string OperationType { get; set; }
       }
   
       public class IdData
       {
           [JsonPropertyName("_data")]
           public string Data { get; set; }
       }
   
       public class ClusterTime
       {
           [JsonPropertyName("$timestamp")]
           public Timestamp Timestamp { get; set; }
       }
   
       public class Timestamp
       {
           [JsonPropertyName("t")]
           public long T { get; set; }
   
           [JsonPropertyName("i")]
           public int I { get; set; }
       }
   
       public class DocumentKey
       {
           [JsonPropertyName("_id")]
           public Id Id { get; set; }
       }
   
       public class Id
       {
           [JsonPropertyName("$oid")]
           public string Oid { get; set; }
       }
   
       public class Namespace
       {
           [JsonPropertyName("db")]
           public string Db { get; set; }
   
           [JsonPropertyName("coll")]
           public string Coll { get; set; }
       }
   }
   ```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumir un evento de Amazon DocumentDB con Lambda utilizando Go.  

   ```
   package main
   
   import (
   	"context"
   	"encoding/json"
   	"fmt"
   
   	"github.com/aws/aws-lambda-go/lambda"
   )
   
   type Event struct {
   	Events []Record `json:"events"`
   }
   
   type Record struct {
   	Event struct {
   		OperationType string `json:"operationType"`
   		NS            struct {
   			DB   string `json:"db"`
   			Coll string `json:"coll"`
   		} `json:"ns"`
   		FullDocument interface{} `json:"fullDocument"`
   	} `json:"event"`
   }
   
   func main() {
   	lambda.Start(handler)
   }
   
   func handler(ctx context.Context, event Event) (string, error) {
   	fmt.Println("Loading function")
   	for _, record := range event.Events {
   		logDocumentDBEvent(record)
   	}
   
   	return "OK", nil
   }
   
   func logDocumentDBEvent(record Record) {
   	fmt.Printf("Operation type: %s\n", record.Event.OperationType)
   	fmt.Printf("db: %s\n", record.Event.NS.DB)
   	fmt.Printf("collection: %s\n", record.Event.NS.Coll)
   	docBytes, _ := json.MarshalIndent(record.Event.FullDocument, "", "  ")
   	fmt.Printf("Full document: %s\n", string(docBytes))
   }
   ```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Cómo consumir un evento de Amazon DocumentDB con Lambda mediante Java.  

   ```
   import java.util.List;
   import java.util.Map;
   
   import com.amazonaws.services.lambda.runtime.Context;
   import com.amazonaws.services.lambda.runtime.RequestHandler;
   
   public class Example implements RequestHandler<Map<String, Object>, String> {
   
       @SuppressWarnings("unchecked")
       @Override
       public String handleRequest(Map<String, Object> event, Context context) {
           List<Map<String, Object>> events = (List<Map<String, Object>>) event.get("events");
           for (Map<String, Object> record : events) {
               Map<String, Object> eventData = (Map<String, Object>) record.get("event");
               processEventData(eventData);
           }
   
           return "OK";
       }
   
       @SuppressWarnings("unchecked")
       private void processEventData(Map<String, Object> eventData) {
           String operationType = (String) eventData.get("operationType");
           System.out.println("operationType: %s".formatted(operationType));
   
           Map<String, Object> ns = (Map<String, Object>) eventData.get("ns");
   
           String db = (String) ns.get("db");
           System.out.println("db: %s".formatted(db));
           String coll = (String) ns.get("coll");
           System.out.println("coll: %s".formatted(coll));
   
           Map<String, Object> fullDocument = (Map<String, Object>) eventData.get("fullDocument");
           System.out.println("fullDocument: %s".formatted(fullDocument));
       }
   
   }
   ```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumo de un evento de Amazon DocumentDB con Lambda mediante JavaScript.  

   ```
   console.log('Loading function');
   exports.handler = async (event, context) => {
       event.events.forEach(record => {
           logDocumentDBEvent(record);
       });
       return 'OK';
   };
   
   const logDocumentDBEvent = (record) => {
       console.log('Operation type: ' + record.event.operationType);
       console.log('db: ' + record.event.ns.db);
       console.log('collection: ' + record.event.ns.coll);
       console.log('Full document:', JSON.stringify(record.event.fullDocument, null, 2));
   };
   ```
Consumo de un evento de Amazon DocumentDB con Lambda mediante TypeScript  

   ```
   import { DocumentDBEventRecord, DocumentDBEventSubscriptionContext } from 'aws-lambda';
   
   console.log('Loading function');
   
   export const handler = async (
     event: DocumentDBEventSubscriptionContext,
     context: any
   ): Promise<string> => {
     event.events.forEach((record: DocumentDBEventRecord) => {
       logDocumentDBEvent(record);
     });
     return 'OK';
   };
   
   const logDocumentDBEvent = (record: DocumentDBEventRecord): void => {
     console.log('Operation type: ' + record.event.operationType);
     console.log('db: ' + record.event.ns.db);
     console.log('collection: ' + record.event.ns.coll);
     console.log('Full document:', JSON.stringify(record.event.fullDocument, null, 2));
   };
   ```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumo de un evento de Amazon DocumentDB con Lambda mediante PHP.  

   ```
   <?php
   
   require __DIR__.'/vendor/autoload.php';
   
   use Bref\Context\Context;
   use Bref\Event\Handler;
   
   class DocumentDBEventHandler implements Handler
   {
       public function handle($event, Context $context): string
       {
   
           $events = $event['events'] ?? [];
           foreach ($events as $record) {
               $this->logDocumentDBEvent($record['event']);
           }
           return 'OK';
       }
   
       private function logDocumentDBEvent($event): void
       {
           // Extract information from the event record
   
           $operationType = $event['operationType'] ?? 'Unknown';
           $db = $event['ns']['db'] ?? 'Unknown';
           $collection = $event['ns']['coll'] ?? 'Unknown';
           $fullDocument = $event['fullDocument'] ?? [];
   
           // Log the event details
   
           echo "Operation type: $operationType\n";
           echo "Database: $db\n";
           echo "Collection: $collection\n";
           echo "Full document: " . json_encode($fullDocument, JSON_PRETTY_PRINT) . "\n";
       }
   }
   return new DocumentDBEventHandler();
   ```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumo de un evento de Amazon DocumentDB con Lambda mediante Python.  

   ```
   import json
   
   def lambda_handler(event, context):
       for record in event.get('events', []):
           log_document_db_event(record)
       return 'OK'
   
   def log_document_db_event(record):
       event_data = record.get('event', {})
       operation_type = event_data.get('operationType', 'Unknown')
       db = event_data.get('ns', {}).get('db', 'Unknown')
       collection = event_data.get('ns', {}).get('coll', 'Unknown')
       full_document = event_data.get('fullDocument', {})
   
       print(f"Operation type: {operation_type}")
       print(f"db: {db}")
       print(f"collection: {collection}")
       print("Full document:", json.dumps(full_document, indent=2))
   ```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumo de un evento de Amazon DocumentDB con Lambda mediante Ruby.  

   ```
   require 'json'
   
   def lambda_handler(event:, context:)
     event['events'].each do |record|
       log_document_db_event(record)
     end
     'OK'
   end
   
   def log_document_db_event(record)
     event_data = record['event'] || {}
     operation_type = event_data['operationType'] || 'Unknown'
     db = event_data.dig('ns', 'db') || 'Unknown'
     collection = event_data.dig('ns', 'coll') || 'Unknown'
     full_document = event_data['fullDocument'] || {}
   
     puts "Operation type: #{operation_type}"
     puts "db: #{db}"
     puts "collection: #{collection}"
     puts "Full document: #{JSON.pretty_generate(full_document)}"
   end
   ```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumo de un evento de Amazon DocumentDB con Lambda mediante Rust.  

   ```
   use lambda_runtime::{service_fn, tracing, Error, LambdaEvent};
   use aws_lambda_events::{
       event::documentdb::{DocumentDbEvent, DocumentDbInnerEvent},
      };
   
   
   // Built with the following dependencies:
   //lambda_runtime = "0.11.1"
   //serde_json = "1.0"
   //tokio = { version = "1", features = ["macros"] }
   //tracing = { version = "0.1", features = ["log"] }
   //tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] }
   //aws_lambda_events = "0.15.0"
   
   async fn function_handler(event: LambdaEvent<DocumentDbEvent>) ->Result<(), Error> {
       
       tracing::info!("Event Source ARN: {:?}", event.payload.event_source_arn);
       tracing::info!("Event Source: {:?}", event.payload.event_source);
     
       let records = &event.payload.events;
      
       if records.is_empty() {
           tracing::info!("No records found. Exiting.");
           return Ok(());
       }
   
       for record in records{
           log_document_db_event(record);
       }
   
       tracing::info!("Document db records processed");
   
       // Prepare the response
       Ok(())
   
   }
   
   fn log_document_db_event(record: &DocumentDbInnerEvent)-> Result<(), Error>{
       tracing::info!("Change Event: {:?}", record.event);
       
       Ok(())
   
   }
   
   #[tokio::main]
   async fn main() -> Result<(), Error> {
       tracing_subscriber::fmt()
       .with_max_level(tracing::Level::INFO)
       .with_target(false)
       .without_time()
       .init();
   
       let func = service_fn(function_handler);
       lambda_runtime::run(func).await?;
       Ok(())
       
   }
   ```

------

1. En el panel **Código fuente** de la consola de Lambda, pegue el siguiente código en el editor de código y sustituya el código creado por Lambda.

1. En la sección **IMPLEMENTAR** elija **Implementar** para actualizar el código de la función:  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

## Crear la asignación de orígenes de eventos de Lambda
<a name="docdb-create-the-lambda-event-source-mapping"></a>

 Cree la asignación de orígenes de eventos que asocie su flujo de cambios de Amazon DocumentDB a la función de Lambda. Una vez creada esta asignación de orígenes de eventos, AWS Lambda comienza a sondear el flujo. 

**Para crear la asignación de orígenes de eventos**

1. Abra la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija la función `ProcessDocumentDBRecords` que creó anteriormente.

1. Elija la pestaña **Configuración** y, a continuación, elija **Desencadenadores** en el menú de la izquierda.

1. Elija **Add trigger (Añadir disparador)**.

1. En **Configuración del desencadenador**, para el origen, seleccione **Amazon DocumentDB**.

1. Cree la asignación de orígenes de eventos con la siguiente configuración:
   + **Clúster de Amazon DocumentDB**: elija el clúster que creó anteriormente.
   + **Nombre de la base de datos:** docdbdemo
   + **Nombre de la colección**: productos
   + **Tamaño del lote**: 1
   + **Posición inicial**: más reciente
   + **Autenticación**: BASIC\$1AUTH
   + **Clave de Secrets Manager**: elija el secreto de su clúster de Amazon DocumentDB. Tendrá un nombre similar a `rds!cluster-12345678-a6f0-52c0-b290-db4aga89274f`.
   + **Intervalo del lote**: 1
   + **Configuración de documentos completa**: UpdateLookup

1. Elija **Agregar**. Crear la asignación de orígenes de eventos puede tardar unos minutos.

## Comprobación de la función de
<a name="docdb-test-insert"></a>

Espere a que la asignación de orígenes de eventos llegue al estado **Habilitado**. Esto puede tardar varios minutos. A continuación, inserte, actualice y elimine los registros de base de datos para probar la configuración integral. Antes de empezar:

1. [Vuelva a conectarse al clúster de Amazon DocumentDB](#docdb-connect-to-cluster) en su entorno de CloudShell.

1. Ejecute el siguiente comando para asegurarse de que utiliza la base de datos `docdbdemo`:

   ```
   use docdbdemo
   ```

### Inserción de un registro
<a name="docdb-test-insert"></a>

Inserte un registro en la colección `products` de la base de datos `docdbdemo`:

```
db.products.insertOne({"name":"Pencil", "price": 1.00})
```

Para verificar que la función procesó correctamente este evento, [compruebe los Registros de CloudWatch](monitoring-cloudwatchlogs-view.md#monitoring-cloudwatchlogs-console). Debería ver un registro como este:

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/documentdb-insert-log.png)


### Actualización de un registro
<a name="docdb-test-update"></a>

Actualice el registro que acaba de insertar con el siguiente comando:

```
db.products.updateOne(
    { "name": "Pencil" },
    { $set: { "price": 0.50 }}
)
```

Para verificar que la función procesó correctamente este evento, [compruebe los Registros de CloudWatch](monitoring-cloudwatchlogs-view.md#monitoring-cloudwatchlogs-console). Debería ver un registro como este:

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/documentdb-update-log.png)


### Eliminación de un registro
<a name="docdb-test-delete"></a>

Elimine el registro que acaba de actualizar con el siguiente comando:

```
db.products.deleteOne( { "name": "Pencil" } )
```

Para verificar que la función procesó correctamente este evento, [compruebe los Registros de CloudWatch](monitoring-cloudwatchlogs-view.md#monitoring-cloudwatchlogs-console). Debería ver un registro como este:

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/documentdb-delete-log.png)


## Solución de problemas
<a name="docdb-lambda-troubleshooting"></a>

Si no ve ningún evento de base de datos en los registros de CloudWatch de la función, compruebe lo siguiente:
+ Asegúrese de que el estado de la asignación de orígenes de eventos de Lambda (también conocida como desencadenador) sea **Habilitado**. La creación de las asignaciones de orígenes de eventos puede tardar varios minutos.
+ Si la asignación de orígenes de eventos está **habilitada**, pero sigue sin ver los eventos de la base de datos en CloudWatch:
  + Asegúrese de que el **nombre de la base de datos** en la asignación de orígenes de eventos esté establecido en `docdbdemo`.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/documentdb-trigger.png)
  + Compruebe el campo **Resultado del último procesamiento** de la asignación de orígenes de eventos para ver el siguiente mensaje: “PROBLEMA: error de conexión. Su VPC debe poder conectarse a Lambda y STS, así como a Secrets Manager si se requiere autenticación”. Si ve este error, asegúrese de haber [creado los puntos de conexión de la interfaz de VPC de Lambda y Secrets Manager](#docdb-create-interface-vpc-endpoints) y de que los puntos de conexión utilicen la misma VPC y las mismas subredes que utiliza su clúster de Amazon DocumentDB.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/documentdb-lastprocessingresult.png)

## Eliminación de sus recursos
<a name="docdb-cleanup"></a>

 A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS. 

**Cómo eliminar la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que ha creado.

1. Elija **Acciones**, **Eliminar**.

1. Escriba **confirm** en el campo de entrada de texto y elija **Delete**(Eliminar).

**Cómo eliminar el rol de ejecución**

1. Abra la página [Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione el rol de ejecución que creó.

1. Elija **Eliminar**.

1. Si desea continuar, escriba el nombre del rol en el campo de entrada de texto y elija **Delete** (Eliminar).

**Para eliminar los puntos de conexión de VPC**

1. Abra la [consola de VPC](https://console.aws.amazon.com/vpc/home#). En el menú de la izquierda, en **Nube privada virtual**, seleccione **Puntos de conexión**.

1. Seleccione los puntos de conexión que ha creado.

1. Elija **Acciones**, **Eliminar puntos de conexión de VPC**.

1. Introduzca **delete** en el campo de entrada de texto.

1. Elija **Eliminar**.

**Para eliminar el clúster de Amazon DocumentDB**

1. Abra la [consola de Amazon DocumentDB](https://console.aws.amazon.com/docdb/home#).

1. Elija el clúster de Amazon DocumentDB que creó para este tutorial y deshabilite la protección contra la eliminación.

1. En la página principal **Clústeres**, vuelva a elegir el clúster de Amazon DocumentDB.

1. Elija **Acciones**, **Eliminar**.

1. En **Crear instantánea final del clúster**, seleccione **No**.

1. Introduzca **delete** en el campo de entrada de texto.

1. Elija **Eliminar**.

**Para eliminar el secreto en Secrets Manager**

1. Abra la [consola de Secrets Manager](https://console.aws.amazon.com/secretsmanager/home#).

1. Elija el secreto que ha creado para este tutorial.

1. Elija **Acciones**, **Eliminar secreto**.

1. Elija **Schedule deletion**.

# Uso de AWS Lambda con Amazon DynamoDB
<a name="with-ddb"></a>

**nota**  
Si desea enviar datos a un destino que no sea una función de Lambda o enriquecer los datos antes de enviarlos, consulte [Amazon EventBridge Pipes](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html) (Canalizaciones de Amazon EventBridge).

Puede utilizar una función AWS Lambda para procesar los registros de un [flujo de Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html). Con DynamoDB Streams, puede activar una función de Lambda para realizar trabajo adicional cada vez que se actualice una tabla de DynamoDB.

Cuando se procesan transmisiones de DynamoDB, se debe implementar una lógica de respuesta por lotes parcial para evitar que se intente reprocesar los registros ya procesados correctamente cuando algunos registros de un lote fallan. La [utilidad de procesador por lotes](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) de Powertools para AWS Lambda está disponible en Python, TypeScript, .NET y Java y simplifica esta implementación al gestionar de manera automática la lógica de respuesta parcial por lotes, lo que reduce el tiempo de desarrollo y mejora la fiabilidad.

**Topics**
+ [

## Sondeo y procesamiento por lotes de flujos
](#dynamodb-polling-and-batching)
+ [

## Posiciones iniciales de flujos y sondeo
](#dyanmo-db-stream-poll)
+ [

## Lectores simultáneos de una partición en DynamoDB Streams
](#events-dynamodb-simultaneous-readers)
+ [

## Evento de ejemplo
](#events-sample-dynamodb)
+ [

# Proceso de registros de DynamoDB con Lambda
](services-dynamodb-eventsourcemapping.md)
+ [

# Configuración de la respuesta por lotes parcial con DynamoDB y Lambda
](services-ddb-batchfailurereporting.md)
+ [

# Conservación de registros descartados para un origen de eventos de DynamoDB en Lambda
](services-dynamodb-errors.md)
+ [

# Implementación del procesamiento con estado del flujo DynamoDB en Lambda
](services-ddb-windows.md)
+ [

# Parámetros de Lambda para las asignaciones de orígenes de eventos de Amazon DynamoDB
](services-ddb-params.md)
+ [

# Uso del filtrado de eventos con una fuente de eventos de DynamoDB
](with-ddb-filtering.md)
+ [

# Tutorial: Uso de AWS Lambda con Amazon DynamoDB Streams
](with-ddb-example.md)

## Sondeo y procesamiento por lotes de flujos
<a name="dynamodb-polling-and-batching"></a>

Lambda sondea las particiones del DynamoDB Stream y busca registros 4 veces por segundo. Cuando hay registros disponibles, Lambda invoca la función y espera el resultado. Si el procesamiento se realiza correctamente, Lambda reanuda el sondeo hasta que recibe más registros.

De forma predeterminada, Lambda invoca su función tan pronto como los registros estén disponibles. Si el lote que Lambda lee del origen de eventos solo tiene un registro, Lambda envía solo un registro a la función. Para evitar invocar la función con un número de registros pequeño, puede indicar al origen de eventos que almacene en búfer registros durante hasta 5 minutos configurando un *plazo de procesamiento por lotes*. Antes de invocar la función, Lambda continúa leyendo los registros del origen de eventos hasta que haya recopilado un lote completo, venza el plazo de procesamiento por lotes o el lote alcance el límite de carga de 6 MB. Para obtener más información, consulte [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

**aviso**  
Las asignaciones de orígenes de eventos de Lambda procesan cada evento al menos una vez, y puede producirse un procesamiento duplicado de registros. Para evitar posibles problemas relacionados con la duplicación de eventos, le recomendamos encarecidamente que haga que el código de la función sea idempotente. Para obtener más información, consulte [¿Cómo puedo hacer que mi función de Lambda sea idempotente?](https://repost.aws/knowledge-center/lambda-function-idempotent) en el Centro de conocimientos de AWS.

Lambda no espera a que se completen las [extensiones](lambda-extensions.md) configuradas antes de enviar el siguiente lote para su procesamiento. En otras palabras, las extensiones pueden seguir ejecutándose mientras Lambda procesa el siguiente lote de registros. Esto puede provocar problemas de limitación si infringe alguno de los ajustes o límites de [simultaneidad](lambda-concurrency.md) de la cuenta. Para detectar si se trata de un posible problema, supervise sus funciones y compruebe si ve [métricas de simultaneidad](monitoring-concurrency.md#general-concurrency-metrics) más elevadas de lo esperado para la asignación de orígenes de eventos. Debido a los tiempos cortos entre invocaciones, Lambda puede informar brevemente un uso de simultaneidad superior al número de particiones. Esto puede ser cierto incluso para las funciones de Lambda sin extensiones.

Ajuste la configuración de [ParallelizationFactor](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-ParallelizationFactor) para procesar una partición de un flujo de DynamoDB con más de una invocación de Lambda simultáneamente. Puede especificar el número de lotes simultáneos que Lambda sondea desde una partición a través de un factor de paralelización de 1 (predeterminado) a 10. Por ejemplo, cuando establece `ParallelizationFactor` en 2, puede tener un máximo de 200 invocaciones de Lambda simultáneas para procesar 100 particiones de flujos de DynamoDB (aunque, en la práctica, es posible que observe diferentes valores para la métrica `ConcurrentExecutions`). Esto ayuda a escalar verticalmente el rendimiento de procesamiento cuando el volumen de datos es volátil y la [IteratorAge](monitoring-metrics-types.md#performance-metrics) es alta. Si aumenta el número de lotes simultáneos por partición, Lambda sigue garantizando el procesamiento en orden del nivel del elemento (partición y clave de clasificación).

## Posiciones iniciales de flujos y sondeo
<a name="dyanmo-db-stream-poll"></a>

Tenga en cuenta que el sondeo de flujos durante la creación y las actualizaciones de la asignación de orígenes de eventos es, en última instancia, coherente.
+ Durante la creación de la asignación de orígenes de eventos, es posible que se demore varios minutos en iniciar el sondeo de los eventos del flujo.
+ Durante las actualizaciones de la asignación de orígenes de eventos, es posible que se demore varios minutos en detener y reiniciar el sondeo de los eventos del flujo.

Este comportamiento significa que, si especifica `LATEST` como posición inicial del flujo, la asignación de orígenes de eventos podría omitir eventos durante la creación o las actualizaciones. Para garantizar que no se pierda ningún evento, especifique la posición inicial del flujo como `TRIM_HORIZON`.

## Lectores simultáneos de una partición en DynamoDB Streams
<a name="events-dynamodb-simultaneous-readers"></a>

En el caso de las tablas de una sola región que no sean tablas globales, puede diseñar hasta dos funciones de Lambda para leer desde la misma partición de DynamoDB Streams al mismo tiempo. Si excede este límite, puede producirse una limitación controlada de las solicitudes. En el caso de las tablas globales, le recomendamos que limite el número de funciones simultáneas a uno para evitar la limitación de solicitudes.

## Evento de ejemplo
<a name="events-sample-dynamodb"></a>

**Example**  

```
{
  "Records": [
    {
      "eventID": "1",
      "eventVersion": "1.0",
      "dynamodb": {
        "Keys": {
          "Id": {
            "N": "101"
          }
        },
        "NewImage": {
          "Message": {
            "S": "New item!"
          },
          "Id": {
            "N": "101"
          }
        },
        "StreamViewType": "NEW_AND_OLD_IMAGES",
        "SequenceNumber": "111",
        "SizeBytes": 26
      },
      "awsRegion": "us-west-2",
      "eventName": "INSERT",
      "eventSourceARN": "arn:aws:dynamodb:us-east-2:123456789012:table/my-table/stream/2024-06-10T19:26:16.525",
      "eventSource": "aws:dynamodb"
    },
    {
      "eventID": "2",
      "eventVersion": "1.0",
      "dynamodb": {
        "OldImage": {
          "Message": {
            "S": "New item!"
          },
          "Id": {
            "N": "101"
          }
        },
        "SequenceNumber": "222",
        "Keys": {
          "Id": {
            "N": "101"
          }
        },
        "SizeBytes": 59,
        "NewImage": {
          "Message": {
            "S": "This item has changed"
          },
          "Id": {
            "N": "101"
          }
        },
        "StreamViewType": "NEW_AND_OLD_IMAGES"
      },
      "awsRegion": "us-west-2",
      "eventName": "MODIFY",
      "eventSourceARN": "arn:aws:dynamodb:us-east-2:123456789012:table/my-table/stream/2024-06-10T19:26:16.525",
      "eventSource": "aws:dynamodb"
    }
  ]}
```

# Proceso de registros de DynamoDB con Lambda
<a name="services-dynamodb-eventsourcemapping"></a>

Cree una asignación de orígenes de eventos para indicar a Lambda que envíe registros desde un flujo a una función de Lambda. Puede crear varias asignaciones de orígenes de eventos para procesar los mismos datos con distintas funciones de Lambda o para procesar elementos de varios flujos con una sola función.

Puede configurar las asignaciones de orígenes de eventos para procesar los registros de un flujo en una Cuenta de AWS diferente. Para obtener más información, consulte [Creación de asignaciones de orígenes de eventos entre cuentas](#services-dynamodb-eventsourcemapping-cross-account).

Para configurar la función para que lea desde el flujo de DynamoDB, adjunte la política administrada de AWS [AWSLambdaDynamoDBExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaDynamoDBExecutionRole.html) al rol de ejecución y, a continuación, cree un desencadenador de **DynamoDB**.

**Cómo agregar permisos y crear un desencadenador**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de una función.

1. Elija la pestaña **Configuración** y, a continuación, elija **Permisos**.

1. En **Nombre del rol**, elija el enlace al rol de ejecución. Este enlace abre el rol en la consola de IAM.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/execution-role.png)

1. Elija **Agregar permisos** y luego **Adjuntar políticas**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/attach-policies.png)

1. En el campo de búsqueda, escriba `AWSLambdaDynamoDBExecutionRole`. Agregue esta política al rol de ejecución. Se trata de una política administrada por AWS que contiene los permisos que la función necesita para leer desde un flujo de DynamoDB. Para obtener más información acerca de esta política, consulte [AWSLambdaDynamoDBExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaDynamoDBExecutionRole.html) en la *Referencia de políticas administradas de AWS*.

1. Regrese a la función en la consola de Lambda. En **Descripción general de la función**, elija **Agregar desencadenador**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/add-trigger.png)

1. Elija un tipo de desencadenador.

1. Configure las opciones requeridas y luego elija **Add** (Agregar).

Lambda admite las siguientes opciones para los orígenes de eventos de DynamoDB:

**Opciones de origen de eventos**
+ **Tabla DynamoDB**: la tabla de DynamoDB de la que leer registros.
+ **Tamaño del lote**: número de registros que se enviarán a la función en cada lote, hasta 10 000. Lambda pasa todos los registros del lote a la función en una sola llamada, siempre y cuando el tamaño total de los eventos no exceda el [límite de carga](gettingstarted-limits.md) para la invocación síncrona (6 MB).
+ **Ventana de lote**: especifique la cantidad de tiempo máxima para recopilar registros antes de invocar la función, en segundos.
+ **Posición inicial**: procesar solo los registros nuevos o todos los registros existentes.
  + **Más recientes**: procesar los registros nuevos que se agreguen al flujo principal.
  + **Horizonte de supresión**: procesar todos los registros del flujo.

  Tras procesar cualquier registro existente, la función es alcanzada y continúa procesando registros nuevos.
+ **Destino en caso de error**: una cola de SQS estándar o un tema de SNS estándar para los registros que no se puedan procesar. Cuando Lambda descarta un lote de registros demasiado antiguo o que ha agotado todos los reintentos, Lambda envía detalles sobre el lote a la cola o al tema.
+ **Número de reintentos**: número máximo de reintentos que Lambda realiza cuando la función devuelve un error. Esto no se aplica a errores de servicio o limitaciones controladas en los que el lote no alcanzó la función.
+ **Edad máxima de registro**: antigüedad máxima de un registro que Lambda envía a su función.
+ **División del lote en caso de error**: cuando la función devuelve un error, divida el lote en dos antes de volver a intentarlo. La configuración de tamaño de lote original permanece sin cambios.
+ **Lotes simultáneos por partición**: procese simultáneamente varios lotes desde la misma partición.
+ **Habilitado**: establézcalo en verdadero para habilitar la asignación de orígenes de eventos. Establézcalo en falso para detener el procesamiento de registros. Lambda toma nota del último registro procesado y sigue procesando desde ese punto cuando se habilita de nuevo el mapeo.

**nota**  
No se cobran las llamadas a la API GetRecords invocadas por Lambda como parte de los desencadenadores de DynamoDB.

Para administrar la configuración de origen de evento más tarde, elija el desencadenador en el diseñador.

## Creación de asignaciones de orígenes de eventos entre cuentas
<a name="services-dynamodb-eventsourcemapping-cross-account"></a>

Ahora Amazon DynamoDB admite las [políticas basadas en recursos](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/access-control-resource-based.html). Con esta capacidad, puede procesar los datos de un flujo de DynamoDB en una Cuenta de AWS con una función de Lambda en otra cuenta.

Para crear una asignación de orígenes de eventos para la función de Lambda mediante un flujo de DynamoDB en otra Cuenta de AWS, debe configurar el flujo mediante una política basada en recursos para conceder a la función de Lambda permiso para leer registros. Para obtener información sobre cómo configurar el flujo para permitir el acceso entre cuentas, consulte [Acceso compartido con funciones de Lambda entre cuentas](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/rbac-cross-account-access.html#rbac-analyze-cross-account-lambda-access) en la *Guía para desarrolladores de Amazon DynamoDB*.

Una vez que haya configurado el flujo con una política basada en recursos que otorgue a la función de Lambda los permisos necesarios, cree la asignación de orígenes de eventos con el ARN del flujo entre cuentas. Puede encontrar el ARN del flujo en la pestaña **Exportaciones y flujos** de la tabla de la consola de DynamoDB entre cuentas. 

Cuando utilice la consola de Lambda, pegue el ARN del flujo directamente en el campo de entrada de la tabla de DynamoDB en la página de creación de asignaciones de orígenes de eventos.

 **Nota:** No se admiten los activadores entre regiones. 

# Configuración de la respuesta por lotes parcial con DynamoDB y Lambda
<a name="services-ddb-batchfailurereporting"></a>

Al consumir y procesar datos de streaming desde un origen de eventos, de forma predeterminada, Lambda comprueba hasta el número de secuencia más alto de un lote solo cuando el lote se ha completado con éxito. Lambda trata todos los demás resultados como un error completo y vuelve a intentar procesar el lote hasta el límite de reintentos. Para permitir éxitos parciales al procesar lotes de una secuencia, active `ReportBatchItemFailures`. Permitir éxitos parciales puede ayudar a reducir el número de reintentos en un registro, aunque no impide por completo la posibilidad de reintentos en un registro exitoso.

Para activar `ReportBatchItemFailures`, incluya el valor enumerado **ReportBatchItemFailures** en la lista [FunctionResponseTypes](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-FunctionResponseTypes). Esta lista indica qué tipos de respuesta están habilitados para su función. Puede configurar esta lista al [crear](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) o [actualizar](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) una asignación de orígenes de eventos.

**nota**  
Incluso cuando el código de función devuelva respuestas de fallos parciales por lotes, Lambda no procesará estas respuestas a menos que la característica `ReportBatchItemFailures` esté activada explícitamente para la asignación de orígenes de eventos.

## Sintaxis del informe
<a name="streams-batchfailurereporting-syntax"></a>

Al configurar los informes sobre errores de elementos por lotes, la clase `StreamsEventResponse` se devuelve con una lista de errores de elementos de lote. Puede utilizar un objeto `StreamsEventResponse` para devolver el número de secuencia del primer registro fallido del lote. También puede crear su propia clase personalizada usando la sintaxis de respuesta correcta. La siguiente estructura JSON muestra la sintaxis de respuesta requerida:

```
{ 
  "batchItemFailures": [ 
        {
            "itemIdentifier": "<SequenceNumber>"
        }
    ]
}
```

**nota**  
Si la matriz `batchItemFailures` contiene varios elementos, Lambda usa el registro con el número de secuencia más bajo como punto de control. Luego Lambda vuelve a probar todos los registros a partir de ese punto de control.

## Condiciones de éxito y fracaso
<a name="streams-batchfailurereporting-conditions"></a>

Lambda trata un lote como un éxito completo si devuelve cualquiera de los siguientes elementos:
+ Una lista `batchItemFailure` vacía
+ Una lista `batchItemFailure` nula
+ Una `EventResponse` vacía
+ Un nulo `EventResponse`

Lambda trata un lote como un error completo si devuelve cualquiera de los siguientes elementos:
+ Una cadena `itemIdentifier` vacía
+ Una nula `itemIdentifier`
+ Un `itemIdentifier` con un mal nombre de clave

Lambda reintentos fallidos basados en su estrategia de reintento.

## Bisecar un lote
<a name="streams-batchfailurereporting-bisect"></a>

Si su invocación falla y `BisectBatchOnFunctionError` está activada, el lote se divide en bisectos independientemente de su configuración `ReportBatchItemFailures`.

Cuando se recibe una respuesta de éxito parcial de lote y se activan tanto `BisectBatchOnFunctionError` como `ReportBatchItemFailures`, el lote se divide en el número de secuencia devuelto y Lambda vuelve a intentar solo los registros restantes.

Para simplificar la implementación de la lógica de respuesta parcial por lotes, considere la posibilidad de utilizar la [utilidad Batch Processor](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) de PowertoolsAWS Lambda, que gestiona automáticamente estas complejidades para usted.

Estos son algunos ejemplos de código de función que devuelven la lista de IDs de mensajes fallidos del lote:

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de DynamoDB con Lambda mediante .NET.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
using System.Text.Json;
using System.Text;
using Amazon.Lambda.Core;
using Amazon.Lambda.DynamoDBEvents;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace AWSLambda_DDB;

public class Function
{
    public StreamsEventResponse FunctionHandler(DynamoDBEvent dynamoEvent, ILambdaContext context)

    {
        context.Logger.LogInformation($"Beginning to process {dynamoEvent.Records.Count} records...");
        List<StreamsEventResponse.BatchItemFailure> batchItemFailures = new List<StreamsEventResponse.BatchItemFailure>();
        StreamsEventResponse streamsEventResponse = new StreamsEventResponse();

        foreach (var record in dynamoEvent.Records)
        {
            try
            {
                var sequenceNumber = record.Dynamodb.SequenceNumber;
                context.Logger.LogInformation(sequenceNumber);
            }
            catch (Exception ex)
            {
                context.Logger.LogError(ex.Message);
                batchItemFailures.Add(new StreamsEventResponse.BatchItemFailure() { ItemIdentifier = record.Dynamodb.SequenceNumber });
            }
        }

        if (batchItemFailures.Count > 0)
        {
            streamsEventResponse.BatchItemFailures = batchItemFailures;
        }

        context.Logger.LogInformation("Stream processing complete.");
        return streamsEventResponse;
    }
}
```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de DynamoDB con Lambda mediante Go.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package main

import (
	"context"
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

type BatchItemFailure struct {
	ItemIdentifier string `json:"ItemIdentifier"`
}

type BatchResult struct {
	BatchItemFailures []BatchItemFailure `json:"BatchItemFailures"`
}

func HandleRequest(ctx context.Context, event events.DynamoDBEvent) (*BatchResult, error) {
	var batchItemFailures []BatchItemFailure
	curRecordSequenceNumber := ""

	for _, record := range event.Records {
		// Process your record
		curRecordSequenceNumber = record.Change.SequenceNumber
	}

	if curRecordSequenceNumber != "" {
		batchItemFailures = append(batchItemFailures, BatchItemFailure{ItemIdentifier: curRecordSequenceNumber})
	}
	
	batchResult := BatchResult{
		BatchItemFailures: batchItemFailures,
	}

	return &batchResult, nil
}

func main() {
	lambda.Start(HandleRequest)
}
```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de DynamoDB con Lambda mediante Java.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.DynamodbEvent;
import com.amazonaws.services.lambda.runtime.events.StreamsEventResponse;
import com.amazonaws.services.lambda.runtime.events.models.dynamodb.StreamRecord;

import java.util.ArrayList;
import java.util.List;

public class ProcessDynamodbRecords implements RequestHandler<DynamodbEvent, StreamsEventResponse> {

    @Override
    public StreamsEventResponse handleRequest(DynamodbEvent input, Context context) {

        List<StreamsEventResponse.BatchItemFailure> batchItemFailures = new ArrayList<>();
        String curRecordSequenceNumber = "";

        for (DynamodbEvent.DynamodbStreamRecord dynamodbStreamRecord : input.getRecords()) {
          try {
                //Process your record
                StreamRecord dynamodbRecord = dynamodbStreamRecord.getDynamodb();
                curRecordSequenceNumber = dynamodbRecord.getSequenceNumber();
                
            } catch (Exception e) {
                /* Since we are working with streams, we can return the failed item immediately.
                   Lambda will immediately begin to retry processing from this failed item onwards. */
                batchItemFailures.add(new StreamsEventResponse.BatchItemFailure(curRecordSequenceNumber));
                return new StreamsEventResponse(batchItemFailures);
            }
        }
       
       return new StreamsEventResponse();   
    }
}
```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de DynamoDB con Lambda mediante JavaScript.  

```
export const handler = async (event) => {
  const records = event.Records;
  let curRecordSequenceNumber = "";

  for (const record of records) {
    try {
      // Process your record
      curRecordSequenceNumber = record.dynamodb.SequenceNumber;
    } catch (e) {
      // Return failed record's sequence number
      return { batchItemFailures: [{ itemIdentifier: curRecordSequenceNumber }] };
    }
  }

  return { batchItemFailures: [] };
};
```
Notificación de los errores de los elementos del lote de DynamoDB con Lambda mediante TypeScript.  

```
import {
  DynamoDBBatchResponse,
  DynamoDBBatchItemFailure,
  DynamoDBStreamEvent,
} from "aws-lambda";

export const handler = async (
  event: DynamoDBStreamEvent
): Promise<DynamoDBBatchResponse> => {
  const batchItemFailures: DynamoDBBatchItemFailure[] = [];
  let curRecordSequenceNumber;

  for (const record of event.Records) {
    curRecordSequenceNumber = record.dynamodb?.SequenceNumber;

    if (curRecordSequenceNumber) {
      batchItemFailures.push({
        itemIdentifier: curRecordSequenceNumber,
      });
    }
  }

  return { batchItemFailures: batchItemFailures };
};
```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de DynamoDB con Lambda mediante PHP.  

```
<?php

# using bref/bref and bref/logger for simplicity

use Bref\Context\Context;
use Bref\Event\DynamoDb\DynamoDbEvent;
use Bref\Event\Handler as StdHandler;
use Bref\Logger\StderrLogger;

require __DIR__ . '/vendor/autoload.php';

class Handler implements StdHandler
{
    private StderrLogger $logger;
    public function __construct(StderrLogger $logger)
    {
        $this->logger = $logger;
    }

    /**
     * @throws JsonException
     * @throws \Bref\Event\InvalidLambdaEvent
     */
    public function handle(mixed $event, Context $context): array
    {
        $dynamoDbEvent = new DynamoDbEvent($event);
        $this->logger->info("Processing records");

        $records = $dynamoDbEvent->getRecords();
        $failedRecords = [];
        foreach ($records as $record) {
            try {
                $data = $record->getData();
                $this->logger->info(json_encode($data));
                // TODO: Do interesting work based on the new data
            } catch (Exception $e) {
                $this->logger->error($e->getMessage());
                // failed processing the record
                $failedRecords[] = $record->getSequenceNumber();
            }
        }
        $totalRecords = count($records);
        $this->logger->info("Successfully processed $totalRecords records");

        // change format for the response
        $failures = array_map(
            fn(string $sequenceNumber) => ['itemIdentifier' => $sequenceNumber],
            $failedRecords
        );

        return [
            'batchItemFailures' => $failures
        ];
    }
}

$logger = new StderrLogger();
return new Handler($logger);
```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de DynamoDB con Lambda mediante Python.  

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
def handler(event, context):
    records = event.get("Records")
    curRecordSequenceNumber = ""
    
    for record in records:
        try:
            # Process your record
            curRecordSequenceNumber = record["dynamodb"]["SequenceNumber"]
        except Exception as e:
            # Return failed record's sequence number
            return {"batchItemFailures":[{"itemIdentifier": curRecordSequenceNumber}]}

    return {"batchItemFailures":[]}
```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de DynamoDB con Lambda mediante Ruby.  

```
def lambda_handler(event:, context:)
    records = event["Records"]
    cur_record_sequence_number = ""
  
    records.each do |record|
      begin
        # Process your record
        cur_record_sequence_number = record["dynamodb"]["SequenceNumber"]
      rescue StandardError => e
        # Return failed record's sequence number
        return {"batchItemFailures" => [{"itemIdentifier" => cur_record_sequence_number}]}
      end
    end
  
    {"batchItemFailures" => []}
  end
```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de DynamoDB con Lambda mediante Rust.  

```
use aws_lambda_events::{
    event::dynamodb::{Event, EventRecord, StreamRecord},
    streams::{DynamoDbBatchItemFailure, DynamoDbEventResponse},
};
use lambda_runtime::{run, service_fn, Error, LambdaEvent};

/// Process the stream record
fn process_record(record: &EventRecord) -> Result<(), Error> {
    let stream_record: &StreamRecord = &record.change;

    // process your stream record here...
    tracing::info!("Data: {:?}", stream_record);

    Ok(())
}

/// Main Lambda handler here...
async fn function_handler(event: LambdaEvent<Event>) -> Result<DynamoDbEventResponse, Error> {
    let mut response = DynamoDbEventResponse {
        batch_item_failures: vec![],
    };

    let records = &event.payload.records;

    if records.is_empty() {
        tracing::info!("No records found. Exiting.");
        return Ok(response);
    }

    for record in records {
        tracing::info!("EventId: {}", record.event_id);

        // Couldn't find a sequence number
        if record.change.sequence_number.is_none() {
            response.batch_item_failures.push(DynamoDbBatchItemFailure {
                item_identifier: Some("".to_string()),
            });
            return Ok(response);
        }

        // Process your record here...
        if process_record(record).is_err() {
            response.batch_item_failures.push(DynamoDbBatchItemFailure {
                item_identifier: record.change.sequence_number.clone(),
            });
            /* Since we are working with streams, we can return the failed item immediately.
            Lambda will immediately begin to retry processing from this failed item onwards. */
            return Ok(response);
        }
    }

    tracing::info!("Successfully processed {} record(s)", records.len());

    Ok(response)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        // disable printing the name of the module in every log line.
        .with_target(false)
        // disabling time is handy because CloudWatch will add the ingestion time.
        .without_time()
        .init();

    run(service_fn(function_handler)).await
}
```

------

## Uso de Powertools para el procesador por lotes de AWS Lambda
<a name="services-ddb-batchfailurereporting-powertools"></a>

La utilidad de procesamiento por lotes de Powertools para AWS Lambda gestiona de manera automática la lógica de respuesta parcial de los lotes, lo que reduce la complejidad de implementar la notificación de fallas en los lotes. Estos son algunos ejemplos del uso del procesador por lotes:

**Python**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/).
Procesamiento de registros de flujos de DynamoDB con un procesador por lotes AWS Lambda.  

```
import json
from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.batch import BatchProcessor, EventType, process_partial_response
from aws_lambda_powertools.utilities.data_classes import DynamoDBStreamEvent
from aws_lambda_powertools.utilities.typing import LambdaContext

processor = BatchProcessor(event_type=EventType.DynamoDBStreams)
logger = Logger()

def record_handler(record):
    logger.info(record)
    # Your business logic here
    # Raise an exception to mark this record as failed
    
def lambda_handler(event, context: LambdaContext):
    return process_partial_response(
        event=event, 
        record_handler=record_handler, 
        processor=processor,
        context=context
    )
```

**TypeScript**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.aws.amazon.com/powertools/typescript/latest/features/batch/).
Procesamiento de registros de flujos de DynamoDB con un procesador por lotes AWS Lambda.  

```
import { BatchProcessor, EventType, processPartialResponse } from '@aws-lambda-powertools/batch';
import { Logger } from '@aws-lambda-powertools/logger';
import type { DynamoDBStreamEvent, Context } from 'aws-lambda';

const processor = new BatchProcessor(EventType.DynamoDBStreams);
const logger = new Logger();

const recordHandler = async (record: any): Promise<void> => {
    logger.info('Processing record', { record });
    // Your business logic here
    // Throw an error to mark this record as failed
};

export const handler = async (event: DynamoDBStreamEvent, context: Context) => {
    return processPartialResponse(event, recordHandler, processor, {
        context,
    });
};
```

**Java**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.powertools.aws.dev/lambda/java/latest/utilities/batch/).
Procesamiento de registros de flujos de DynamoDB con un procesador por lotes AWS Lambda.  

```
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.DynamodbEvent;
import com.amazonaws.services.lambda.runtime.events.StreamsEventResponse;
import software.amazon.lambda.powertools.batch.BatchMessageHandlerBuilder;
import software.amazon.lambda.powertools.batch.handler.BatchMessageHandler;

public class DynamoDBStreamBatchHandler implements RequestHandler<DynamodbEvent, StreamsEventResponse> {

    private final BatchMessageHandler<DynamodbEvent, StreamsEventResponse> handler;

    public DynamoDBStreamBatchHandler() {
        handler = new BatchMessageHandlerBuilder()
                .withDynamoDbBatchHandler()
                .buildWithRawMessageHandler(this::processMessage);
    }

    @Override
    public StreamsEventResponse handleRequest(DynamodbEvent ddbEvent, Context context) {
        return handler.processBatch(ddbEvent, context);
    }

    private void processMessage(DynamodbEvent.DynamodbStreamRecord dynamodbStreamRecord, Context context) {
        // Process the change record
    }
}
```

**.NET**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.aws.amazon.com/powertools/dotnet/utilities/batch-processing/).
Procesamiento de registros de flujos de DynamoDB AWS Lambdacon un procesador por lotes.  

```
using System;
using System.Threading;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Amazon.Lambda.DynamoDBEvents;
using Amazon.Lambda.Serialization.SystemTextJson;
using AWS.Lambda.Powertools.BatchProcessing;

[assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]

namespace HelloWorld;

public class Customer
{
    public string? CustomerId { get; set; }
    public string? Name { get; set; }
    public string? Email { get; set; }
    public DateTime CreatedAt { get; set; }
}

internal class TypedDynamoDbRecordHandler : ITypedRecordHandler<Customer> 
{
    public async Task<RecordHandlerResult> HandleAsync(Customer customer, CancellationToken cancellationToken)
    {
        if (string.IsNullOrEmpty(customer.Email)) 
        {
            throw new ArgumentException("Customer email is required");
        }

        return await Task.FromResult(RecordHandlerResult.None); 
    }
}

public class Function
{
    [BatchProcessor(TypedRecordHandler = typeof(TypedDynamoDbRecordHandler))]
    public BatchItemFailuresResponse HandlerUsingTypedAttribute(DynamoDBEvent _)
    {
        return TypedDynamoDbStreamBatchProcessor.Result.BatchItemFailuresResponse; 
    }
}
```

# Conservación de registros descartados para un origen de eventos de DynamoDB en Lambda
<a name="services-dynamodb-errors"></a>

La gestión de errores en las asignaciones de orígenes de eventos de DynamoDB depende de si el error se produce antes de que se invoque la función o durante la invocación de la función:
+ **Antes de la invocación:** si una asignación de orígenes de eventos de Lambda no puede invocar la función debido a una limitación u otros problemas, lo vuelve a intentar hasta que los registros caduquen o superen la antigüedad máxima configurada en la asignación de orígenes de eventos ([MaximumRecordageInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)).
+ **Durante invocación:** [si se invoca la función pero devuelve un error, Lambda vuelve a intentarlo hasta que los registros caduquen, superen la antigüedad [máxima (MaximumRecordageInSeconds) o alcancen la cuota de reintento configurada (MaximumRetryAttempts](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)).](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRetryAttempts) En el caso de errores de función, también puede configurar [BisectBatchOnFunctionError](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-response-BisectBatchOnFunctionError), que divide un lote fallido en dos lotes más pequeños, aislando registros fallidos y evitando tiempos de espera. La división de lotes no consume la cuota de reintentos.

Si las medidas de administración de errores fallan, Lambda descarta los registros y continúa procesando lotes del flujo. Con la configuración predeterminada, esto significa que un registro incorrecto puede bloquear el procesamiento en la partición afectada durante un máximo de un día. Para evitar esto, configure el mapeo de fuente de eventos de su función con un número razonable de reintentos y una antigüedad máxima de registro que se ajuste a su caso de uso.

## Configuración de destinos para invocaciones fallidas
<a name="dynamodb-on-failure-destination-console"></a>

Para retener los registros de las invocaciones de asignación de orígenes de eventos fallidos, agregue un destino a la asignación de orígenes de eventos de su función. Cada registro enviado al destino es un documento JSON que contiene metadatos sobre la invocación fallida. Para los destinos de Amazon S3, Lambda envía también todo el registro de invocación junto con los metadatos. Puede configurar cualquier tema de Amazon SNS, cola de Amazon SQS, bucket de Amazon S3 o Kafka como destino.

Con los destinos de Amazon S3, puede utilizar la característica de [notificaciones de eventos de Amazon S3](https://docs.aws.amazon.com/) para recibir notificaciones cuando se carguen objetos en el bucket de S3 de destino. También puede configurar las notificaciones de eventos de S3 para que invoquen otra función de Lambda para realizar el procesamiento automatizado de los lotes fallidos.

Su rol de ejecución debe tener permisos para el destino:
+ **En el caso de un destino de SQS:** [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)
+ **En el caso de un destino de SNS:** [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)
+ **En el caso de un destino de S3:** [ s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) y [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/ListObjectsV2.html)
+ **Para un destino de Kafka:** [kafka-cluster:WriteData](https://docs.aws.amazon.com/msk/latest/developerguide/kafka-actions.html)

Puede configurar un tema de Kafka como destino en caso de error para las asignaciones de orígenes de eventos de Kafka. Cuando Lambda no puede procesar los registros tras agotar los reintentos o cuando los registros superan la antigüedad máxima, Lambda envía los registros fallidos al tema de Kafka especificado para su posterior procesamiento. Consulte [Uso de un tema de Kafka como destino en caso de error](kafka-on-failure-destination.md).

Si tiene activado el cifrado con su propia clave de KMS para un destino de S3, el rol de ejecución de la función también debe tener permiso para llamar a [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html). Si la clave de KMS y el destino del bucket de S3 están en una cuenta diferente a la de su función de Lambda y rol de ejecución, configure la clave de KMS para que confíe en el rol de ejecución y permita kms:GenerateDataKey.

Para configurar un destino en caso de error mediante la consola, siga estos pasos:

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija una función.

1. En **Descripción general de la función**, elija **Agregar destino**.

1. En **Origen**, elija **Invocación de asignación de orígenes de eventos**.

1. Para la **Asignación de orígenes de eventos**, elija un origen de eventos que esté configurado para esta función.

1. En **Condición**, seleccione **En caso de error**. Para las invocaciones de asignación de orígenes de eventos, esta es la única condición aceptada.

1. En **Tipo de destino**, elija el tipo de destino al que Lambda envía los registros de invocación.

1. En **Destino**, elija un recurso.

1. Seleccione **Save**.

También puede configurar un destino en caso de error mediante la AWS Command Line Interface (AWS CLI). Por ejemplo, el siguiente comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) agrega una asignación de orígenes de eventos con un destino de SQS en caso de error a `MyFunction`:

```
aws lambda create-event-source-mapping \
--function-name "MyFunction" \
--event-source-arn arn:aws:dynamodb:us-east-2:123456789012:table/my-table/stream/2024-06-10T19:26:16.525 \
--destination-config '{"OnFailure": {"Destination": "arn:aws:sqs:us-east-1:123456789012:dest-queue"}}'
```

El siguiente comando [update-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) actualiza una asignación de orígenes de eventos para enviar registros de invocación fallida a un destino de SNS después de dos intentos de reintento, o si los registros tienen más de una hora de antigüedad.

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--maximum-retry-attempts 2 \
--maximum-record-age-in-seconds 3600 \
--destination-config '{"OnFailure": {"Destination": "arn:aws:sns:us-east-1:123456789012:dest-topic"}}'
```

La configuración actualizada se aplica de forma asincrónica y no se refleja en la salida hasta que se completa el proceso. Utilice el comando [get-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-event-source-mapping.html) para ver el estado actual.

Para eliminar un destino, introduzca una cadena vacía como argumento del parámetro `destination-config`:

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--destination-config '{"OnFailure": {"Destination": ""}}'
```

### Prácticas recomendadas de seguridad para destinos de Amazon S3
<a name="ddb-s3-destination-security"></a>

Eliminar un bucket de S3 que está configurado como destino sin eliminar el destino de la configuración de la función puede suponer un riesgo de seguridad. Si otro usuario conoce el nombre del bucket de destino, puede volver a crear el bucket en su Cuenta de AWS. Los registros de las invocaciones fallidas se enviarán a su bucket, lo que podría exponer los datos de su función.

**aviso**  
Para asegurarse de que los registros de invocación de su función no se puedan enviar a un bucket de S3 de otra Cuenta de AWS, agregue una condición al rol de ejecución de la función que limite los permisos `s3:PutObject` a los buckets de su cuenta. 

En el siguiente ejemplo, se muestra una política de IAM que limita los permisos `s3:PutObject` de la función a los buckets de la cuenta. Esta política también otorga a Lambda el permiso `s3:ListBucket` que necesita para usar un bucket de S3 como destino.

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "S3BucketResourceAccountWrite",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::*/*",
                "arn:aws:s3:::*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:ResourceAccount": "111122223333"
                }
            }
        }
    ]
}
```

Para agregar una política de permisos al rol de ejecución de su función mediante la Consola de administración de AWS o la AWS CLI, consulte las instrucciones de los siguientes procedimientos:

------
#### [ Console ]

**Cómo agregar una política de permisos al rol de ejecución de la función (consola)**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función de Lambda cuyo rol de ejecución desee modificar.

1. En la pestaña **Configuración**, elija **Permisos**.

1. En la pestaña **Rol de ejecución**, seleccione el **nombre del rol** de la función para abrir la página de la consola de IAM del rol.

1. Agregue una política de permisos al rol de la siguiente manera:

   1. En el panel **Política de permisos**, elija **Agregar permisos** y seleccione **Crear política insertada**.

   1. En el **editor de políticas**, seleccione **JSON**.

   1. Pegue la política que desee agregar en el editor (sustituyendo el JSON existente) y, a continuación, seleccione **Siguiente**.

   1. En **Detalles de política**, ingrese un **Nombre de política**.

   1. Seleccione **Crear política**.

------
#### [ AWS CLI ]

**Cómo agregar una política de permisos al rol de ejecución de la función (CLI)**

1. Cree un documento de política de JSON con los permisos necesarios y guárdelo en un directorio local.

1. Utilice el comando de la CLI de IAM `put-role-policy` para agregar permisos al rol de ejecución de la función. Ejecute el siguiente comando desde el directorio en el que guardó el documento de política JSON y sustituya el nombre del rol, el nombre de la política y el documento de política por sus propios valores.

   ```
   aws iam put-role-policy \
   --role-name my_lambda_role \
   --policy-name LambdaS3DestinationPolicy \
   --policy-document file://my_policy.json
   ```

------

### Ejemplo de registro de invocación de Amazon SNS y Amazon SQS
<a name="kinesis-on-failure-destination-example-sns-sqs"></a>

En el siguiente ejemplo, se muestra un registro de invocación que Lambda envía a un destino de SQS o SNS para un flujo de DynamoDB.

```
{
    "requestContext": {
        "requestId": "316aa6d0-8154-xmpl-9af7-85d5f4a6bc81",
        "functionArn": "arn:aws:lambda:us-east-2:123456789012:function:myfunction",
        "condition": "RetryAttemptsExhausted",
        "approximateInvokeCount": 1
    },
    "responseContext": {
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "version": "1.0",
    "timestamp": "2019-11-14T00:13:49.717Z",
    "DDBStreamBatchInfo": {
        "shardId": "shardId-00000001573689847184-864758bb",
        "startSequenceNumber": "800000000003126276362",
        "endSequenceNumber": "800000000003126276362",
        "approximateArrivalOfFirstRecord": "2019-11-14T00:13:19Z",
        "approximateArrivalOfLastRecord": "2019-11-14T00:13:19Z",
        "batchSize": 1,
        "streamArn": "arn:aws:dynamodb:us-east-2:123456789012:table/mytable/stream/2019-11-14T00:04:06.388"
    }
}
```

Puede utilizar esta información para recuperar los registros afectados del flujo para solucionar problemas. Los registros reales no están incluidos, por lo que debe procesar este registro y recuperarlos del flujo antes de que caduquen y se pierdan.

### Ejemplo de registro de invocación de Amazon S3
<a name="kinesis-on-failure-destination-example-sns-sqs-s3"></a>

En el siguiente ejemplo, se muestra un registro de invocación que Lambda envía a un bucket de S3 para un flujo de DynamoDB. Además de todos los campos del ejemplo anterior para los destinos de SQS y SNS, el campo `payload` contiene el registro de invocación original en forma de cadena JSON de escape.

```
{
    "requestContext": {
        "requestId": "316aa6d0-8154-xmpl-9af7-85d5f4a6bc81",
        "functionArn": "arn:aws:lambda:us-east-2:123456789012:function:myfunction",
        "condition": "RetryAttemptsExhausted",
        "approximateInvokeCount": 1
    },
    "responseContext": {
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "version": "1.0",
    "timestamp": "2019-11-14T00:13:49.717Z",
    "DDBStreamBatchInfo": {
        "shardId": "shardId-00000001573689847184-864758bb",
        "startSequenceNumber": "800000000003126276362",
        "endSequenceNumber": "800000000003126276362",
        "approximateArrivalOfFirstRecord": "2019-11-14T00:13:19Z",
        "approximateArrivalOfLastRecord": "2019-11-14T00:13:19Z",
        "batchSize": 1,
        "streamArn": "arn:aws:dynamodb:us-east-2:123456789012:table/mytable/stream/2019-11-14T00:04:06.388"
    },
    "payload": "<Whole Event>" // Only available in S3
}
```

El objeto de S3 que contiene el registro de invocación utiliza la siguiente convención de nomenclatura:

```
aws/lambda/<ESM-UUID>/<shardID>/YYYY/MM/DD/YYYY-MM-DDTHH.MM.SS-<Random UUID>
```

# Implementación del procesamiento con estado del flujo DynamoDB en Lambda
<a name="services-ddb-windows"></a>

Las funciones de Lambda pueden ejecutar aplicaciones de procesamiento de flujo continuo. Una secuencia representa datos ilimitados que fluyen de forma continua a través de su aplicación. Para analizar la información de esta entrada de actualización continua, puede enlazar los registros incluidos mediante una ventana definida en términos de tiempo.

Las ventanas de salto constante son ventanas de tiempo distintas que se abren y cierran a intervalos regulares. De forma predeterminada, las invocaciones de Lambda no tienen estado: no se pueden utilizar para procesar datos en múltiples invocaciones continuas sin una base de datos externa. Sin embargo, con las ventanas de salto constante, puede mantener su estado en todas las invocaciones. Este estado contiene el resultado agregado de los mensajes procesados previamente para la ventana actual. Su estado puede ser un máximo de 1 MB por partición. Si supera ese tamaño, Lambda finaliza la ventana antes de tiempo.

Cada registro de una secuencia pertenece a un periodo específico. Lambda procesará cada registro al menos una vez, pero no garantiza que cada registro se procese solo una vez. En casos excepcionales, como el manejo de errores, es posible que algunos registros se procesen más de una vez. Los registros siempre se procesan en orden la primera vez. Si los registros se procesan más de una vez, es posible que lo hagan de forma desordenada.

## Agregación y procesamiento
<a name="streams-tumbling-processing"></a>

Su función administrada por el usuario se invoca tanto para la agregación como para procesar los resultados finales de esa agregación. Lambda agrega todos los registros recibidos en la ventana. Puede recibir estos registros en varios lotes, cada uno como una invocación independiente. Cada invocación recibe un estado. Por lo tanto, al usar las ventanas de salto constante, su respuesta de la función de Lambda debe contener una propiedad de `state`. Si la respuesta no contiene una propiedad de `state`, Lambda considera que esto es una invocación fallida. Para satisfacer esta condición, la función puede devolver un objeto de `TimeWindowEventResponse`, que tiene la siguiente forma JSON:

**Example `TimeWindowEventResponse`Valores**  

```
{
    "state": {
        "1": 282,
        "2": 715
    },
    "batchItemFailures": []
}
```

**nota**  
Para las funciones Java, se recomienda utilizar un `Map<String, String>` para representar el estado.

Al final de la ventana, el indicador `isFinalInvokeForWindow` está configurado en `true` para indicar que este es el estado final y que está listo para su procesamiento. Después del procesamiento, la ventana se completa y su invocación final se completa, y luego se elimina el estado.

Al final de la ventana, Lambda utiliza el procesamiento final para las acciones en los resultados de agregación. Su procesamiento final se invoca sincrónicamente. Después de la invocación exitosa, los puntos de control de la función, el número de secuencia y el procesamiento de flujo continúa. Si la invocación no tiene éxito, su función de Lambda suspende el procesamiento posterior hasta una invocación exitosa.

**Example DynamodbTimeWindowEvent**  

```
{
   "Records":[
      {
         "eventID":"1",
         "eventName":"INSERT",
         "eventVersion":"1.0",
         "eventSource":"aws:dynamodb",
         "awsRegion":"us-east-1",
         "dynamodb":{
            "Keys":{
               "Id":{
                  "N":"101"
               }
            },
            "NewImage":{
               "Message":{
                  "S":"New item!"
               },
               "Id":{
                  "N":"101"
               }
            },
            "SequenceNumber":"111",
            "SizeBytes":26,
            "StreamViewType":"NEW_AND_OLD_IMAGES"
         },
         "eventSourceARN":"stream-ARN"
      },
      {
         "eventID":"2",
         "eventName":"MODIFY",
         "eventVersion":"1.0",
         "eventSource":"aws:dynamodb",
         "awsRegion":"us-east-1",
         "dynamodb":{
            "Keys":{
               "Id":{
                  "N":"101"
               }
            },
            "NewImage":{
               "Message":{
                  "S":"This item has changed"
               },
               "Id":{
                  "N":"101"
               }
            },
            "OldImage":{
               "Message":{
                  "S":"New item!"
               },
               "Id":{
                  "N":"101"
               }
            },
            "SequenceNumber":"222",
            "SizeBytes":59,
            "StreamViewType":"NEW_AND_OLD_IMAGES"
         },
         "eventSourceARN":"stream-ARN"
      },
      {
         "eventID":"3",
         "eventName":"REMOVE",
         "eventVersion":"1.0",
         "eventSource":"aws:dynamodb",
         "awsRegion":"us-east-1",
         "dynamodb":{
            "Keys":{
               "Id":{
                  "N":"101"
               }
            },
            "OldImage":{
               "Message":{
                  "S":"This item has changed"
               },
               "Id":{
                  "N":"101"
               }
            },
            "SequenceNumber":"333",
            "SizeBytes":38,
            "StreamViewType":"NEW_AND_OLD_IMAGES"
         },
         "eventSourceARN":"stream-ARN"
      }
   ],
    "window": {
        "start": "2020-07-30T17:00:00Z",
        "end": "2020-07-30T17:05:00Z"
    },
    "state": {
        "1": "state1"
    },
    "shardId": "shard123456789",
    "eventSourceARN": "stream-ARN",
    "isFinalInvokeForWindow": false,
    "isWindowTerminatedEarly": false
}
```

## Configuración
<a name="streams-tumbling-config"></a>

Puede configurar ventanas de salto constante al crear o actualizar una asignación de orígenes de eventos. Para configurar una ventana de saltos de tamaño constante, especifique la ventana en segundos ([TumblingWindowInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-TumblingWindowInSeconds)). El siguiente comando de ejemplo AWS Command Line Interface (AWS CLI) crea una asignación de origen de eventos de streaming que tiene una ventana de salto constante de 120 segundos. Se nombra la función de Lambda definida para la agregación y el procesamiento se llama `tumbling-window-example-function`.

```
aws lambda create-event-source-mapping \
--event-source-arn arn:aws:dynamodb:us-east-2:123456789012:table/my-table/stream/2024-06-10T19:26:16.525 \
--function-name tumbling-window-example-function \
--starting-position TRIM_HORIZON \
--tumbling-window-in-seconds 120
```

Lambda determina los límites de la ventana de salto constante en función de la hora en que se insertaron los registros en la secuencia. Todos los registros tienen una marca de hora aproximada disponible que Lambda utiliza en las determinaciones de límites.

Las agregaciones de ventanas de saltos constantes no admiten el reendurecimiento. Cuando el fragmento termina, Lambda considera la ventana cerrada y las particiones secundarias comienzan su propia ventana en un estado fresco.

Ventanas de saltos constantes son totalmente compatibles con las directivas de reintento existentes `maxRetryAttempts` y `maxRecordAge`.

**Example Handler.py: agregación y procesamiento**  
La siguiente función de Python muestra cómo agregar y luego procesar su estado final:  

```
def lambda_handler(event, context):
    print('Incoming event: ', event)
    print('Incoming state: ', event['state'])

#Check if this is the end of the window to either aggregate or process.
    if event['isFinalInvokeForWindow']:
        # logic to handle final state of the window
        print('Destination invoke')
    else:
        print('Aggregate invoke')

#Check for early terminations
    if event['isWindowTerminatedEarly']:
        print('Window terminated early')

    #Aggregation logic
    state = event['state']
    for record in event['Records']:
        state[record['dynamodb']['NewImage']['Id']] = state.get(record['dynamodb']['NewImage']['Id'], 0) + 1

    print('Returning state: ', state)
    return {'state': state}
```

# Parámetros de Lambda para las asignaciones de orígenes de eventos de Amazon DynamoDB
<a name="services-ddb-params"></a>

Todos los tipos de fuente de eventos Lambda comparten las mismas operaciones [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) y [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) de la API. Sin embargo, solo algunos de los parámetros se aplican a Amazon DynamoDB Streams.


| Parámetro | Obligatorio | Predeterminado | Notas | 
| --- | --- | --- | --- | 
|  BatchSize  |  N  |  100  |  Máximo: 10 000  | 
|  BisectBatchOnFunctionError  |  N  |  false  | none  | 
|  DestinationConfig  |  N  | N/A  |  Cola de Amazon SQS estándar o destino de tema de Amazon SNS estándar para registros descartados  | 
|  Habilitado  |  N  |  true  | none  | 
|  EventSourceArn  |  S  | N/A |  ARN del flujo de datos o un consumidor de flujos  | 
|  FilterCriteria  |  N  | N/A  |  [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md)  | 
|  FunctionName  |  S  | N/A  | none  | 
|  FunctionResponseTypes  |  N  | N/A |  Para permitir que la función informe de errores específicos de un lote, incluya el valor `ReportBatchItemFailures` en `FunctionResponseTypes`. Para obtener más información, consulte [Configuración de la respuesta por lotes parcial con DynamoDB y Lambda](services-ddb-batchfailurereporting.md).  | 
|  MaximumBatchingWindowInSeconds  |  N  |  0  | none  | 
|  MaximumRecordAgeInSeconds  |  N  |  -1  |  -1 significa infinito: se vuelven a intentar los registros que han producido error hasta que caduque el registro. El [límite de retención de datos del flujo de DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html#Streams.DataRetention) es de 24 horas. Mínimo: -1 Máximo: 604 800  | 
|  MaximumRetryAttempts  |  N  |  -1  |  -1 significa infinito: se vuelven a intentar los registros que han producido error hasta que caduque el registro Mínimo: 0 Máximo: 10 000  | 
|  ParallelizationFactor  |  N  |  1  |  Máximo: 10  | 
|  StartingPosition  |  S  | N/A  |  TRIM\$1HORIZON o LATEST  | 
|  TumblingWindowInSeconds  |  N  | N/A  |  Mínimo: 0 Máximo: 900  | 

# Uso del filtrado de eventos con una fuente de eventos de DynamoDB
<a name="with-ddb-filtering"></a>

Puede utilizar el filtrado de eventos para controlar qué registros de un flujo o una cola envía Lambda a su función. Para obtener información general sobre cómo funciona el filtrado de eventos, consulte [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md).

Esta sección se centra en el filtrado de eventos para las fuentes de eventos de DynamoDB.

**nota**  
Las asignaciones de orígenes de eventos de DynamoDB solo admiten el filtrado en la clave `dynamodb`.

**Topics**
+ [

## evento de DynamoDB
](#filtering-ddb)
+ [

## Filtrar con atributos de tabla
](#filtering-ddb-attributes)
+ [

## Filtrar con expresiones booleanas
](#filtering-ddb-boolean)
+ [

## Uso del operador Exists
](#filtering-ddb-exists)
+ [

## Formato JSON para filtrado de DynamoDB
](#filtering-ddb-JSON-format)

## evento de DynamoDB
<a name="filtering-ddb"></a>

Supongamos que tiene una tabla de DynamoDB con la clave principal `CustomerName` y los atributos `AccountManager` y `PaymentTerms`. El siguiente es un registro de ejemplo de flujo de la tabla de DynamoDB.

```
{
      "eventID": "1",
      "eventVersion": "1.0",
      "dynamodb": {
          "ApproximateCreationDateTime": "1678831218.0",
          "Keys": {
              "CustomerName": {
                  "S": "AnyCompany Industries"
              }
          },
          "NewImage": {
              "AccountManager": {
                  "S": "Pat Candella"
              },
              "PaymentTerms": {
                  "S": "60 days"
              },
              "CustomerName": {
                  "S": "AnyCompany Industries"
              }
          },
          "SequenceNumber": "111",
          "SizeBytes": 26,
          "StreamViewType": "NEW_IMAGE"
      }
  }
```

Para filtrar en función de los valores de clave y atributos en la tabla de DynamoDB, utilice la clave `dynamodb` del registro. En las siguientes secciones, se muestran ejemplos de diferentes tipos de filtros.

### Filtrar con claves de tabla
<a name="filtering-ddb-keys"></a>

Supongamos que desea que su función procese únicamente los registros en los que la clave principal `CustomerName` sea “AnyCompany Industries”. El objeto `FilterCriteria` sería el siguiente.

```
{
     "Filters": [
          {
              "Pattern": "{ \"dynamodb\" : { \"Keys\" : { \"CustomerName\" : { \"S\" : [ \"AnyCompany Industries\" ] } } } }"
          }
      ]
 }
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado. 

```
{
     "dynamodb": {
          "Keys": {
              "CustomerName": {
                  "S": [ "AnyCompany Industries" ]
                  }
              }
          }
 }
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "dynamodb" : { "Keys" : { "CustomerName" : { "S" : [ "AnyCompany Industries" ] } } } }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:dynamodb:us-east-2:123456789012:table/my-table \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"dynamodb\" : { \"Keys\" : { \"CustomerName\" : { \"S\" : [ \"AnyCompany Industries\" ] } } } }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"dynamodb\" : { \"Keys\" : { \"CustomerName\" : { \"S\" : [ \"AnyCompany Industries\" ] } } } }"}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
   Filters:
     - Pattern: '{ "dynamodb" : { "Keys" : { "CustomerName" : { "S" : [ "AnyCompany Industries" ] } } } }'
```

------

## Filtrar con atributos de tabla
<a name="filtering-ddb-attributes"></a>

Con DynamoDB, también puede utilizar las claves `NewImage` y `OldImage` para filtrar por los valores de los atributos. Supongamos que desea filtrar los registros en los que el atributo `AccountManager` de la última imagen de la tabla sea “Pat Candella” o “Shirley Rodriguez”. El objeto `FilterCriteria` sería el siguiente.

```
{
    "Filters": [
        {
            "Pattern": "{ \"dynamodb\" : { \"NewImage\" : { \"AccountManager\" : { \"S\" : [ \"Pat Candella\", \"Shirley Rodriguez\" ] } } } }"
        }
    ]
}
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado.

```
{
    "dynamodb": {
        "NewImage": {
            "AccountManager": {
                "S": [ "Pat Candella", "Shirley Rodriguez" ]
            }
        }
    }
}
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "dynamodb" : { "NewImage" : { "AccountManager" : { "S" : [ "Pat Candella", "Shirley Rodriguez" ] } } } }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:dynamodb:us-east-2:123456789012:table/my-table \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"dynamodb\" : { \"NewImage\" : { \"AccountManager\" : { \"S\" : [ \"Pat Candella\", \"Shirley Rodriguez\" ] } } } }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"dynamodb\" : { \"NewImage\" : { \"AccountManager\" : { \"S\" : [ \"Pat Candella\", \"Shirley Rodriguez\" ] } } } }"}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "dynamodb" : { "NewImage" : { "AccountManager" : { "S" : [ "Pat Candella", "Shirley Rodriguez" ] } } } }'
```

------

## Filtrar con expresiones booleanas
<a name="filtering-ddb-boolean"></a>

También puede crear filtros mediante expresiones booleanas AND. Estas expresiones pueden incluir tanto los parámetros de clave como los de atributo de la tabla. Supongamos que desea filtrar los registros en los que el valor `NewImage` de `AccountManager` es “Pat Candella” y el valor `OldImage` es “Terry Whitlock”. El objeto `FilterCriteria` sería el siguiente.

```
{
    "Filters": [
        {
            "Pattern": "{ \"dynamodb\" : { \"NewImage\" : { \"AccountManager\" : { \"S\" : [ \"Pat Candella\" ] } } } , \"dynamodb\" : { \"OldImage\" : { \"AccountManager\" : { \"S\" : [ \"Terry Whitlock\" ] } } } }"
        }
    ]
}
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado.

```
{ 
    "dynamodb" : { 
        "NewImage" : { 
            "AccountManager" : { 
                "S" : [ 
                    "Pat Candella" 
                ] 
            } 
        } 
    }, 
    "dynamodb": { 
        "OldImage": { 
            "AccountManager": { 
                "S": [ 
                    "Terry Whitlock" 
                ] 
            } 
        } 
    } 
}
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "dynamodb" : { "NewImage" : { "AccountManager" : { "S" : [ "Pat Candella" ] } } } , "dynamodb" : { "OldImage" : { "AccountManager" : { "S" : [ "Terry Whitlock" ] } } } }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:dynamodb:us-east-2:123456789012:table/my-table \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"dynamodb\" : { \"NewImage\" : { \"AccountManager\" : { \"S\" : [ \"Pat Candella\" ] } } } , \"dynamodb\" : { \"OldImage\" : { \"AccountManager\" : { \"S\" : [ \"Terry Whitlock\" ] } } } } "}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"dynamodb\" : { \"NewImage\" : { \"AccountManager\" : { \"S\" : [ \"Pat Candella\" ] } } } , \"dynamodb\" : { \"OldImage\" : { \"AccountManager\" : { \"S\" : [ \"Terry Whitlock\" ] } } } } "}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "dynamodb" : { "NewImage" : { "AccountManager" : { "S" : [ "Pat Candella" ] } } } , "dynamodb" : { "OldImage" : { "AccountManager" : { "S" : [ "Terry Whitlock" ] } } } }'
```

------

**nota**  
El filtrado de eventos de DynamoDB no es compatible con el uso de operadores numéricos (equivalentes numéricos e intervalo numérico). Incluso si los elementos de la tabla se almacenan como números, estos parámetros se convierten en cadenas en el objeto de registro JSON.

## Uso del operador Exists
<a name="filtering-ddb-exists"></a>

Debido a la forma en que están estructurados los objetos de eventos JSON de DynamoDB, el uso del operador Exists requiere un cuidado especial. El operador Exists solo funciona en los nodos hoja en el evento JSON, por lo que si el patrón de filtro usa Exists para probar la presencia de un nodo intermedio, no funcionará. Considere el siguiente elemento de la tabla de DynamoDB:

```
{
  "UserID": {"S": "12345"},
  "Name": {"S": "John Doe"},
  "Organizations": {"L": [
      {"S":"Sales"},
      {"S":"Marketing"},
      {"S":"Support"}
    ]
  }
}
```

Es posible que deba crear un patrón de filtro como el siguiente para comprobar si hay eventos que contengan `"Organizations"`:

```
{ "dynamodb" : { "NewImage" : { "Organizations" : [ { "exists": true } ] } } }
```

Sin embargo, este patrón de filtro nunca devolvería una coincidencia porque `"Organizations"` no es un nodo hoja. El siguiente ejemplo muestra cómo utilizar correctamente el operador Exists para crear el patrón de filtro deseado:

```
{ "dynamodb" : { "NewImage" : {"Organizations": {"L": {"S": [ {"exists": true } ] } } } } }
```

## Formato JSON para filtrado de DynamoDB
<a name="filtering-ddb-JSON-format"></a>

Para filtrar correctamente los eventos de orígenes de DynamoDB, tanto el campo de datos como los criterios de filtro del campo de datos (`dynamodb`) deben estar en un formato JSON válido. Si el formato JSON de alguno de los campos no es válido, Lambda elimina el mensaje o genera una excepción. En la siguiente tabla se resume el comportamiento específico: 


| Formato de los datos entrantes | Formato del patrón de filtro para las propiedades de datos | Acción resultante | 
| --- | --- | --- | 
|  JSON válido  |  JSON válido  |  Lambda filtra en función de los criterios de filtro.  | 
|  JSON válido  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  JSON válido  |  No JSON  |  Lambda genera una excepción al crear o actualizar la asignación de origen de eventos. El formato JSON del patrón de filtro de las propiedades de datos debe ser válido.  | 
|  No JSON  |  JSON válido  |  Lambda elimina el registro.  | 
|  No JSON  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  No JSON  |  No JSON  |  Lambda genera una excepción al crear o actualizar la asignación de origen de eventos. El formato JSON del patrón de filtro de las propiedades de datos debe ser válido.  | 

# Tutorial: Uso de AWS Lambda con Amazon DynamoDB Streams
<a name="with-ddb-example"></a>

 En este tutorial, se crea una función de Lambda para consumir eventos de Amazon DynamoDB Stream.

## Requisitos previos
<a name="with-ddb-prepare"></a>

### Instala la AWS Command Line Interface
<a name="install_aws_cli"></a>

Si aún no ha instalado AWS Command Line Interface, siga los pasos que se indican en [Instalación o actualización de la versión más reciente de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalarlo.

El tutorial requiere un intérprete de comandos o un terminal de línea de comando para ejecutar los comandos. En Linux y macOS, use su administrador de intérprete de comandos y paquetes preferido.

**nota**  
En Windows, algunos comandos de la CLI de Bash que se utilizan habitualmente con Lambda (por ejemplo, `zip`) no son compatibles con los terminales integrados del sistema operativo. Para obtener una versión de Ubuntu y Bash integrada con Windows, [instale el subsistema de Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Creación del rol de ejecución
<a name="with-ddb-create-execution-role"></a>

Cree el [rol de ejecución](lambda-intro-execution-role.md) que concederá a su función permiso para obtener acceso a los recursos de AWS.

**Para crear un rol de ejecución**

1. Abra la [página Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Elija **Crear rol**.

1. Cree un rol con las propiedades siguientes.
   + **Entidad de confianza**: Lambda.
   + **Permisos**: **AWSLambdaDynamoDBExecutionRole**.
   + **Role name (Nombre de rol** – **lambda-dynamodb-role**.

El **AWSLambdaDynamoDBExecutionRole** tiene los permisos que la función necesita para leer elementos desde DynamoDB y escribir registros al CloudWatch Logs.

## Creación de la función
<a name="with-ddb-example-create-function"></a>

Cree una función de Lambda que procese los eventos de DynamoDB. El código de la función escribe algunos de los datos del evento entrante en CloudWatch Logs.

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumo de un evento de DynamoDB con Lambda mediante .NET.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
using System.Text.Json;
using System.Text;
using Amazon.Lambda.Core;
using Amazon.Lambda.DynamoDBEvents;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace AWSLambda_DDB;

public class Function
{
    public void FunctionHandler(DynamoDBEvent dynamoEvent, ILambdaContext context)
    {
        context.Logger.LogInformation($"Beginning to process {dynamoEvent.Records.Count} records...");

        foreach (var record in dynamoEvent.Records)
        {
            context.Logger.LogInformation($"Event ID: {record.EventID}");
            context.Logger.LogInformation($"Event Name: {record.EventName}");

            context.Logger.LogInformation(JsonSerializer.Serialize(record));
        }

        context.Logger.LogInformation("Stream processing complete.");
    }
}
```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumo de un evento de DynamoDB con Lambda mediante Go.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package main

import (
	"context"
	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-lambda-go/events"
	"fmt"
)

func HandleRequest(ctx context.Context, event events.DynamoDBEvent) (*string, error) {
	if len(event.Records) == 0 {
		return nil, fmt.Errorf("received empty event")
	}

	for _, record := range event.Records {
	 	LogDynamoDBRecord(record)
	}

	message := fmt.Sprintf("Records processed: %d", len(event.Records))
	return &message, nil
}

func main() {
	lambda.Start(HandleRequest)
}

func LogDynamoDBRecord(record events.DynamoDBEventRecord){
	fmt.Println(record.EventID)
	fmt.Println(record.EventName)
	fmt.Printf("%+v\n", record.Change)
}
```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumo de un evento de DynamoDB con Lambda mediante Java.  

```
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.DynamodbEvent;
import com.amazonaws.services.lambda.runtime.events.DynamodbEvent.DynamodbStreamRecord;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class example implements RequestHandler<DynamodbEvent, Void> {

    private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();

    @Override
    public Void handleRequest(DynamodbEvent event, Context context) {
        System.out.println(GSON.toJson(event));
        event.getRecords().forEach(this::logDynamoDBRecord);
        return null;
    }

    private void logDynamoDBRecord(DynamodbStreamRecord record) {
        System.out.println(record.getEventID());
        System.out.println(record.getEventName());
        System.out.println("DynamoDB Record: " + GSON.toJson(record.getDynamodb()));
    }
}
```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumo de un evento de DynamoDB con Lambda mediante JavaScript.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
exports.handler = async (event, context) => {
    console.log(JSON.stringify(event, null, 2));
    event.Records.forEach(record => {
        logDynamoDBRecord(record);
    });
};

const logDynamoDBRecord = (record) => {
    console.log(record.eventID);
    console.log(record.eventName);
    console.log(`DynamoDB Record: ${JSON.stringify(record.dynamodb)}`);
};
```
Consumo de un evento de DynamoDB con Lambda mediante TypeScript.  

```
export const handler = async (event, context) => {
    console.log(JSON.stringify(event, null, 2));
    event.Records.forEach(record => {
        logDynamoDBRecord(record);
    });
}
const logDynamoDBRecord = (record) => {
    console.log(record.eventID);
    console.log(record.eventName);
    console.log(`DynamoDB Record: ${JSON.stringify(record.dynamodb)}`);
};
```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumo de un evento de DynamoDB con Lambda mediante PHP.  

```
<?php

# using bref/bref and bref/logger for simplicity

use Bref\Context\Context;
use Bref\Event\DynamoDb\DynamoDbEvent;
use Bref\Event\DynamoDb\DynamoDbHandler;
use Bref\Logger\StderrLogger;

require __DIR__ . '/vendor/autoload.php';

class Handler extends DynamoDbHandler
{
    private StderrLogger $logger;

    public function __construct(StderrLogger $logger)
    {
        $this->logger = $logger;
    }

    /**
     * @throws JsonException
     * @throws \Bref\Event\InvalidLambdaEvent
     */
    public function handleDynamoDb(DynamoDbEvent $event, Context $context): void
    {
        $this->logger->info("Processing DynamoDb table items");
        $records = $event->getRecords();

        foreach ($records as $record) {
            $eventName = $record->getEventName();
            $keys = $record->getKeys();
            $old = $record->getOldImage();
            $new = $record->getNewImage();
            
            $this->logger->info("Event Name:".$eventName."\n");
            $this->logger->info("Keys:". json_encode($keys)."\n");
            $this->logger->info("Old Image:". json_encode($old)."\n");
            $this->logger->info("New Image:". json_encode($new));
            
            // TODO: Do interesting work based on the new data

            // Any exception thrown will be logged and the invocation will be marked as failed
        }

        $totalRecords = count($records);
        $this->logger->info("Successfully processed $totalRecords items");
    }
}

$logger = new StderrLogger();
return new Handler($logger);
```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumo de un evento de DynamoDB con Lambda mediante Python.  

```
import json

def lambda_handler(event, context):
    print(json.dumps(event, indent=2))

    for record in event['Records']:
        log_dynamodb_record(record)

def log_dynamodb_record(record):
    print(record['eventID'])
    print(record['eventName'])
    print(f"DynamoDB Record: {json.dumps(record['dynamodb'])}")
```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumo de un evento de DynamoDB con Lambda mediante Ruby.  

```
def lambda_handler(event:, context:)
    return 'received empty event' if event['Records'].empty?
  
    event['Records'].each do |record|
      log_dynamodb_record(record)
    end
  
    "Records processed: #{event['Records'].length}"
  end
  
  def log_dynamodb_record(record)
    puts record['eventID']
    puts record['eventName']
    puts "DynamoDB Record: #{JSON.generate(record['dynamodb'])}"
  end
```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumo de un evento de DynamoDB con Lambda mediante Rust.  

```
use lambda_runtime::{service_fn, tracing, Error, LambdaEvent};
use aws_lambda_events::{
    event::dynamodb::{Event, EventRecord},
   };


// Built with the following dependencies:
//lambda_runtime = "0.11.1"
//serde_json = "1.0"
//tokio = { version = "1", features = ["macros"] }
//tracing = { version = "0.1", features = ["log"] }
//tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] }
//aws_lambda_events = "0.15.0"

async fn function_handler(event: LambdaEvent<Event>) ->Result<(), Error> {
    
    let records = &event.payload.records;
    tracing::info!("event payload: {:?}",records);
    if records.is_empty() {
        tracing::info!("No records found. Exiting.");
        return Ok(());
    }

    for record in records{
        log_dynamo_dbrecord(record);
    }

    tracing::info!("Dynamo db records processed");

    // Prepare the response
    Ok(())

}

fn log_dynamo_dbrecord(record: &EventRecord)-> Result<(), Error>{
    tracing::info!("EventId: {}", record.event_id);
    tracing::info!("EventName: {}", record.event_name);
    tracing::info!("DynamoDB Record: {:?}", record.change );
    Ok(())

}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
    .with_max_level(tracing::Level::INFO)
    .with_target(false)
    .without_time()
    .init();

    let func = service_fn(function_handler);
    lambda_runtime::run(func).await?;
    Ok(())
    
}
```

------

**Cómo crear la función**

1. Copie el código de muestra en un archivo con el nombre `example.js`.

1. Cree un paquete de implementación.

   ```
   zip function.zip example.js
   ```

1. Cree una función de Lambda con el comando `create-function`.

   ```
   aws lambda create-function --function-name ProcessDynamoDBRecords \
       --zip-file fileb://function.zip --handler example.handler --runtime nodejs24.x \
       --role arn:aws:iam::111122223333:role/lambda-dynamodb-role
   ```

## Prueba de la función de Lambda
<a name="with-dbb-invoke-manually"></a>

En este paso, invocará la función de Lambda manualmente mediante el comando `invoke` de la CLI de AWS Lambda y el siguiente evento de muestra de DynamoDB. Copie lo siguiente en un archivo denominado `input.txt`.

**Example input.txt**  

```
{
   "Records":[
      {
         "eventID":"1",
         "eventName":"INSERT",
         "eventVersion":"1.0",
         "eventSource":"aws:dynamodb",
         "awsRegion":"us-east-1",
         "dynamodb":{
            "Keys":{
               "Id":{
                  "N":"101"
               }
            },
            "NewImage":{
               "Message":{
                  "S":"New item!"
               },
               "Id":{
                  "N":"101"
               }
            },
            "SequenceNumber":"111",
            "SizeBytes":26,
            "StreamViewType":"NEW_AND_OLD_IMAGES"
         },
         "eventSourceARN":"stream-ARN"
      },
      {
         "eventID":"2",
         "eventName":"MODIFY",
         "eventVersion":"1.0",
         "eventSource":"aws:dynamodb",
         "awsRegion":"us-east-1",
         "dynamodb":{
            "Keys":{
               "Id":{
                  "N":"101"
               }
            },
            "NewImage":{
               "Message":{
                  "S":"This item has changed"
               },
               "Id":{
                  "N":"101"
               }
            },
            "OldImage":{
               "Message":{
                  "S":"New item!"
               },
               "Id":{
                  "N":"101"
               }
            },
            "SequenceNumber":"222",
            "SizeBytes":59,
            "StreamViewType":"NEW_AND_OLD_IMAGES"
         },
         "eventSourceARN":"stream-ARN"
      },
      {
         "eventID":"3",
         "eventName":"REMOVE",
         "eventVersion":"1.0",
         "eventSource":"aws:dynamodb",
         "awsRegion":"us-east-1",
         "dynamodb":{
            "Keys":{
               "Id":{
                  "N":"101"
               }
            },
            "OldImage":{
               "Message":{
                  "S":"This item has changed"
               },
               "Id":{
                  "N":"101"
               }
            },
            "SequenceNumber":"333",
            "SizeBytes":38,
            "StreamViewType":"NEW_AND_OLD_IMAGES"
         },
         "eventSourceARN":"stream-ARN"
      }
   ]
}
```

Ejecute el comando `invoke` siguiente. 

```
aws lambda invoke --function-name ProcessDynamoDBRecords \
    --cli-binary-format raw-in-base64-out \
    --payload file://input.txt outputfile.txt
```

La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 2*.

La función devuelve la cadena `message` en el cuerpo de la respuesta. 

Verifique la salida en el archivo `outputfile.txt`.

## Crear una tabla de DynamoDB con un flujo habilitado
<a name="with-ddb-create-buckets"></a>

Crear una tabla de Amazon DynamoDB con un flujo habilitado.

**Para crear una tabla de DynamoDB**

1. Abra la [consola de DynamoDB](https://console.aws.amazon.com/dynamodb).

1. Seleccione **Create table (Creación de tabla)**.

1. Cree una tabla con la siguiente configuración:
   + **Nombre de la tabla** – **lambda-dynamodb-stream**
   + **Clave principal**: **id** (cadena)

1. Seleccione **Crear**.

**Habilitar secuencias**

1. Abra la [consola de DynamoDB](https://console.aws.amazon.com/dynamodb).

1. Elija **Tables (Tablas)**.

1. Elija la tabla **lambda-dynamodb-stream (Flujo de dynamodb lambda)**.

1. En **Exports and streams** (Exportaciones y flujos), elija **DynamoDB stream details** (Detalles del flujo de DynamoDB).

1. Elija **Turn on**.

1. En **Tipo de vista**, elija **Solo atributos clave**.

1. Seleccione **Activar flujo**.

Anote el ARN del flujo. Lo necesitará en el siguiente paso al asociar el flujo a la función de Lambda. Para obtener más información acerca de cómo habilitar flujos, consulte [Captura de la actividad de las tablas con DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html).

## Añadir un origen de eventos en AWS Lambda
<a name="with-ddb-attach-notification-configuration"></a>

Crear un mapeo de origen de eventos en AWS Lambda. Esta asignación de orígenes de eventos asocia el flujo de DynamoDB a la función de Lambda. Una vez creado este mapeo de origen de eventos, AWS Lambda comienza a sondear el flujo.

Ejecute el siguiente comando `create-event-source-mapping` de la AWS CLI. Después de ejecutar el comando, anote el UUID. Necesitará este UUID para hacer referencia al mapeo de origen de eventos en los comandos, por ejemplo, al eliminar el mapeo de origen de eventos.

```
aws lambda create-event-source-mapping --function-name ProcessDynamoDBRecords \
    --batch-size 100 --starting-position LATEST --event-source DynamoDB-stream-arn
```

 Esto crea un mapeo entre el flujo de DynamoDB especificado y la función de Lambda. Puede asociar un flujo de DynamoDB a varias funciones de Lambda, así como asociar la misma función de Lambda a varios flujos. Sin embargo, las funciones de Lambda compartirán el rendimiento de lectura para el flujo que comparten. 

Para obtener la lista de mapeos de orígenes de eventos, ejecute el siguiente comando.

```
aws lambda list-event-source-mappings
```

La lista devuelve todos los mapeos de orígenes de eventos creados, y para cada uno de ellos muestra el `LastProcessingResult`, entre otras cosas. Este campo se utiliza para proporcionar un mensaje informativo en caso de que surja algún problema. Los valores como `No records processed` (indica que AWS Lambda no ha comenzado el sondeo o que no hay registros en el flujo) y `OK` (indica que AWS Lambda ha leído correctamente los registros del flujo y ha invocado la función de Lambda) indican que no hay ningún problema. Si hay algún problema, recibirá un mensaje de error.

Si tiene muchos mapeos de origen de eventos, use la función nombrar parámetro para reducir los resultados.

```
aws lambda list-event-source-mappings --function-name ProcessDynamoDBRecords
```

## Prueba de la configuración
<a name="with-ddb-final-integration-test-no-iam"></a>

Probar la experiencia integral. A medida que se actualiza la tabla, DynamoDB escribe los registros de eventos en el flujo. Cuando AWS Lambda sondea el flujo, detecta nuevos registros en él e invoca la función de Lambda en nombre del usuario pasando eventos a esta. 

1. En la consola de DynamoDB, agregue, actualice y elimine elementos de la tabla. DynamoDB escribe registros de estas acciones en el flujo.

1. AWS Lambda sondea el flujo y, cuando detecta actualizaciones en este, invoca la función de Lambda pasando los datos de eventos que encuentra en el flujo.

1. La función se ejecuta y crea registros en Amazon CloudWatch. Puede verificar los registros reportados en la consola de Amazon CloudWatch.

## Siguientes pasos
<a name="with-ddb-next-steps"></a>

En este instructivo, se muestran los conceptos básicos del procesamiento de eventos de transmisión de DynamoDB con Lambda. En el caso de las cargas de trabajo de producción, puede implementar una lógica de respuesta por lotes parcial para gestionar los errores de registro individuales de forma más eficiente. La [utilidad de procesador por lotes](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) de Powertools for AWS Lambda está disponible en Python, TypeScript, .NET y Java y ofrece una solución sólida para este fin, ya que gestiona automáticamente la complejidad de las respuestas de lotes parciales y reduce el número de reintentos para los registros que se han procesado correctamente.

## Eliminación de sus recursos
<a name="cleanup"></a>

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

**Cómo eliminar la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que ha creado.

1. Elija **Acciones**, **Eliminar**.

1. Escriba **confirm** en el campo de entrada de texto y elija **Delete**(Eliminar).

**Cómo eliminar el rol de ejecución**

1. Abra la página [Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione el rol de ejecución que creó.

1. Elija **Eliminar**.

1. Si desea continuar, escriba el nombre del rol en el campo de entrada de texto y elija **Delete** (Eliminar).

**Para eliminar la tabla de DynamoDB**

1. Abra la página [Tables (Tablas)](https://console.aws.amazon.com//dynamodb/home#tables:) en la consola de DynamoDB.

1. Seleccione la tabla que ha creado.

1. Elija **Eliminar**.

1. Escriba **delete** en el cuadro de texto.

1. Elija **Delete table (Eliminar tabla)**.

# Procese los eventos del ciclo de vida de Amazon EC2 con una función de Lambda
<a name="services-ec2"></a>

Puede utilizar AWS Lambda para procesar eventos del ciclo de vida desde Amazon Elastic Compute Cloud y administrar los recursos de Amazon EC2. 2Amazon EC2 envía eventos a [Amazon EventBridge (Eventos de CloudWatch)](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) para [eventos del ciclo de vida](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-lifecycle.html), como cuando una instancia cambia de estado, cuando se completa una instantánea de volumen de Amazon Elastic Block Store o cuando se programa que se termine una instancia de spot. Configura EventBridge (CloudWatch Events) para reenviar esos eventos a una función de Lambda para su procesamiento.

EventBridge (CloudWatch Events) invoca su función de Lambda de forma asíncrona con el documento de evento de Amazon EC2.

**Example Ciclo de vida de la instancia**  

```
{
    "version": "0",
    "id": "b6ba298a-7732-2226-xmpl-976312c1a050",
    "detail-type": "EC2 Instance State-change Notification",
    "source": "aws.ec2",
    "account": "111122223333",
    "time": "2019-10-02T17:59:30Z",
    "region": "us-east-1",
    "resources": [
        "arn:aws:ec2:us-east-1:111122223333:instance/i-0c314xmplcd5b8173"
    ],
    "detail": {
        "instance-id": "i-0c314xmplcd5b8173",
        "state": "running"
    }
}
```

Para obtener detalles sobre la configuración de eventos, consulte [Invocación de una función de Lambda según una programación](with-eventbridge-scheduler.md). Para ver una función de ejemplo que procesa las notificaciones de instantáneas de Amazon EBS, consulte [EventBridge Scheduler para](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-cloud-watch-events.html) Amazon EBS.

También puede utilizar AWS SDK para administrar instancias y otros recursos con la API de Amazon EC2. 

## Cómo otorgar permisos a EventBridge (Eventos de CloudWatch)
<a name="services-ec2-permissions"></a>

Para procesar eventos del ciclo de vida desde Amazon EC2, EventBridge (CloudWatch Events) necesita permiso para invocar su función. Este permiso proviene de la [política basada en recursos](access-control-resource-based.md) de la función. Si utiliza la consola de EventBridge (CloudWatch Events) para configurar un desencadenador de eventos, la consola actualiza la política basada en recursos en su nombre. De lo contrario, agregue una declaración como la siguiente:

**Example Instrucción de una política basada en recursos para notificaciones del ciclo de vida de Amazon EC2**  

```
{
  "Sid": "ec2-events",
  "Effect": "Allow",
  "Principal": {
    "Service": "events.amazonaws.com"
  },
  "Action": "lambda:InvokeFunction",
  "Resource": "arn:aws:lambda:us-east-1:12456789012:function:my-function",
  "Condition": {
    "ArnLike": {
      "AWS:SourceArn": "arn:aws:events:us-east-1:12456789012:rule/*"
    }
  }
}
```

Para agregar una instrucción, utilice el comando de la AWS CLI `add-permission`.

```
aws lambda add-permission --action lambda:InvokeFunction --statement-id ec2-events \
--principal events.amazonaws.com --function-name my-function --source-arn 'arn:aws:events:us-east-1:12456789012:rule/*'
```

Si la función utiliza el AWS SDK para administrar recursos de Amazon EC2, agregue permisos de Amazon EC2 al [rol de ejecución](lambda-intro-execution-role.md) de la función.

# Procese las solicitudes de Application Load Balancer con Lambda
<a name="services-alb"></a>

Puede utilizar una función de Lambda para procesar solicitudes de un balanceador de carga de aplicaciones. Elastic Load Balancing admite funciones de Lambda como destino para un balanceador de carga de aplicaciones. Utilice reglas de balanceador de carga para direccionar solicitudes HTTP a una función según la ruta o los valores de encabezado. Procese la solicitud y devuelva una respuesta HTTP desde de su función de Lambda.

Elastic Load Balancing invoca la función de Lambda de forma sincrónica con un evento que contiene el cuerpo de la solicitud y metadatos.

**Example Balanceador de carga de aplicaciones solicita un evento**  

```
{
    "requestContext": {
        "elb": {
            "targetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/lambda-279XGJDqGZ5rsrHC2Fjr/49e9d65c45c6791a"
        }
    },
    "httpMethod": "GET",
    "path": "/lambda",
    "queryStringParameters": {
        "query": "1234ABCD"
    },
    "headers": {
        "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
        "accept-encoding": "gzip",
        "accept-language": "en-US,en;q=0.9",
        "connection": "keep-alive",
        "host": "lambda-alb-123578498.us-east-1.elb.amazonaws.com",
        "upgrade-insecure-requests": "1",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36",
        "x-amzn-trace-id": "Root=1-5c536348-3d683b8b04734faae651f476",
        "x-forwarded-for": "72.12.164.125",
        "x-forwarded-port": "80",
        "x-forwarded-proto": "http",
        "x-imforwards": "20"
    },
    "body": "",
    "isBase64Encoded": False
}
```

Su función procesa el evento y devuelve un documento de respuesta al balanceador de carga en JSON. Elastic Load Balancing convierte el documento en una respuesta HTTP de éxito o error y lo devuelve al usuario.

**Example formato del documento de respuesta**  

```
{
    "statusCode": 200,
    "statusDescription": "200 OK",
    "isBase64Encoded": False,
    "headers": {
        "Content-Type": "text/html"
    },
    "body": "<h1>Hello from Lambda!</h1>"
}
```

Para configurar un balanceador de carga de aplicaciones como desencadenador de funciones, conceda a Elastic Load Balancing permiso para ejecutar la función, cree un grupo de destino que envíe las solicitudes a la función y agregue una regla al balanceador de carga para enviar las solicitudes al grupo de destino.

Utilice el comando `add-permission` para añadir una instrucción de permiso a la política basada en recursos de la función.

```
aws lambda add-permission --function-name alb-function \
--statement-id load-balancer --action "lambda:InvokeFunction" \
--principal elasticloadbalancing.amazonaws.com
```

Debería ver los siguientes datos de salida:

```
{
    "Statement": "{\"Sid\":\"load-balancer\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"elasticloadbalancing.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-west-2:123456789012:function:alb-function\"}"
}
```

Para ver instrucciones sobre cómo configurar el agente de escucha de balanceador de carga de aplicaciones, consulte [Funciones de Lambda como destino](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html) en la *Guía del usuario para balanceadores de carga de aplicaciones*.

## Controlador de eventos de Powertools para AWS Lambda
<a name="services-alb-powertools"></a>

El controlador de eventos del kit de herramientas de Powertools para AWS Lambda proporciona enrutamiento, middleware, configuración CORS, generación de especificaciones de OpenAPI, validación de solicitudes, manejo de errores y otras características útiles durante la escritura de funciones de Lambda invocadas por un equilibrador de carga de aplicación. La utilidad de controlador de eventos está disponible para Python. Para obtener más información, consulte la [API de REST del controlador de eventos](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/) en la documentación de *Powertools para AWS Lambda (Python)*.

### Python
<a name="services-alb-powertools-python"></a>

```
import requests
from requests import Response

from aws_lambda_powertools import Logger, Tracer
from aws_lambda_powertools.event_handler import ALBResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing import LambdaContext

tracer = Tracer()
logger = Logger()
app = ALBResolver()


@app.get("/todos")
@tracer.capture_method
def get_todos():
    todos: Response = requests.get("https://jsonplaceholder.typicode.com/todos")
    todos.raise_for_status()

    # for brevity, we'll limit to the first 10 only
    return {"todos": todos.json()[:10]}


# You can continue to use other utilities just as before
@logger.inject_lambda_context(correlation_id_path=correlation_paths.APPLICATION_LOAD_BALANCER)
@tracer.capture_lambda_handler
def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)
```

# Invocación de una función de Lambda según una programación
<a name="with-eventbridge-scheduler"></a>

El [Programador de Amazon EventBridge](https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html) es un programador sin servidor que le permite crear, ejecutar y administrar tareas desde un servicio administrado y centralizado. Con el Programador de EventBridge, puede crear programadores mediante expresiones cron y rate para patrones recurrentes, o configurar invocaciones únicas. Puede configurar intervalos de tiempo flexibles para la entrega, definir límites de reintentos y establecer el tiempo máximo de retención para los eventos sin procesar.

Al configurar el Programador de EventBridge con Lambda, el Programador de EventBridge invoca la función de Lambda de forma asíncrona. En esta página, se explica cómo utilizar el Programador de EventBridge para invocar una función de Lambda según una programación.

## Configurar el rol de ejecución
<a name="using-eventbridge-scheduler-execution-role"></a>

 Al crear una programación nueva, el Programador de EventBridge debe tener permiso para invocar la operación de la API de destino en su nombre. Estos permisos se conceden al Programador de EventBridge mediante un *rol de ejecución*. La política de permisos que adjunta a la función de ejecución de su programación define los permisos necesarios. Estos permisos dependen de la API de destino que quiera que invoque el Programador de EventBridge.

 Al utilizar la consola del Programador de EventBridge para crear una programación, como en el siguiente procedimiento, el Programador de EventBridge configura de forma automática un rol de ejecución en función del destino seleccionado. Si desea crear una programación con uno de los SDK del Programador de EventBridge, la AWS CLI o CloudFormation, debe tener un rol de ejecución existente que conceda los permisos que el Programador de EventBridge requiere para invocar un destino. A fin de obtener más información sobre cómo configurar de forma manual un rol de ejecución para su programación, consulte [Setting up the execution role](https://docs.aws.amazon.com/scheduler/latest/UserGuide/setting-up.html#setting-up-execution-role) en *EventBridge Scheduler User Guide*. 

## Crear una programación
<a name="using-eventbridge-scheduler-create"></a>

**Para crear una programación con la consola, realice lo siguiente:**

1. Abra la consola del Programador de Amazon EventBridge en[https://console.aws.amazon.com/scheduler/home](https://console.aws.amazon.com/scheduler/home/).

1.  En la página de **Programaciones**, elija **Crear programación**. 

1.  En la página de **Especificar los detalles de la programación**, en la sección de **Nombre y descripción de la programación**, realice lo siguiente: 

   1. En **Nombre de la programación**, escriba un nombre para la programación. Por ejemplo, **MyTestSchedule**. 

   1. (Opcional) En **Descripción**, escriba una descripción para su programación. Por ejemplo, **My first schedule**.

   1. En **Grupo de programaciones**, elija un grupo de programaciones de la lista desplegable. Si no tiene un grupo, elija **predeterminado**. Para crear un grupo de programaciones, elija **crear mi propia programación**. 

      Los grupos de programaciones se utilizan para agregar etiquetas a grupos de programaciones. 

1. 

   1. Elija sus opciones de programación.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/with-eventbridge-scheduler.html)

1. (Opcional) Si elige **Programación recurrente** en el paso anterior, en la sección de **Periodo de tiempo**, realice lo siguiente: 

   1. En **Zona horaria**, elija una zona horaria. 

   1. En **Fecha y hora de inicio**, ingrese una fecha válida en el formato `YYYY/MM/DD` y, a continuación, especifique una marca de tiempo en el formato `hh:mm` de 24 horas. 

   1. En **Fecha y hora de finalización**, ingrese una fecha válida en el formato `YYYY/MM/DD` y, a continuación, especifique una marca de tiempo en el formato `hh:mm` de 24 horas. 

1. Seleccione **Siguiente**. 

1. En la página **Seleccionar destino**, elija la operación de la API de AWS que invoca el Programador de EventBridge: 

   1. Elija **Invocación de AWS Lambda**.

   1. En la sección de **Invocar**, seleccione una función o elija **Crear función de Lambda nueva**.

   1. (Opcional) Ingrese una carga útil de JSON. Si no ingresa una carga útil, el Programador de EventBridge utilizará un evento vacío para invocar la función.

1. Elija **Siguiente**. 

1. En la página **Configuración**, haga lo siguiente: 

   1. Para activar la programación, en **Estado de la programación**, cambie a **Habilitar programación**. 

   1. A fin de configurar una política de reintentos para su programación, en **Política de reintento y cola de mensajes fallidos (DLQ)**, realice lo siguiente:
      + Cambie a **Reintentar**.
      + En **Antigüedad máxima del evento**, ingrese el máximo de **horas** y **minutos** que el Programador de EventBridge debe mantener un evento sin procesar.
      + El tiempo máximo es de 24 horas.
      + En **Cantidad máxima de reintentos**, ingrese el número máximo de veces que el Programador de EventBridge reintenta la programación si el objetivo devuelve un error. 

         El valor máximo es 185 reintentos. 

      Con las políticas de reintentos, si un programa no puede invocar su objetivo, el Programador de EventBridge vuelve a ejecutar el programa. Si se encuentra configurado, debe establecer el tiempo máximo de retención y los reintentos máximos para la programación.

   1. Elija dónde almacena los eventos no entregados el Programador de EventBridge.     
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/with-eventbridge-scheduler.html)

   1. Para utilizar una clave administrada por el cliente a fin de cifrar la entrada de destino, en **Cifrado**, elija **Personalizar la configuración de cifrado (avanzado)**. 

      Si elige esta opción, ingrese un ARN de clave de KMS existente o elija **Crear una AWS KMS key** para navegar hasta la consola de AWS KMS. Para obtener más información sobre cómo el Programador de EventBridge cifra los datos en reposo, consulte [Encryption at rest](https://docs.aws.amazon.com/scheduler/latest/UserGuide/encryption-rest.html) en *Amazon EventBridge Scheduler User Guide*. 

   1. Para que el Programador de EventBridge cree un rol de ejecución nuevo en su nombre, elija **Crear un nuevo rol para esta programación**. A continuación, ingrese un nombre para el **Nombre de rol**. Si elige esta opción, el Programador de EventBridge adjunta al rol los permisos necesarios para el objetivo creado con la plantilla.

1. Elija **Siguiente**. 

1.  En la página de **Revisar y crear una programación**, revise los detalles de su programación. En cada sección, elija **Editar** para volver a ese paso y editar sus detalles. 

1. Elija **Crear programación**. 

   Puede ver una lista de sus programaciones nuevas y existentes en la página de **Programaciones**. En la columna de **Estado**, verifique que su programación nueva se encuentre **Habilitada**. 

Para confirmar que el Programador de EventBridge ha invocado la función, [compruebe Registros de Amazon CloudWatch de la función](monitoring-cloudwatchlogs-view.md#monitoring-cloudwatchlogs-console).

## Recursos relacionados
<a name="using-eventbridge-scheduler-related-resources"></a>

 Para obtener más información sobre el Programador de EventBridge, consulte lo siguiente: 
+ [EventBridge Scheduler User Guide](https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html)
+ [Referencia de la API del Programador de EventBridge](https://docs.aws.amazon.com/scheduler/latest/APIReference/Welcome.html)
+ [Precios del Programador de EventBridge](https://aws.amazon.com/eventbridge/pricing/#Scheduler)

# Uso de AWS Lambda con AWS IoT
<a name="services-iot"></a>

AWS IoT proporciona una comunicación segura entre dispositivos conectados a Internet (como sensores) y la nube de AWS. Esto le permite recopilar, almacenar y analizar los datos de telemetría de varios dispositivos.

Puede crear reglas de AWS IoT para que sus dispositivos interactúen con los Servicios de AWS. El [motor de reglas](https://docs.aws.amazon.com/iot/latest/developerguide/iot-rules.html) de AWS IoT proporciona un lenguaje basado en SQL para seleccionar datos de cargas de mensajes y enviar los datos a otros servicios como Amazon S3, Amazon DynamoDB y AWS Lambda. Cuando quiera invocar otro servicio de AWS o un servicio de terceros, defina una regla para invocar una función de Lambda. 

Cuando un mensaje de IoT entrante desencadena la regla, AWS IoT invoca su función de Lambda [de forma asíncrona](invocation-async.md) y pasa los datos del mensaje de IoT a la función. 

El siguiente ejemplo muestra una lectura de humedad del sensor de un invernadero. Los valores **row** y **pos** identifican la ubicación del sensor. Este evento de ejemplo se basa en el tipo de invernadero de los [Tutoriales de reglas de AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-rules-tutorial.html). 

**Example Evento de mensaje de AWS IoT**  

```
{
    "row" : "10",
    "pos" : "23",
    "moisture" : "75"
}
```

En la invocación asincrónica, Lambda pone en cola el mensaje y, si la función devuelve un error, [lo intenta de nuevo](invocation-retries.md). Configure su función con un [destination](invocation-async-retain-records.md#invocation-async-destinations) para retener eventos que su función no pudo procesar.

Debe conceder permiso para que el servicio AWS IoT invoque su función de Lambda. Utilice el comando `add-permission` para añadir una instrucción de permiso a la política basada en recursos de la función.

```
aws lambda add-permission --function-name my-function \
--statement-id iot-events --action "lambda:InvokeFunction" --principal iot.amazonaws.com
```

Debería ver los siguientes datos de salida:

```
{
    "Statement": "{\"Sid\":\"iot-events\",\"Effect\":\"Allow\",\"Principal\":{\"Service\":\"iot.amazonaws.com\"},\"Action\":\"lambda:InvokeFunction\",\"Resource\":\"arn:aws:lambda:us-east-1:123456789012:function:my-function\"}"
}
```

Para obtener más información acerca de cómo utilizar Lambda con AWS IoT, consulte [Creación de una regla de AWS Lambda](https://docs.aws.amazon.com/iot/latest/developerguide/iot-lambda-rule.html). 

# Uso de Lambda para procesar los registros de Amazon Kinesis Data Streams
<a name="with-kinesis"></a>

Puede utilizar una función de Lambda para procesar los registros de un [flujo de datos de Amazon Kinesis](https://docs.aws.amazon.com/streams/latest/dev/introduction.html). Puede asignar una función de Lambda a un consumidor de rendimiento compartido (iterador estándar) de Kinesis Data Streams o a un consumidor de rendimiento dedicado con [distribución ramificada mejorada](https://docs.aws.amazon.com/kinesis/latest/dev/enhanced-consumers.html). Para iteradores estándar, Lambda sondea cada partición de la secuencia de Kinesis en busca de registros utilizando el protocolo HTTP. El mapeo de origen de eventos comparte el rendimiento de lectura con otros consumidores de la partición.

 Para obtener información detallada sobre los flujos de datos de Kinesis, consulte [Lectura de datos de Amazon Kinesis Data Streams](https://docs.aws.amazon.com/kinesis/latest/dev/building-consumers.html).

**nota**  
Kinesis cobra por cada partición y, para una distribución ramificada mejorada, por los datos leídos desde el flujo. Para obtener más información sobre precios, consulte [Precios de Amazon Kinesis](https://aws.amazon.com/kinesis/data-streams/pricing).

## Flujos de sondeo y procesamiento por lotes
<a name="kinesis-polling-and-batching"></a>

Lambda lee los registros del flujo de datos e invoca la función [sincrónicamente](invocation-sync.md) con un evento que contiene registros de flujo. Lambda lee los registros por lotes e invoca la función para procesar los registros del lote. Cada lote contiene registros de una única partición o flujo de datos.

Su función de Lambda es una aplicación consumidora para su flujo de datos. Procesa un lote de registros a la vez desde cada partición. Puede asignar una función Lambda a un consumidor de rendimiento compartido (iterador estándar) o a un consumidor de rendimiento dedicado con distribución ramificada mejorada.
+ **Iterador estándar:** Lambda sondea cada partición del flujo de Kinesis y busca registros a una velocidad base de una vez por segundo. Cuando hay más registros disponibles, Lambda sigue procesando lotes hasta que la función se pone al día con el flujo. El mapeo de origen de eventos comparte el rendimiento de lectura con otros consumidores de la partición.
+ **Distribución ramificada mejorada:** para minimizar la latencia y maximizar el rendimiento de lectura, cree un consumidor de flujo de datos con [distribución ramificada mejorada](https://docs.aws.amazon.com/streams/latest/dev/enhanced-consumers.html). Los consumidores con distribución ramificada mejorada obtienen una conexión dedicada a cada partición que no afecta a las demás aplicaciones que leen el flujo. Los consumidores de flujos utilizan HTTP/2 para reducir la latencia enviando los registros a Lambda a través de una conexión de larga duración y mediante la compresión de los encabezados de las solicitudes. Es posible crear un consumidor de flujos con la API [RegisterStreamConsumer](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_RegisterStreamConsumer.html) de Kinesis.

```
aws kinesis register-stream-consumer \
--consumer-name con1 \
--stream-arn arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream
```

Debería ver los siguientes datos de salida:

```
{
    "Consumer": {
        "ConsumerName": "con1",
        "ConsumerARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream/consumer/con1:1540591608",
        "ConsumerStatus": "CREATING",
        "ConsumerCreationTimestamp": 1540591608.0
    }
}
```

Para incrementar la velocidad con la que la función procesa los registros, [agregue particiones al flujo de datos](https://repost.aws/knowledge-center/kinesis-data-streams-open-shards). Lambda procesa registros en cada partición en orden. Deja de procesar registros adicionales en una partición si la función devuelve un error. Al haber más particiones, se procesan más lotes simultáneamente, lo que reduce el impacto de los errores de simultaneidad.

Si la función no puede aumentar para administrar el número total de lotes simultáneos, [solicite un aumento de cuota](https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html) o [reserve la simultaneidad](configuration-concurrency.md) para la función.

De forma predeterminada, Lambda invoca su función tan pronto como los registros estén disponibles. Si el lote que Lambda lee del origen de eventos solo tiene un registro, Lambda envía solo un registro a la función. Para evitar invocar la función con un número de registros pequeño, puede indicar al origen de eventos que almacene en búfer registros durante hasta 5 minutos configurando un *plazo de procesamiento por lotes*. Antes de invocar la función, Lambda continúa leyendo los registros del origen de eventos hasta que haya recopilado un lote completo, venza el plazo de procesamiento por lotes o el lote alcance el límite de carga de 6 MB. Para obtener más información, consulte [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

**aviso**  
Las asignaciones de orígenes de eventos de Lambda procesan cada evento al menos una vez, y puede producirse un procesamiento duplicado de registros. Para evitar posibles problemas relacionados con la duplicación de eventos, le recomendamos encarecidamente que haga que el código de la función sea idempotente. Para obtener más información, consulte [¿Cómo puedo hacer que mi función de Lambda sea idempotente?](https://repost.aws/knowledge-center/lambda-function-idempotent) en el Centro de conocimientos de AWS.

Lambda no espera a que se completen las [extensiones](lambda-extensions.md) configuradas antes de enviar el siguiente lote para su procesamiento. En otras palabras, las extensiones pueden seguir ejecutándose mientras Lambda procesa el siguiente lote de registros. Esto puede provocar problemas de limitación si infringe alguno de los ajustes o límites de [simultaneidad](lambda-concurrency.md) de la cuenta. Para detectar si se trata de un posible problema, supervise sus funciones y compruebe si ve [métricas de simultaneidad](monitoring-concurrency.md#general-concurrency-metrics) más elevadas de lo esperado para la asignación de orígenes de eventos. Debido a los tiempos cortos entre invocaciones, Lambda puede informar brevemente un uso de simultaneidad superior al número de particiones. Esto puede ser cierto incluso para las funciones de Lambda sin extensiones.

Defina la configuración [ParallelizationFactor](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-ParallelizationFactor) para procesar una partición de un flujo de datos de Kinesis con más de una invocación de Lambda simultáneamente. Puede especificar el número de lotes simultáneos que Lambda sondea desde una partición a través de un factor de paralelización de 1 (predeterminado) a 10. Por ejemplo, cuando establece `ParallelizationFactor` en 2, puede tener un máximo de 200 invocaciones de Lambda simultáneas para procesar 100 particiones de datos de Kinesis (aunque, en la práctica, es posible que observe diferentes valores para la métrica `ConcurrentExecutions`). Esto ayuda a escalar verticalmente el rendimiento de procesamiento cuando el volumen de datos es volátil y el `IteratorAge` es alto. Cuando aumenta el número de lotes simultáneos por partición, Lambda sigue garantizando el procesamiento en orden a nivel de clave de partición.

También puede utilizar `ParallelizationFactor` con la agregación de Kinesis. El comportamiento de la asignación de orígenes de eventos depende de si utiliza la [distribución ramificada mejorada](https://docs.aws.amazon.com/streams/latest/dev/enhanced-consumers.html):
+ **Sin distribución ramificada mejorada**: todos los eventos incluidos en un evento agregado deben tener la misma clave de partición. La clave de partición también debe coincidir con la del evento agregado. Si los eventos incluidos en el evento agregado tienen claves de partición diferentes, Lambda no puede garantizar el procesamiento de los eventos ordenados por clave de partición.
+ **Con distribución ramificada mejorada**: en primer lugar, Lambda decodifica el evento agregado en sus eventos individuales. El evento agregado puede tener una clave de partición diferente a la de los eventos que contiene. Sin embargo, los eventos que no se corresponden con la clave de partición [se eliminan y se pierden](https://github.com/awslabs/kinesis-aggregation/blob/master/potential_data_loss.md). Lambda no procesa estos eventos ni los envía a un destino de error configurado.

## Evento de ejemplo
<a name="services-kinesis-event-example"></a>

**Example**  

```
{
    "Records": [
        {
            "kinesis": {
                "kinesisSchemaVersion": "1.0",
                "partitionKey": "1",
                "sequenceNumber": "49590338271490256608559692538361571095921575989136588898",
                "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==",
                "approximateArrivalTimestamp": 1545084650.987
            },
            "eventSource": "aws:kinesis",
            "eventVersion": "1.0",
            "eventID": "shardId-000000000006:49590338271490256608559692538361571095921575989136588898",
            "eventName": "aws:kinesis:record",
            "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-role",
            "awsRegion": "us-east-2",
            "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream"
        },
        {
            "kinesis": {
                "kinesisSchemaVersion": "1.0",
                "partitionKey": "1",
                "sequenceNumber": "49590338271490256608559692540925702759324208523137515618",
                "data": "VGhpcyBpcyBvbmx5IGEgdGVzdC4=",
                "approximateArrivalTimestamp": 1545084711.166
            },
            "eventSource": "aws:kinesis",
            "eventVersion": "1.0",
            "eventID": "shardId-000000000006:49590338271490256608559692540925702759324208523137515618",
            "eventName": "aws:kinesis:record",
            "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-role",
            "awsRegion": "us-east-2",
            "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream"
        }
    ]
}
```

# Procesamiento de registros de Amazon Kinesis Data Streams
<a name="services-kinesis-create"></a>

Para procesar los registros de Amazon Kinesis Data Streams con Lambda, cree una asignación de orígenes de eventos de Lambda. Puede asignar una función de Lambda a un iterador estándar o a un consumidor de distribución ramificada mejorada. Para obtener más información, consulte [Flujos de sondeo y procesamiento por lotes](with-kinesis.md#kinesis-polling-and-batching).

## Crear la asignación de orígenes de eventos de Kinesis
<a name="services-kinesis-eventsourcemapping"></a>

Para invocar la función de Lambda con registros del flujo de datos, cree una [asignación de orígenes de eventos](invocation-eventsourcemapping.md). Puede crear varias asignaciones de orígenes de eventos para procesar los mismos datos con distintas funciones de Lambda o para procesar elementos de varios flujos de datos con una sola función. Al procesar elementos de múltiples flujos de datos, cada lote solo contendrá registros de una única partición o flujo.

Puede configurar las asignaciones de orígenes de eventos para procesar los registros de un flujo en una Cuenta de AWS diferente. Para obtener más información, consulte [Creación de asignaciones de orígenes de eventos entre cuentas](#services-kinesis-eventsourcemapping-cross-account).

Antes de crear una asignación de orígenes de eventos, debe dar permiso a la función de Lambda para leer desde un flujo de datos de Kinesis. Lambda necesita los siguientes permisos para administrar los recursos relacionados con el flujo de datos de Kinesis:
+ [kinesis:DescribeStream](https://docs.aws.amazon.com/lambda/latest/api/API_DescribeStream.html)
+ [kinesis:DescribeStreamSummary](https://docs.aws.amazon.com/lambda/latest/api/API_DescribeStreamSummary.html)
+ [kinesis:GetRecords](https://docs.aws.amazon.com/lambda/latest/api/API_GetRecords.html)
+ [kinesis:GetShardIterator](https://docs.aws.amazon.com/lambda/latest/api/API_GetShardIterator.html)
+ [kinesis:ListShards](https://docs.aws.amazon.com/lambda/latest/api/API_ListShards.html)
+ [kinesis:SubscribeToShard](https://docs.aws.amazon.com/lambda/latest/api/API_SubscribeToShard.html)

La política administrada de AWS [AWSLambdaKinesisExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaKinesisExecutionRole.html) incluye estos permisos. Agregue esta política administrada a la función, tal como se describe en el siguiente procedimiento.

**nota**  
No necesita el permiso `kinesis:ListStreams` para crear y administrar las asignaciones de orígenes de eventos para Kinesis. Sin embargo, si crea una asignación de orígenes de eventos en la consola y no tiene este permiso, no podrá seleccionar una transmisión de Kinesis de la lista desplegable, y la consola mostrará un error. Para crear la asignación de orígenes de eventos, tendrá que introducir manualmente el Nombre de recurso de Amazon (ARN) de la transmisión.
Lambda realiza llamadas a las API `kinesis:GetRecords` y `kinesis:GetShardIterator` cuando vuelve a intentar las invocaciones fallidas.

------
#### [ Consola de administración de AWS ]

**Cómo añadir permisos de Kinesis a la función**

1. Abra la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) de la consola de Lambda y seleccione su función.

1. En la pestaña **Configuración**, elija **Permisos**.

1. En el panel de **Roles de ejecución**, en **Nombre del rol**, elija el enlace al rol de ejecución de la función. Este enlace abre la página para ese rol en la consola de IAM.

1. En el panel **Políticas de permisos**, elija **Agregar permisos** y, a continuación, elija **Adjuntar políticas**.

1. En el campo de búsqueda, escriba **AWSLambdaKinesisExecutionRole**.

1. Seleccione la casilla situada junto a la política y elija **Añadir permisos**.

------
#### [ AWS CLI ]

**Cómo añadir permisos de Kinesis a la función**
+ Ejecute el siguiente comando de la CLI para adjuntar la política de `AWSLambdaKinesisExecutionRole` al rol de ejecución de la función:

  ```
  aws iam attach-role-policy \
  --role-name MyFunctionRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaKinesisExecutionRole
  ```

------
#### [ AWS SAM ]

**Cómo añadir permisos de Kinesis a la función**
+ En la definición de la función, agregue la propiedad `Policies`, tal como se muestra en el siguiente ejemplo:

  ```
  Resources:
    MyFunction:
      Type: AWS::Serverless::Function
      Properties:
        CodeUri: ./my-function/
        Handler: index.handler
        Runtime: nodejs24.x
        Policies:
          - AWSLambdaKinesisExecutionRole
  ```

------

Una vez que haya configurado los permisos necesarios, cree la asignación de orígenes de eventos.

------
#### [ Consola de administración de AWS ]

**Cómo crear la asignación de orígenes de eventos para Kinesis**

1. Abra la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) de la consola de Lambda y seleccione su función.

1. En el panel **Información general de la función**, elija **Agregar desencadenador**.

1. En **Configuración del desencadenador**, para el origen, seleccione **Kinesis**.

1. Seleccione el flujo de Kinesis para el que quiere crear la asignación de orígenes de eventos y, si lo desea, un consumidor del flujo.

1. (Opcional) Edite el **tamaño del lote**, la **posición inicial** y la **ventana del lote** para la asignación de orígenes de eventos.

1. Elija **Agregar**.

Al crear la asignación de orígenes de eventos desde la consola, el rol de IAM debe tener los permisos [kinesis:ListStreams](https://docs.aws.amazon.com/lambda/latest/api/API_ListStreams.html) y [kinesis:ListStreamConsumers](https://docs.aws.amazon.com/lambda/latest/api/API_ListStreamConsumers.html).

------
#### [ AWS CLI ]

**Cómo crear la asignación de orígenes de eventos de Kinesis**
+ Ejecute el siguiente comando de la CLI para crear una asignación de orígenes de eventos de Kinesis. Elija su propio tamaño de lote y posición inicial según su caso de uso.

  ```
  aws lambda create-event-source-mapping \
  --function-name MyFunction \
  --event-source-arn arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream \
  --starting-position LATEST \
  --batch-size 100
  ```

Para especificar una ventana de procesamiento por lotes, agregue la opción `--maximum-batching-window-in-seconds`. Para obtener más información sobre el uso de este u otros parámetros, consulte [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) en la *Referencia de comandos de la AWS CLI*.

------
#### [ AWS SAM ]

**Cómo crear la asignación de orígenes de eventos de Kinesis**
+ En la definición de la función, agregue la propiedad `KinesisEvent`, tal como se muestra en el siguiente ejemplo:

  ```
  Resources:
    MyFunction:
      Type: AWS::Serverless::Function
      Properties:
        CodeUri: ./my-function/
        Handler: index.handler
        Runtime: nodejs24.x
        Policies:
          - AWSLambdaKinesisExecutionRole
        Events:
          KinesisEvent:
            Type: Kinesis
            Properties:
              Stream: !GetAtt MyKinesisStream.Arn
              StartingPosition: LATEST
              BatchSize: 100
  
    MyKinesisStream:
      Type: AWS::Kinesis::Stream
      Properties:
        ShardCount: 1
  ```

Para obtener más información sobre cómo crear una asignación de orígenes de eventos para Kinesis Data Streams en AWS SAM, consulte [Kinesis](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-kinesis.html) en la *Guía para desarrolladores de AWS Serverless Application Model*.

------

## Posición inicial de flujos y sondeo
<a name="services-kinesis-stream-start-pos"></a>

Tenga en cuenta que el sondeo de flujos durante la creación y las actualizaciones de la asignación de orígenes de eventos es, en última instancia, coherente.
+ Durante la creación de la asignación de orígenes de eventos, es posible que se demore varios minutos en iniciar el sondeo de los eventos del flujo.
+ Durante las actualizaciones de la asignación de orígenes de eventos, es posible que se demore varios minutos en detener y reiniciar el sondeo de los eventos del flujo.

Este comportamiento significa que, si especifica `LATEST` como posición inicial del flujo, la asignación de orígenes de eventos podría omitir eventos durante la creación o las actualizaciones. Para garantizar que no se pierda ningún evento, especifique la posición inicial del flujo como `TRIM_HORIZON` o `AT_TIMESTAMP`.

## Creación de asignaciones de orígenes de eventos entre cuentas
<a name="services-kinesis-eventsourcemapping-cross-account"></a>

Amazon Kinesis Data Streams admite [políticas basadas en recursos](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_identity-vs-resource.html). En consecuencia, puede procesar los datos ingeridos en un flujo en una Cuenta de AWS con una función de Lambda en otra cuenta.

Para crear una asignación de orígenes de eventos para la función de Lambda mediante un flujo de Kinesis en otra Cuenta de AWS, debe configurar el flujo mediante una política basada en recursos para conceder a la función de Lambda permiso para leer elementos. Para obtener información sobre cómo configurar la transmisión para permitir el acceso entre cuentas, consulte [Acceso compartido con funciones de AWS Lambda entre cuentas](https://docs.aws.amazon.com/streams/latest/dev/resource-based-policy-examples.html#Resource-based-policy-examples-lambda) en la *Guía para desarrolladores de Amazon Kinesis Streams*.

Una vez que haya configurado la transmisión con una política basada en recursos que otorgue a la función de Lambda los permisos necesarios, cree la asignación de orígenes de eventos mediante cualquiera de los métodos descritos en la sección anterior.

Si decide crear la asignación de orígenes de eventos mediante la consola Lambda, pegue el ARN de la transmisión directamente en el campo de entrada. Si quiere especificar un consumidor para la transmisión, al pegar el ARN del consumidor se rellena en forma automática el campo de transmisión.

# Configuración de la respuesta por lotes parcial con Kinesis Data Streams y Lambda
<a name="services-kinesis-batchfailurereporting"></a>

Al consumir y procesar datos de streaming desde un origen de eventos, de forma predeterminada, Lambda comprueba hasta el número de secuencia más alto de un lote solo cuando el lote se ha completado con éxito. Lambda trata todos los demás resultados como un error completo y vuelve a intentar procesar el lote hasta el límite de reintentos. Para permitir éxitos parciales al procesar lotes de una secuencia, active `ReportBatchItemFailures`. Permitir éxitos parciales puede ayudar a reducir el número de reintentos en un registro, aunque no impide por completo la posibilidad de reintentos en un registro exitoso.

Para activar `ReportBatchItemFailures`, incluya el valor enumerado **ReportBatchItemFailures** en la lista [FunctionResponseTypes](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-FunctionResponseTypes). Esta lista indica qué tipos de respuesta están habilitados para su función. Puede configurar esta lista al [crear](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) o [actualizar](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) una asignación de orígenes de eventos.

**nota**  
Incluso cuando el código de función devuelva respuestas de fallos parciales por lotes, Lambda no procesará estas respuestas a menos que la característica `ReportBatchItemFailures` esté activada explícitamente para la asignación de orígenes de eventos.

## Sintaxis del informe
<a name="streams-batchfailurereporting-syntax"></a>

Al configurar los informes sobre errores de elementos por lotes, la clase `StreamsEventResponse` se devuelve con una lista de errores de elementos de lote. Puede utilizar un objeto `StreamsEventResponse` para devolver el número de secuencia del primer registro fallido del lote. También puede crear su propia clase personalizada usando la sintaxis de respuesta correcta. La siguiente estructura JSON muestra la sintaxis de respuesta requerida:

```
{ 
  "batchItemFailures": [ 
        {
            "itemIdentifier": "<SequenceNumber>"
        }
    ]
}
```

**nota**  
Si la matriz `batchItemFailures` contiene varios elementos, Lambda usa el registro con el número de secuencia más bajo como punto de control. Luego Lambda vuelve a probar todos los registros a partir de ese punto de control.

## Condiciones de éxito y fracaso
<a name="streams-batchfailurereporting-conditions"></a>

Lambda trata un lote como un éxito completo si devuelve cualquiera de los siguientes elementos:
+ Una lista `batchItemFailure` vacía
+ Una lista `batchItemFailure` nula
+ Una `EventResponse` vacía
+ Un nulo `EventResponse`

Lambda trata un lote como un error completo si devuelve cualquiera de los siguientes elementos:
+ Una cadena `itemIdentifier` vacía
+ Una nula `itemIdentifier`
+ Un `itemIdentifier` con un mal nombre de clave

Lambda reintentos fallidos basados en su estrategia de reintento.

## Bisecar un lote
<a name="streams-batchfailurereporting-bisect"></a>

Si su invocación falla y `BisectBatchOnFunctionError` está activada, el lote se divide en bisectos independientemente de su configuración `ReportBatchItemFailures`.

Cuando se recibe una respuesta de éxito parcial de lote y se activan tanto `BisectBatchOnFunctionError` como `ReportBatchItemFailures`, el lote se divide en el número de secuencia devuelto y Lambda vuelve a intentar solo los registros restantes.

Para simplificar la implementación de la lógica de respuesta parcial por lotes, considere la posibilidad de utilizar la [utilidad Batch Processor](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) de PowertoolsAWS Lambda, que gestiona automáticamente estas complejidades para usted.

Estos son algunos ejemplos de código de función que devuelven la lista de IDs de mensajes fallidos del lote:

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de Kinesis con Lambda mediante .NET.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
﻿using System.Text;
using System.Text.Json.Serialization;
using Amazon.Lambda.Core;
using Amazon.Lambda.KinesisEvents;
using AWS.Lambda.Powertools.Logging;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace KinesisIntegration;

public class Function
{
    // Powertools Logger requires an environment variables against your function
    // POWERTOOLS_SERVICE_NAME
    [Logging(LogEvent = true)]
    public async Task<StreamsEventResponse> FunctionHandler(KinesisEvent evnt, ILambdaContext context)
    {
        if (evnt.Records.Count == 0)
        {
            Logger.LogInformation("Empty Kinesis Event received");
            return new StreamsEventResponse();
        }

        foreach (var record in evnt.Records)
        {
            try
            {
                Logger.LogInformation($"Processed Event with EventId: {record.EventId}");
                string data = await GetRecordDataAsync(record.Kinesis, context);
                Logger.LogInformation($"Data: {data}");
                // TODO: Do interesting work based on the new data
            }
            catch (Exception ex)
            {
                Logger.LogError($"An error occurred {ex.Message}");
                /* Since we are working with streams, we can return the failed item immediately.
                   Lambda will immediately begin to retry processing from this failed item onwards. */
                return new StreamsEventResponse
                {
                    BatchItemFailures = new List<StreamsEventResponse.BatchItemFailure>
                    {
                        new StreamsEventResponse.BatchItemFailure { ItemIdentifier = record.Kinesis.SequenceNumber }
                    }
                };
            }
        }
        Logger.LogInformation($"Successfully processed {evnt.Records.Count} records.");
        return new StreamsEventResponse();
    }

    private async Task<string> GetRecordDataAsync(KinesisEvent.Record record, ILambdaContext context)
    {
        byte[] bytes = record.Data.ToArray();
        string data = Encoding.UTF8.GetString(bytes);
        await Task.CompletedTask; //Placeholder for actual async work
        return data;
    }
}

public class StreamsEventResponse
{
    [JsonPropertyName("batchItemFailures")]
    public IList<BatchItemFailure> BatchItemFailures { get; set; }
    public class BatchItemFailure
    {
        [JsonPropertyName("itemIdentifier")]
        public string ItemIdentifier { get; set; }
    }
}
```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de Kinesis con Lambda mediante Go.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package main

import (
	"context"
	"fmt"
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handler(ctx context.Context, kinesisEvent events.KinesisEvent) (map[string]interface{}, error) {
	batchItemFailures := []map[string]interface{}{}

	for _, record := range kinesisEvent.Records {
		curRecordSequenceNumber := ""

		// Process your record
		if /* Your record processing condition here */ {
			curRecordSequenceNumber = record.Kinesis.SequenceNumber
		}

		// Add a condition to check if the record processing failed
		if curRecordSequenceNumber != "" {
			batchItemFailures = append(batchItemFailures, map[string]interface{}{"itemIdentifier": curRecordSequenceNumber})
		}
	}

	kinesisBatchResponse := map[string]interface{}{
		"batchItemFailures": batchItemFailures,
	}
	return kinesisBatchResponse, nil
}

func main() {
	lambda.Start(handler)
}
```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de Kinesis con Lambda mediante Java.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
import com.amazonaws.services.lambda.runtime.events.StreamsEventResponse;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class ProcessKinesisRecords implements RequestHandler<KinesisEvent, StreamsEventResponse> {

    @Override
    public StreamsEventResponse handleRequest(KinesisEvent input, Context context) {

        List<StreamsEventResponse.BatchItemFailure> batchItemFailures = new ArrayList<>();
        String curRecordSequenceNumber = "";

        for (KinesisEvent.KinesisEventRecord kinesisEventRecord : input.getRecords()) {
            try {
                //Process your record
                KinesisEvent.Record kinesisRecord = kinesisEventRecord.getKinesis();
                curRecordSequenceNumber = kinesisRecord.getSequenceNumber();

            } catch (Exception e) {
                /* Since we are working with streams, we can return the failed item immediately.
                   Lambda will immediately begin to retry processing from this failed item onwards. */
                batchItemFailures.add(new StreamsEventResponse.BatchItemFailure(curRecordSequenceNumber));
                return new StreamsEventResponse(batchItemFailures);
            }
        }
       
       return new StreamsEventResponse(batchItemFailures);   
    }
}
```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/blob/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de Kinesis con Lambda mediante Javascript.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
exports.handler = async (event, context) => {
  for (const record of event.Records) {
    try {
      console.log(`Processed Kinesis Event - EventID: ${record.eventID}`);
      const recordData = await getRecordDataAsync(record.kinesis);
      console.log(`Record Data: ${recordData}`);
      // TODO: Do interesting work based on the new data
    } catch (err) {
      console.error(`An error occurred ${err}`);
      /* Since we are working with streams, we can return the failed item immediately.
            Lambda will immediately begin to retry processing from this failed item onwards. */
      return {
        batchItemFailures: [{ itemIdentifier: record.kinesis.sequenceNumber }],
      };
    }
  }
  console.log(`Successfully processed ${event.Records.length} records.`);
  return { batchItemFailures: [] };
};

async function getRecordDataAsync(payload) {
  var data = Buffer.from(payload.data, "base64").toString("utf-8");
  await Promise.resolve(1); //Placeholder for actual async work
  return data;
}
```
Notificación de los errores de los elementos del lote de Kinesis con Lambda mediante TypeScript.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import {
  KinesisStreamEvent,
  Context,
  KinesisStreamHandler,
  KinesisStreamRecordPayload,
  KinesisStreamBatchResponse,
} from "aws-lambda";
import { Buffer } from "buffer";
import { Logger } from "@aws-lambda-powertools/logger";

const logger = new Logger({
  logLevel: "INFO",
  serviceName: "kinesis-stream-handler-sample",
});

export const functionHandler: KinesisStreamHandler = async (
  event: KinesisStreamEvent,
  context: Context
): Promise<KinesisStreamBatchResponse> => {
  for (const record of event.Records) {
    try {
      logger.info(`Processed Kinesis Event - EventID: ${record.eventID}`);
      const recordData = await getRecordDataAsync(record.kinesis);
      logger.info(`Record Data: ${recordData}`);
      // TODO: Do interesting work based on the new data
    } catch (err) {
      logger.error(`An error occurred ${err}`);
      /* Since we are working with streams, we can return the failed item immediately.
            Lambda will immediately begin to retry processing from this failed item onwards. */
      return {
        batchItemFailures: [{ itemIdentifier: record.kinesis.sequenceNumber }],
      };
    }
  }
  logger.info(`Successfully processed ${event.Records.length} records.`);
  return { batchItemFailures: [] };
};

async function getRecordDataAsync(
  payload: KinesisStreamRecordPayload
): Promise<string> {
  var data = Buffer.from(payload.data, "base64").toString("utf-8");
  await Promise.resolve(1); //Placeholder for actual async work
  return data;
}
```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de Kinesis con Lambda mediante PHP.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
<?php

# using bref/bref and bref/logger for simplicity

use Bref\Context\Context;
use Bref\Event\Kinesis\KinesisEvent;
use Bref\Event\Handler as StdHandler;
use Bref\Logger\StderrLogger;

require __DIR__ . '/vendor/autoload.php';

class Handler implements StdHandler
{
    private StderrLogger $logger;
    public function __construct(StderrLogger $logger)
    {
        $this->logger = $logger;
    }

    /**
     * @throws JsonException
     * @throws \Bref\Event\InvalidLambdaEvent
     */
    public function handle(mixed $event, Context $context): array
    {
        $kinesisEvent = new KinesisEvent($event);
        $this->logger->info("Processing records");
        $records = $kinesisEvent->getRecords();

        $failedRecords = [];
        foreach ($records as $record) {
            try {
                $data = $record->getData();
                $this->logger->info(json_encode($data));
                // TODO: Do interesting work based on the new data
            } catch (Exception $e) {
                $this->logger->error($e->getMessage());
                // failed processing the record
                $failedRecords[] = $record->getSequenceNumber();
            }
        }
        $totalRecords = count($records);
        $this->logger->info("Successfully processed $totalRecords records");

        // change format for the response
        $failures = array_map(
            fn(string $sequenceNumber) => ['itemIdentifier' => $sequenceNumber],
            $failedRecords
        );

        return [
            'batchItemFailures' => $failures
        ];
    }
}

$logger = new StderrLogger();
return new Handler($logger);
```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de Kinesis con Lambda mediante Python.  

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
def handler(event, context):
    records = event.get("Records")
    curRecordSequenceNumber = ""
    
    for record in records:
        try:
            # Process your record
            curRecordSequenceNumber = record["kinesis"]["sequenceNumber"]
        except Exception as e:
            # Return failed record's sequence number
            return {"batchItemFailures":[{"itemIdentifier": curRecordSequenceNumber}]}

    return {"batchItemFailures":[]}
```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de Kinesis con Lambda mediante Ruby.  

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
require 'aws-sdk'

def lambda_handler(event:, context:)
  batch_item_failures = []

  event['Records'].each do |record|
    begin
      puts "Processed Kinesis Event - EventID: #{record['eventID']}"
      record_data = get_record_data_async(record['kinesis'])
      puts "Record Data: #{record_data}"
      # TODO: Do interesting work based on the new data
    rescue StandardError => err
      puts "An error occurred #{err}"
      # Since we are working with streams, we can return the failed item immediately.
      # Lambda will immediately begin to retry processing from this failed item onwards.
      return { batchItemFailures: [{ itemIdentifier: record['kinesis']['sequenceNumber'] }] }
    end
  end

  puts "Successfully processed #{event['Records'].length} records."
  { batchItemFailures: batch_item_failures }
end

def get_record_data_async(payload)
  data = Base64.decode64(payload['data']).force_encoding('utf-8')
  # Placeholder for actual async work
  sleep(1)
  data
end
```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de Kinesis con Lambda mediante Rust.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use aws_lambda_events::{
    event::kinesis::KinesisEvent,
    kinesis::KinesisEventRecord,
    streams::{KinesisBatchItemFailure, KinesisEventResponse},
};
use lambda_runtime::{run, service_fn, Error, LambdaEvent};

async fn function_handler(event: LambdaEvent<KinesisEvent>) -> Result<KinesisEventResponse, Error> {
    let mut response = KinesisEventResponse {
        batch_item_failures: vec![],
    };

    if event.payload.records.is_empty() {
        tracing::info!("No records found. Exiting.");
        return Ok(response);
    }

    for record in &event.payload.records {
        tracing::info!(
            "EventId: {}",
            record.event_id.as_deref().unwrap_or_default()
        );

        let record_processing_result = process_record(record);

        if record_processing_result.is_err() {
            response.batch_item_failures.push(KinesisBatchItemFailure {
                item_identifier: record.kinesis.sequence_number.clone(),
            });
            /* Since we are working with streams, we can return the failed item immediately.
            Lambda will immediately begin to retry processing from this failed item onwards. */
            return Ok(response);
        }
    }

    tracing::info!(
        "Successfully processed {} records",
        event.payload.records.len()
    );

    Ok(response)
}

fn process_record(record: &KinesisEventRecord) -> Result<(), Error> {
    let record_data = std::str::from_utf8(record.kinesis.data.as_slice());

    if let Some(err) = record_data.err() {
        tracing::error!("Error: {}", err);
        return Err(Error::from(err));
    }

    let record_data = record_data.unwrap_or_default();

    // do something interesting with the data
    tracing::info!("Data: {}", record_data);

    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        // disable printing the name of the module in every log line.
        .with_target(false)
        // disabling time is handy because CloudWatch will add the ingestion time.
        .without_time()
        .init();

    run(service_fn(function_handler)).await
}
```

------

## Uso de Powertools para el procesador por lotes de AWS Lambda
<a name="services-kinesis-batchfailurereporting-powertools"></a>

La utilidad de procesamiento por lotes de Powertools para AWS Lambda gestiona de manera automática la lógica de respuesta parcial de los lotes, lo que reduce la complejidad de implementar la notificación de fallas en los lotes. Estos son algunos ejemplos del uso del procesador por lotes:

**Python**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/).
Procesamiento de registros de flujos de Kinesis Data Streams con el procesador por lotes AWS Lambda.  

```
import json
from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.batch import BatchProcessor, EventType, process_partial_response
from aws_lambda_powertools.utilities.data_classes import KinesisEvent
from aws_lambda_powertools.utilities.typing import LambdaContext

processor = BatchProcessor(event_type=EventType.KinesisDataStreams)
logger = Logger()

def record_handler(record):
    logger.info(record)
    # Your business logic here
    # Raise an exception to mark this record as failed
    
def lambda_handler(event, context: LambdaContext):
    return process_partial_response(
        event=event, 
        record_handler=record_handler, 
        processor=processor,
        context=context
    )
```

**TypeScript**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.aws.amazon.com/powertools/typescript/latest/features/batch/).
Procesamiento de registros de flujos de Kinesis Data Streams con un procesador por lotes AWS Lambda.  

```
import { BatchProcessor, EventType, processPartialResponse } from '@aws-lambda-powertools/batch';
import { Logger } from '@aws-lambda-powertools/logger';
import type { KinesisEvent, Context } from 'aws-lambda';

const processor = new BatchProcessor(EventType.KinesisDataStreams);
const logger = new Logger();

const recordHandler = async (record: any): Promise<void> => {
    logger.info('Processing record', { record });
    // Your business logic here
    // Throw an error to mark this record as failed
};

export const handler = async (event: KinesisEvent, context: Context) => {
    return processPartialResponse(event, recordHandler, processor, {
        context,
    });
};
```

**Java**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.powertools.aws.dev/lambda/java/latest/utilities/batch/).
Procesamiento de registros de flujos de Kinesis Data Streams con un procesador por lotes AWS Lambda.  

```
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.KinesisEvent;
import com.amazonaws.services.lambda.runtime.events.StreamsEventResponse;
import software.amazon.lambda.powertools.batch.BatchMessageHandlerBuilder;
import software.amazon.lambda.powertools.batch.handler.BatchMessageHandler;

public class KinesisStreamBatchHandler implements RequestHandler<KinesisEvent, StreamsEventResponse> {

    private final BatchMessageHandler<KinesisEvent, StreamsEventResponse> handler;

    public KinesisStreamBatchHandler() {
        handler = new BatchMessageHandlerBuilder()
                .withKinesisBatchHandler()
                .buildWithRawMessageHandler(this::processMessage);
    }

    @Override
    public StreamsEventResponse handleRequest(KinesisEvent kinesisEvent, Context context) {
        return handler.processBatch(kinesisEvent, context);
    }

    private void processMessage(KinesisEvent.KinesisEventRecord kinesisEventRecord, Context context) {
        // Process the stream record
    }
}
```

**.NET**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.aws.amazon.com/powertools/dotnet/utilities/batch-processing/).
Procesamiento de registros de flujos de Kinesis Data Streams con un procesador por lotes AWS Lambda.  

```
using System;
using System.Threading;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Amazon.Lambda.KinesisEvents;
using Amazon.Lambda.Serialization.SystemTextJson;
using AWS.Lambda.Powertools.BatchProcessing;

[assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]

namespace HelloWorld;

public class OrderEvent
{
    public string? OrderId { get; set; }
    public string? CustomerId { get; set; }
    public decimal Amount { get; set; }
    public DateTime OrderDate { get; set; }
}

internal class TypedKinesisRecordHandler : ITypedRecordHandler<OrderEvent> 
{
    public async Task<RecordHandlerResult> HandleAsync(OrderEvent orderEvent, CancellationToken cancellationToken)
    {
        if (string.IsNullOrEmpty(orderEvent.OrderId)) 
        {
            throw new ArgumentException("Order ID is required");
        }

        return await Task.FromResult(RecordHandlerResult.None); 
    }
}

public class Function
{
    [BatchProcessor(TypedRecordHandler = typeof(TypedKinesisRecordHandler))]
    public BatchItemFailuresResponse HandlerUsingTypedAttribute(KinesisEvent _)
    {
        return TypedKinesisStreamBatchProcessor.Result.BatchItemFailuresResponse; 
    }
}
```

# Conserve los registros de lotes descartados para unorigen de eventos de Kinesis Data Streams en Lambda
<a name="kinesis-on-failure-destination"></a>

La gestión de errores en las asignaciones de orígenes de eventos de Kinesis depende de si el error se produce antes de que se invoque la función o durante la invocación de la función:
+ **Antes de la invocación:** si una asignación de orígenes de eventos de Lambda no puede invocar la función debido a una limitación u otros problemas, lo vuelve a intentar hasta que los registros caduquen o superen la antigüedad máxima configurada en la asignación de orígenes de eventos ([MaximumRecordageInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)).
+ **Durante invocación:** [si se invoca la función pero devuelve un error, Lambda vuelve a intentarlo hasta que los registros caduquen, superen la antigüedad [máxima (MaximumRecordageInSeconds) o alcancen la cuota de reintento configurada (MaximumRetryAttempts](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)).](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRetryAttempts) En el caso de errores de función, también puede configurar [BisectBatchOnFunctionError](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-response-BisectBatchOnFunctionError), que divide un lote fallido en dos lotes más pequeños, aislando registros fallidos y evitando tiempos de espera. La división de lotes no consume la cuota de reintentos.

Si las medidas de administración de errores fallan, Lambda descarta los registros y continúa procesando lotes del flujo. Con la configuración predeterminada, esto significa que un registro incorrecto puede bloquear el procesamiento en la partición afectada durante un máximo de una semana. Para evitar esto, configure la asignación de orígenes de eventos de su función con un número razonable de reintentos y una antigüedad máxima de registro que se ajuste a su caso de uso.

## Configuración de destinos para invocaciones fallidas
<a name="kinesis-on-failure-destination-console"></a>

Para retener los registros de las invocaciones de asignación de orígenes de eventos fallidos, agregue un destino a la asignación de orígenes de eventos de su función. Cada registro enviado al destino es un documento JSON que contiene metadatos sobre la invocación fallida. Para los destinos de Amazon S3, Lambda envía también todo el registro de invocación junto con los metadatos. Puede configurar cualquier tema de Amazon SNS, cola de Amazon SQS, bucket de Amazon S3 o Kafka como destino.

Con los destinos de Amazon S3, puede utilizar la característica de [notificaciones de eventos de Amazon S3](https://docs.aws.amazon.com/) para recibir notificaciones cuando se carguen objetos en el bucket de S3 de destino. También puede configurar las notificaciones de eventos de S3 para que invoquen otra función de Lambda para realizar el procesamiento automatizado de los lotes fallidos.

Su rol de ejecución debe tener permisos para el destino:
+ **En el caso de un destino de SQS:** [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)
+ **En el caso de un destino de SNS:** [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)
+ **En el caso de un destino de S3:** [ s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) y [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/ListObjectsV2.html)
+ **Para un destino de Kafka:** [kafka-cluster:WriteData](https://docs.aws.amazon.com/msk/latest/developerguide/kafka-actions.html)

Puede configurar un tema de Kafka como destino en caso de error para las asignaciones de orígenes de eventos de Kafka. Cuando Lambda no puede procesar los registros tras agotar los reintentos, o cuando los registros superan la antigüedad máxima, Lambda envía los registros fallidos al tema de Kafka especificado para su posterior procesamiento. Consulte [Uso de un tema de Kafka como destino en caso de error](kafka-on-failure-destination.md).

Si tiene activado el cifrado con su propia clave de KMS para un destino de S3, el rol de ejecución de la función también debe tener permiso para llamar a [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html). Si la clave de KMS y el destino del bucket de S3 están en una cuenta diferente a la de su función de Lambda y rol de ejecución, configure la clave de KMS para que confíe en el rol de ejecución y permita kms:GenerateDataKey.

Para configurar un destino en caso de error mediante la consola, siga estos pasos:

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija una función.

1. En **Descripción general de la función**, elija **Agregar destino**.

1. En **Origen**, elija **Invocación de asignación de orígenes de eventos**.

1. Para la **Asignación de orígenes de eventos**, elija un origen de eventos que esté configurado para esta función.

1. En **Condición**, seleccione **En caso de error**. Para las invocaciones de asignación de orígenes de eventos, esta es la única condición aceptada.

1. En **Tipo de destino**, elija el tipo de destino al que Lambda envía los registros de invocación.

1. En **Destino**, elija un recurso.

1. Seleccione **Save**.

También puede configurar un destino en caso de error mediante la AWS Command Line Interface (AWS CLI). Por ejemplo, el siguiente comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) agrega una asignación de orígenes de eventos con un destino de SQS en caso de error a `MyFunction`:

```
aws lambda create-event-source-mapping \
--function-name "MyFunction" \
--event-source-arn arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream \
--destination-config '{"OnFailure": {"Destination": "arn:aws:sqs:us-east-1:123456789012:dest-queue"}}'
```

El siguiente comando [update-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) actualiza una asignación de orígenes de eventos para enviar registros de invocación fallida a un destino de SNS después de dos intentos de reintento, o si los registros tienen más de una hora de antigüedad.

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--maximum-retry-attempts 2 \
--maximum-record-age-in-seconds 3600 \
--destination-config '{"OnFailure": {"Destination": "arn:aws:sns:us-east-1:123456789012:dest-topic"}}'
```

La configuración actualizada se aplica de forma asincrónica y no se refleja en la salida hasta que se completa el proceso. Utilice el comando [get-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-event-source-mapping.html) para ver el estado actual.

Para eliminar un destino, introduzca una cadena vacía como argumento del parámetro `destination-config`:

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--destination-config '{"OnFailure": {"Destination": ""}}'
```

### Prácticas recomendadas de seguridad para destinos de Amazon S3
<a name="kinesis-s3-destination-security"></a>

Eliminar un bucket de S3 que está configurado como destino sin eliminar el destino de la configuración de la función puede suponer un riesgo de seguridad. Si otro usuario conoce el nombre del bucket de destino, puede volver a crear el bucket en su Cuenta de AWS. Los registros de las invocaciones fallidas se enviarán a su bucket, lo que podría exponer los datos de su función.

**aviso**  
Para asegurarse de que los registros de invocación de su función no se puedan enviar a un bucket de S3 de otra Cuenta de AWS, agregue una condición al rol de ejecución de la función que limite los permisos `s3:PutObject` a los buckets de su cuenta. 

En el siguiente ejemplo, se muestra una política de IAM que limita los permisos `s3:PutObject` de la función a los buckets de la cuenta. Esta política también otorga a Lambda el permiso `s3:ListBucket` que necesita para usar un bucket de S3 como destino.

```
{
    "Version": "2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "S3BucketResourceAccountWrite",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::*/*",
                "arn:aws:s3:::*"
            ],
            "Condition": {
                "StringEquals": {
                    "s3:ResourceAccount": "111122223333"
                }
            }
        }
    ]
}
```

Para agregar una política de permisos al rol de ejecución de su función mediante la Consola de administración de AWS o la AWS CLI, consulte las instrucciones de los siguientes procedimientos:

------
#### [ Console ]

**Cómo agregar una política de permisos al rol de ejecución de la función (consola)**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función de Lambda cuyo rol de ejecución desee modificar.

1. En la pestaña **Configuración**, elija **Permisos**.

1. En la pestaña **Rol de ejecución**, seleccione el **nombre del rol** de la función para abrir la página de la consola de IAM del rol.

1. Agregue una política de permisos al rol de la siguiente manera:

   1. En el panel **Política de permisos**, elija **Agregar permisos** y seleccione **Crear política insertada**.

   1. En el **editor de políticas**, seleccione **JSON**.

   1. Pegue la política que desee agregar en el editor (sustituyendo el JSON existente) y, a continuación, seleccione **Siguiente**.

   1. En **Detalles de política**, ingrese un **Nombre de política**.

   1. Seleccione **Crear política**.

------
#### [ AWS CLI ]

**Cómo agregar una política de permisos al rol de ejecución de la función (CLI)**

1. Cree un documento de política de JSON con los permisos necesarios y guárdelo en un directorio local.

1. Utilice el comando de la CLI de IAM `put-role-policy` para agregar permisos al rol de ejecución de la función. Ejecute el siguiente comando desde el directorio en el que guardó el documento de política JSON y sustituya el nombre del rol, el nombre de la política y el documento de política por sus propios valores.

   ```
   aws iam put-role-policy \
   --role-name my_lambda_role \
   --policy-name LambdaS3DestinationPolicy \
   --policy-document file://my_policy.json
   ```

------

### Ejemplo de registro de invocación de Amazon SNS y Amazon SQS
<a name="kinesis-on-failure-destination-example-sns-sqs"></a>

El siguiente ejemplo muestra lo que Lambda envía a un destino de tema de SNS o cola de SQS cuando se produce un error en la invocación de un origen de eventos de Kafka. Como Lambda envía solo los metadatos para estos tipos de destino, utilice los campos `streamArn`, `shardId`, `startSequenceNumber` y `endSequenceNumber` para obtener el registro original completo. Todos los campos que se muestran en la propiedad `KinesisBatchInfo` siempre estarán presentes.

```
{
    "requestContext": {
        "requestId": "c9b8fa9f-5a7f-xmpl-af9c-0c604cde93a5",
        "functionArn": "arn:aws:lambda:us-east-2:123456789012:function:myfunction",
        "condition": "RetryAttemptsExhausted",
        "approximateInvokeCount": 1
    },
    "responseContext": {
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "version": "1.0",
    "timestamp": "2019-11-14T00:38:06.021Z",
    "KinesisBatchInfo": {
        "shardId": "shardId-000000000001",
        "startSequenceNumber": "49601189658422359378836298521827638475320189012309704722",
        "endSequenceNumber": "49601189658422359378836298522902373528957594348623495186",
        "approximateArrivalOfFirstRecord": "2019-11-14T00:38:04.835Z",
        "approximateArrivalOfLastRecord": "2019-11-14T00:38:05.580Z",
        "batchSize": 500,
        "streamArn": "arn:aws:kinesis:us-east-2:123456789012:stream/mystream"
    }
}
```

Puede utilizar esta información para recuperar los registros afectados del flujo para solucionar problemas. Los registros reales no están incluidos, por lo que debe procesar este registro y recuperarlos del flujo antes de que caduquen y se pierdan.

### Ejemplo de registro de invocación de Amazon S3
<a name="kinesis-on-failure-destination-example-sns-sqs-s3"></a>

En el siguiente ejemplo, se muestra lo que Lambda envía a un bucket de Amazon S3 cuando se produce un error en la invocación de un origen de eventos de Kinesis. Además de todos los campos del ejemplo anterior para los destinos de SQS y SNS, el campo `payload` contiene el registro de invocación original en forma de cadena JSON de escape.

```
{
    "requestContext": {
        "requestId": "c9b8fa9f-5a7f-xmpl-af9c-0c604cde93a5",
        "functionArn": "arn:aws:lambda:us-east-2:123456789012:function:myfunction",
        "condition": "RetryAttemptsExhausted",
        "approximateInvokeCount": 1
    },
    "responseContext": {
        "statusCode": 200,
        "executedVersion": "$LATEST",
        "functionError": "Unhandled"
    },
    "version": "1.0",
    "timestamp": "2019-11-14T00:38:06.021Z",
    "KinesisBatchInfo": {
        "shardId": "shardId-000000000001",
        "startSequenceNumber": "49601189658422359378836298521827638475320189012309704722",
        "endSequenceNumber": "49601189658422359378836298522902373528957594348623495186",
        "approximateArrivalOfFirstRecord": "2019-11-14T00:38:04.835Z",
        "approximateArrivalOfLastRecord": "2019-11-14T00:38:05.580Z",
        "batchSize": 500,
        "streamArn": "arn:aws:kinesis:us-east-2:123456789012:stream/mystream"
    },
    "payload": "<Whole Event>" // Only available in S3
}
```

El objeto de S3 que contiene el registro de invocación utiliza la siguiente convención de nomenclatura:

```
aws/lambda/<ESM-UUID>/<shardID>/YYYY/MM/DD/YYYY-MM-DDTHH.MM.SS-<Random UUID>
```

# Implementación del procesamiento con estado de Kinesis Data Streams en Lambda
<a name="services-kinesis-windows"></a>

Las funciones de Lambda pueden ejecutar aplicaciones de procesamiento de flujo continuo. Una secuencia representa datos ilimitados que fluyen de forma continua a través de su aplicación. Para analizar la información de esta entrada de actualización continua, puede enlazar los registros incluidos mediante una ventana definida en términos de tiempo.

Las ventanas de salto constante son ventanas de tiempo distintas que se abren y cierran a intervalos regulares. De forma predeterminada, las invocaciones de Lambda no tienen estado: no se pueden utilizar para procesar datos en múltiples invocaciones continuas sin una base de datos externa. Sin embargo, con las ventanas de salto constante, puede mantener su estado en todas las invocaciones. Este estado contiene el resultado agregado de los mensajes procesados previamente para la ventana actual. Su estado puede ser un máximo de 1 MB por partición. Si supera ese tamaño, Lambda finaliza la ventana antes de tiempo.

Cada registro de una secuencia pertenece a un periodo específico. Lambda procesará cada registro al menos una vez, pero no garantiza que cada registro se procese solo una vez. En casos excepcionales, como el manejo de errores, es posible que algunos registros se procesen más de una vez. Los registros siempre se procesan en orden la primera vez. Si los registros se procesan más de una vez, es posible que lo hagan de forma desordenada.

## Agregación y procesamiento
<a name="streams-tumbling-processing"></a>

Su función administrada por el usuario se invoca tanto para la agregación como para procesar los resultados finales de esa agregación. Lambda agrega todos los registros recibidos en la ventana. Puede recibir estos registros en varios lotes, cada uno como una invocación independiente. Cada invocación recibe un estado. Por lo tanto, al usar las ventanas de salto constante, su respuesta de la función de Lambda debe contener una propiedad de `state`. Si la respuesta no contiene una propiedad de `state`, Lambda considera que esto es una invocación fallida. Para satisfacer esta condición, la función puede devolver un objeto de `TimeWindowEventResponse`, que tiene la siguiente forma JSON:

**Example `TimeWindowEventResponse`Valores**  

```
{
    "state": {
        "1": 282,
        "2": 715
    },
    "batchItemFailures": []
}
```

**nota**  
Para las funciones Java, se recomienda utilizar un `Map<String, String>` para representar el estado.

Al final de la ventana, el indicador `isFinalInvokeForWindow` está configurado en `true` para indicar que este es el estado final y que está listo para su procesamiento. Después del procesamiento, la ventana se completa y su invocación final se completa, y luego se elimina el estado.

Al final de la ventana, Lambda utiliza el procesamiento final para las acciones en los resultados de agregación. Su procesamiento final se invoca sincrónicamente. Después de la invocación exitosa, los puntos de control de la función, el número de secuencia y el procesamiento de flujo continúa. Si la invocación no tiene éxito, su función de Lambda suspende el procesamiento posterior hasta una invocación exitosa.

**Example KinesisTimeWindowEvent**  

```
{
    "Records": [
        {
            "kinesis": {
                "kinesisSchemaVersion": "1.0",
                "partitionKey": "1",
                "sequenceNumber": "49590338271490256608559692538361571095921575989136588898",
                "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==",
                "approximateArrivalTimestamp": 1607497475.000
            },
            "eventSource": "aws:kinesis",
            "eventVersion": "1.0",
            "eventID": "shardId-000000000006:49590338271490256608559692538361571095921575989136588898",
            "eventName": "aws:kinesis:record",
            "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-kinesis-role",
            "awsRegion": "us-east-1",
            "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/lambda-stream"
        }
    ],
    "window": {
        "start": "2020-12-09T07:04:00Z",
        "end": "2020-12-09T07:06:00Z"
    },
    "state": {
        "1": 282,
        "2": 715
    },
    "shardId": "shardId-000000000006",
    "eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/lambda-stream",
    "isFinalInvokeForWindow": false,
    "isWindowTerminatedEarly": false
}
```

## Configuración
<a name="streams-tumbling-config"></a>

Puede configurar ventanas de salto constante al crear o actualizar una asignación de orígenes de eventos. Para configurar una ventana de saltos de tamaño constante, especifique la ventana en segundos ([TumblingWindowInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-TumblingWindowInSeconds)). El siguiente comando de ejemplo AWS Command Line Interface (AWS CLI) crea una asignación de origen de eventos de streaming que tiene una ventana de salto constante de 120 segundos. Se nombra la función de Lambda definida para la agregación y el procesamiento se llama `tumbling-window-example-function`.

```
aws lambda create-event-source-mapping \
--event-source-arn arn:aws:kinesis:us-east-1:123456789012:stream/lambda-stream \
--function-name tumbling-window-example-function \
--starting-position TRIM_HORIZON \
--tumbling-window-in-seconds 120
```

Lambda determina los límites de la ventana de salto constante en función de la hora en que se insertaron los registros en la secuencia. Todos los registros tienen una marca de hora aproximada disponible que Lambda utiliza en las determinaciones de límites.

Las agregaciones de ventanas de saltos constantes no admiten el reendurecimiento. Cuando una partición termina, Lambda considera la ventana actual como cerrada y las particiones secundarias comienzan su propia ventana en un estado renovado. Cuando no se agrega ningún registro nuevo a la ventana actual, Lambda espera hasta 2 minutos antes de considerar que la ventana ha terminado. Esto ayuda a garantizar que la función lea todos los registros de la ventana actual, incluso si los registros se agregan de forma intermitente.

Ventanas de saltos constantes son totalmente compatibles con las directivas de reintento existentes `maxRetryAttempts` y `maxRecordAge`.

**Example Handler.py: agregación y procesamiento**  
La siguiente función de Python muestra cómo agregar y luego procesar su estado final:  

```
def lambda_handler(event, context):
    print('Incoming event: ', event)
    print('Incoming state: ', event['state'])

#Check if this is the end of the window to either aggregate or process.
    if event['isFinalInvokeForWindow']:
        # logic to handle final state of the window
        print('Destination invoke')
    else:
        print('Aggregate invoke')

#Check for early terminations
    if event['isWindowTerminatedEarly']:
        print('Window terminated early')

    #Aggregation logic
    state = event['state']
    for record in event['Records']:
        state[record['kinesis']['partitionKey']] = state.get(record['kinesis']['partitionKey'], 0) + 1

    print('Returning state: ', state)
    return {'state': state}
```

# Parámetros de Lambda para las asignaciones de orígenes de eventos de Amazon Kinesis Data Streams
<a name="services-kinesis-parameters"></a>

Todos los tipos de asignación de orígenes de eventos de Lambda comparten las mismas operaciones [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) y [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) de la API. Sin embargo, solo algunos de los parámetros se aplican a Amazon Kinesis.


| Parámetro | Obligatoria | Predeterminado | Notas | 
| --- | --- | --- | --- | 
|  [BatchSize](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-BatchSize)  |  N  |  100  |  Máximo: 10 000  | 
|  [BisectBatchOnFunctionError](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-BisectBatchOnFunctionError)  |  N  |  false  |  Ninguno | 
|  [DestinationConfig](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-DestinationConfig)  |  N  | N/A |  Destino de tema de la cola de Amazon SQS o de Amazon SNS para registros descartados Para obtener más información, consulte [Configuración de destinos para invocaciones fallidas](kinesis-on-failure-destination.md#kinesis-on-failure-destination-console).  | 
|  [Enabled (Habilitado)](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-Enabled)  |  N  |  true  |  Ninguno | 
|  [EventSourceArn](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-EventSourceArn)  |  Y  | N/A |  ARN del flujo de datos o un consumidor de flujos  | 
|  [FunctionName](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-FunctionName)  |  Y  | N/A |  Ninguno | 
|  [FunctionResponseTypes](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-FunctionResponseTypes)  |  N  |  N/A |  Para permitir que la función informe de errores específicos de un lote, incluya el valor `ReportBatchItemFailures` en `FunctionResponseTypes`. Para obtener más información, consulte [Configuración de la respuesta por lotes parcial con Kinesis Data Streams y Lambda](services-kinesis-batchfailurereporting.md).  | 
|  [MaximumBatchingWindowInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumBatchingWindowInSeconds)  |  N  |  0  |  Ninguno | 
|  [MaximumRecordAgeInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)  |  N  |  -1  |  -1 significa infinito: Lambda no descarta registros (se sigue aplicando la [configuración de retención de datos de Kinesis Data Streams](https://docs.aws.amazon.com/streams/latest/dev/kinesis-extended-retention.html)). Mínimo: -1 Máximo: 604 800  | 
|  [MaximumRetryAttempts](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRetryAttempts)  |  N  |  -1  |  -1 significa infinito: se vuelven a intentar los registros que han producido error hasta que caduque el registro Mínimo: -1 Máximo: 10 000  | 
|  [ParallelizationFactor](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-ParallelizationFactor)  |  N  |  1  |  Máximo: 10  | 
|  [StartingPosition](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-StartingPosition)  |  Y  |  N/A |  AT\$1TIMESTAMP, TRIM\$1HORIZON o LATEST  | 
|  [StartingPositionTimestamp](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-StartingPositionTimestamp)  |  N  |  N/A |  Sólo es válido si StartingPosition se establece en AT\$1TIMESTAMP. El tiempo a partir del cual comenzar la lectura, en segundos de tiempo Unix  | 
|  [TumblingWindowInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-TumblingWindowInSeconds)  |  N  |  N/A |  Mínimo: 0 Máximo: 900  | 

# Uso del filtrado de eventos con una fuente de eventos de Kinesis
<a name="with-kinesis-filtering"></a>

Puede utilizar el filtrado de eventos para controlar qué registros de un flujo o una cola envía Lambda a su función. Para obtener información general sobre cómo funciona el filtrado de eventos, consulte [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md).

Esta sección se centra en el filtrado de eventos para las fuentes de eventos de Kinesis.

**nota**  
Las asignaciones de orígenes de eventos de Kinesis solo admiten el filtrado en la clave `data`.

**Topics**
+ [

## Conceptos básicos del filtrado de eventos de Kinesis
](#filtering-kinesis)
+ [

## Filtrado de registros agregados de Kinesis
](#filtering-kinesis-efo)

## Conceptos básicos del filtrado de eventos de Kinesis
<a name="filtering-kinesis"></a>

Supongamos que un productor incluye datos con formato JSON en su flujo de datos de Kinesis. Un registro de ejemplo tendría el siguiente aspecto, con los datos JSON convertidos en una cadena codificada en Base64 en el campo `data`.

```
{
    "kinesis": {
        "kinesisSchemaVersion": "1.0",
        "partitionKey": "1",
        "sequenceNumber": "49590338271490256608559692538361571095921575989136588898",
        "data": "eyJSZWNvcmROdW1iZXIiOiAiMDAwMSIsICJUaW1lU3RhbXAiOiAieXl5eS1tbS1kZFRoaDptbTpzcyIsICJSZXF1ZXN0Q29kZSI6ICJBQUFBIn0=",
        "approximateArrivalTimestamp": 1545084650.987
        },
    "eventSource": "aws:kinesis",
    "eventVersion": "1.0",
    "eventID": "shardId-000000000006:49590338271490256608559692538361571095921575989136588898",
    "eventName": "aws:kinesis:record",
    "invokeIdentityArn": "arn:aws:iam::123456789012:role/lambda-role",
    "awsRegion": "us-east-2",
    "eventSourceARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream"
}
```

Siempre que los datos que el productor incluya en el flujo sean JSON válidos, puede usar el filtrado de eventos para filtrar registros mediante la clave `data`. Supongamos que un productor incluye registros en su flujo de Kinesis en el siguiente formato JSON.

```
{
    "record": 12345,
    "order": {
        "type": "buy",
        "stock": "ANYCO",
        "quantity": 1000
        }
}
```

Para filtrar solo los registros en los que el tipo de pedido sea “comprar”, el objeto `FilterCriteria` sería el siguiente.

```
{
    "Filters": [
        {
            "Pattern": "{ \"data\" : { \"order\" : { \"type\" : [ \"buy\" ] } } }"
        }
    ]
}
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado. 

```
{
    "data": {
        "order": {
            "type": [ "buy" ]
            }
      }
}
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "data" : { "order" : { "type" : [ "buy" ] } } }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:kinesis:us-east-2:123456789012:stream/my-stream \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : { \"order\" : { \"type\" : [ \"buy\" ] } } }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : { \"order\" : { \"type\" : [ \"buy\" ] } } }"}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "data" : { "order" : { "type" : [ "buy" ] } } }'
```

------

Para filtrar correctamente los eventos de orígenes de Kinesis, tanto el campo de datos como los criterios de filtro del campo de datos deben estar en un formato JSON válido. Si el formato JSON de alguno de los campos no es válido, Lambda elimina el mensaje o genera una excepción. En la siguiente tabla se resume el comportamiento específico: 


| Formato de los datos entrantes | Formato del patrón de filtro para las propiedades de datos | Acción resultante | 
| --- | --- | --- | 
|  JSON válido  |  JSON válido  |  Lambda filtra en función de los criterios de filtro.  | 
|  JSON válido  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  JSON válido  |  No JSON  |  Lambda genera una excepción al crear o actualizar la asignación de origen de eventos. El formato JSON del patrón de filtro de las propiedades de datos debe ser válido.  | 
|  No JSON  |  JSON válido  |  Lambda elimina el registro.  | 
|  No JSON  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  No JSON  |  No JSON  |  Lambda genera una excepción al crear o actualizar la asignación de origen de eventos. El formato JSON del patrón de filtro de las propiedades de datos debe ser válido.  | 

## Filtrado de registros agregados de Kinesis
<a name="filtering-kinesis-efo"></a>

Con Kinesis, puede agregar varios registros en un solo registro de Kinesis Data Streams para aumentar el rendimiento de sus datos. Lambda solo puede aplicar criterios de filtro a los registros agregados cuando se utiliza la [distribución mejorada](https://docs.aws.amazon.com/streams/latest/dev/enhanced-consumers.html) de Kinesis. El filtrado de registros agregados con Kinesis estándar no es compatible. Al utilizar la distribución mejorada, usted configura un consumidor de rendimiento dedicado de Kinesis para que actúe como desencadenador de la función de Lambda. A continuación, Lambda filtra los registros agregados y solo pasa los registros que cumplen los criterios de filtro.

Para obtener más información sobre la agregación de registros de Kinesis, consulte la sección [Agregación](https://docs.aws.amazon.com/streams/latest/dev/kinesis-kpl-concepts.html#kinesis-kpl-concepts-aggretation) de la página de conceptos clave de la Kinesis Producer Library (KPL). Para obtener más información sobre el uso de Lambda con la expansión mejorada de Kinesis, consulte [Aumento del rendimiento del procesamiento de transmisiones en tiempo real con la distribución mejorada de Amazon Kinesis Data Streams y AWS Lambda](https://aws.amazon.com/blogs/compute/increasing-real-time-stream-processing-performance-with-amazon-kinesis-data-streams-enhanced-fan-out-and-aws-lambda/) en el blog de informática de AWS.

# Tutorial: Uso de Lambda con Kinesis Data Streams
<a name="with-kinesis-example"></a>

En este tutorial, creará una función de Lambda para consumir eventos de un flujo de datos de Amazon Kinesis. 

1. Una aplicación personalizada escribe los registros en el flujo.

1. AWS Lambda sondea el flujo y, cuando detecta registros nuevos en él, llama a la función de Lambda.

1. AWS Lambda ejecuta la función de Lambda asumiendo el rol de ejecución que se especificó en el momento de crear la función de Lambda.

## Requisitos previos
<a name="with-kinesis-prepare"></a>

### Instala la AWS Command Line Interface
<a name="install_aws_cli"></a>

Si aún no ha instalado AWS Command Line Interface, siga los pasos que se indican en [Instalación o actualización de la versión más reciente de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalarlo.

El tutorial requiere un intérprete de comandos o un terminal de línea de comando para ejecutar los comandos. En Linux y macOS, use su administrador de intérprete de comandos y paquetes preferido.

**nota**  
En Windows, algunos comandos de la CLI de Bash que se utilizan habitualmente con Lambda (por ejemplo, `zip`) no son compatibles con los terminales integrados del sistema operativo. Para obtener una versión de Ubuntu y Bash integrada con Windows, [instale el subsistema de Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Creación del rol de ejecución
<a name="with-kinesis-example-create-iam-role"></a>

Cree el [rol de ejecución](lambda-intro-execution-role.md) que concederá a su función permiso para obtener acceso a los recursos de AWS.

**Para crear un rol de ejecución**

1. Abra la [página Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Elija **Crear rol**.

1. Cree un rol con las propiedades siguientes.
   + **Trusted entity (Entidad de confianza** – **AWS Lambda**.
   + **Permisos**: **AWSLambdaKinesisExecutionRole**.
   + **Role name (Nombre de rol** – **lambda-kinesis-role**.

La política **AWSLambdaKinesisExecutionRole** tiene permisos que la función necesita para leer elementos de Kinesis y escribir registros a Registros de CloudWatch.

## Creación de la función
<a name="with-kinesis-example-create-function"></a>

Cree una función de Lambda: que procese los mensajes de Kinesis. El código de función registra el ID del evento y los datos del evento del registro de Kinesis en Registros de CloudWatch.

En este tutorial, se utiliza el tiempo de ejecución de Node.js 24, pero también hemos proporcionado archivos de código de ejemplo en otros lenguajes de tiempo de ejecución. Puede seleccionar la pestaña del siguiente cuadro para ver el código del tiempo de ejecución que le interesa. El código JavaScript que usará en este paso está en el primer ejemplo que se muestra en la pestaña **JavaScript**.

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Uso de un evento de Kinesis con Lambda mediante .NET.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
﻿using System.Text;
using Amazon.Lambda.Core;
using Amazon.Lambda.KinesisEvents;
using AWS.Lambda.Powertools.Logging;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace KinesisIntegrationSampleCode;

public class Function
{
    // Powertools Logger requires an environment variables against your function
    // POWERTOOLS_SERVICE_NAME
    [Logging(LogEvent = true)]
    public async Task FunctionHandler(KinesisEvent evnt, ILambdaContext context)
    {
        if (evnt.Records.Count == 0)
        {
            Logger.LogInformation("Empty Kinesis Event received");
            return;
        }

        foreach (var record in evnt.Records)
        {
            try
            {
                Logger.LogInformation($"Processed Event with EventId: {record.EventId}");
                string data = await GetRecordDataAsync(record.Kinesis, context);
                Logger.LogInformation($"Data: {data}");
                // TODO: Do interesting work based on the new data
            }
            catch (Exception ex)
            {
                Logger.LogError($"An error occurred {ex.Message}");
                throw;
            }
        }
        Logger.LogInformation($"Successfully processed {evnt.Records.Count} records.");
    }

    private async Task<string> GetRecordDataAsync(KinesisEvent.Record record, ILambdaContext context)
    {
        byte[] bytes = record.Data.ToArray();
        string data = Encoding.UTF8.GetString(bytes);
        await Task.CompletedTask; //Placeholder for actual async work
        return data;
    }
}
```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Uso de un evento de Kinesis con Lambda mediante Go.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package main

import (
	"context"
	"log"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handler(ctx context.Context, kinesisEvent events.KinesisEvent) error {
	if len(kinesisEvent.Records) == 0 {
		log.Printf("empty Kinesis event received")
		return nil
	}

	for _, record := range kinesisEvent.Records {
		log.Printf("processed Kinesis event with EventId: %v", record.EventID)
		recordDataBytes := record.Kinesis.Data
		recordDataText := string(recordDataBytes)
		log.Printf("record data: %v", recordDataText)
		// TODO: Do interesting work based on the new data
	}
	log.Printf("successfully processed %v records", len(kinesisEvent.Records))
	return nil
}

func main() {
	lambda.Start(handler)
}
```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Uso de un evento de Kinesis con Lambda mediante Java.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.KinesisEvent;

public class Handler implements RequestHandler<KinesisEvent, Void> {
    @Override
    public Void handleRequest(final KinesisEvent event, final Context context) {
        LambdaLogger logger = context.getLogger();
        if (event.getRecords().isEmpty()) {
            logger.log("Empty Kinesis Event received");
            return null;
        }
        for (KinesisEvent.KinesisEventRecord record : event.getRecords()) {
            try {
                logger.log("Processed Event with EventId: "+record.getEventID());
                String data = new String(record.getKinesis().getData().array());
                logger.log("Data:"+ data);
                // TODO: Do interesting work based on the new data
            }
            catch (Exception ex) {
                logger.log("An error occurred:"+ex.getMessage());
                throw ex;
            }
        }
        logger.log("Successfully processed:"+event.getRecords().size()+" records");
        return null;
    }

}
```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/blob/main/integration-kinesis-to-lambda). 
Uso de un evento de Kinesis con Lambda mediante JavaScript.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
exports.handler = async (event, context) => {
  for (const record of event.Records) {
    try {
      console.log(`Processed Kinesis Event - EventID: ${record.eventID}`);
      const recordData = await getRecordDataAsync(record.kinesis);
      console.log(`Record Data: ${recordData}`);
      // TODO: Do interesting work based on the new data
    } catch (err) {
      console.error(`An error occurred ${err}`);
      throw err;
    }
  }
  console.log(`Successfully processed ${event.Records.length} records.`);
};

async function getRecordDataAsync(payload) {
  var data = Buffer.from(payload.data, "base64").toString("utf-8");
  await Promise.resolve(1); //Placeholder for actual async work
  return data;
}
```
Uso de un evento de Kinesis con Lambda mediante TypeScript.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import {
  KinesisStreamEvent,
  Context,
  KinesisStreamHandler,
  KinesisStreamRecordPayload,
} from "aws-lambda";
import { Buffer } from "buffer";
import { Logger } from "@aws-lambda-powertools/logger";

const logger = new Logger({
  logLevel: "INFO",
  serviceName: "kinesis-stream-handler-sample",
});

export const functionHandler: KinesisStreamHandler = async (
  event: KinesisStreamEvent,
  context: Context
): Promise<void> => {
  for (const record of event.Records) {
    try {
      logger.info(`Processed Kinesis Event - EventID: ${record.eventID}`);
      const recordData = await getRecordDataAsync(record.kinesis);
      logger.info(`Record Data: ${recordData}`);
      // TODO: Do interesting work based on the new data
    } catch (err) {
      logger.error(`An error occurred ${err}`);
      throw err;
    }
    logger.info(`Successfully processed ${event.Records.length} records.`);
  }
};

async function getRecordDataAsync(
  payload: KinesisStreamRecordPayload
): Promise<string> {
  var data = Buffer.from(payload.data, "base64").toString("utf-8");
  await Promise.resolve(1); //Placeholder for actual async work
  return data;
}
```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Uso de un evento de Kinesis con Lambda mediante PHP.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
<?php

# using bref/bref and bref/logger for simplicity

use Bref\Context\Context;
use Bref\Event\Kinesis\KinesisEvent;
use Bref\Event\Kinesis\KinesisHandler;
use Bref\Logger\StderrLogger;

require __DIR__ . '/vendor/autoload.php';

class Handler extends KinesisHandler
{
    private StderrLogger $logger;
    public function __construct(StderrLogger $logger)
    {
        $this->logger = $logger;
    }

    /**
     * @throws JsonException
     * @throws \Bref\Event\InvalidLambdaEvent
     */
    public function handleKinesis(KinesisEvent $event, Context $context): void
    {
        $this->logger->info("Processing records");
        $records = $event->getRecords();
        foreach ($records as $record) {
            $data = $record->getData();
            $this->logger->info(json_encode($data));
            // TODO: Do interesting work based on the new data

            // Any exception thrown will be logged and the invocation will be marked as failed
        }
        $totalRecords = count($records);
        $this->logger->info("Successfully processed $totalRecords records");
    }
}

$logger = new StderrLogger();
return new Handler($logger);
```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Uso de un evento de Kinesis con Lambda mediante Python.  

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
import base64
def lambda_handler(event, context):

    for record in event['Records']:
        try:
            print(f"Processed Kinesis Event - EventID: {record['eventID']}")
            record_data = base64.b64decode(record['kinesis']['data']).decode('utf-8')
            print(f"Record Data: {record_data}")
            # TODO: Do interesting work based on the new data
        except Exception as e:
            print(f"An error occurred {e}")
            raise e
    print(f"Successfully processed {len(event['Records'])} records.")
```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Uso de un evento de Kinesis con Lambda mediante Ruby.  

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
require 'aws-sdk'

def lambda_handler(event:, context:)
  event['Records'].each do |record|
    begin
      puts "Processed Kinesis Event - EventID: #{record['eventID']}"
      record_data = get_record_data_async(record['kinesis'])
      puts "Record Data: #{record_data}"
      # TODO: Do interesting work based on the new data
    rescue => err
      $stderr.puts "An error occurred #{err}"
      raise err
    end
  end
  puts "Successfully processed #{event['Records'].length} records."
end

def get_record_data_async(payload)
  data = Base64.decode64(payload['data']).force_encoding('UTF-8')
  # Placeholder for actual async work
  # You can use Ruby's asynchronous programming tools like async/await or fibers here.
  return data
end
```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Consumir un evento de Kinesis con Lambda mediante Rust.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use aws_lambda_events::event::kinesis::KinesisEvent;
use lambda_runtime::{run, service_fn, Error, LambdaEvent};

async fn function_handler(event: LambdaEvent<KinesisEvent>) -> Result<(), Error> {
    if event.payload.records.is_empty() {
        tracing::info!("No records found. Exiting.");
        return Ok(());
    }

    event.payload.records.iter().for_each(|record| {
        tracing::info!("EventId: {}",record.event_id.as_deref().unwrap_or_default());

        let record_data = std::str::from_utf8(&record.kinesis.data);

        match record_data {
            Ok(data) => {
                // log the record data
                tracing::info!("Data: {}", data);
            }
            Err(e) => {
                tracing::error!("Error: {}", e);
            }
        }
    });

    tracing::info!(
        "Successfully processed {} records",
        event.payload.records.len()
    );

    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        // disable printing the name of the module in every log line.
        .with_target(false)
        // disabling time is handy because CloudWatch will add the ingestion time.
        .without_time()
        .init();

    run(service_fn(function_handler)).await
}
```

------

**Cómo crear la función**

1. Cree un directorio para el proyecto y, a continuación, cambie a ese directorio.

   ```
   mkdir kinesis-tutorial
   cd kinesis-tutorial
   ```

1. Copie el código de muestra de JavaScript en un nuevo archivo con el nombre `index.js`.

1. Cree un paquete de implementación.

   ```
   zip function.zip index.js
   ```

1. Cree una función de Lambda con el comando `create-function`.

   ```
   aws lambda create-function --function-name ProcessKinesisRecords \
   --zip-file fileb://function.zip --handler index.handler --runtime nodejs24.x \
   --role arn:aws:iam::111122223333:role/lambda-kinesis-role
   ```

## Prueba de la función de Lambda
<a name="walkthrough-kinesis-events-adminuser-create-test-function-upload-zip-test-manual-invoke"></a>

Invoque la función de Lambda manualmente mediante el comando de la CLI de `invoke` AWS Lambda y un evento de Kinesis de muestra.

**Probar la función de Lambda**

1. Copie el siguiente JSON en un archivo y guárdelo como `input.txt`. 

   ```
   {
       "Records": [
           {
               "kinesis": {
                   "kinesisSchemaVersion": "1.0",
                   "partitionKey": "1",
                   "sequenceNumber": "49590338271490256608559692538361571095921575989136588898",
                   "data": "SGVsbG8sIHRoaXMgaXMgYSB0ZXN0Lg==",
                   "approximateArrivalTimestamp": 1545084650.987
               },
               "eventSource": "aws:kinesis",
               "eventVersion": "1.0",
               "eventID": "shardId-000000000006:49590338271490256608559692538361571095921575989136588898",
               "eventName": "aws:kinesis:record",
               "invokeIdentityArn": "arn:aws:iam::111122223333:role/lambda-kinesis-role",
               "awsRegion": "us-east-2",
               "eventSourceARN": "arn:aws:kinesis:us-east-2:111122223333:stream/lambda-stream"
           }
       ]
   }
   ```

1. Utilice el comando `invoke` para enviar el evento a la función.

   ```
   aws lambda invoke --function-name ProcessKinesisRecords \
   --cli-binary-format raw-in-base64-out \
   --payload file://input.txt outputfile.txt
   ```

   La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 2*.

   La respuesta se guardará en el archivo `out.txt`.

## Creación de un flujo de Kinesis
<a name="with-kinesis-example-configure-event-source-create"></a>

Utilice el comando `create-stream ` para crear un flujo.

```
aws kinesis create-stream --stream-name lambda-stream --shard-count 1
```

Ejecute el siguiente comando `describe-stream` para obtener el ARN del flujo.

```
aws kinesis describe-stream --stream-name lambda-stream
```

Debería ver los siguientes datos de salida:

```
{
    "StreamDescription": {
        "Shards": [
            {
                "ShardId": "shardId-000000000000",
                "HashKeyRange": {
                    "StartingHashKey": "0",
                    "EndingHashKey": "340282366920746074317682119384634633455"
                },
                "SequenceNumberRange": {
                    "StartingSequenceNumber": "49591073947768692513481539594623130411957558361251844610"
                }
            }
        ],
        "StreamARN": "arn:aws:kinesis:us-east-1:111122223333:stream/lambda-stream",
        "StreamName": "lambda-stream",
        "StreamStatus": "ACTIVE",
        "RetentionPeriodHours": 24,
        "EnhancedMonitoring": [
            {
                "ShardLevelMetrics": []
            }
        ],
        "EncryptionType": "NONE",
        "KeyId": null,
        "StreamCreationTimestamp": 1544828156.0
    }
}
```

Utilice el ARN del flujo en el siguiente paso para asociar el flujo a la función de Lambda.

## Añadir un origen de eventos en AWS Lambda
<a name="with-kinesis-example-configure-event-source-add-event-source"></a>

Ejecute el siguiente comando `add-event-source` de la AWS CLI.

```
aws lambda create-event-source-mapping --function-name ProcessKinesisRecords \
--event-source  arn:aws:kinesis:us-east-1:111122223333:stream/lambda-stream \
--batch-size 100 --starting-position LATEST
```

Tenga en cuenta el ID de mapeo para un uso posterior. Para obtener una lista de mapeos de orígenes de eventos, ejecute el comando `list-event-source-mappings`.

```
aws lambda list-event-source-mappings --function-name ProcessKinesisRecords \
--event-source arn:aws:kinesis:us-east-1:111122223333:stream/lambda-stream
```

En la respuesta, puede verificar que el valor de estado es `enabled`. Las asignaciones de orígenes de eventos se pueden deshabilitar para poner en pausa temporalmente el sondeo sin perder de registros.

## Prueba de la configuración
<a name="with-kinesis-example-configure-event-source-test-end-to-end"></a>

Para probar la asignación de orígenes de eventos, agregue los registros de eventos a su flujo de Kinesis. El valor de `--data` es una cadena que la CLI codifica en base64 antes de enviarlo a Kinesis. Puede ejecutar el mismo comando más de una vez para añadir varios registros al flujo.

```
aws kinesis put-record --stream-name lambda-stream --partition-key 1 \
--data "Hello, this is a test."
```

Lambda utiliza el rol de ejecución para leer los registros desde el flujo. A continuación, se invoca la función de Lambda y se pasan lotes de registros. La función descodifica los datos de cada registro y los registra, enviando la salida a Registros de CloudWatch. Puede ver los registros en la [consola de CloudWatch](https://console.aws.amazon.com/cloudwatch).

## Eliminación de sus recursos
<a name="cleanup"></a>

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

**Cómo eliminar el rol de ejecución**

1. Abra la página [Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione el rol de ejecución que creó.

1. Elija **Eliminar**.

1. Si desea continuar, escriba el nombre del rol en el campo de entrada de texto y elija **Delete** (Eliminar).

**Cómo eliminar la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que ha creado.

1. Elija **Acciones**, **Eliminar**.

1. Escriba **confirm** en el campo de entrada de texto y elija **Delete** (Eliminar).

**Para eliminar el flujo de Kinesis**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de Kinesis en [https://console.aws.amazon.com/kinesis](https://console.aws.amazon.com/kinesis).

1. Seleccione el flujo que ha creado.

1. Elija **Actions** (Acciones), **Delete** (Eliminar).

1. Introduzca **delete** en el campo de entrada de texto.

1. Elija **Eliminar**.

# Uso de Lambda con Kubernetes
<a name="with-kubernetes"></a>

Puede implementar y administrar las funciones de Lambda con la API de Kubernetes mediante los [Controladores para Kubernetes (ACK) de AWS](https://aws-controllers-k8s.github.io/community/docs/community/overview/) o [Crossplane](https://docs.crossplane.io/latest/packages/providers/).

## Controladores para Kubernetes (ACK) de AWS
<a name="kubernetes-ack"></a>

Puede utilizar ACK para implementar y administrar recursos de AWS de la API de Kubernetes. A través de ACK, AWS proporciona controladores personalizados de código abierto para servicios de AWS, como Lambda, Amazon Elastic Container Registry (Amazon ECR), Amazon Simple Storage Service (Amazon S3) y Amazon SageMaker IA. Cada servicio de AWS compatible tiene su propio controlador personalizado. En su clúster de Kubernetes, instale un controlador para cada servicio de AWS que desee utilizar. Luego, cree una [Definición de recursos personalizada (CRD)](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/) para definir los recursos de AWS.

Se recomienda que utilice [Helm 3.8 o posterior](https://helm.sh/docs/intro/install/) a fin de instalar los controladores para ACK. Cada controlador para ACK viene con su propio gráfico de Helm, que instala el controlador, los CRD y las reglas RBAC de Kubernetes. Para obtener más información, consulte [Instalar un controlador para ACK](https://aws-controllers-k8s.github.io/community/docs/user-docs/install/) en la documentación de ACK.

Después de crear el recurso personalizado de ACK, puede utilizarlo como cualquier otro objeto de Kubernetes integrado. Por ejemplo, puede implementar y administrar las funciones de Lambda con las cadenas de herramientas de Kubernetes que prefiera, como [kubectl](https://kubernetes.io/docs/reference/kubectl/).

Estos son algunos ejemplos de casos de uso para el aprovisionamiento de funciones de Lambda a través de ACK:
+ Su organización utiliza el [control de acceso basado en roles (RBAC)](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) y [roles de IAM para cuentas de servicio](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) a fin de crear límites de permisos. Con ACK, puede reutilizar este modelo de seguridad para Lambda sin tener que crear políticas ni usuarios nuevos.
+ Su organización cuenta con un proceso de DevOps para implementar recursos en un clúster de Amazon Elastic Kubernetes Service (Amazon EKS) mediante manifiestos de Kubernetes. Con ACK, puede utilizar un manifiesto para aprovisionar funciones de Lambda sin tener que crear una infraestructura independiente en forma de plantillas de código.

Para obtener más información sobre el uso de ACK, consulte el [Tutorial de Lambda en la documentación de ACK](https://aws-controllers-k8s.github.io/community/docs/tutorials/lambda-oci-example/).

## Crossplane
<a name="kubernetes-crossplane"></a>

[Crossplane](https://docs.crossplane.io/latest/packages/providers/) es un proyecto de código abierto de la Cloud Native Computing Foundation (CNCF) que utiliza Kubernetes para administrar los recursos de la infraestructura en la nube. Con Crossplane, los desarrolladores pueden solicitar infraestructura sin necesidad de entender sus complejidades. Los equipos de plataformas mantienen el control sobre cómo se aprovisiona y administra la infraestructura.

Con Crossplane, puede implementar y administrar las funciones de Lambda con sus cadenas de herramientas de Kubernetes preferidas, como [kubectl](https://kubernetes.io/docs/reference/kubectl/) y cualquier canalización de CI/CD que pueda implementar manifiestos en Kubernetes. Estos son algunos ejemplos de casos de uso para el aprovisionamiento de funciones de Lambda a través de Crossplane:
+ Su organización quiere garantizar el cumplimiento de las normas al garantizar que las funciones de Lambda tengan las [etiquetas](configuration-tags.md) correctas. Los equipos de plataformas pueden utilizar [Composiciones de Crossplane](https://docs.crossplane.io/latest/get-started/get-started-with-composition/) para definir esta política mediante abstracciones de API. Luego, los desarrolladores pueden utilizar estas abstracciones para implementar funciones de Lambda con etiquetas.
+ Su proyecto utiliza GitOps con Kubernetes. En este modelo, Kubernetes reconcilia continuamente el repositorio de git (estado deseado) con los recursos que se ejecutan dentro del clúster (estado actual). Si hay diferencias, el proceso de GitOps realiza cambios de forma automática en el clúster. Puede utilizar GitOps con Kubernetes para implementar y administrar las funciones de Lambda a través de Crossplane, mediante herramientas y conceptos conocidos de Kubernetes, como [CRD](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/) y [Controladores](https://kubernetes.io/docs/concepts/architecture/controller/).

Para obtener más información sobre el uso de Crossplane con Lambda, consulte lo siguiente:
+ [Esquemas para Crossplane de AWS](https://github.com/awslabs/crossplane-on-eks/blob/main/examples/upbound-aws-provider/README.md#deploy-the-examples): este repositorio incluye ejemplos de cómo utilizar Crossplane para implementar recursos de AWS, incluidas las funciones de Lambda.
**nota**  
Los Esquemas para Crossplane de AWS se encuentran en fase de desarrollo activo y no deberían utilizarse en la producción.
+ [Implementación de Lambda con Amazon EKS y Crossplane](https://www.youtube.com/watch?v=m-9KLq29K4k): en este video se muestra un ejemplo avanzado de implementación de una arquitectura sin servidor de AWS con Crossplane, que explora el diseño desde la perspectiva del desarrollador y de la plataforma.

# Uso de Lambda con Amazon MQ
<a name="with-mq"></a>

**nota**  
Si desea enviar datos a un destino que no sea una función de Lambda o enriquecer los datos antes de enviarlos, consulte [Amazon EventBridge Pipes](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html) (Canalizaciones de Amazon EventBridge).

Amazon MQ es un servicio de agente de mensajes administrado para [Apache ActiveMQ](https://activemq.apache.org/) y [RabbitMQ](https://www.rabbitmq.com). Un *agente de mensajes* permite que las aplicaciones de software y los componentes se comuniquen mediante varios lenguajes de programación, sistemas operativos y protocolos de mensajería formales a través de destinos de eventos de tema o de cola.

Amazon MQ también puede administrar instancias de Amazon Elastic Compute Cloud (Amazon EC2) en su nombre instalando agentes de ActiveMQ o RabbitMQ proporcionando diferentes topologías de red y otras necesidades de infraestructura.

Puede utilizar una función de Lambda para procesar registros de su agente de mensajes de Amazon MQ. Lambda invoca su función a través de una [asignación de orígenes de eventos](invocation-eventsourcemapping.md), un recurso de Lambda que lee los mensajes de su agente e invoca la función [sincrónicamente](invocation-sync.md).

**aviso**  
Las asignaciones de orígenes de eventos de Lambda procesan cada evento al menos una vez, y puede producirse un procesamiento duplicado de registros. Para evitar posibles problemas relacionados con la duplicación de eventos, le recomendamos encarecidamente que haga que el código de la función sea idempotente. Para obtener más información, consulte [¿Cómo puedo hacer que mi función de Lambda sea idempotente?](https://repost.aws/knowledge-center/lambda-function-idempotent) en el Centro de conocimientos de AWS.

La asignación de orígenes de eventos de Amazon MQ tiene las siguientes restricciones de configuración:
+ Simultaneidad: las funciones de Lambda que utilizan una asignación de orígenes de eventos de Amazon MQ tienen una configuración de [simultaneidad](lambda-concurrency.md) máxima predeterminada. Para ActiveMQ, el servicio Lambda limita la cantidad de entornos de ejecución simultánea a cinco por cada asignación de orígenes de eventos de Amazon MQ. Para RabbitMQ, la cantidad de entornos de ejecución simultánea está limitada a uno por cada asignación de orígenes de eventos de Amazon MQ. Incluso si cambia la configuración de simultaneidad reservada o aprovisionada de la función, el servicio Lambda no ofrecerá más entornos de ejecución disponibles. Para solicitar un aumento de la simultaneidad máxima predeterminada de una sola asignación de orígenes de eventos de Amazon MQ, póngase en contacto con Soporte con el UUID de la asignación de orígenes de eventos y la región. Como los aumentos se aplican al nivel de asignación de orígenes de eventos específico, no a nivel de cuenta o región, debe solicitar manualmente un aumento de escala para cada asignación de orígenes de eventos.
+ Cuentas cruzadas: Lambda no admite el procesamiento de cuentas cruzadas. No se puede utilizar Lambda para procesar registros de un agente de mensajes de Amazon MQ que se encuentra en una Cuenta de AWS diferente.
+ Autenticación: para ActiveMQm solo se admite ActiveMQ [SimpleAuthenticationPlugin](https://activemq.apache.org/security#simple-authentication-plugin). Para RabbitMQ, solo se admite el mecanismo de autenticación [PLAIN](https://www.rabbitmq.com/access-control.html#mechanisms). Los usuarios deben utilizar AWS Secrets Manager para administrar sus credenciales. Para obtener más información acerca de la autenticación de ActiveMQ, consulte [Integración de agentes de ActiveMQ con LDAP](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/security-authentication-authorization.html) en la *Guía para desarrolladores de Amazon MQ*.
+ Cuota de conexión: los agentes de cuota de conexión tienen un número máximo de conexiones permitidas por protocolo de nivel de cable. Esta cuota se basa en el tipo de instancia del broker. Para obtener más información, consulte la sección de [Agentes](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-limits.html#broker-limits) de **Cuotas en Amazon MQ** en la *Guía para desarrolladores de Amazon MQ*.
+ Conectividad: puede crear agentes en la nube privada virtual (VPC) pública o privada. En el caso de las VPC privadas, su función de Lambda necesita acceso a la VPC para recibir mensajes. Para obtener más información, consulte [Configuración de la seguridad de la red](process-mq-messages-with-lambda.md#process-mq-messages-with-lambda-networkconfiguration) más adelante en este tema.
+ Destinos de eventos: solo se admiten los destinos de cola. Sin embargo, puede utilizar un tema virtual, que se comporta como un tema internamente mientras interactúa con Lambda como una cola. Para obtener más información, consulte [Destinos virtuales](https://activemq.apache.org/virtual-destinations) en el sitio web de Apache ActiveMQ y [Virtual Hosts](https://www.rabbitmq.com/vhosts.html) en el sitio web RabbitMQ.
+ Topología de red: para ActiveMQ, solo se admite una instancia única o agente en espera por asignación de orígenes de eventos. Para RabbitMQ, solo se admite una implementación de agente o clúster de una instancia única por asignación de orígenes de eventos. Los agentes de instancia única requieren un punto de conexión de conmutación por error. Para obtener más información acerca de estos modos de implementación de agente, consulte [Arquitectura de agente Active MQ](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-broker-architecture.html) y [Arquitectura de agente de Rabbit MQ](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/rabbitmq-broker-architecture.html) en la *Guía para desarrolladores de Amazon MQ*.
+ Protocolos: los protocolos compatibles dependen del tipo de integración de Amazon MQ.
  + Para las integraciones de ActiveMQ, Lambda consume mensajes mediante el protocolo OpenWire/Servicio de mensajes de Java (JMS). No se admiten otros protocolos para consumir mensajes. Dentro del protocolo JMS, solo [https://activemq.apache.org/components/cms/api_docs/activemqcpp-3.6.0/html/classactivemq_1_1commands_1_1_active_m_q_text_message.html](https://activemq.apache.org/components/cms/api_docs/activemqcpp-3.6.0/html/classactivemq_1_1commands_1_1_active_m_q_text_message.html) y [https://activemq.apache.org/components/cms/api_docs/activemqcpp-3.9.0/html/classactivemq_1_1commands_1_1_active_m_q_bytes_message.html](https://activemq.apache.org/components/cms/api_docs/activemqcpp-3.9.0/html/classactivemq_1_1commands_1_1_active_m_q_bytes_message.html) son compatibles. Lambda también admite las propiedades personalizadas de JMS. Para obtener más información acerca del protocolo OpenWire, consulte [OpenWire](https://activemq.apache.org/openwire.html) en el sitio web de Apache ActiveMQ.
  + Para las integraciones de RabbitMQ, Lambda consume mensajes utilizando el protocolo AMQP 0-9-1. No se admiten otros protocolos para consumir mensajes. Para obtener más información acerca de la implementación de RabbitMQ del protocolo AMQP 0-9-1, consulte la [Guía de referencia completa de AMQP 0-9-1](https://www.rabbitmq.com/amqp-0-9-1-reference.html) en el sitio web de RabbitMQ.

Lambda admite automáticamente las últimas versiones de ActiveMQ y RabbitMQ que admite Amazon MQ. Para obtener las últimas versiones compatibles, consulte [Notas de la versión de Amazon MQ](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-release-notes.html) en la *Guía para desarrolladores de Amazon MQ*.

**nota**  
De forma predeterminada, Amazon MQ tiene una ventana de mantenimiento semanal para los agentes. Durante esa ventana de tiempo, los corredores no están disponibles. Para los agentes sin espera, Lambda no puede procesar ningún mensaje durante esa ventana.

**Topics**
+ [

## Comprender el grupo de consumidores de Lambda para Amazon MQ
](#services-mq-configure)
+ [

# Configuración de orígenes de eventos de Amazon MQ para Lambda
](process-mq-messages-with-lambda.md)
+ [

# Parámetros de asignación de orígenes de eventos
](services-mq-params.md)
+ [

# Filtrar eventos de una fuente de eventos de Amazon MQ
](with-mq-filtering.md)
+ [

# Solución de problemas de asignación de orígenes de eventos de Amazon MQ
](services-mq-errors.md)

## Comprender el grupo de consumidores de Lambda para Amazon MQ
<a name="services-mq-configure"></a>

Para interactuar con Amazon MQ, Lambda crea un grupo de consumidores que puede leer de sus agentes de Amazon MQ. El grupo de consumidores se crea con el mismo ID que el UUID de asignación de orígenes de eventos.

Para los orígenes de eventos de Amazon MQ, Lambda agrupa los registros y los envía a su función en una sola carga. Para controlar el comportamiento, puede configurar el plazo de procesamiento por lotes y el tamaño del lote. Lambda extrae mensajes hasta que procesa el tamaño de carga máximo de 6 MB, el plazo de procesamiento por lotes vence o el número de registros alcanza el tamaño completo del lote. Para obtener más información, consulte [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

El grupo de consumidores recupera los mensajes como un BLOB de bytes, los codifica con base64 en una sola carga JSON y luego invoca la función. Si su función devuelve un error para cualquiera de los mensajes de un lote, Lambda reintenta todo el lote de mensajes hasta que el procesamiento sea correcto o los mensajes caduquen.

**nota**  
Si bien las funciones de Lambda suelen tener un límite de tiempo de espera máximo de 15 minutos, las asignaciones de orígenes de eventos para Amazon MSK, Apache Kafka autoadministrado, Amazon DocumentDB y Amazon MQ para ActiveMQ y RabbitMQ solo admiten funciones con límites de tiempo de espera máximos de 14 minutos. Esta restricción garantiza que la asignación de orígenes de eventos pueda gestionar correctamente los errores y reintentos de las funciones.

Puede supervisar el uso de concurrencia de una función determinada utilizando la métrica `ConcurrentExecutions` en Amazon CloudWatch. Para obtener más información acerca de la simultaneidad, consulte [Configurar la simultaneidad reservada para una función](configuration-concurrency.md).

**Example Eventos de registro de Amazon MQ**  

```
{
   "eventSource": "aws:mq",
   "eventSourceArn": "arn:aws:mq:us-east-2:111122223333:broker:test:b-9bcfa592-423a-4942-879d-eb284b418fc8",
   "messages": [
      { 
        "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1---mq---us-east-2.amazonaws.com.rproxy.goskope.com-37557-1234520418293-4:1:1:1:1", 
        "messageType": "jms/text-message",
        "deliveryMode": 1,
        "replyTo": null,
        "type": null,
        "expiration": "60000",
        "priority": 1,
        "correlationId": "myJMSCoID",
        "redelivered": false,
        "destination": { 
          "physicalName": "testQueue" 
        },
        "data":"QUJDOkFBQUE=",
        "timestamp": 1598827811958,
        "brokerInTime": 1598827811958, 
        "brokerOutTime": 1598827811959, 
        "properties": {
          "index": "1",
          "doAlarm": "false",
          "myCustomProperty": "value"
        }
      },
      { 
        "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1---mq---us-east-2.amazonaws.com.rproxy.goskope.com-37557-1234520418293-4:1:1:1:1",
        "messageType": "jms/bytes-message",
        "deliveryMode": 1,
        "replyTo": null,
        "type": null,
        "expiration": "60000",
        "priority": 2,
        "correlationId": "myJMSCoID1",
        "redelivered": false,
        "destination": { 
          "physicalName": "testQueue" 
        },
        "data":"LQaGQ82S48k=",
        "timestamp": 1598827811958,
        "brokerInTime": 1598827811958, 
        "brokerOutTime": 1598827811959, 
        "properties": {
          "index": "1",
          "doAlarm": "false",
          "myCustomProperty": "value"
        }
      }
   ]
}
```

```
{
  "eventSource": "aws:rmq",
  "eventSourceArn": "arn:aws:mq:us-east-2:111122223333:broker:pizzaBroker:b-9bcfa592-423a-4942-879d-eb284b418fc8",
  "rmqMessagesByQueue": {
    "pizzaQueue::/": [
      {
        "basicProperties": {
          "contentType": "text/plain",
          "contentEncoding": null,
          "headers": {
            "header1": {
              "bytes": [
                118,
                97,
                108,
                117,
                101,
                49
              ]
            },
            "header2": {
              "bytes": [
                118,
                97,
                108,
                117,
                101,
                50
              ]
            },
            "numberInHeader": 10
          },
          "deliveryMode": 1,
          "priority": 34,
          "correlationId": null,
          "replyTo": null,
          "expiration": "60000",
          "messageId": null,
          "timestamp": "Jan 1, 1970, 12:33:41 AM",
          "type": null,
          "userId": "AIDACKCEVSQ6C2EXAMPLE",
          "appId": null,
          "clusterId": null,
          "bodySize": 80
        },
        "redelivered": false,
        "data": "eyJ0aW1lb3V0IjowLCJkYXRhIjoiQ1pybWYwR3c4T3Y0YnFMUXhENEUifQ=="
      }
    ]
  }
}
```
En el ejemplo de RabbitMQ, `pizzaQueue` es el nombre de la cola de RabbitMQ y `/` es el nombre del host virtual. Al recibir mensajes, el origen de eventos muestra los mensajes en`pizzaQueue::/`.

# Configuración de orígenes de eventos de Amazon MQ para Lambda
<a name="process-mq-messages-with-lambda"></a>

**Topics**
+ [

## Configuración de la seguridad de la red
](#process-mq-messages-with-lambda-networkconfiguration)
+ [

## Creación de la asignación de orígenes de eventos
](#services-mq-eventsourcemapping)

## Configuración de la seguridad de la red
<a name="process-mq-messages-with-lambda-networkconfiguration"></a>

Para que Lambda tenga acceso completo a Amazon MQ a través de la asignación de orígenes de eventos, el agente debe utilizar un punto de conexión público (dirección IP pública) o bien debe proporcionar acceso a la instancia de Amazon VPC en la que creó el agente.

Cuando utilice Amazon MQ con Lambda, recomendamos crear [puntos de conexión de VPC de AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html) y proporcionar a su función acceso a los recursos de su Amazon VPC.

**nota**  
Los puntos de conexión de VPC de AWS PrivateLink son necesarios para las funciones con asignaciones de orígenes de eventos que utilizan el modo predeterminado (bajo demanda) para los sondeos de eventos. Si la asignación de orígenes de eventos utiliza el [modo aprovisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode), no es necesario configurar los puntos de conexión de VPC de AWS PrivateLink.

Cree un punto de conexión para proporcionar acceso a los siguientes recursos:
+  Lambda: cree un punto de conexión para la entidad principal del servicio de Lambda. 
+  AWS STS: cree un punto de conexión para AWS STS con el objetivo de que la entidad principal del servicio asuma un rol en su nombre. 
+  Secrets Manager: si el agente usa Secrets Manager para almacenar las credenciales, cree un punto de conexión para Secrets Manager. 

Como alternativa, configure una puerta de enlace de NAT en cada subred pública de la Amazon VPC. Para obtener más información, consulte [Habilitación del acceso a Internet para funciones de Lambda conectadas a VPC](configuration-vpc-internet.md).

Al crear una asignación de orígenes de eventos para Amazon MQ, Lambda comprueba si las interfaces de red elásticas (ENI) ya están presentes en las subredes y los grupos de seguridad configurados para la Amazon VPC. Si Lambda encuentra ENI existentes, intenta reutilizarlos. De lo contrario, Lambda crea nuevos ENI para conectarse al origen de eventos e invocar la función.

**nota**  
Las funciones de Lambda siempre se ejecutan dentro de VPC propiedad del servicio de Lambda. La configuración de VPC de la función no afecta la asignación de orígenes de eventos. Solo la configuración de red del origen de eventos determina cómo se conecta Lambda al origen de eventos.

Configure los grupos de seguridad para la Amazon VPC que contiene el agente. De forma predeterminada, Amazon MQ utiliza los siguientes puertos: `61617` (Amazon MQ para ActiveMQ) y `5671` (Amazon MQ para RabbitMQ).
+ Reglas de entrada: permiten todo el tráfico en el puerto del agente predeterminado para el grupo de seguridad asociado al origen de eventos. Como alternativa, puede usar una regla de grupo de seguridad con autorreferencia para permitir el acceso desde instancias que pertenecen al mismo grupo de seguridad.
+ Reglas de salida: permiten que todo el tráfico en el puerto `443` vaya a destinos externos en caso de que su función necesite comunicarse con servicios de AWS. Como alternativa, también puede usar una regla de grupo de seguridad con autorreferencia para limitar el acceso al agente en caso de que no necesite comunicarse con otros servicios de AWS.
+ Reglas de entrada del punto de conexión de Amazon VPC: si usa un punto de conexión de Amazon VPC, el grupo de seguridad asociado al punto de conexión de Amazon VPC debe permitir el tráfico entrante en el puerto `443` desde el grupo de seguridad del agente.

Si el agente utiliza la autenticación, también puede restringir la política del punto de conexión para el punto de conexión de Secrets Manager. Para llamar a la API de Secrets Manager, Lambda usa su rol de función, no la entidad principal de servicio de Lambda.

**Example Política de punto de conexión de VPC: punto de conexión de Secrets Manager**  

```
{
      "Statement": [
          {
              "Action": "secretsmanager:GetSecretValue",
              "Effect": "Allow",
              "Principal": {
                  "AWS": [
                      "arn:aws::iam::123456789012:role/my-role"
                  ]
              },
              "Resource": "arn:aws::secretsmanager:us-west-2:123456789012:secret:my-secret"
          }
      ]
  }
```

Cuando utiliza los puntos de conexión de VPC de Amazon, AWS enruta las llamadas a la API para invocar una función mediante la interfaz de red elástica (ENI) del punto de conexión. La entidad principal del servicio de Lambda debe llamar a `lambda:InvokeFunction` en cualquier rol y función que utilicen esas ENI.

De forma predeterminada, los puntos de conexión de VPC de Amazon tienen políticas de IAM abiertas que permiten un amplio acceso a los recursos. La práctica recomendada es restringir estas políticas para realizar las acciones necesarias mediante ese punto de conexión. Para garantizar que la asignación de orígenes de eventos pueda invocar la función de Lambda, la política de punto de conexión de VPC debe permitir que la entidad principal del servicio de Lambda llame a `sts:AssumeRole` y `lambda:InvokeFunction`. Restringir las políticas de punto de conexión de VPC para permitir únicamente las llamadas a la API que se originen en su organización impide que la asignación de orígenes de eventos funcione correctamente, por lo que en estas políticas es necesario `"Resource": "*"`.

En el siguiente ejemplo de políticas de puntos de conexión de VPC, se muestra cómo conceder el acceso necesario a las entidades principales del servicio de Lambda para AWS STS y los puntos de conexión de Lambda.

**Example Política de punto de conexión de VPC: punto de conexión de AWS STS**  

```
{
      "Statement": [
          {
              "Action": "sts:AssumeRole",
              "Effect": "Allow",
              "Principal": {
                  "Service": [
                      "lambda.amazonaws.com"
                  ]
              },
              "Resource": "*"
          }
      ]
    }
```

**Example Política de punto de conexión de VPC: punto de conexión de Lambda**  

```
{
      "Statement": [
          {
              "Action": "lambda:InvokeFunction",
              "Effect": "Allow",
              "Principal": {
                  "Service": [
                      "lambda.amazonaws.com"
                  ]
              },
              "Resource": "*"
          }
      ]
  }
```

## Creación de la asignación de orígenes de eventos
<a name="services-mq-eventsourcemapping"></a>

Cree una [asignación de orígenes de eventos](invocation-eventsourcemapping.md) para indicar que envíe registros de un agente de Amazon MQ a una función de Lambda. Puede crear varias asignaciones de orígenes de eventos para procesar los mismos datos con distintas funciones o para procesar elementos de varios orígenes con una sola función.

Para configurar la función para leer de Amazon MQ, agregue los permisos requeridos y cree un desencadenador de **MQ** en la consola de Lambda.

Para leer registros desde un agente de Amazon MQ, la función de Lambda necesita los siguientes permisos. Para conceder a Lambda permiso para interactuar con el agente de Amazon MQ y sus recursos subyacentes, agregue instrucciones de permisos a la función del [rol de ejecución](lambda-intro-execution-role.md):
+ [mq:DescribeBroker](https://docs.aws.amazon.com/amazon-mq/latest/api-reference/brokers-broker-id.html#brokers-broker-id-http-methods)
+ [secretsmanager:GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html)
+ [ec2:CreateNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateNetworkInterface.html)
+ [ec2:DeleteNetworkInterface](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteNetworkInterface.html)
+ [ec2:DescribeNetworkInterfaces](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeNetworkInterfaces.html)
+ [ec2:DescribeSecurityGroups](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html)
+ [ec2:DescribeSubnets](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSubnets.html)
+ [ec2:DescribeVpcs](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeVpcs.html)
+ [logs:CreateLogGroup](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogGroup.html)
+ [logs:CreateLogStream](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_CreateLogStream.html)
+ [logs:PutLogEvents](https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_PutLogEvents.html)

**nota**  
Cuando utilice una clave administrada por el cliente cifrada, agregue también el permiso `[kms:Decrypt](https://docs.aws.amazon.com/msk/1.0/apireference/clusters-clusterarn-bootstrap-brokers.html#clusters-clusterarn-bootstrap-brokersget)`.

**Cómo agregar permisos y crear un desencadenador**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de una función.

1. Elija la pestaña **Configuración** y, a continuación, elija **Permisos**.

1. En **Nombre del rol**, elija el enlace al rol de ejecución. Este enlace abre el rol en la consola de IAM.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/execution-role.png)

1. Seleccione **Agregar permisos** y, a continuación, **Crear política insertada**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/inline-policy.png)

1. En **Editor de políticas**, elija **JSON**. Escriba la siguiente política. La función necesita estos permisos de lectura desde un agente de Amazon MQ.

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
         {
           "Effect": "Allow",
           "Action": [
             "mq:DescribeBroker",
             "secretsmanager:GetSecretValue",
             "ec2:CreateNetworkInterface",
             "ec2:DeleteNetworkInterface",
             "ec2:DescribeNetworkInterfaces", 
             "ec2:DescribeSecurityGroups",
             "ec2:DescribeSubnets",
             "ec2:DescribeVpcs",
             "logs:CreateLogGroup",
             "logs:CreateLogStream", 
             "logs:PutLogEvents"		
           ],
           "Resource": "*"
         }
       ]
     }
   ```

------
**nota**  
Cuando utilice una clave cifrada y administrada por el cliente, agregue también el permiso `kms:Decrypt`.

1. Elija **Siguiente**. Introduzca un nombre de política y, a continuación, elija **Crear política**.

1. Regrese a la función en la consola de Lambda. En **Descripción general de la función**, elija **Agregar desencadenador**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/add-trigger.png)

1. Elija el tipo de desencadenador **MQ**.

1. Configure las opciones requeridas y luego elija **Agregar**.

Lambda admite las siguientes opciones para los orígenes de eventos de Amazon MQ.
+ **Agente de MQ**: seleccione un agente de Amazon MQ.
+ **Tamaño del lote**; establezca el número máximo de mensajes que se recuperarán en un solo lote.
+ **Nombre de la cola**: escriba la cola de Amazon MQ que se va a consumir.
+ **Configuración del acceso al origen**: introduzca la información del host virtual y el secreto de Secrets Manager que almacena las credenciales del agente.
+ **Activar desencadenador**: desactive el desencadenador para detener el procesamiento de registros.

Para habilitar o desactivar el desencadenador (o eliminarlo), elija el desencadenador de **MQ** en el diseñador. Para volver a configurar el desencadenador, utilice las operaciones de API de asignación de origen de eventos.

# Parámetros de asignación de orígenes de eventos
<a name="services-mq-params"></a>

Todos los tipos de fuente de eventos Lambda comparten las mismas operaciones [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) y [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) de la API. Sin embargo, solo algunos de los parámetros se aplican a Amazon MQ y RabbitMQ.


| Parámetro | Obligatoria | Predeterminado | Notas | 
| --- | --- | --- | --- | 
|  BatchSize  |  N  |  100  |  Máximo: 10 000  | 
|  Habilitado  |  N  |  true  | Ninguno | 
|  FunctionName  |  Y  | N/A  | Ninguno | 
|  FilterCriteria  |  N  |  N/A   |  [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md)  | 
|  MaximumBatchingWindowInSeconds  |  N  |  500 ms  |  [Comportamiento de procesamiento por lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching)  | 
|  Queues  |  N  | N/A |  Nombre de la cola de destino del agente de Amazon MQ que se va a consumir.  | 
|  SourceAccessConfigurations  |  N  | N/A  |  Para ActiveMQ, credenciales BASIC\$1AUTH. Para RabbitMQ, puede contener tanto credenciales BASIC\$1AUTH como información de VIRTUAL\$1HOST.  | 

# Filtrar eventos de una fuente de eventos de Amazon MQ
<a name="with-mq-filtering"></a>

Puede utilizar el filtrado de eventos para controlar qué registros de un flujo o una cola envía Lambda a su función. Para obtener información general sobre cómo funciona el filtrado de eventos, consulte [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md).

Esta sección se centra en el filtrado de eventos para las fuentes de eventos de Amazon MQ.

**nota**  
Las asignaciones de orígenes de eventos de Amazon MQ solo admiten el filtrado en la clave `data`.

**Topics**
+ [

## Conceptos básicos de filtrado de eventos de Amazon MQ
](#filtering-AMQ)

## Conceptos básicos de filtrado de eventos de Amazon MQ
<a name="filtering-AMQ"></a>

Supongamos que su cola de mensajes de Amazon MQ contiene mensajes en formato JSON válido o como cadenas simples. Un registro de ejemplo tendría el siguiente aspecto, con los datos convertidos en una cadena codificada en Base64 en el campo `data`.

------
#### [ ActiveMQ ]

```
{ 
    "messageID": "ID:b-9bcfa592-423a-4942-879d-eb284b418fc8-1---mq---us-east-2.amazonaws.com.rproxy.goskope.com-37557-1234520418293-4:1:1:1:1", 
    "messageType": "jms/text-message",
    "deliveryMode": 1,
    "replyTo": null,
    "type": null,
    "expiration": "60000",
    "priority": 1,
    "correlationId": "myJMSCoID",
    "redelivered": false,
    "destination": { 
      "physicalName": "testQueue" 
    },
    "data":"QUJDOkFBQUE=",
    "timestamp": 1598827811958,
    "brokerInTime": 1598827811958, 
    "brokerOutTime": 1598827811959, 
    "properties": {
      "index": "1",
      "doAlarm": "false",
      "myCustomProperty": "value"
    }
}
```

------
#### [ RabbitMQ ]

```
{
    "basicProperties": {
        "contentType": "text/plain",
        "contentEncoding": null,
        "headers": {
            "header1": {
                "bytes": [
                  118,
                  97,
                  108,
                  117,
                  101,
                  49
                ]
            },
            "header2": {
                "bytes": [
                  118,
                  97,
                  108,
                  117,
                  101,
                  50
                ]
            },
            "numberInHeader": 10
        },
        "deliveryMode": 1,
        "priority": 34,
        "correlationId": null,
        "replyTo": null,
        "expiration": "60000",
        "messageId": null,
        "timestamp": "Jan 1, 1970, 12:33:41 AM",
        "type": null,
        "userId": "AIDACKCEVSQ6C2EXAMPLE",
        "appId": null,
        "clusterId": null,
        "bodySize": 80
        },
    "redelivered": false,
    "data": "eyJ0aW1lb3V0IjowLCJkYXRhIjoiQ1pybWYwR3c4T3Y0YnFMUXhENEUifQ=="
}
```

------

Tanto para los agentes de Active MQ como los de Rabbit MQ, puede utilizar el filtrado de eventos para filtrar los registros mediante la clave `data`. Supongamos que su cola de Amazon MQ contiene mensajes en el siguiente formato JSON.

```
{
    "timeout": 0,
    "IPAddress": "203.0.113.254"
}
```

Para filtrar solo los registros en los que el campo `timeout` sea mayor que 0, el objeto `FilterCriteria` sería el siguiente.

```
{
    "Filters": [
        {
            "Pattern": "{ \"data\" : { \"timeout\" : [ { \"numeric\": [ \">\", 0] } } ] } }"
        }
    ]
}
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado.

```
{
    "data": {
        "timeout": [ { "numeric": [ ">", 0 ] } ]
        }
}
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "data" : { "timeout" : [ { "numeric": [ ">", 0 ] } ] } }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:mq:us-east-2:123456789012:broker:my-broker:b-8ac7cc01-5898-482d-be2f-a6b596050ea8 \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : { \"timeout\" : [ { \"numeric\": [ \">\", 0 ] } ] } }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : { \"timeout\" : [ { \"numeric\": [ \">\", 0 ] } ] } }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : { \"timeout\" : [ { \"numeric\": [ \">\", 0 ] } ] } }"}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "data" : { "timeout" : [ { "numeric": [ ">", 0 ] } ] } }'
```

------

Con Amazon MQ, también puede filtrar los registros en los que el mensaje sea una cadena simple. Supongamos que desea procesar solo los registros en los que el mensaje comienza por “Resultado:”. El objeto `FilterCriteria` tendría el siguiente aspecto.

```
{
    "Filters": [
        {
            "Pattern": "{ \"data\" : [ { \"prefix\": \"Result: \" } ] }"
        }
    ]
}
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado.

```
{
    "data": [
        {
        "prefix": "Result: "
        }
    ]
}
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "data" : [ { "prefix": "Result: " } ] }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:mq:us-east-2:123456789012:broker:my-broker:b-8ac7cc01-5898-482d-be2f-a6b596050ea8 \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : [ { \"prefix\": \"Result: \" } ] }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : [ { \"prefix\": \"Result: \" } ] }"}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "data" : [ { "prefix": "Result " } ] }'
```

------

Los mensajes de Amazon MQ deben ser cadenas codificadas en UTF-8, cadenas simples o en formato JSON. Esto se debe a que Lambda decodifica las matrices de bytes de Amazon MQ en UTF-8 antes de aplicar los criterios de filtro. Si los mensajes utilizan otra codificación, como UTF-16 o ASCII, o el formato del mensaje no coincide con el formato de `FilterCriteria`, Lambda solo procesa los filtros de metadatos. En la siguiente tabla se resume el comportamiento específico:


| Formato del mensaje entrante | Formato del patrón de filtro para las propiedades del mensaje | Acción resultante | 
| --- | --- | --- | 
|  Cadena sin formato  |  Cadena sin formato  |  Lambda filtra en función de los criterios de filtro.  | 
|  Cadena sin formato  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  Cadena sin formato  |  JSON válido  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  JSON válido  |  Cadena sin formato  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  JSON válido  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  JSON válido  |  JSON válido  |  Lambda filtra en función de los criterios de filtro.  | 
|  Cadena no codificada con UTF-8  |  JSON, cadena sin formato o sin patrón  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 

# Solución de problemas de asignación de orígenes de eventos de Amazon MQ
<a name="services-mq-errors"></a>

Cuando una función de Lambda encuentra un error irrecuperable, el consumidor de Amazon MQ dejará de procesar registros. Cualquier otro consumidor puede continuar procesando, siempre que no encuentre el mismo error. Para determinar la causa potencial de un consumidor detenido, marque el campo `StateTransitionReason` en los detalles de devolución de su `EventSourceMapping` para obtener uno de los siguientes códigos:

**`ESM_CONFIG_NOT_VALID`**  
La configuración de asignación de orígenes de eventos no es válida.

**`EVENT_SOURCE_AUTHN_ERROR`**  
Lambda ha producido un error al autenticar el origen del evento.

**`EVENT_SOURCE_AUTHZ_ERROR`**  
Lambda no tiene los permisos necesarios para acceder al origen de eventos.

**`FUNCTION_CONFIG_NOT_VALID`**  
La configuración de la función no es válida.

Los registros también quedan sin procesar si Lambda los elimina debido a su tamaño. El límite de tamaño para los registros de Lambda es de 6 MB. Para volver a entregar mensajes en caso de error de función, puede utilizar una política de cola de mensajes fallidos (DLQ). Para obtener más información, consulte [Reentrega de mensajes y administración de DLQ](https://activemq.apache.org/message-redelivery-and-dlq-handling) en el sitio web de Apache ActiveMQ y [Guía de la fiabilidad](https://www.rabbitmq.com/reliability.html) en el sitio web de RabbitMQ.

**nota**  
Lambda no admite políticas de reenvío personalizadas. En su lugar, Lambda utiliza una política con los valores predeterminados de la página de [Política de reentrega](https://activemq.apache.org/redelivery-policy) en el sitio web de Apache ActiveMQ, con `maximumRedeliveries` establecido en 6.

# Uso de AWS Lambda con Amazon RDS
<a name="services-rds"></a>

Puede conectar una función de Lambda a una base de datos de Amazon Relational Database Service (Amazon RDS) directamente y a través de un Amazon RDS Proxy. Las conexiones directas son útiles en escenarios sencillos y los proxies se recomiendan para la producción. Un proxy de base de datos administra un grupo de conexiones de bases de datos compartidas que permite que su función alcance niveles altos de simultaneidad sin agotar las conexiones de base de datos.

Se recomienda utilizar Amazon RDS Proxy para las funciones de Lambda que establezcan conexiones cortas y frecuentes a bases de datos o que abran y cierren una gran cantidad de conexiones a bases de datos. Para obtener más información, consulte [Conexión automática de una función de Lambda y una instancia de base de datos](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/lambda-rds-connect.html) en la Guía para desarrolladores de Amazon Relational Database Service.

**sugerencia**  
Para conectar rápidamente una función de Lambda a una base de datos de Amazon RDS, puede utilizar el asistente guiado de la consola. Para abrir el asistente, haga lo siguiente:  
Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.
Seleccione la función a la que desea conectar una base de datos.
En la pestaña **Configuración**, seleccione **Bases de datos de RDS**.
Seleccione **Conectar a la base de datos de RDS**.
Después de haber conectado la función a una base de datos, podrá crear un proxy. Para ello, elija **Agregar proxy**.

## Configuración de la función para que funcione con los recursos de RDS
<a name="rds-configuration"></a>

En la consola de Lambda, puede configurar y aprovisionar determinadas instancias de bases de datos y recursos de proxy de Amazon RDS. Para ello, vaya a las **bases de datos de RDS** en la pestaña **Configuración**. Como alternativa, también puede crear y configurar conexiones a funciones de Lambda en la consola de Amazon RDS. Al configurar una instancia de base de datos de RDS para utilizarla con Lambda, tenga en cuenta los siguientes criterios:
+ Para conectarse a una base de datos, su función debe estar en la misma Amazon VPC donde se ejecuta la base de datos.
+ Puede utilizar las bases de datos de Amazon RDS con los motores MySQL, MariaDB, PostgreSQL o Microsoft SQL Server.
+ También puede utilizar clústeres de bases de datos de Aurora con motores MySQL o PostgreSQL.
+ Debe proporcionar un secreto de Secrets Manager para la autenticación de la base de datos.
+ Un rol de IAM debe otorgar permiso para utilizar el secreto y una política de confianza debe permitir que Amazon RDS asuma el rol.
+  La entidad principal de IAM que usa la consola para configurar el recurso de Amazon RDS y conectarlo a su función debe tener los siguientes permisos:

### Ejemplo de política de permisos
<a name="rds-lambda-permissions"></a>

**nota**  
 Solo necesitará los permisos de Amazon RDS Proxy si configura un Amazon RDS Proxy para administrar un grupo de conexiones de base de datos. 

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

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ec2:CreateSecurityGroup",
        "ec2:DescribeSecurityGroups",
        "ec2:DescribeSubnets",
        "ec2:DescribeVpcs",
        "ec2:AuthorizeSecurityGroupIngress",
        "ec2:AuthorizeSecurityGroupEgress",
        "ec2:RevokeSecurityGroupEgress",
        "ec2:CreateNetworkInterface",
        "ec2:DeleteNetworkInterface",
        "ec2:DescribeNetworkInterfaces"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "rds-db:connect",
        "rds:CreateDBProxy",
        "rds:CreateDBInstance",
        "rds:CreateDBSubnetGroup",
        "rds:DescribeDBClusters",
        "rds:DescribeDBInstances",
        "rds:DescribeDBSubnetGroups",
        "rds:DescribeDBProxies",
        "rds:DescribeDBProxyTargets",
        "rds:DescribeDBProxyTargetGroups",
        "rds:RegisterDBProxyTargets",
        "rds:ModifyDBInstance",
        "rds:ModifyDBProxy"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "lambda:CreateFunction",
        "lambda:ListFunctions",
        "lambda:UpdateFunctionConfiguration"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "iam:AttachRolePolicy",
        "iam:CreateRole",
        "iam:CreatePolicy"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "secretsmanager:GetResourcePolicy",
        "secretsmanager:GetSecretValue",
        "secretsmanager:DescribeSecret",
        "secretsmanager:ListSecretVersionIds",
        "secretsmanager:CreateSecret"
      ],
      "Resource": "*"
    }
  ]
}
```

------

Amazon RDS cobra una tarifa por hora para los proxies en función del tamaño de la instancia de la base de datos. Consulte los [precios de los proxies de RDS](https://aws.amazon.com/rds/proxy/pricing/) para obtener más información. Para obtener más información general sobre las conexiones proxy, consulte [Uso de Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) en la Guía del usuario de Amazon RDS.

### Requisitos de SSL/TLS para las conexiones de Amazon RDS
<a name="rds-lambda-certificates"></a>

Para establecer conexiones SSL/TLS seguras a una instancia de base de datos de Amazon RDS, la función de Lambda debe verificar la identidad del servidor de base de datos mediante un certificado de confianza. Lambda administra estos certificados de forma diferente según el tipo de paquete de implementación:
+ [Archivos en formato .zip](configuration-function-zip.md): la gestión de los certificados varía según el tiempo de ejecución:
  + **Node.js 18 y versiones anteriores**: Lambda incluye de manera automática los certificados CA y los certificados RDS.
  + **Node.js 20 y posteriores**: Lambda ya no carga certificados CA adicionales de forma predeterminada. Establezca la variable de entorno `NODE_EXTRA_CA_CERTS` en `/var/runtime/ca-cert.pem`.

  Los certificados de Amazon RDS de las nuevas Regiones de AWS pueden tardar hasta 4 semanas en agregarse a los tiempos de ejecución administrados por Lambda.
+ [Imágenes de contenedores](images-create.md): las imágenes de base de AWS solo incluyen certificados de CA. Si su función se conecta a una instancia de base de datos de Amazon RDS, es necesario que incluya los certificados correspondientes en la imagen del contenedor. En su Dockerfile, descargue el [paquete de certificados correspondiente a la Región de AWS donde se aloja su base de datos](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html#UsingWithRDS.SSL.CertificatesDownload). Ejemplo:

  ```
  RUN curl https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem -o /us-east-1-bundle.pem
  ```

Este comando descarga el paquete de certificados de Amazon RDS y lo guarda en la ruta absoluta `/us-east-1-bundle.pem` en el directorio raíz de su contenedor. Cuando configure la conexión a la base de datos en el código de su función, debe hacer referencia a esta ruta exacta. Ejemplo:

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

La función `readFileSync` es necesaria porque los clientes de bases de datos de Node.js necesitan el contenido real del certificado en la memoria, no solo la ruta al archivo de certificado. Sin `readFileSync`, el cliente interpreta la cadena de ruta como contenido del certificado, lo que genera un error “certificado autofirmado en la cadena de certificados”.

**Example Configuración de una conexión de Node.js para la función de OCI**  

```
import { readFileSync } from 'fs';

// ...

let connectionConfig = {
    host: process.env.ProxyHostName,
    user: process.env.DBUserName,
    password: token,
    database: process.env.DBName,
    ssl: {
        ca: readFileSync('/us-east-1-bundle.pem') // Load RDS certificate content from file into memory
    }
};
```

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

**Example Configuración de una conexión de Python para la función de OCI**  

```
connection = pymysql.connect(
    host=proxy_host_name,
    user=db_username,
    password=token,
    db=db_name,
    port=port,
    ssl={'ca': '/us-east-1-bundle.pem'}  #Path to the certificate in container
)
```

------
#### [ Java ]

Para las funciones de Java que usan conexiones de JDBC, la cadena de conexión debe incluir lo siguiente:
+ `useSSL=true`
+ `requireSSL=true`
+ Un parámetro `sslCA` que apunte a la ubicación del certificado de Amazon RDS en la imagen del contenedor

**Example Cadena de conexión de Java para la función de OCI**  

```
// Define connection string
String connectionString = String.format("jdbc:mysql://%s:%s/%s?useSSL=true&requireSSL=true&sslCA=/us-east-1-bundle.pem", // Path to the certificate in container
        System.getenv("ProxyHostName"),
        System.getenv("Port"),
        System.getenv("DBName"));
```

------
#### [ .NET ]

**Example Cadena de conexión de .NET para la conexión de MySQL en la función de OCI**  

```
/// Build the Connection String with the Token 
string connectionString = $"Server={Environment.GetEnvironmentVariable("RDS_ENDPOINT")};" +
                         $"Port={Environment.GetEnvironmentVariable("RDS_PORT")};" +
                         $"Uid={Environment.GetEnvironmentVariable("RDS_USERNAME")};" +
                         $"Pwd={authToken};" +
                         "SslMode=Required;" +
                         "SslCa=/us-east-1-bundle.pem";  // Path to the certificate in container
```

------
#### [ Go ]

Para las funciones de Go que usan conexiones de MySQL, cargue el certificado de Amazon RDS en un grupo de certificados y regístrelo con el controlador de MySQL. A continuación, la cadena de conexión debe hacer referencia a esta configuración mediante el parámetro `tls`.

**Example Código de Go para la conexión de MySQL en la función de OCI**  

```
import (
    "crypto/tls"
    "crypto/x509"
    "os"
    "github.com/go-sql-driver/mysql"
)

...

// Create certificate pool and register TLS config
rootCertPool := x509.NewCertPool()
pem, err := os.ReadFile("/us-east-1-bundle.pem")  // Path to the certificate in container
if err != nil {
    panic("failed to read certificate file: " + err.Error())
}
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
    panic("failed to append PEM")
}

mysql.RegisterTLSConfig("custom", &tls.Config{
    RootCAs: rootCertPool,
})

dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?allowCleartextPasswords=true&tls=custom",
    dbUser, authenticationToken, dbEndpoint, dbName,
)
```

------
#### [ Ruby ]

**Example Configuración de una conexión de Ruby para la función de OCI**  

```
conn = Mysql2::Client.new(
    host: endpoint,
    username: user,
    password: token,
    port: port,
    database: db_name,
    sslca: '/us-east-1-bundle.pem',  # Path to the certificate in container
    sslverify: true
)
```

------

## Conexión a una base de datos de Amazon RDS en una función de Lambda
<a name="rds-connection"></a>

En el siguiente ejemplo de código, se muestra cómo se lleva a cabo la implementación de una función de Lambda que se conecta a una base de datos de Amazon RDS. La función realiza una solicitud sencilla a la base de datos y devuelve el resultado.

**nota**  
Estos ejemplos de código son válidos únicamente para [paquetes de implementación .zip](configuration-function-zip.md). Si va a implementar la función mediante una [imagen de contenedor](images-create.md), debe especificar el archivo de certificado de Amazon RDS en el código de la función, tal como se explica en la [sección anterior](#oci-certificate).

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conexión a una base de datos de Amazon RDS en una función de Lambda mediante .NET.  

```
using System.Data;
using System.Text.Json;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Core;
using MySql.Data.MySqlClient;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace aws_rds;

public class InputModel
{
    public string key1 { get; set; }
    public string key2 { get; set; }
}

public class Function
{
    /// <summary>
    // Handles the Lambda function execution for connecting to RDS using IAM authentication.
    /// </summary>
    /// <param name="input">The input event data passed to the Lambda function</param>
    /// <param name="context">The Lambda execution context that provides runtime information</param>
    /// <returns>A response object containing the execution result</returns>

    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        // Sample Input: {"body": "{\"key1\":\"20\", \"key2\":\"25\"}"}
        var input = JsonSerializer.Deserialize<InputModel>(request.Body);

        /// Obtain authentication token
        var authToken = RDSAuthTokenGenerator.GenerateAuthToken(
            Environment.GetEnvironmentVariable("RDS_ENDPOINT"),
            Convert.ToInt32(Environment.GetEnvironmentVariable("RDS_PORT")),
            Environment.GetEnvironmentVariable("RDS_USERNAME")
        );

        /// Build the Connection String with the Token 
        string connectionString = $"Server={Environment.GetEnvironmentVariable("RDS_ENDPOINT")};" +
                                  $"Port={Environment.GetEnvironmentVariable("RDS_PORT")};" +
                                  $"Uid={Environment.GetEnvironmentVariable("RDS_USERNAME")};" +
                                  $"Pwd={authToken};";


        try
        {
            await using var connection = new MySqlConnection(connectionString);
            await connection.OpenAsync();

            const string sql = "SELECT @param1 + @param2 AS Sum";

            await using var command = new MySqlCommand(sql, connection);
            command.Parameters.AddWithValue("@param1", int.Parse(input.key1 ?? "0"));
            command.Parameters.AddWithValue("@param2", int.Parse(input.key2 ?? "0"));

            await using var reader = await command.ExecuteReaderAsync();
            if (await reader.ReadAsync())
            {
                int result = reader.GetInt32("Sum");

                //Sample Response: {"statusCode":200,"body":"{\"message\":\"The sum is: 45\"}","isBase64Encoded":false}
                return new APIGatewayProxyResponse
                {
                    StatusCode = 200,
                    Body = JsonSerializer.Serialize(new { message = $"The sum is: {result}" })
                };
            }

        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error: {ex.Message}");
        }

        return new APIGatewayProxyResponse
        {
            StatusCode = 500,
            Body = JsonSerializer.Serialize(new { error = "Internal server error" })
        };
    }
}
```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conexión a una base de datos de Amazon RDS en una función de Lambda mediante Go.  

```
/*
Golang v2 code here.
*/

package main

import (
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"os"

	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/feature/rds/auth"
	_ "github.com/go-sql-driver/mysql"
)

type MyEvent struct {
	Name string `json:"name"`
}

func HandleRequest(event *MyEvent) (map[string]interface{}, error) {

	var dbName string = os.Getenv("DatabaseName")
	var dbUser string = os.Getenv("DatabaseUser")
	var dbHost string = os.Getenv("DBHost") // Add hostname without https
	var dbPort int = os.Getenv("Port")      // Add port number
	var dbEndpoint string = fmt.Sprintf("%s:%d", dbHost, dbPort)
	var region string = os.Getenv("AWS_REGION")

	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		panic("configuration error: " + err.Error())
	}

	authenticationToken, err := auth.BuildAuthToken(
		context.TODO(), dbEndpoint, region, dbUser, cfg.Credentials)
	if err != nil {
		panic("failed to create authentication token: " + err.Error())
	}

	dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=true&allowCleartextPasswords=true",
		dbUser, authenticationToken, dbEndpoint, dbName,
	)

	db, err := sql.Open("mysql", dsn)
	if err != nil {
		panic(err)
	}

	defer db.Close()

	var sum int
	err = db.QueryRow("SELECT ?+? AS sum", 3, 2).Scan(&sum)
	if err != nil {
		panic(err)
	}
	s := fmt.Sprint(sum)
	message := fmt.Sprintf("The selected sum is: %s", s)

	messageBytes, err := json.Marshal(message)
	if err != nil {
		return nil, err
	}

	messageString := string(messageBytes)
	return map[string]interface{}{
		"statusCode": 200,
		"headers":    map[string]string{"Content-Type": "application/json"},
		"body":       messageString,
	}, nil
}

func main() {
	lambda.Start(HandleRequest)
}
```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conexión a una base de datos de Amazon RDS en una función de Lambda mediante Java.  

```
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.rdsdata.RdsDataClient;
import software.amazon.awssdk.services.rdsdata.model.ExecuteStatementRequest;
import software.amazon.awssdk.services.rdsdata.model.ExecuteStatementResponse;
import software.amazon.awssdk.services.rdsdata.model.Field;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class RdsLambdaHandler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {

    @Override
    public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent event, Context context) {
        APIGatewayProxyResponseEvent response = new APIGatewayProxyResponseEvent();

        try {
            // Obtain auth token
            String token = createAuthToken();

            // Define connection configuration
            String connectionString = String.format("jdbc:mysql://%s:%s/%s?useSSL=true&requireSSL=true",
                    System.getenv("ProxyHostName"),
                    System.getenv("Port"),
                    System.getenv("DBName"));

            // Establish a connection to the database
            try (Connection connection = DriverManager.getConnection(connectionString, System.getenv("DBUserName"), token);
                 PreparedStatement statement = connection.prepareStatement("SELECT ? + ? AS sum")) {

                statement.setInt(1, 3);
                statement.setInt(2, 2);

                try (ResultSet resultSet = statement.executeQuery()) {
                    if (resultSet.next()) {
                        int sum = resultSet.getInt("sum");
                        response.setStatusCode(200);
                        response.setBody("The selected sum is: " + sum);
                    }
                }
            }

        } catch (Exception e) {
            response.setStatusCode(500);
            response.setBody("Error: " + e.getMessage());
        }

        return response;
    }

    private String createAuthToken() {
        // Create RDS Data Service client
        RdsDataClient rdsDataClient = RdsDataClient.builder()
                .region(Region.of(System.getenv("AWS_REGION")))
                .credentialsProvider(DefaultCredentialsProvider.create())
                .build();

        // Define authentication request
        ExecuteStatementRequest request = ExecuteStatementRequest.builder()
                .resourceArn(System.getenv("ProxyHostName"))
                .secretArn(System.getenv("DBUserName"))
                .database(System.getenv("DBName"))
                .sql("SELECT 'RDS IAM Authentication'")
                .build();

        // Execute request and obtain authentication token
        ExecuteStatementResponse response = rdsDataClient.executeStatement(request);
        Field tokenField = response.records().get(0).get(0);

        return tokenField.stringValue();
    }
}
```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conexión a una base de datos de Amazon RDS en una función de Lambda mediante JavaScript.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/* 
Node.js code here.
*/
// ES6+ example
import { Signer } from "@aws-sdk/rds-signer";
import mysql from 'mysql2/promise';

async function createAuthToken() {
  // Define connection authentication parameters
  const dbinfo = {

    hostname: process.env.ProxyHostName,
    port: process.env.Port,
    username: process.env.DBUserName,
    region: process.env.AWS_REGION,

  }

  // Create RDS Signer object
  const signer = new Signer(dbinfo);

  // Request authorization token from RDS, specifying the username
  const token = await signer.getAuthToken();
  return token;
}

async function dbOps() {

  // Obtain auth token
  const token = await createAuthToken();
  // Define connection configuration
  let connectionConfig = {
    host: process.env.ProxyHostName,
    user: process.env.DBUserName,
    password: token,
    database: process.env.DBName,
    ssl: 'Amazon RDS'
  }
  // Create the connection to the DB
  const conn = await mysql.createConnection(connectionConfig);
  // Obtain the result of the query
  const [res,] = await conn.execute('select ?+? as sum', [3, 2]);
  return res;

}

export const handler = async (event) => {
  // Execute database flow
  const result = await dbOps();
  // Return result
  return {
    statusCode: 200,
    body: JSON.stringify("The selected sum is: " + result[0].sum)
  }
};
```
Conexión a una base de datos de Amazon RDS en una función de Lambda mediante TypeScript.  

```
import { Signer } from "@aws-sdk/rds-signer";
import mysql from 'mysql2/promise';

// RDS settings
// Using '!' (non-null assertion operator) to tell the TypeScript compiler that the DB settings are not null or undefined,
const proxy_host_name = process.env.PROXY_HOST_NAME!
const port = parseInt(process.env.PORT!)
const db_name = process.env.DB_NAME!
const db_user_name = process.env.DB_USER_NAME!
const aws_region = process.env.AWS_REGION!


async function createAuthToken(): Promise<string> {

    // Create RDS Signer object
    const signer = new Signer({
        hostname: proxy_host_name,
        port: port,
        region: aws_region,
        username: db_user_name
    });

    // Request authorization token from RDS, specifying the username
    const token = await signer.getAuthToken();
    return token;
}

async function dbOps(): Promise<mysql.QueryResult | undefined> {
    try {
        // Obtain auth token
        const token = await createAuthToken();
        const conn = await mysql.createConnection({
            host: proxy_host_name,
            user: db_user_name,
            password: token,
            database: db_name,
            ssl: 'Amazon RDS' // Ensure you have the CA bundle for SSL connection
        });
        const [rows, fields] = await conn.execute('SELECT ? + ? AS sum', [3, 2]);
        console.log('result:', rows);
        return rows;
    }
    catch (err) {
        console.log(err);
    }
}

export const lambdaHandler = async (event: any): Promise<{ statusCode: number; body: string }> => {
    // Execute database flow
    const result = await dbOps();

    // Return error is result is undefined
    if (result == undefined)
        return {
            statusCode: 500,
            body: JSON.stringify(`Error with connection to DB host`)
        }

    // Return result
    return {
        statusCode: 200,
        body: JSON.stringify(`The selected sum is: ${result[0].sum}`)
    };
};
```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conexión a una base de datos de Amazon RDS en una función de Lambda mediante PHP.  

```
<?php
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# using bref/bref and bref/logger for simplicity

use Bref\Context\Context;
use Bref\Event\Handler as StdHandler;
use Bref\Logger\StderrLogger;
use Aws\Rds\AuthTokenGenerator;
use Aws\Credentials\CredentialProvider;

require __DIR__ . '/vendor/autoload.php';

class Handler implements StdHandler
{
    private StderrLogger $logger;
    public function __construct(StderrLogger $logger)
    {
        $this->logger = $logger;
    }


    private function getAuthToken(): string {
        // Define connection authentication parameters
        $dbConnection = [
            'hostname' => getenv('DB_HOSTNAME'),
            'port' => getenv('DB_PORT'),
            'username' => getenv('DB_USERNAME'),
            'region' => getenv('AWS_REGION'),
        ];

        // Create RDS AuthTokenGenerator object
        $generator = new AuthTokenGenerator(CredentialProvider::defaultProvider());

        // Request authorization token from RDS, specifying the username
        return $generator->createToken(
            $dbConnection['hostname'] . ':' . $dbConnection['port'],
            $dbConnection['region'],
            $dbConnection['username']
        );
    }

    private function getQueryResults() {
        // Obtain auth token
        $token = $this->getAuthToken();

        // Define connection configuration
        $connectionConfig = [
            'host' => getenv('DB_HOSTNAME'),
            'user' => getenv('DB_USERNAME'),
            'password' => $token,
            'database' => getenv('DB_NAME'),
        ];

        // Create the connection to the DB
        $conn = new PDO(
            "mysql:host={$connectionConfig['host']};dbname={$connectionConfig['database']}",
            $connectionConfig['user'],
            $connectionConfig['password'],
            [
                PDO::MYSQL_ATTR_SSL_CA => '/path/to/rds-ca-2019-root.pem',
                PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT => true,
            ]
        );

        // Obtain the result of the query
        $stmt = $conn->prepare('SELECT ?+? AS sum');
        $stmt->execute([3, 2]);

        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    /**
     * @param mixed $event
     * @param Context $context
     * @return array
     */
    public function handle(mixed $event, Context $context): array
    {
        $this->logger->info("Processing query");

        // Execute database flow
        $result = $this->getQueryResults();

        return [
            'sum' => $result['sum']
        ];
    }
}

$logger = new StderrLogger();
return new Handler($logger);
```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conexión a una base de datos de Amazon RDS en una función de Lambda mediante Python.  

```
import json
import os
import boto3
import pymysql

# RDS settings
proxy_host_name = os.environ['PROXY_HOST_NAME']
port = int(os.environ['PORT'])
db_name = os.environ['DB_NAME']
db_user_name = os.environ['DB_USER_NAME']
aws_region = os.environ['AWS_REGION']


# Fetch RDS Auth Token
def get_auth_token():
    client = boto3.client('rds')
    token = client.generate_db_auth_token(
        DBHostname=proxy_host_name,
        Port=port
        DBUsername=db_user_name
        Region=aws_region
    )
    return token

def lambda_handler(event, context):
    token = get_auth_token()
    try:
        connection = pymysql.connect(
            host=proxy_host_name,
            user=db_user_name,
            password=token,
            db=db_name,
            port=port,
            ssl={'ca': 'Amazon RDS'}  # Ensure you have the CA bundle for SSL connection
        )
        
        with connection.cursor() as cursor:
            cursor.execute('SELECT %s + %s AS sum', (3, 2))
            result = cursor.fetchone()

        return result
        
    except Exception as e:
        return (f"Error: {str(e)}")  # Return an error message if an exception occurs
```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conexión a una base de datos de Amazon RDS en una función de Lambda mediante Ruby.  

```
# Ruby code here.

require 'aws-sdk-rds'
require 'json'
require 'mysql2'

def lambda_handler(event:, context:)
  endpoint = ENV['DBEndpoint'] # Add the endpoint without https"
  port = ENV['Port']           # 3306
  user = ENV['DBUser']
  region = ENV['DBRegion']     # 'us-east-1'
  db_name = ENV['DBName']

  credentials = Aws::Credentials.new(
    ENV['AWS_ACCESS_KEY_ID'],
    ENV['AWS_SECRET_ACCESS_KEY'],
    ENV['AWS_SESSION_TOKEN']
  )
  rds_client = Aws::RDS::AuthTokenGenerator.new(
    region: region, 
    credentials: credentials
  )

  token = rds_client.auth_token(
    endpoint: endpoint+ ':' + port,
    user_name: user,
    region: region
  )

  begin
    conn = Mysql2::Client.new(
      host: endpoint,
      username: user,
      password: token,
      port: port,
      database: db_name,
      sslca: '/var/task/global-bundle.pem', 
      sslverify: true,
      enable_cleartext_plugin: true
    )
    a = 3
    b = 2
    result = conn.query("SELECT #{a} + #{b} AS sum").first['sum']
    puts result
    conn.close
    {
      statusCode: 200,
      body: result.to_json
    }
  rescue => e
    puts "Database connection failed due to #{e}"
  end
end
```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conexión a una base de datos de Amazon RDS en una función de Lambda mediante Rust.  

```
use aws_config::BehaviorVersion;
use aws_credential_types::provider::ProvideCredentials;
use aws_sigv4::{
    http_request::{sign, SignableBody, SignableRequest, SigningSettings},
    sign::v4,
};
use lambda_runtime::{run, service_fn, Error, LambdaEvent};
use serde_json::{json, Value};
use sqlx::postgres::PgConnectOptions;
use std::env;
use std::time::{Duration, SystemTime};

const RDS_CERTS: &[u8] = include_bytes!("global-bundle.pem");

async fn generate_rds_iam_token(
    db_hostname: &str,
    port: u16,
    db_username: &str,
) -> Result<String, Error> {
    let config = aws_config::load_defaults(BehaviorVersion::v2024_03_28()).await;

    let credentials = config
        .credentials_provider()
        .expect("no credentials provider found")
        .provide_credentials()
        .await
        .expect("unable to load credentials");
    let identity = credentials.into();
    let region = config.region().unwrap().to_string();

    let mut signing_settings = SigningSettings::default();
    signing_settings.expires_in = Some(Duration::from_secs(900));
    signing_settings.signature_location = aws_sigv4::http_request::SignatureLocation::QueryParams;

    let signing_params = v4::SigningParams::builder()
        .identity(&identity)
        .region(&region)
        .name("rds-db")
        .time(SystemTime::now())
        .settings(signing_settings)
        .build()?;

    let url = format!(
        "https://{db_hostname}:{port}/?Action=connect&DBUser={db_user}",
        db_hostname = db_hostname,
        port = port,
        db_user = db_username
    );

    let signable_request =
        SignableRequest::new("GET", &url, std::iter::empty(), SignableBody::Bytes(&[]))
            .expect("signable request");

    let (signing_instructions, _signature) =
        sign(signable_request, &signing_params.into())?.into_parts();

    let mut url = url::Url::parse(&url).unwrap();
    for (name, value) in signing_instructions.params() {
        url.query_pairs_mut().append_pair(name, &value);
    }

    let response = url.to_string().split_off("https://".len());

    Ok(response)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    run(service_fn(handler)).await
}

async fn handler(_event: LambdaEvent<Value>) -> Result<Value, Error> {
    let db_host = env::var("DB_HOSTNAME").expect("DB_HOSTNAME must be set");
    let db_port = env::var("DB_PORT")
        .expect("DB_PORT must be set")
        .parse::<u16>()
        .expect("PORT must be a valid number");
    let db_name = env::var("DB_NAME").expect("DB_NAME must be set");
    let db_user_name = env::var("DB_USERNAME").expect("DB_USERNAME must be set");

    let token = generate_rds_iam_token(&db_host, db_port, &db_user_name).await?;

    let opts = PgConnectOptions::new()
        .host(&db_host)
        .port(db_port)
        .username(&db_user_name)
        .password(&token)
        .database(&db_name)
        .ssl_root_cert_from_pem(RDS_CERTS.to_vec())
        .ssl_mode(sqlx::postgres::PgSslMode::Require);

    let pool = sqlx::postgres::PgPoolOptions::new()
        .connect_with(opts)
        .await?;

    let result: i32 = sqlx::query_scalar("SELECT $1 + $2")
        .bind(3)
        .bind(2)
        .fetch_one(&pool)
        .await?;

    println!("Result: {:?}", result);

    Ok(json!({
        "statusCode": 200,
        "content-type": "text/plain",
        "body": format!("The selected sum is: {result}")
    }))
}
```

------

## Procesamiento de las notificaciones de eventos de Amazon RDS
<a name="rds-events"></a>

Puede utilizar Lambda para procesar las notificaciones de eventos desde una base de datos de Amazon RDS. Amazon RDS envía notificaciones a un tema de Amazon Simple Notification Service (Amazon SNS), que puede configurar para invocar una función Lambda. Amazon SNS ajusta el mensaje de Amazon RDS en su propio documento de evento y lo envía a su función.

Para obtener más información sobre cómo configurar una base de datos de Amazon RDS a fin de enviar notificaciones, consulte [Uso de las notificaciones de eventos de Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html). 

**Example Mensaje de Amazon RDS en un evento de Amazon SNS**  

```
{
        "Records": [
          {
            "EventVersion": "1.0",
            "EventSubscriptionArn": "arn:aws:sns:us-east-2:123456789012:rds-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
            "EventSource": "aws:sns",
            "Sns": {
              "SignatureVersion": "1",
              "Timestamp": "2023-01-02T12:45:07.000Z",
              "Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==",
              "SigningCertUrl": "https://sns.us-east-2.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem",
              "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
              "Message": "{\"Event Source\":\"db-instance\",\"Event Time\":\"2023-01-02 12:45:06.000\",\"Identifier Link\":\"https://console.aws.amazon.com/rds/home?region=eu-west-1#dbinstance:id=dbinstanceid\",\"Source ID\":\"dbinstanceid\",\"Event ID\":\"http://docs.amazonwebservices.com/AmazonRDS/latest/UserGuide/USER_Events.html#RDS-EVENT-0002\",\"Event Message\":\"Finished DB Instance backup\"}",
              "MessageAttributes": {},
              "Type": "Notification",
              "UnsubscribeUrl": "https://sns.us-east-2.amazonaws.com/?Action=Unsubscribe&amp;SubscriptionArn=arn:aws:sns:us-east-2:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
              "TopicArn":"arn:aws:sns:us-east-2:123456789012:sns-lambda",
              "Subject": "RDS Notification Message"
            }
          }
        ]
      }
```

## Tutorial completo de Lambda y Amazon RDS
<a name="rds-database-samples"></a>
+ [Uso de una función de Lambda para acceder a una base de datos de Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html): con la Guía del usuario de Amazon RDS, puede aprender a utilizar una función de Lambda para escribir datos en una base de datos de Amazon RDS a través de Amazon RDS Proxy. La función de Lambda leerá registros de una cola de Amazon SQS y escribirá elementos nuevos en una tabla de la base de datos siempre que se agrega un mensaje.

# Seleccione un servicio de base de datos para sus aplicaciones basadas en Lambda
<a name="ddb-rds-database-decision"></a>

Muchas aplicaciones sin servidor necesitan almacenar y recuperar datos. AWS ofrece varias opciones de bases de datos que funcionan con funciones de Lambda. Dos de las opciones más populares son Amazon DynamoDB, un servicio de base de datos NoSQL, y Amazon RDS, una solución de base de datos relacional tradicional. En las siguientes secciones se explican las principales diferencias entre estos servicios cuando se utilizan con Lambda y se lo ayuda a seleccionar el servicio de base de datos adecuado para su aplicación sin servidor.

Para obtener más información sobre los demás servicios de bases de datos que AWS ofrece y comprender sus casos de uso y sus desventajas de manera más general, consulte [Elegir un servicio de base de datos de AWS](https://docs.aws.amazon.com/decision-guides/latest/databases-on-aws-how-to-choose/databases-on-aws-how-to-choose.html). Todos los servicios de bases de datos de AWS son compatibles con Lambda, pero es posible que no todos sean adecuados para su caso de uso particular.

## ¿Cuáles son sus opciones al momento de seleccionar un servicio de base de datos con Lambda?
<a name="w2aad101d101c19b9"></a>

AWS ofrece varios servicios de bases de datos. Para las aplicaciones sin servidor, dos de las opciones más populares son DynamoDB y Amazon RDS.
+ **DynamoDB** es una base de datos NoSQL completamente administrada y optimizada para aplicaciones sin servidor. Ofrece un escalado fluido y un rendimiento uniforme de milisegundos de un solo dígito a cualquier escala.
+ **Amazon RDS** es un servicio de base de datos relacional gestionado que admite varios motores de bases de datos, incluidos MySQL y PostgreSQL. Proporciona funciones SQL conocidas con una infraestructura gestionada.

## Recomendaciones si ya conoce sus requisitos
<a name="w2aad101d101c19c11"></a>

Si ya tiene claros sus requisitos, estas son nuestras recomendaciones básicas:

Recomendamos [DynamoDB](with-ddb.md) para las aplicaciones sin servidor que necesitan un rendimiento uniforme de baja latencia, escalado automático y que no requieren uniones ni transacciones complejas. Es especialmente adecuado para aplicaciones basadas en Lambda debido a su naturaleza sin servidor.

[Amazon RDS](services-rds.md) es una mejor opción cuando necesita consultas SQL complejas, uniones o si tiene aplicaciones existentes que utilizan bases de datos relacionales. Sin embargo, tenga en cuenta que la conexión de las funciones de Lambda a Amazon RDS requiere una configuración adicional y puede afectar a los tiempos de arranque en frío.

## Aspectos a tener en cuenta al seleccionar un servicio de base de datos
<a name="w2aad101d101c19c13"></a>

Al elegir entre DynamoDB y Amazon RDS para sus aplicaciones Lambda, tenga en cuenta los siguientes factores:
+ Administración de conexiones y arranques en frío
+ Patrones de acceso a datos
+ Complejidad de la consulta
+ Requisitos de consistencia de datos
+ Características de escalado
+ Modelo de costos

Si comprende estos factores, puede seleccionar la opción que mejor se adapte a sus necesidades de uso específicas.

### Administración de conexiones y arranques en frío
<a name="w2aad101d101c19c13b9b1"></a>
+ DynamoDB utiliza una API HTTP para todas las operaciones. Las funciones de Lambda pueden realizar solicitudes inmediatas sin mantener las conexiones, lo que se traduce en un mejor rendimiento de arranque en frío. Cada solicitud se autentica mediante credenciales de AWS sin sobrecargar la conexión.
+ Amazon RDS requiere la administración de grupos de conexiones, ya que utiliza conexiones de bases de datos tradicionales. Esto puede afectar a los arranques en frío, ya que las nuevas instancias de Lambda necesitan establecer conexiones. Tendrá que implementar estrategias de agrupación de conexiones y, posiblemente, utilizar [Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) para gestionar las conexiones de forma eficaz. Tenga en cuenta que el uso de Amazon RDS Proxy conlleva costos adicionales.

### Patrones de acceso a datos
<a name="w2aad101d101c19c13b9b3"></a>
+ DynamoDB funciona mejor con patrones de acceso conocidos y diseños de tabla única. Es ideal para las aplicaciones de Lambda que necesitan un acceso uniforme de baja latencia a los datos en función de claves principales o índices secundarios.
+ Amazon RDS proporciona flexibilidad para consultas complejas y patrones de acceso cambiantes. Es más adecuado cuando las funciones de Lambda necesitan realizar consultas únicas y personalizadas, o uniones complejas en varias tablas.

### Complejidad de la consulta
<a name="w2aad101d101c19c13b9b5"></a>
+ DynamoDB se destaca por sus operaciones sencillas basadas en claves y por sus patrones de acceso predefinidos. Las consultas complejas deben diseñarse en torno a estructuras de índices y las uniones deben gestionarse en el código de la aplicación.
+ Amazon RDS admite consultas SQL complejas con uniones, subconsultas y agregaciones. Esto puede simplificar el código de la función de Lambda cuando se necesitan operaciones de datos complejas.

### Requisitos de consistencia de datos
<a name="w2aad101d101c19c13b9b7"></a>
+ DynamoDB ofrece opciones de consistencia posterior y alta, con una consistencia alta disponible para lecturas de un solo elemento. Se admiten transacciones, pero con algunas limitaciones.
+ Amazon RDS es totalmente compatibles con las propiedades de atomicidad, coherencia, aislamiento y durabilidad (ACID), y admite transacciones complejas. Si sus funciones de Lambda requieren transacciones complejas o una consistencia alta en varios registros, Amazon RDS podría ser más adecuado.

### Características de escalado
<a name="w2aad101d101c19c13b9b9"></a>
+ DynamoDB escala automáticamente en función de su carga de trabajo. Puede gestionar picos repentinos de tráfico procedentes de las funciones de Lambda sin necesidad de aprovisionamiento previo. Puede utilizar el modo de capacidad bajo demanda para pagar solo lo que utilice, lo que se adapta perfectamente al modelo de escalado de Lambda.
+ Amazon RDS tiene una capacidad fija en función del tamaño de instancia que elija. Si varias funciones de Lambda intentan conectarse al mismo tiempo, es posible que supere la cuota de conexión. Debe administrar cuidadosamente los grupos de conexiones y, si es posible, implementar una lógica de reintento.

### Modelo de costos
<a name="w2aad101d101c19c13b9c11"></a>
+ Los precios de DynamoDB se ajustan bien a los de las aplicaciones sin servidor. Con la capacidad bajo demanda, solo paga las lecturas y escrituras reales que realizan sus funciones de Lambda. No se cobran cargos por el tiempo de inactividad.
+ Amazon RDS cobra por la instancia en ejecución independientemente del uso. Esto puede resultar menos rentable para las cargas de trabajo esporádicas que pueden ser típicas de las aplicaciones sin servidor. Sin embargo, podría resultar más económico para las cargas de trabajo de alto rendimiento con un uso constante.

## Comenzar a usar el servicio de base de datos de su elección
<a name="w2aad101d101c19c15"></a>

Ahora que ha leído los criterios para seleccionar entre DynamoDB y Amazon RDS y las principales diferencias entre ellos, puede seleccionar la opción que mejor se adapte a sus necesidades y utilizar los siguientes recursos para empezar a utilizarla.

------
#### [ DynamoDB ]

**Comenzar a usar DynamoDB con los siguientes recursos**
+ Para obtener una introducción al servicio de DynamoDB, consulte [¿Qué es DynamoDB?](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) en la *Guía para desarrolladores de Amazon DynamoDB*.
+ Siga el tutorial [Uso de Lambda con API Gateway](services-apigateway-tutorial.md) para ver un ejemplo del uso de una función de Lambda para realizar operaciones CRUD en una tabla de DynamoDB en respuesta a una solicitud de API.
+ Lea [Programación con DynamoDB y los SDK de AWS](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.html) en la *Guía para desarrolladores de Amazon DynamoDB* para obtener más información sobre cómo acceder a DynamoDB desde la función de Lambda mediante uno de los SDK de AWS.

------
#### [ Amazon RDS ]

**Comience a usar Amazon RDS con los siguientes recursos**
+ Para obtener una introducción al servicio de Amazon RDS, consulte [¿Qué es Amazon Relational Database Service (Amazon RDS)?](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) en la *Guía del usuario de Amazon Relational Database Service*.
+ Siga el tutorial [Uso de una función de Lambda para acceder a una base de datos de Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html) en la *Guía del usuario de Amazon Relational Database Service*.
+ Obtenga más información sobre el uso de Lambda con Amazon RDS en [Uso de AWS Lambda con Amazon RDS](services-rds.md).

------

# Procese las notificaciones de eventos de Amazon S3 con Lambda.
<a name="with-s3"></a>

Puede usar Lambda para procesar [notificaciones de eventos](https://docs.aws.amazon.com/AmazonS3/latest/userguide/NotificationHowTo.html) de Amazon Simple Storage Service. Amazon S3 puede enviar un evento a una función de Lambda cuando se crea o elimina un objeto. Puede configurar las opciones de notificación en un bucket y conceder a Amazon S3 permiso para invocar una función en la política de permisos basada en recursos de la función.

**aviso**  
Si la función de Lambda utiliza el mismo bucket que el que la desencadena, podría ocurrir que la ejecución de la función entrara en un bucle. Por ejemplo, si el bucket activa una función cada vez que se carga un objeto y la función carga un objeto en el bucket, la función se activa indirectamente a sí misma. Para evitarlo, utilice dos buckets o configure el desencadenador para que solo se aplique a un prefijo que se utiliza para los objetos entrantes.

Amazon S3 invoca la función de [forma asíncrona](invocation-async.md) con un evento que contiene detalles sobre el objeto. En el siguiente ejemplo se muestra un evento que envió Amazon S3 cuando se cargó un paquete de implementación en Amazon S3.

**Example Evento de notificaciones de Amazon S3**  

```
{
  "Records": [
    {
      "eventVersion": "2.1",
      "eventSource": "aws:s3",
      "awsRegion": "us-east-2",
      "eventTime": "2019-09-03T19:37:27.192Z",
      "eventName": "ObjectCreated:Put",
      "userIdentity": {
        "principalId": "AWS:AIDAINPONIXQXHT3IKHL2"
      },
      "requestParameters": {
        "sourceIPAddress": "205.255.255.255"
      },
      "responseElements": {
        "x-amz-request-id": "D82B88E5F771F645",
        "x-amz-id-2": "vlR7PnpV2Ce81l0PRw6jlUpck7Jo5ZsQjryTjKlc5aLWGVHPZLj5NeC6qMa0emYBDXOo6QBU0Wo="
      },
      "s3": {
        "s3SchemaVersion": "1.0",
        "configurationId": "828aa6fc-f7b5-4305-8584-487c791949c1",
        "bucket": {
          "name": "amzn-s3-demo-bucket",
          "ownerIdentity": {
            "principalId": "A3I5XTEXAMAI3E"
          },
          "arn": "arn:aws:s3:::lambda-artifacts-deafc19498e3f2df"
        },
        "object": {
          "key": "b21b84d653bb07b05b1e6b33684dc11b",
          "size": 1305107,
          "eTag": "b21b84d653bb07b05b1e6b33684dc11b",
          "sequencer": "0C0F6F405D6ED209E1"
        }
      }
    }
  ]
}
```

Para invocar la función, Amazon S3 necesita permiso de la [política basada en recursos](access-control-resource-based.md) de la función. Al configurar un desencadenador de Amazon S3 en la consola de Lambda, esta modifica la política basada en recursos para permitir a Amazon S3 invocar la función si el nombre del bucket y el ID de cuenta coinciden. Si configura la notificación en Amazon S3, utilice la API de Lambda para actualizar la política. También puede utilizar la API de Lambda para conceder permisos a otra cuenta o restringir el permiso a un alias designado.

Si la función utiliza el SDK de AWS para administrar los recursos de Amazon S3, también necesita permisos de Amazon S3 en su [rol de ejecución](lambda-intro-execution-role.md). 

**Topics**
+ [

# Tutorial: Uso de un desencadenador de Amazon S3 para invocar una función de Lambda
](with-s3-example.md)
+ [

# Tutorial: Uso de un desencadenador de Amazon S3 para crear imágenes en miniatura
](with-s3-tutorial.md)

# Tutorial: Uso de un desencadenador de Amazon S3 para invocar una función de Lambda
<a name="with-s3-example"></a>

En este tutorial, se utiliza la consola a fin de crear una función de Lambda y configurar un desencadenador para un bucket de Amazon Simple Storage Service (Amazon S3). Cada vez que agrega un objeto al bucket de Amazon S3, la función se ejecuta y muestra el tipo de objeto en Registros de Amazon CloudWatch.

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3_tut_config.png)


En este tutorial se muestra cómo:

1. Cree un bucket de Amazon S3.

1. Cree una función de Lambda que devuelva el tipo de objeto de los objetos en un bucket de Amazon S3.

1. Configure un desencadenador de Lambda que invoque su función cuando se carguen objetos en su bucket.

1. Pruebe su función, primero con un evento de prueba y, a continuación, con el desencadenador.

Al completar estos pasos, aprenderá a configurar una función de Lambda para que se ejecute siempre que se agreguen objetos a un bucket de Amazon S3 o se eliminen de él. Solo puede completar este tutorial mediante la Consola de administración de AWS.

## Crear un bucket de Amazon S3
<a name="with-s3-example-create-bucket"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps1.png)


**Creación de un bucket de Amazon S3**

1. Abra la [consola de Amazon S3](https://console.aws.amazon.com/s3) y seleccione la página **Buckets de uso general**.

1. Seleccione la Región de AWS más cercana a su ubicación geográfica. Puede cambiar la región por medio de la lista desplegable de la parte superior de la pantalla. Más adelante en el tutorial, debe crear la función de Lambda en la misma región.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/console_region_select.png)

1. Elija **Crear bucket**.

1. En **Configuración general**, haga lo siguiente:

   1. En **Tipo de bucket**, asegúrese de que **Uso general** está seleccionado.

   1. Para el **nombre del bucket**, ingrese un nombre único a nivel mundial que cumpla las [reglas de nomenclatura de bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html) de Amazon S3. Los nombres de bucket pueden contener únicamente letras minúsculas, números, puntos (.) y guiones (-).

1. Deje el resto de las opciones con sus valores predeterminados y seleccione **Crear bucket**.

## Cargar un objeto de prueba en un bucket
<a name="with-s3-example-upload-test-object"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps2.png)


**Para cargar un objeto de prueba**

1. Abra la página [Buckets](https://console.aws.amazon.com/s3/buckets) de la consola de Amazon S3 y elija el bucket que creó durante el paso anterior.

1. Seleccione **Cargar**.

1. Elija **Agregar archivos** y seleccione el objeto que desea cargar. Puede seleccionar cualquier archivo (por ejemplo, `HappyFace.jpg`).

1. Elija **Abrir** y, a continuación, **Cargar**.

Más adelante en el tutorial, probará la función de Lambda con este objeto.

## Creación de una política de permisos
<a name="with-s3-example-create-policy"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps3.png)


Cree una política de permisos que le permita a Lambda obtener objetos de un bucket de Amazon S3 y escribir en los Registros de Amazon CloudWatch. 

**Para crear la política de**

1. Abra la página de [Policies (Políticas)](https://console.aws.amazon.com/iam/home#/policies) de la consola de IAM.

1. Seleccione **Crear política**.

1. Elija la pestaña **JSON** y pegue la siguiente política personalizada en el editor JSON.

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "logs:PutLogEvents",
                   "logs:CreateLogGroup",
                   "logs:CreateLogStream"
               ],
               "Resource": "arn:aws:logs:*:*:*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "s3:GetObject"
               ],
               "Resource": "arn:aws:s3:::*/*"
           }
       ]
   }
   ```

------

1. Elija **Siguiente: Etiquetas**.

1. Elija **Siguiente: Revisar**.

1. En **Review policy (Revisar política)**, para el **Name (Nombre)** de la política, ingrese **s3-trigger-tutorial**.

1. Elija **Crear política**.

## Creación de un rol de ejecución
<a name="with-s3-example-create-role"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps4.png)


Un [rol de ejecución](lambda-intro-execution-role.md) es un rol de AWS Identity and Access Management (IAM) que concede a la función de Lambda permiso para acceder a recursos y Servicios de AWS. En este paso, creará un rol de ejecución mediante la política de permisos que creó en el paso anterior.

**Para crear una función de ejecución y adjuntar su política de permisos personalizada**

1. Abra la [página Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Elija **Create role** (Crear rol).

1. Para el tipo de entidad de confianza, seleccione **Servicio de AWS** y, para el caso de uso, elija **Lambda**.

1. Elija **Siguiente**.

1. En el cuadro de búsqueda de políticas, escriba **s3-trigger-tutorial**.

1. En los resultados de búsqueda, seleccione la política que ha creado (`s3-trigger-tutorial`), y luego **Next** (Siguiente).

1. En **Role details** (Detalles del rol), introduzca **lambda-s3-trigger-role** en **Role name** (Nombre del rol) y, luego, elija **Create role** (Crear rol).

## Crear la función de Lambda
<a name="with-s3-example-create-function"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps5.png)


Cree una función de Lambda en la consola con el tiempo de ejecución de Python 3.14.

**Para crear la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Asegúrese de trabajar en la misma Región de AWS en la que creó el bucket de Amazon S3. Puede cambiar la región mediante la lista desplegable de la parte superior de la pantalla.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/console_region_select.png)

1. Seleccione **Creación de función**.

1. Elija **Crear desde cero**.

1. Bajo **Información básica**, haga lo siguiente:

   1. En **Nombre de la función**, ingrese `s3-trigger-tutorial`.

   1. En **Tiempo de ejecución**, seleccione **Python 3.14**.

   1. En **Arquitectura**, elija **x86\$164**.

1. En la pestaña **Cambiar rol de ejecución predeterminado**, haga lo siguiente:

   1. Amplíe la pestaña y, a continuación, elija **Utilizar un rol existente**.

   1. Seleccione el `lambda-s3-trigger-role` que creó anteriormente.

1. Seleccione **Creación de función**.

## Implementar el código de la función
<a name="with-s3-example-deploy-code"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps6.png)


En este tutorial, se utiliza el tiempo de ejecución de Python 3.14, pero también proporcionamos archivos de código de ejemplo para otros tiempos de ejecución. Puede seleccionar la pestaña del siguiente cuadro para ver el código del tiempo de ejecución que le interesa.

La función de Lambda recuperará el nombre de clave del objeto cargado y el nombre del bucket desde el parámetro `event` que recibe de Amazon S3. A continuación, la función utiliza el método [get\$1object](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/get_object.html) de AWS SDK para Python (Boto3) para recuperar los metadatos del objeto, incluido el tipo de contenido (tipo MIME) del objeto cargado.

**Para implementar el código de la función**

1. Seleccione la pestaña **Python** en el siguiente cuadro y copie el código.

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Uso de un evento de S3 con Lambda mediante .NET.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   ﻿using System.Threading.Tasks;
   using Amazon.Lambda.Core;
   using Amazon.S3;
   using System;
   using Amazon.Lambda.S3Events;
   using System.Web;
   
   // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
   [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
   
   namespace S3Integration
   {
       public class Function
       {
           private static AmazonS3Client _s3Client;
           public Function() : this(null)
           {
           }
   
           internal Function(AmazonS3Client s3Client)
           {
               _s3Client = s3Client ?? new AmazonS3Client();
           }
   
           public async Task<string> Handler(S3Event evt, ILambdaContext context)
           {
               try
               {
                   if (evt.Records.Count <= 0)
                   {
                       context.Logger.LogLine("Empty S3 Event received");
                       return string.Empty;
                   }
   
                   var bucket = evt.Records[0].S3.Bucket.Name;
                   var key = HttpUtility.UrlDecode(evt.Records[0].S3.Object.Key);
   
                   context.Logger.LogLine($"Request is for {bucket} and {key}");
   
                   var objectResult = await _s3Client.GetObjectAsync(bucket, key);
   
                   context.Logger.LogLine($"Returning {objectResult.Key}");
   
                   return objectResult.Key;
               }
               catch (Exception e)
               {
                   context.Logger.LogLine($"Error processing request - {e.Message}");
   
                   return string.Empty;
               }
           }
       }
   }
   ```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Uso de un evento de S3 con Lambda mediante Go.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   package main
   
   import (
   	"context"
   	"log"
   
   	"github.com/aws/aws-lambda-go/events"
   	"github.com/aws/aws-lambda-go/lambda"
   	"github.com/aws/aws-sdk-go-v2/config"
   	"github.com/aws/aws-sdk-go-v2/service/s3"
   )
   
   func handler(ctx context.Context, s3Event events.S3Event) error {
   	sdkConfig, err := config.LoadDefaultConfig(ctx)
   	if err != nil {
   		log.Printf("failed to load default config: %s", err)
   		return err
   	}
   	s3Client := s3.NewFromConfig(sdkConfig)
   
   	for _, record := range s3Event.Records {
   		bucket := record.S3.Bucket.Name
   		key := record.S3.Object.URLDecodedKey
   		headOutput, err := s3Client.HeadObject(ctx, &s3.HeadObjectInput{
   			Bucket: &bucket,
   			Key:    &key,
   		})
   		if err != nil {
   			log.Printf("error getting head of object %s/%s: %s", bucket, key, err)
   			return err
   		}
   		log.Printf("successfully retrieved %s/%s of type %s", bucket, key, *headOutput.ContentType)
   	}
   
   	return nil
   }
   
   func main() {
   	lambda.Start(handler)
   }
   ```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Uso de un evento de S3 con Lambda mediante Java.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   package example;
   
   import software.amazon.awssdk.services.s3.model.HeadObjectRequest;
   import software.amazon.awssdk.services.s3.model.HeadObjectResponse;
   import software.amazon.awssdk.services.s3.S3Client;
   
   import com.amazonaws.services.lambda.runtime.Context;
   import com.amazonaws.services.lambda.runtime.RequestHandler;
   import com.amazonaws.services.lambda.runtime.events.S3Event;
   import com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification.S3EventNotificationRecord;
   
   import org.slf4j.Logger;
   import org.slf4j.LoggerFactory;
   
   public class Handler implements RequestHandler<S3Event, String> {
       private static final Logger logger = LoggerFactory.getLogger(Handler.class);
       @Override
       public String handleRequest(S3Event s3event, Context context) {
           try {
             S3EventNotificationRecord record = s3event.getRecords().get(0);
             String srcBucket = record.getS3().getBucket().getName();
             String srcKey = record.getS3().getObject().getUrlDecodedKey();
   
             S3Client s3Client = S3Client.builder().build();
             HeadObjectResponse headObject = getHeadObject(s3Client, srcBucket, srcKey);
   
             logger.info("Successfully retrieved " + srcBucket + "/" + srcKey + " of type " + headObject.contentType());
   
             return "Ok";
           } catch (Exception e) {
             throw new RuntimeException(e);
           }
       }
   
       private HeadObjectResponse getHeadObject(S3Client s3Client, String bucket, String key) {
           HeadObjectRequest headObjectRequest = HeadObjectRequest.builder()
                   .bucket(bucket)
                   .key(key)
                   .build();
           return s3Client.headObject(headObjectRequest);
       }
   }
   ```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Uso de un evento de S3 con Lambda mediante JavaScript.  

   ```
   import { S3Client, HeadObjectCommand } from "@aws-sdk/client-s3";
   
   const client = new S3Client();
   
   export const handler = async (event, context) => {
   
       // Get the object from the event and show its content type
       const bucket = event.Records[0].s3.bucket.name;
       const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
   
       try {
           const { ContentType } = await client.send(new HeadObjectCommand({
               Bucket: bucket,
               Key: key,
           }));
   
           console.log('CONTENT TYPE:', ContentType);
           return ContentType;
   
       } catch (err) {
           console.log(err);
           const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
           console.log(message);
           throw new Error(message);
       }
   };
   ```
Uso de un evento de S3 con Lambda mediante TypeScript.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   import { S3Event } from 'aws-lambda';
   import { S3Client, HeadObjectCommand } from '@aws-sdk/client-s3';
   
   const s3 = new S3Client({ region: process.env.AWS_REGION });
   
   export const handler = async (event: S3Event): Promise<string | undefined> => {
     // Get the object from the event and show its content type
     const bucket = event.Records[0].s3.bucket.name;
     const key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
     const params = {
       Bucket: bucket,
       Key: key,
     };
     try {
       const { ContentType } = await s3.send(new HeadObjectCommand(params));
       console.log('CONTENT TYPE:', ContentType);
       return ContentType;
     } catch (err) {
       console.log(err);
       const message = `Error getting object ${key} from bucket ${bucket}. Make sure they exist and your bucket is in the same region as this function.`;
       console.log(message);
       throw new Error(message);
     }
   };
   ```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Consumo de un evento de S3 con Lambda mediante PHP.  

   ```
   <?php
   
   use Bref\Context\Context;
   use Bref\Event\S3\S3Event;
   use Bref\Event\S3\S3Handler;
   use Bref\Logger\StderrLogger;
   
   require __DIR__ . '/vendor/autoload.php';
   
   
   class Handler extends S3Handler 
   {
       private StderrLogger $logger;
       public function __construct(StderrLogger $logger)
       {
           $this->logger = $logger;
       }
       
       public function handleS3(S3Event $event, Context $context) : void
       {
           $this->logger->info("Processing S3 records");
   
           // Get the object from the event and show its content type
           $records = $event->getRecords();
           
           foreach ($records as $record) 
           {
               $bucket = $record->getBucket()->getName();
               $key = urldecode($record->getObject()->getKey());
   
               try {
                   $fileSize = urldecode($record->getObject()->getSize());
                   echo "File Size: " . $fileSize . "\n";
                   // TODO: Implement your custom processing logic here
               } catch (Exception $e) {
                   echo $e->getMessage() . "\n";
                   echo 'Error getting object ' . $key . ' from bucket ' . $bucket . '. Make sure they exist and your bucket is in the same region as this function.' . "\n";
                   throw $e;
               }
           }
       }
   }
   
   $logger = new StderrLogger();
   return new Handler($logger);
   ```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Uso de un evento de S3 con Lambda mediante Python.  

   ```
   # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # SPDX-License-Identifier: Apache-2.0
   import json
   import urllib.parse
   import boto3
   
   print('Loading function')
   
   s3 = boto3.client('s3')
   
   
   def lambda_handler(event, context):
       #print("Received event: " + json.dumps(event, indent=2))
   
       # Get the object from the event and show its content type
       bucket = event['Records'][0]['s3']['bucket']['name']
       key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
       try:
           response = s3.get_object(Bucket=bucket, Key=key)
           print("CONTENT TYPE: " + response['ContentType'])
           return response['ContentType']
       except Exception as e:
           print(e)
           print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket))
           raise e
   ```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Consumo de un evento de S3 con Lambda mediante Ruby.  

   ```
   require 'json'
   require 'uri'
   require 'aws-sdk'
   
   puts 'Loading function'
   
   def lambda_handler(event:, context:)
     s3 = Aws::S3::Client.new(region: 'region') # Your AWS region
     # puts "Received event: #{JSON.dump(event)}"
   
     # Get the object from the event and show its content type
     bucket = event['Records'][0]['s3']['bucket']['name']
     key = URI.decode_www_form_component(event['Records'][0]['s3']['object']['key'], Encoding::UTF_8)
     begin
       response = s3.get_object(bucket: bucket, key: key)
       puts "CONTENT TYPE: #{response.content_type}"
       return response.content_type
     rescue StandardError => e
       puts e.message
       puts "Error getting object #{key} from bucket #{bucket}. Make sure they exist and your bucket is in the same region as this function."
       raise e
     end
   end
   ```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Uso de un evento de S3 con Lambda mediante Rust.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   use aws_lambda_events::event::s3::S3Event;
   use aws_sdk_s3::{Client};
   use lambda_runtime::{run, service_fn, Error, LambdaEvent};
   
   
   /// Main function
   #[tokio::main]
   async fn main() -> Result<(), Error> {
       tracing_subscriber::fmt()
           .with_max_level(tracing::Level::INFO)
           .with_target(false)
           .without_time()
           .init();
   
       // Initialize the AWS SDK for Rust
       let config = aws_config::load_from_env().await;
       let s3_client = Client::new(&config);
   
       let res = run(service_fn(|request: LambdaEvent<S3Event>| {
           function_handler(&s3_client, request)
       })).await;
   
       res
   }
   
   async fn function_handler(
       s3_client: &Client,
       evt: LambdaEvent<S3Event>
   ) -> Result<(), Error> {
       tracing::info!(records = ?evt.payload.records.len(), "Received request from SQS");
   
       if evt.payload.records.len() == 0 {
           tracing::info!("Empty S3 event received");
       }
   
       let bucket = evt.payload.records[0].s3.bucket.name.as_ref().expect("Bucket name to exist");
       let key = evt.payload.records[0].s3.object.key.as_ref().expect("Object key to exist");
   
       tracing::info!("Request is for {} and object {}", bucket, key);
   
       let s3_get_object_result = s3_client
           .get_object()
           .bucket(bucket)
           .key(key)
           .send()
           .await;
   
       match s3_get_object_result {
           Ok(_) => tracing::info!("S3 Get Object success, the s3GetObjectResult contains a 'body' property of type ByteStream"),
           Err(_) => tracing::info!("Failure with S3 Get Object request")
       }
   
       Ok(())
   }
   ```

------

1. En el panel **Código fuente** de la consola de Lambda, pegue el siguiente código en el editor de código y sustituya el código creado por Lambda.

1. En la sección **IMPLEMENTAR** elija **Implementar** para actualizar el código de la función:  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

## Cree un desencadenador de Amazon S3
<a name="with-s3-example-create-trigger"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps7.png)


**Para crear el desencadenador de Amazon S3**

1. En el panel **Información general de la función**, elija **Agregar desencadenador**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/overview-trigger.png)

1. Seleccione **S3**.

1. En **Bucket**, seleccione el bucket que creó anteriormente en el tutorial.

1. En **Tipos de eventos**, asegúrese de seleccionar **Todos los eventos de creación de objetos**.

1. En **Invocación recursiva**, marque la casilla de verificación para confirmar que no se recomienda utilizar el mismo bucket de Amazon S3 para la entrada y la salida.

1. Elija **Agregar**.

**nota**  
Cuando crea un desencadenador de Amazon S3 para una función de Lambda mediante la consola de Lambda, Amazon S3 configura una [notificación de eventos](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventNotifications.html) en el bucket que especifique. Antes de configurar esta notificación de evento, Amazon S3 realiza una serie de comprobaciones para confirmar que el destino del evento existe y tiene las políticas de IAM requeridas. Amazon S3 también realiza estas pruebas en cualquier otra notificación de eventos configurada para ese bucket.  
Gracias a esta comprobación, si el bucket ha configurado previamente destinos de eventos para recursos que ya no existen o para recursos que no tienen las políticas de permisos requeridas, Amazon S3 no podrá crear la nueva notificación de evento. Verá el siguiente mensaje de error que indica que no se ha podido crear el desencadenador:  

```
An error occurred when creating the trigger: Unable to validate the following destination configurations.
```
Puede ver este error si anteriormente configuró un desencadenador para otra función de Lambda con el mismo bucket y, desde entonces, ha eliminado la función o modificado sus políticas de permisos.

## Probar la función de Lambda con un evento de prueba
<a name="with-s3-example-test-dummy-event"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps8.png)


**Para probar la función de Lambda con un evento de prueba**

1. En la página de la consola de Lambda para la función, seleccione la pestaña **Prueba**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/test-tab.png)

1. En **Nombre del evento**, escriba `MyTestEvent`.

1. En el **Evento JSON**, pegue el siguiente evento de prueba. Asegúrese de reemplazar los siguientes valores:
   + Reemplace `us-east-1` por la región en la que creó el bucket de Amazon S3.
   + Reemplace ambas instancias de `amzn-s3-demo-bucket` por el nombre de su bucket de Amazon S3.
   + Reemplace `test%2FKey` por el nombre del objeto de prueba que cargó anteriormente al bucket (por ejemplo, `HappyFace.jpg`).

   ```
   {
     "Records": [
       {
         "eventVersion": "2.0",
         "eventSource": "aws:s3",
         "awsRegion": "us-east-1",
         "eventTime": "1970-01-01T00:00:00.000Z",
         "eventName": "ObjectCreated:Put",
         "userIdentity": {
           "principalId": "EXAMPLE"
         },
         "requestParameters": {
           "sourceIPAddress": "127.0.0.1"
         },
         "responseElements": {
           "x-amz-request-id": "EXAMPLE123456789",
           "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
         },
         "s3": {
           "s3SchemaVersion": "1.0",
           "configurationId": "testConfigRule",
           "bucket": {
             "name": "amzn-s3-demo-bucket",
             "ownerIdentity": {
               "principalId": "EXAMPLE"
             },
             "arn": "arn:aws:s3:::amzn-s3-demo-bucket"
           },
           "object": {
             "key": "test%2Fkey",
             "size": 1024,
             "eTag": "0123456789abcdef0123456789abcdef",
             "sequencer": "0A1B2C3D4E5F678901"
           }
         }
       }
     ]
   }
   ```

1. Seleccione **Save**.

1. Seleccione **Probar**

1. Si la función se ejecuta correctamente, verá un resultado similar al siguiente en la pestaña **Resultados de ejecución**.

   ```
   Response
   "image/jpeg"
   
   Function Logs
   START RequestId: 12b3cae7-5f4e-415e-93e6-416b8f8b66e6 Version: $LATEST
   2021-02-18T21:40:59.280Z    12b3cae7-5f4e-415e-93e6-416b8f8b66e6    INFO    INPUT BUCKET AND KEY:  { Bucket: 'amzn-s3-demo-bucket', Key: 'HappyFace.jpg' }
   2021-02-18T21:41:00.215Z    12b3cae7-5f4e-415e-93e6-416b8f8b66e6    INFO    CONTENT TYPE: image/jpeg
   END RequestId: 12b3cae7-5f4e-415e-93e6-416b8f8b66e6
   REPORT RequestId: 12b3cae7-5f4e-415e-93e6-416b8f8b66e6    Duration: 976.25 ms    Billed Duration: 977 ms    Memory Size: 128 MB    Max Memory Used: 90 MB    Init Duration: 430.47 ms        
   
   Request ID
   12b3cae7-5f4e-415e-93e6-416b8f8b66e6
   ```

### Probar la función de Lambda con el desencadenador de Amazon S3
<a name="with-s3-example-test-s3-trigger"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps9.png)


Para probar la función con el desencadenador configurado, se carga un objeto al bucket de Amazon S3 mediante la consola. Para comprobar que la función de Lambda se ha ejecutado correctamente, utilice Registros de CloudWatch para ver la salida de la función.

**Para cargar un objeto en un bucket de Amazon S3**

1. Abra la página [Buckets](https://console.aws.amazon.com/s3/buckets) de la consola de Amazon S3 y elija el nombre del bucket que creó anteriormente.

1. Seleccione **Cargar**.

1. Elija **Agregar archivos** y utilice el selector de archivos para elegir el objeto que desee cargar. Este objeto puede ser cualquier archivo que elija.

1. Elija **Abrir** y, a continuación, **Cargar**.

**Comprobación de la invocación de la función mediante Registros de CloudWatch**

1. [Abra la consola de CloudWatch](https://console.aws.amazon.com/cloudwatch/home).

1. Asegúrese de trabajar en la misma Región de AWS en la que creó la función de Lambda. Puede cambiar la región mediante la lista desplegable de la parte superior de la pantalla.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/console_region_select.png)

1. Elija **Registros** y, a continuación, **Grupos de registro**.

1. Elija el grupo de registro para la función (`/aws/lambda/s3-trigger-tutorial`).

1. En **Flujos de registro**, elija el flujo de registro más reciente.

1. Si su función se ha invocado correctamente en respuesta a su desencadenador de Amazon S3, verá un resultado similar al siguiente. El `CONTENT TYPE` que vea depende del tipo de archivo que haya subido a su bucket.

   ```
   2022-05-09T23:17:28.702Z	0cae7f5a-b0af-4c73-8563-a3430333cc10	INFO	CONTENT TYPE: image/jpeg
   ```

## Eliminación de sus recursos
<a name="cleanup"></a>

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

**Cómo eliminar la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que ha creado.

1. Elija **Acciones**, **Eliminar**.

1. Escriba **confirm** en el campo de entrada de texto y elija **Delete**(Eliminar).

**Cómo eliminar el rol de ejecución**

1. Abra la página [Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione el rol de ejecución que creó.

1. Elija **Eliminar**.

1. Si desea continuar, escriba el nombre del rol en el campo de entrada de texto y elija **Delete** (Eliminar).

**Para eliminar el bucket de S3**

1. Abra la [consola de Amazon S3](https://console.aws.amazon.com//s3/home#).

1. Seleccione el bucket que ha creado.

1. Elija **Eliminar**.

1. Introduzca el nombre del bucket en el campo de entrada de texto.

1. Elija **Delete bucket (Eliminar bucket)**.

## Siguientes pasos
<a name="next-steps"></a>

En [Tutorial: Uso de un desencadenador de Amazon S3 para crear imágenes en miniatura](with-s3-tutorial.md), el desencadenador de Amazon S3 invoca una función que crea una imagen en miniatura para cada archivo de imagen que se carga en el bucket. Este tutorial requiere un nivel moderado de conocimiento del dominio de AWS y Lambda. Demuestra cómo crear recursos usando la AWS Command Line Interface (AWS CLI) y cómo crear un paquete de implementación de archivo .zip para la función y sus dependencias.

# Tutorial: Uso de un desencadenador de Amazon S3 para crear imágenes en miniatura
<a name="with-s3-tutorial"></a>

En este tutorial, se crea y configura una función de Lambda para cambiar el tamaño de las imágenes agregadas a un bucket de Amazon Simple Storage Service (Amazon S3). Al agregar un archivo de imagen al bucket, Amazon S3 invoca la función de Lambda. A continuación, la función crea una versión en miniatura de la imagen y la envía a otro bucket de Amazon S3.

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_resources.png)


Para completar este tutorial, lleve a cabo los siguientes pasos:

1. Cree buckets de origen y destino de Amazon S3 y cargue una imagen de muestra.

1. Cree una función de Lambda que cambie el tamaño de una imagen y genere una miniatura en un bucket de Amazon S3.

1. Configure un desencadenador de Lambda que invoque la función cuando se carguen objetos en el bucket de origen.

1. Pruebe la función, primero con un evento ficticio y, a continuación, cargando una imagen al bucket de origen.

Al completar estos pasos, aprenderá a utilizar Lambda para llevar a cabo una tarea de procesamiento de archivos en objetos agregados a un bucket de Amazon S3. Puede completar esta tarea mediante la AWS Command Line Interface (AWS CLI) o la Consola de administración de AWS.

Si busca un ejemplo más sencillo para aprender a configurar un desencadenador de Amazon S3 para Lambda, puede probar el [Tutorial: Uso de un desencadenador de Amazon S3 para invocar una función de Lambda](https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html).

**Topics**
+ [

## Requisitos previos
](#with-s3-example-prereqs)
+ [

## Crear dos buckets de Amazon S3
](#with-s3-tutorial-prepare-create-buckets)
+ [

## Cargar una imagen de prueba al bucket de origen
](#with-s3-tutorial-test-image)
+ [

## Creación de una política de permisos
](#with-s3-tutorial-create-policy)
+ [

## Creación de un rol de ejecución
](#with-s3-tutorial-create-execution-role)
+ [

## Crear el paquete de despliegue de la función
](#with-s3-tutorial-create-function-package)
+ [

## Crear la función de Lambda
](#with-s3-tutorial-create-function-createfunction)
+ [

## Configurar Amazon S3 para invocar una función
](#with-s3-tutorial-configure-s3-trigger)
+ [

## Probar la función de Lambda con un evento de prueba
](#with-s3-tutorial-dummy-test)
+ [

## Probar la función con el desencadenador de Amazon S3
](#with-s3-tutorial-test-s3)
+ [

## Eliminación de sus recursos
](#s3-tutorial-cleanup)

## Requisitos previos
<a name="with-s3-example-prereqs"></a>

Si desea utilizar la AWS CLI para completar el tutorial, instale la [versión más reciente de la AWS Command Line Interface]().

Para el código de la función de Lambda, puede utilizar Python o Node.js. Instale las herramientas de soporte de lenguajes y un administrador de paquetes para el lenguaje que desee utilizar. 

### Instala la AWS Command Line Interface
<a name="install_aws_cli"></a>

Si aún no ha instalado AWS Command Line Interface, siga los pasos que se indican en [Instalación o actualización de la versión más reciente de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalarlo.

El tutorial requiere un intérprete de comandos o un terminal de línea de comando para ejecutar los comandos. En Linux y macOS, use su administrador de intérprete de comandos y paquetes preferido.

**nota**  
En Windows, algunos comandos de la CLI de Bash que se utilizan habitualmente con Lambda (por ejemplo, `zip`) no son compatibles con los terminales integrados del sistema operativo. Para obtener una versión de Ubuntu y Bash integrada con Windows, [instale el subsistema de Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Crear dos buckets de Amazon S3
<a name="with-s3-tutorial-prepare-create-buckets"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps1.png)


Primero, cree dos buckets de Amazon S3. El primer bucket es el bucket de origen al que subirá las imágenes. Lambda utiliza el segundo bucket para guardar las miniaturas redimensionadas cuando se invoca la función.

------
#### [ Consola de administración de AWS ]

**Para crear buckets de Amazon S3 (consola)**

1. Abra la [consola de Amazon S3](https://console.aws.amazon.com/s3) y seleccione la página **Buckets de uso general**.

1. Seleccione la Región de AWS más cercana a su ubicación geográfica. Puede cambiar la región por medio de la lista desplegable de la parte superior de la pantalla. Más adelante en el tutorial, debe crear la función de Lambda en la misma región.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/console_region_select.png)

1. Elija **Crear bucket**.

1. En **Configuración general**, haga lo siguiente:

   1. En **Tipo de bucket**, asegúrese de que **Uso general** está seleccionado.

   1. Para el **nombre del bucket**, ingrese un nombre único a nivel mundial que cumpla las [reglas de nomenclatura de bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html) de Amazon S3. Los nombres de bucket pueden contener únicamente letras minúsculas, números, puntos (.) y guiones (-).

1. Deje el resto de las opciones con sus valores predeterminados y seleccione **Crear bucket**.

1. Repita los pasos 1 a 5 para crear el bucket de destino. En **Nombre del bucket**, introduzca `amzn-s3-demo-source-bucket-resized`, donde `amzn-s3-demo-source-bucket` es el nombre del bucket de origen que acaba de crear.

------
#### [ AWS CLI ]

**Para crear buckets de Amazon S3 (AWS CLI)**

1. Ejecute el siguiente comando de la CLI para crear el bucket de origen. El nombre que elija para el bucket debe ser globalmente único y seguir las [reglas de nomenclatura de buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html) de Amazon S3. Los nombres pueden contener únicamente letras minúsculas, números, puntos (.) y guiones (-). Para `region` y `LocationConstraint`, elija la [Región de AWS](https://docs.aws.amazon.com/general/latest/gr/lambda-service.html) más cercana a su ubicación geográfica.

   ```
   aws s3api create-bucket --bucket amzn-s3-demo-source-bucket --region us-east-1 \
   --create-bucket-configuration LocationConstraint=us-east-1
   ```

   Más adelante en el tutorial, debe crear la función de Lambda en la misma Región de AWS que la del bucket de origen, por lo que debe anotar la región que eligió.

1. Ejecute el siguiente comando para crear el bucket de destino. Para el nombre del bucket, debe utilizar `amzn-s3-demo-source-bucket-resized`, donde `amzn-s3-demo-source-bucket` es el nombre del bucket de origen que creó en el paso 1. Para `region` y `LocationConstraint`, elija la misma Región de AWS que usó para crear el bucket de origen.

   ```
   aws s3api create-bucket --bucket amzn-s3-demo-source-bucket-resized --region us-east-1 \
   --create-bucket-configuration LocationConstraint=us-east-1
   ```

------

## Cargar una imagen de prueba al bucket de origen
<a name="with-s3-tutorial-test-image"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps2.png)


Más adelante en el tutorial, probará la función de Lambda al invocarla mediante la AWS CLI o la consola de Lambda. Para confirmar que la función se ejecuta correctamente, el bucket de origen debe contener una imagen de prueba. Esta imagen puede ser cualquier archivo JPG o PNG que elija.

------
#### [ Consola de administración de AWS ]

**Para cargar una imagen de prueba al bucket de origen (consola)**

1. En la consola de Amazon S3, abra la página [Buckets](https://console.aws.amazon.com/s3/buckets).

1. Seleccione el bucket de origen que creó en el paso anterior.

1. Seleccione **Cargar**.

1. Elija **Agregar archivos** y utilice el selector de archivos para elegir el objeto que desea cargar.

1. Elija **Abrir** y, a continuación, **Cargar**.

------
#### [ AWS CLI ]

**Para cargar una imagen de prueba al bucket de origen (AWS CLI)**
+ Desde el directorio que contiene la imagen que desea cargar, ejecute el siguiente comando de la CLI. Reemplace el parámetro `--bucket` con el nombre del bucket de origen. Para los parámetros `--key` y `--body`, utilice el nombre de archivo de la imagen de prueba.

  ```
  aws s3api put-object --bucket amzn-s3-demo-source-bucket --key HappyFace.jpg --body ./HappyFace.jpg
  ```

------

## Creación de una política de permisos
<a name="with-s3-tutorial-create-policy"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps3.png)


El primer paso para crear la función de Lambda es crear una política de permisos. Esta política concede a la función los permisos que necesita para acceder a otros recursos de AWS. En este tutorial, la política concede permisos de lectura y escritura a Lambda para los buckets de Amazon S3 y permite que escriba en los Registros de Amazon CloudWatch.

------
#### [ Consola de administración de AWS ]

**Para crear la política (consola)**

1. Abra la página de [Policies (Políticas)](https://console.aws.amazon.com/iamv2/home#policies) de la consola AWS Identity and Access Management (IAM).

1. Elija **Crear política**.

1. Elija la pestaña **JSON** y pegue la siguiente política personalizada en el editor JSON.  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "logs:PutLogEvents",
                   "logs:CreateLogGroup",
                   "logs:CreateLogStream"
               ],
               "Resource": "arn:aws:logs:*:*:*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "s3:GetObject"
               ],
               "Resource": "arn:aws:s3:::*/*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "s3:PutObject"
               ],
               "Resource": "arn:aws:s3:::*/*"
           }
       ]
   }
   ```

1. Elija **Siguiente**.

1. En **Detalles de política**, para el **Nombre de la política**, ingrese `LambdaS3Policy`.

1. Elija **Crear política**.

------
#### [ AWS CLI ]

**Para crear la política (AWS CLI)**

1. Guarde el siguiente JSON en un archivo llamado `policy.json`.  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "logs:PutLogEvents",
                   "logs:CreateLogGroup",
                   "logs:CreateLogStream"
               ],
               "Resource": "arn:aws:logs:*:*:*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "s3:GetObject"
               ],
               "Resource": "arn:aws:s3:::*/*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "s3:PutObject"
               ],
               "Resource": "arn:aws:s3:::*/*"
           }
       ]
   }
   ```

1. Desde el directorio en el que guardó el documento de política JSON, ejecute el siguiente comando de la CLI.

   ```
   aws iam create-policy --policy-name LambdaS3Policy --policy-document file://policy.json
   ```

------

## Creación de un rol de ejecución
<a name="with-s3-tutorial-create-execution-role"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps4.png)


Un rol de ejecución es un rol de IAM que concede a la función de Lambda permiso para acceder a servicios y recursos de Servicios de AWS. Para conceder a la función acceso de lectura y escritura a un bucket de Amazon S3, debe adjuntar la política de permisos que creó en el paso anterior.

------
#### [ Consola de administración de AWS ]

**Para crear un rol de ejecución y adjuntar la política de permisos (consola)**

1. Abra la página [Roles](https://console.aws.amazon.com/iamv2/home#roles) en la consola (IAM).

1. Elija **Creación de rol**.

1. En **Tipo de entidad de confianza**, seleccione el **Servicio de AWS**; en **Caso de uso**, seleccione **Lambda**.

1. Elija **Siguiente**.

1. Agregue la política de permisos que creó en el paso anterior de la siguiente manera:

   1. En el cuadro de búsqueda de políticas, escriba `LambdaS3Policy`.

   1. En los resultados de búsqueda, seleccione la casilla de verificación para `LambdaS3Policy`.

   1. Elija **Siguiente**.

1. En **Detalles del rol**, para el **Nombre del rol**, ingrese `LambdaS3Role`.

1. Elija **Creación de rol**.

------
#### [ AWS CLI ]

**Para crear un rol de ejecución y adjuntar la política de permisos (AWS CLI)**

1. Guarde el siguiente JSON en un archivo llamado `trust-policy.json`. Esta política de confianza permite a Lambda utilizar los permisos del rol al dar permiso al servicio principal `lambda.amazonaws.com` para llamar a la acción de AWS Security Token Service (AWS STS) `AssumeRole`.  
****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "lambda.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

1. Desde el directorio en el que guardó el documento de política de confianza JSON, ejecute el siguiente comando de la CLI para crear el rol de ejecución.

   ```
   aws iam create-role --role-name LambdaS3Role --assume-role-policy-document file://trust-policy.json
   ```

1. Para adjuntar la política de permisos que creó en el paso anterior, ejecute el siguiente comando de la CLI. Reemplace el número de Cuenta de AWS en el ARN de la política por su propio número de cuenta.

   ```
   aws iam attach-role-policy --role-name LambdaS3Role --policy-arn arn:aws:iam::123456789012:policy/LambdaS3Policy
   ```

------

## Crear el paquete de despliegue de la función
<a name="with-s3-tutorial-create-function-package"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps5.png)


Para crear una función, debe crear un *paquete de despliegue* que contenga el código y las dependencias de la función. Para esta función `CreateThumbnail`, el código de la función utiliza una biblioteca independiente para cambiar el tamaño de la imagen. Siga las instrucciones del lenguaje elegido para crear un paquete de despliegue que contenga la biblioteca requerida.

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

**Para crear el paquete de despliegue (Node.js)**

1. Cree un directorio llamado `lambda-s3` para el código y las dependencias de la función y desplácese hasta él.

   ```
   mkdir lambda-s3
   cd lambda-s3
   ```

1. Cree un nuevo proyecto de Node.js con `npm`. Para aceptar las opciones predeterminadas proporcionadas en la experiencia interactiva, oprima `Enter`.

   ```
   npm init
   ```

1. Guarde el siguiente código de función en un archivo llamado `index.mjs`. Asegúrese de reemplazar `us-east-1` por la Región de AWS en la que creó sus propios buckets de origen y destino.

   ```
   // dependencies
   import { S3Client, GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3';
   
   import { Readable } from 'stream';
   
   import sharp from 'sharp';
   import util from 'util';
   
   
   // create S3 client
   const s3 = new S3Client({region: 'us-east-1'});
   
   // define the handler function
   export const handler = async (event, context) => {
   
   // Read options from the event parameter and get the source bucket
   console.log("Reading options from event:\n", util.inspect(event, {depth: 5}));
     const srcBucket = event.Records[0].s3.bucket.name;
     
   // Object key may have spaces or unicode non-ASCII characters
   const srcKey    = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " "));
   const dstBucket = srcBucket + "-resized";
   const dstKey    = "resized-" + srcKey;
   
   // Infer the image type from the file suffix
   const typeMatch = srcKey.match(/\.([^.]*)$/);
   if (!typeMatch) {
     console.log("Could not determine the image type.");
     return;
   }
   
   // Check that the image type is supported
   const imageType = typeMatch[1].toLowerCase();
   if (imageType != "jpg" && imageType != "png") {
     console.log(`Unsupported image type: ${imageType}`);
     return;
   }
   
   // Get the image from the source bucket. GetObjectCommand returns a stream.
   try {
     const params = {
       Bucket: srcBucket,
       Key: srcKey
     };
     var response = await s3.send(new GetObjectCommand(params));
     var stream = response.Body;
     
   // Convert stream to buffer to pass to sharp resize function.
     if (stream instanceof Readable) {
       var content_buffer = Buffer.concat(await stream.toArray());
       
     } else {
       throw new Error('Unknown object stream type');
     }
   
   
   } catch (error) {
     console.log(error);
     return;
   }
   
     
   // set thumbnail width. Resize will set the height automatically to maintain aspect ratio.
   const width  = 200;
   
   // Use the sharp module to resize the image and save in a buffer.
   try {    
     var output_buffer = await sharp(content_buffer).resize(width).toBuffer();
   
   } catch (error) {
     console.log(error);
     return;
   }
   
   // Upload the thumbnail image to the destination bucket
   try {
     const destparams = {
       Bucket: dstBucket,
       Key: dstKey,
       Body: output_buffer,
       ContentType: "image"
     };
   
     const putResult = await s3.send(new PutObjectCommand(destparams));
   
     } catch (error) {
       console.log(error);
       return;
     }
   
     console.log('Successfully resized ' + srcBucket + '/' + srcKey +
       ' and uploaded to ' + dstBucket + '/' + dstKey);
     };
   ```

1. En el directorio `lambda-s3`, instale la biblioteca sharp con npm. Tenga en cuenta que la última versión de sharp (0.33) no es compatible con Lambda. Instale la versión 0.32.6 para completar este tutorial.

   ```
   npm install sharp@0.32.6
   ```

   El comando npm `install` crea un directorio `node_modules` para los módulos. Después de este paso, la estructura de directorios debería tener el siguiente aspecto.

   ```
   lambda-s3
   |- index.mjs
   |- node_modules
   |  |- base64js
   |  |- bl
   |  |- buffer
   ...
   |- package-lock.json
   |- package.json
   ```

1. Cree un paquete de despliegue .zip que contenga el código y las dependencias de la función. En Linux o macOS, ejecute el siguiente comando.

   ```
   zip -r function.zip .
   ```

   En Windows, utilice la utilidad de compresión que prefiera para crear un archivo .zip. Asegúrese de que los archivos `index.mjs`, `package.json`, `package-lock.json` y el directorio `node_modules` estén todos en la raíz del archivo .zip.

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

**Para crear el paquete de despliegue (Python)**

1. Guarde el código de ejemplo como un archivo denominado `lambda_function.py`.

   ```
   import boto3
   import os
   import sys
   import uuid
   from urllib.parse import unquote_plus
   from PIL import Image
   import PIL.Image
               
   s3_client = boto3.client('s3')
               
   def resize_image(image_path, resized_path):
     with Image.open(image_path) as image:
       image.thumbnail(tuple(x / 2 for x in image.size))
       image.save(resized_path)
               
   def lambda_handler(event, context):
     for record in event['Records']:
       bucket = record['s3']['bucket']['name']
       key = unquote_plus(record['s3']['object']['key'])
       tmpkey = key.replace('/', '')
       download_path = '/tmp/{}{}'.format(uuid.uuid4(), tmpkey)
       upload_path = '/tmp/resized-{}'.format(tmpkey)
       s3_client.download_file(bucket, key, download_path)
       resize_image(download_path, upload_path)
       s3_client.upload_file(upload_path, '{}-resized'.format(bucket), 'resized-{}'.format(key))
   ```

1. En el mismo directorio en el que creó el archivo `lambda_function.py`, cree un nuevo directorio llamado `package` e instale la biblioteca [Pillow (PIL)](https://pypi.org/project/Pillow/) y AWS SDK para Python (Boto3). Si bien el tiempo de ejecución de Lambda Python incluye una versión del SDK Boto3, recomendamos agregar todas las dependencias de la función al paquete de despliegue, incluso si están incluidas en el tiempo de ejecución. Para obtener más información, consulte [Dependencias del tiempo de ejecución en Python](https://docs.aws.amazon.com/lambda/latest/dg/python-package.html#python-package-dependencies).

   ```
   mkdir package
   pip install \
   --platform manylinux2014_x86_64 \
   --target=package \
   --implementation cp \
   --python-version 3.12 \
   --only-binary=:all: --upgrade \
   pillow boto3
   ```

   La biblioteca Pillow contiene código C y C\$1\$1. Al utilizar las opciones `--platform manylinux_2014_x86_64` y `--only-binary=:all:`, pip descargará e instalará una versión de Pillow que contiene archivos binarios precompilados compatibles con el sistema operativo Amazon Linux 2. Esto garantiza que el paquete de implementación funcione en el entorno de ejecución de Lambda, independientemente del sistema operativo y la arquitectura del equipo de compilación local.

1. Cree un archivo .zip que contenga el código de la aplicación y las bibliotecas Pillow y Boto3. En Linux o macOS, ejecute los siguientes comandos desde la interfaz de la línea de comandos.

   ```
   cd package
   zip -r ../lambda_function.zip .
   cd ..
   zip lambda_function.zip lambda_function.py
   ```

    En Windows, utilice la herramienta de compresión que prefiera para crear el archivo `lambda_function.zip`. Asegúrese de que el archivo `lambda_function.py` y las carpetas que contienen las dependencias estén en la raíz del archivo .zip.

También puede crear su paquete de implementación mediante un entorno virtual de Python. Consulte [Uso de archivos .zip para funciones de Lambda en Python](python-package.md)

------

## Crear la función de Lambda
<a name="with-s3-tutorial-create-function-createfunction"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps6.png)


También puede crear la función de Lambda con la AWS CLI o la consola de Lambda. Siga las instrucciones del lenguaje elegido para crear la función.

------
#### [ Consola de administración de AWS ]

**Para crear la función (consola)**

Para crear una función de Lambda con la consola, primero debe crear una función básica que contenga el código “Hola, mundo”. A continuación, reemplace este código por su propio código de función mediante la carga del archivo .zip o JAR que creó en el paso anterior.

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Asegúrese de trabajar en la misma Región de AWS en la que creó el bucket de Amazon S3. Puede cambiar la región por medio de la lista desplegable de la parte superior de la pantalla.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/console_region_select.png)

1. Elija **Crear función**.

1. Elija **Crear desde cero**.

1. Bajo **Información básica**, haga lo siguiente:

   1. En **Nombre de la función**, introduzca `CreateThumbnail`.

   1. En **Tiempo de ejecución**, elija **Node.js 22.x** o **Python 3.12**, según el lenguaje que elija para la función.

   1. En **Arquitectura**, elija **x86\$164**.

1. En la pestaña **Cambiar rol de ejecución predeterminado**, haga lo siguiente:

   1. Amplíe la pestaña y, a continuación, elija **Utilizar un rol existente**.

   1. Seleccione el `LambdaS3Role` que creó anteriormente.

1. Elija **Crear función**.

**Para cargar el código de la función (consola)**

1. En el panel **Código fuente**, elija **Cargar desde**.

1. Elija un **archivo .zip**. 

1. Seleccione **Cargar**.

1. En el selector de archivos, seleccione un archivo .zip y luego elija **Abrir**.

1. Seleccione **Save**.

------
#### [ AWS CLI ]

**Para crear la función (AWS CLI)**
+ Ejecute el comando de CLI para el lenguaje elegido. En el parámetro `role`, asegúrese de reemplazar `123456789012` por el ID de la Cuenta de AWS. En el parámetro `region`, reemplace `us-east-1` por la región en la que creó los buckets de Amazon S3.
  + Para **Node.js**, ejecute el siguiente comando desde el directorio que contiene el archivo `function.zip`.

    ```
    aws lambda create-function --function-name CreateThumbnail \
    --zip-file fileb://function.zip --handler index.handler --runtime nodejs24.x \
    --timeout 10 --memory-size 1024 \
    --role arn:aws:iam::123456789012:role/LambdaS3Role --region us-east-1
    ```
  + Para **Python**, ejecute el siguiente comando desde el directorio que contiene el archivo `lambda_function.zip`.

    ```
    aws lambda create-function --function-name CreateThumbnail \
    --zip-file fileb://lambda_function.zip --handler lambda_function.lambda_handler \
    --runtime python3.14 --timeout 10 --memory-size 1024 \
    --role arn:aws:iam::123456789012:role/LambdaS3Role --region us-east-1
    ```

------

## Configurar Amazon S3 para invocar una función
<a name="with-s3-tutorial-configure-s3-trigger"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps7.png)


Para que la función de Lambda se ejecute cuando carga una imagen al bucket de origen, debe configurar un desencadenador para la función. Puede configurar el desencadenador de Amazon S3 mediante la consola o la AWS CLI.

**importante**  
Este procedimiento configura el bucket de Amazon S3 para invocar la función cada vez que se crea un objeto en el bucket. Asegúrese de configurar esto solo en el bucket de origen. Si la función de Lambda crea objetos en el mismo bucket que la invoca, la función se puede [invocar de forma continua en un bucle](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/recursive-runaway). Esto puede provocar que se facturen cargos imprevistos en su Cuenta de AWS.

------
#### [ Consola de administración de AWS ]

**Para configurar el desencadenador de Amazon S3 (consola)**

1. Abra la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) de la consola de Lambda y elija la función (`CreateThumbnail`).

1. Elija **Add trigger (Añadir disparador)**.

1. Seleccione **S3**.

1. En **Bucket**, seleccione el bucket de origen.

1. En **Tipos de eventos**, seleccione **Todos los eventos de creación de objetos**.

1. En **Invocación recursiva**, marque la casilla de verificación para confirmar que no se recomienda utilizar el mismo bucket de Amazon S3 para la entrada y la salida. Puede obtener más información sobre los patrones de invocación recursiva en Lambda en [Patrones recursivos que provocan funciones de Lambda descontroladas](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/recursive-runaway) en Serverless Land.

1. Elija **Agregar**.

   Al crear un desencadenador mediante la consola de Lambda, Lambda crea automáticamente una [política basada en recursos](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html) para conceder permiso al servicio que seleccione para invocar la función. 

------
#### [ AWS CLI ]

**Para configurar el desencadenador de Amazon S3 (AWS CLI)**

1. Para que el bucket de origen de Amazon S3 invoque la función al agregar un archivo de imagen, primero debe configurar los permisos de la función mediante una [política basada en recursos](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html). Una instrucción de política basada en recursos concede permisos a otros Servicios de AWS para invocar la función. Para conceder permisos a Amazon S3 para invocar la función, ejecute el siguiente comando de la CLI. Asegúrese de reemplazar el parámetro `source-account` por su propio ID de Cuenta de AWS y de utilizar su propio nombre de bucket de origen.

   ```
   aws lambda add-permission --function-name CreateThumbnail \
   --principal s3.amazonaws.com --statement-id s3invoke --action "lambda:InvokeFunction" \
   --source-arn arn:aws:s3:::amzn-s3-demo-source-bucket \
   --source-account 123456789012
   ```

   La política que defina con este comando permite a Amazon S3 invocar la función solo cuando se lleva a cabo una acción en el bucket de origen.
**nota**  
Si bien los nombres de los buckets de Amazon S3 son globalmente únicos, cuando se utilizan políticas basadas en recursos, se recomienda aclarar que el bucket debe pertenecer a la cuenta. Esto sucede porque si elimina un bucket, es posible que otra Cuenta de AWS cree un bucket con el mismo Nombre de recurso de Amazon (ARN).

1. Guarde el siguiente JSON en un archivo llamado `notification.json`. Cuando se aplica al bucket de origen, este JSON configura el bucket para enviar una notificación a la función de Lambda cada vez que se agrega un objeto nuevo. Reemplace el número de Cuenta de AWS y la Región de AWS en el ARN de la función de Lambda por su número de cuenta y su región.

   ```
   {
   "LambdaFunctionConfigurations": [
       {
         "Id": "CreateThumbnailEventConfiguration",
         "LambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:CreateThumbnail",
         "Events": [ "s3:ObjectCreated:Put" ]
       }
     ]
   }
   ```

1. Ejecute el siguiente comando de la CLI para aplicar la configuración de notificación del archivo JSON que creó al bucket de origen. Reemplace `amzn-s3-demo-source-bucket` por el nombre del bucket de origen.

   ```
   aws s3api put-bucket-notification-configuration --bucket amzn-s3-demo-source-bucket \
   --notification-configuration file://notification.json
   ```

   Para obtener más información sobre el comando `put-bucket-notification-configuration` y la opción `notification-configuration`, consulte [put-bucket-notification-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-bucket-notification-configuration.html) en la *Referencia de comandos de la CLI AWS*.

------

## Probar la función de Lambda con un evento de prueba
<a name="with-s3-tutorial-dummy-test"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps8.png)


Antes de probar toda la configuración al agregar un archivo de imagen al bucket de origen de Amazon S3, debe comprobar que la función de Lambda funciona correctamente al invocarla con un evento ficticio. Un evento en Lambda es un documento con formato JSON que contiene datos para que una función los procese. Cuando Amazon S3 invoca la función, el evento enviado a la función contiene información como el nombre del bucket, el ARN del bucket y la clave del objeto.

------
#### [ Consola de administración de AWS ]

**Para probar la función de Lambda con un evento ficticio (consola)**

1. Abra la [página Funciones](https://console.aws.amazon.com/lambda/home#/functions) de la consola de Lambda y elija la función (`CreateThumbnail`).

1. Elija la pestaña **Prueba**.

1. Para crear el evento de prueba, en el panel **Evento de prueba**, haga lo siguiente:

   1. En **Acción del evento de prueba**, seleccione **Crear nuevo evento**.

   1. En **Nombre del evento**, escriba **myTestEvent**.

   1. En **Plantilla**, seleccione **S3 Put**.

   1. Reemplace los valores de los siguientes parámetros por sus propios valores.
      + En `awsRegion`, reemplace `us-east-1` por la Región de AWS en la que creó el bucket de Amazon S3.
      + En `name`, reemplace `amzn-s3-demo-bucket` por el nombre del bucket de origen de Amazon S3.
      + En `key`, reemplace `test%2Fkey` por el nombre del objeto de prueba que cargó al bucket de origen en el paso [Cargar una imagen de prueba al bucket de origen](#with-s3-tutorial-test-image).

      ```
      {
        "Records": [
          {
            "eventVersion": "2.0",
            "eventSource": "aws:s3",
            "awsRegion": "us-east-1",
            "eventTime": "1970-01-01T00:00:00.000Z",
            "eventName": "ObjectCreated:Put",
            "userIdentity": {
              "principalId": "EXAMPLE"
            },
            "requestParameters": {
              "sourceIPAddress": "127.0.0.1"
            },
            "responseElements": {
              "x-amz-request-id": "EXAMPLE123456789",
              "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
            },
            "s3": {
              "s3SchemaVersion": "1.0",
              "configurationId": "testConfigRule",
              "bucket": {
                "name": "amzn-s3-demo-bucket",
                "ownerIdentity": {
                  "principalId": "EXAMPLE"
                },
                "arn": "arn:aws:s3:::amzn-s3-demo-bucket"
              },
              "object": {
                "key": "test%2Fkey",
                "size": 1024,
                "eTag": "0123456789abcdef0123456789abcdef",
                "sequencer": "0A1B2C3D4E5F678901"
              }
            }
          }
        ]
      }
      ```

   1. Seleccione **Save**.

1. En el panel **Evento de prueba**, seleccione **Prueba**.

1. Para comprobar que la función creó una versión redimensionada de la imagen y la almacenó en el bucket de Amazon S3 de destino, haga lo siguiente:

   1. En la consola de Amazon S3, abra la página [Buckets](https://console.aws.amazon.com/s3/buckets).

   1. Elija el bucket de destino y confirme que el archivo redimensionado aparezca en el panel **Objetos**.

------
#### [ AWS CLI ]

**Para probar la función de Lambda con un evento ficticio (AWS CLI)**

1. Guarde el siguiente JSON en un archivo llamado `dummyS3Event.json`. Reemplace los valores de los siguientes parámetros por sus propios valores:
   + En `awsRegion`, reemplace `us-east-1` por la Región de AWS en la que creó el bucket de Amazon S3.
   + En `name`, reemplace `amzn-s3-demo-bucket` por el nombre del bucket de origen de Amazon S3.
   + En `key`, reemplace `test%2Fkey` por el nombre del objeto de prueba que cargó al bucket de origen en el paso [Cargar una imagen de prueba al bucket de origen](#with-s3-tutorial-test-image).

   ```
   {
     "Records": [
       {
         "eventVersion": "2.0",
         "eventSource": "aws:s3",
         "awsRegion": "us-east-1",
         "eventTime": "1970-01-01T00:00:00.000Z",
         "eventName": "ObjectCreated:Put",
         "userIdentity": {
           "principalId": "EXAMPLE"
         },
         "requestParameters": {
           "sourceIPAddress": "127.0.0.1"
         },
         "responseElements": {
           "x-amz-request-id": "EXAMPLE123456789",
           "x-amz-id-2": "EXAMPLE123/5678abcdefghijklambdaisawesome/mnopqrstuvwxyzABCDEFGH"
         },
         "s3": {
           "s3SchemaVersion": "1.0",
           "configurationId": "testConfigRule",
           "bucket": {
             "name": "amzn-s3-demo-bucket",
             "ownerIdentity": {
               "principalId": "EXAMPLE"
             },
             "arn": "arn:aws:s3:::amzn-s3-demo-bucket"
           },
           "object": {
             "key": "test%2Fkey",
             "size": 1024,
             "eTag": "0123456789abcdef0123456789abcdef",
             "sequencer": "0A1B2C3D4E5F678901"
           }
         }
       }
     ]
   }
   ```

1. Desde el directorio en el que guardó el archivo `dummyS3Event.json`, invoque la función mediante la ejecución del siguiente comando de la CLI. Este comando invoca la función de Lambda de forma sincrónica al definir `RequestResponse` como valor del parámetro de tipo de invocación. Para obtener más información sobre la invocación sincrónica y asíncrona, consulte [Invocación de funciones de Lambda](https://docs.aws.amazon.com/lambda/latest/dg/lambda-invocation.html).

   ```
   aws lambda invoke --function-name CreateThumbnail \
   --invocation-type RequestResponse --cli-binary-format raw-in-base64-out \
   --payload file://dummyS3Event.json outputfile.txt
   ```

   La opción cli-binary-format es obligatoria si utiliza la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [las opciones globales de la línea de comandos admitidas de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list).

1. Compruebe que la función haya creado una versión en miniatura de la imagen y la haya guardado en el bucket de Amazon S3 de destino. Ejecute el siguiente comando de la CLI, para ello reemplace `amzn-s3-demo-source-bucket-resized` por el nombre del bucket de destino.

   ```
   aws s3api list-objects-v2 --bucket amzn-s3-demo-source-bucket-resized
   ```

   Debería ver un resultado similar a este. El parámetro `Key` muestra el nombre del archivo de imagen redimensionado.

   ```
   {
       "Contents": [
           {
               "Key": "resized-HappyFace.jpg",
               "LastModified": "2023-06-06T21:40:07+00:00",
               "ETag": "\"d8ca652ffe83ba6b721ffc20d9d7174a\"",
               "Size": 2633,
               "StorageClass": "STANDARD"
           }
       ]
   }
   ```

------

## Probar la función con el desencadenador de Amazon S3
<a name="with-s3-tutorial-test-s3"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps9.png)


Ahora que confirmó que la función de Lambda se ejecuta correctamente, puede probar toda la configuración al agregar un archivo de imagen al bucket de origen de Amazon S3. Al agregar la imagen al bucket de origen, la función de Lambda se debe invocar automáticamente. La función crea una versión redimensionada del archivo y la almacena en el bucket de destino.

------
#### [ Consola de administración de AWS ]

**Para probar la función de Lambda mediante el desencadenador de Amazon S3 (consola)**

1. Para cargar una imagen en el bucket de Amazon S3, haga lo siguiente:

   1. Abra la página [Buckets](https://console.aws.amazon.com/s3/buckets) de la consola de Amazon S3 y elija el bucket de origen.

   1. Seleccione **Cargar**.

   1. Elija **Agregar archivos** y utilice el selector de archivos para elegir el archivo de imagen que desea cargar. El objeto de imagen puede ser cualquier archivo .jpg o .png.

   1. Elija **Abrir** y, a continuación, **Cargar**.

1. Compruebe que Lambda haya guardado una versión redimensionada del archivo de imagen en el bucket de destino, de la siguiente manera:

   1. Vuelva a la página [Buckets](https://console.aws.amazon.com/s3/buckets) de la consola de Amazon S3 y elija el bucket de destino.

   1. En el panel **Objetos**, debería ver dos archivos de imagen redimensionados, uno de cada prueba de la función de Lambda. Para descargar la imagen redimensionada, selecciona el archivo y luego elija **Descargar**.

------
#### [ AWS CLI ]

**Para probar la función de Lambda mediante el desencadenador de Amazon S3 (AWS CLI)**

1. Desde el directorio que contiene la imagen que desea cargar, ejecute el siguiente comando de la CLI. Reemplace el parámetro `--bucket` con el nombre del bucket de origen. Para los parámetros `--key` y `--body`, utilice el nombre de archivo de la imagen de prueba. La imagen de prueba puede ser cualquier archivo .jpg o .png.

   ```
   aws s3api put-object --bucket amzn-s3-demo-source-bucket --key SmileyFace.jpg --body ./SmileyFace.jpg
   ```

1. Compruebe que la función haya creado una versión en miniatura de la imagen y la haya guardado en el bucket de Amazon S3 de destino. Ejecute el siguiente comando de la CLI, para ello reemplace `amzn-s3-demo-source-bucket-resized` por el nombre del bucket de destino.

   ```
   aws s3api list-objects-v2 --bucket amzn-s3-demo-source-bucket-resized
   ```

   Si la función se ejecuta correctamente, verá un resultado similar al siguiente. El bucket de destino ahora debería contener dos archivos redimensionados.

   ```
   {
       "Contents": [
           {
               "Key": "resized-HappyFace.jpg",
               "LastModified": "2023-06-07T00:15:50+00:00",
               "ETag": "\"7781a43e765a8301713f533d70968a1e\"",
               "Size": 2763,
               "StorageClass": "STANDARD"
           },
           {
               "Key": "resized-SmileyFace.jpg",
               "LastModified": "2023-06-07T00:13:18+00:00",
               "ETag": "\"ca536e5a1b9e32b22cd549e18792cdbc\"",
               "Size": 1245,
               "StorageClass": "STANDARD"
           }
       ]
   }
   ```

------

## Eliminación de sus recursos
<a name="s3-tutorial-cleanup"></a>

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

**Cómo eliminar la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que ha creado.

1. Elija **Acciones**, **Eliminar**.

1. Escriba **confirm** en el campo de entrada de texto y elija **Delete** (Eliminar).

**Para eliminar la política que creó**

1. Abra la página de [Policies (Políticas)](https://console.aws.amazon.com/iam/home#/policies) de la consola de IAM.

1. Seleccione la política que creó (**AWSLambdas3Policy**).

1. Elija **Policy actions (Acciones de política)**, **Delete (Eliminar)**.

1. Elija **Eliminar**.

**Cómo eliminar el rol de ejecución**

1. Abra la página [Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione el rol de ejecución que creó.

1. Elija **Eliminar**.

1. Si desea continuar, escriba el nombre del rol en el campo de entrada de texto y elija **Delete** (Eliminar).

**Para eliminar el bucket de S3**

1. Abra la [consola de Amazon S3](https://console.aws.amazon.com//s3/home#).

1. Seleccione el bucket que ha creado.

1. Elija **Eliminar**.

1. Introduzca el nombre del bucket en el campo de entrada de texto.

1. Elija **Delete bucket (Eliminar bucket)**.

# Uso de secretos de Secrets Manager en Funciones de Lambda
<a name="with-secrets-manager"></a>

AWS Secrets Manager lo ayuda a administrar credenciales, claves de API y otros secretos que necesitan sus funciones de Lambda. Existen dos enfoques principales para recuperar secretos en sus funciones de Lambda, y ambos ofrecen un mejor rendimiento y costos más bajos en comparación con la recuperación de secretos de manera directa mediante AWS SDK:
+ **Extensión de Lambda para parámetros y secretos de AWS**: una solución independiente del tiempo de ejecución que proporciona una interfaz HTTP sencilla para la recuperación de secretos
+ **Powertools para la utilidad de parámetros de AWS Lambda**: una solución integrada en el código compatible con varios proveedores (Secrets Manager, Parameter Store, AppConfig) con transformaciones integradas

Ambos enfoques mantienen una caché local de secretos, lo que elimina la necesidad de que la función llame a Secrets Manager por cada invocación. Cuando la función solicita un secreto, primero se comprueba la caché. Si el secreto está disponible y no ha caducado, se devuelve de inmediato. De lo contrario, se recupera de Secrets Manager, se almacena en caché y se devuelve. Este mecanismo de almacenamiento en caché se traduce en tiempos de respuesta más rápidos y costos reducidos al minimizar las llamadas a la API.

## Elección de un enfoque
<a name="lambda-secrets-manager-choosing-approach"></a>

Tenga en cuenta estos factores al elegir entre la extensión y PowerTools:

Se debe utilizar la extensión de Lambda para parámetros y secretos de AWS en los siguientes casos:  
+ Se desea una solución independiente del tiempo de ejecución que funcione con cualquier entorno de ejecución de Lambda
+ Se prefiere no agregar dependencias de código a su función
+ Solo se necesitan recuperar secretos de Secrets Manager o Parameter Store

Se debe utilizar la utilidad de Powertools para parámetros de AWS Lambda en los siguientes casos:  
+ Se desea una experiencia de desarrollo integrada con el código de su aplicación
+ Se requiere soporte para varios proveedores (Secrets Manager, Parameter Store, AppConfig)
+ Se quiere contar con transformaciones de datos integradas (análisis de JSON, decodificación de base64)
+ Se están utilizando tiempos de ejecución de Python, TypeScript, Java o .NET

## Cuándo usar Secrets Manager con Lambda
<a name="lambda-secrets-manager-when-to-use"></a>

Entre los escenarios más comunes para usar Secrets Manager con Lambda se incluyen los siguientes:
+ Almacenar las credenciales de base de datos que su función utiliza para conectarse a Amazon RDS u otras bases de datos
+ Administrar las claves de API para los servicios externos a los que llama su función
+ Almacenar claves de cifrado u otros datos de configuración confidenciales
+ Rotar de forma automática las credenciales sin necesidad de actualizar el código de función

## Uso de la extensión de Lambda para parámetros y secretos de AWS
<a name="lambda-secrets-manager-extension-approach"></a>

La extensión de Lambda para parámetros y secretos de AWS utiliza una interfaz HTTP sencilla compatible con cualquier tiempo de ejecución de Lambda. De forma predeterminada, guarda en caché los secretos durante 300 segundos (5 minutos) y puede almacenar hasta 1000 secretos. Puede [personalizar estos ajustes con variables de entorno](#lambda-secrets-manager-env-vars).

### Uso de Secrets Manager en una función de Lambda
<a name="lambda-secrets-manager-setup"></a>

En esta sección se supone que ya tiene un secreto de Secrets Manager. Para crear un secreto, consulte [Creación de un secreto de AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html).

#### Crear el paquete de implementación
<a name="lambda-secrets-manager-function-code"></a>

Elige tu tiempo de ejecución preferido y sigue los pasos para crear una función que recupere los secretos de Secrets Manager. La función de ejemplo recupera un secreto de Secrets Manager y se puede utilizar para acceder a las credenciales de la base de datos, las claves de API u otros datos de configuración confidenciales de sus aplicaciones.

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

**Para crear una función Python**

1. Cree y navegue hasta un nuevo directorio del proyecto. Ejemplo:

   ```
   mkdir my_function
   cd my_function
   ```

1. Cree un archivo llamado `lambda_function.py` con el siguiente código. Para `secret_name`, use el nombre o el nombre de recurso de Amazon (ARN) de su secreto.

   ```
   import json
   import os
   import requests
   
   def lambda_handler(event, context):
       try:
           # Replace with the name or ARN of your secret
           secret_name = "arn:aws:secretsmanager:us-east-1:111122223333:secret:SECRET_NAME"
           
           secrets_extension_endpoint = f"http://localhost:2773/secretsmanager/get?secretId={secret_name}"
           headers = {"X-Aws-Parameters-Secrets-Token": os.environ.get('AWS_SESSION_TOKEN')}
           
           response = requests.get(secrets_extension_endpoint, headers=headers)
           print(f"Response status code: {response.status_code}")
           
           secret = json.loads(response.text)["SecretString"]
           print(f"Retrieved secret: {secret}")
           
           return {
               'statusCode': response.status_code,
               'body': json.dumps({
                   'message': 'Successfully retrieved secret',
                   'secretRetrieved': True
               })
           }
       
       except Exception as e:
           print(f"Error: {str(e)}")
           return {
               'statusCode': 500,
               'body': json.dumps({
                   'message': 'Error retrieving secret',
                   'error': str(e)
               })
           }
   ```

1. Cree un archivo llamado `requirements.txt` con este contenido:

   ```
   requests
   ```

1. Instale las dependencias:

   ```
   pip install -r requirements.txt -t .
   ```

1. Cree un archivo .zip que contenga todos los archivos:

   ```
   zip -r function.zip .
   ```

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

**Para crear una función de Node.js.**

1. Cree y navegue hasta un nuevo directorio del proyecto. Ejemplo:

   ```
   mkdir my_function
   cd my_function
   ```

1. Cree un archivo llamado `index.mjs` con el siguiente código. Para `secret_name`, use el nombre o el nombre de recurso de Amazon (ARN) de su secreto.

   ```
   import http from 'http';
   
   export const handler = async (event) => {
       try {
           // Replace with the name or ARN of your secret
           const secretName = "arn:aws:secretsmanager:us-east-1:111122223333:secret:SECRET_NAME";
           const options = {
               hostname: 'localhost',
               port: 2773,
               path: `/secretsmanager/get?secretId=${secretName}`,
               headers: {
                   'X-Aws-Parameters-Secrets-Token': process.env.AWS_SESSION_TOKEN
               }
           };
   
           const response = await new Promise((resolve, reject) => {
               http.get(options, (res) => {
                   let data = '';
                   res.on('data', (chunk) => { data += chunk; });
                   res.on('end', () => {
                       resolve({ 
                           statusCode: res.statusCode, 
                           body: data 
                       });
                   });
               }).on('error', reject);
           });
   
           const secret = JSON.parse(response.body).SecretString;
           console.log('Retrieved secret:', secret);
   
           return {
               statusCode: response.statusCode,
               body: JSON.stringify({
                   message: 'Successfully retrieved secret',
                   secretRetrieved: true
               })
           };
       } catch (error) {
           console.error('Error:', error);
           return {
               statusCode: 500,
               body: JSON.stringify({
                   message: 'Error retrieving secret',
                   error: error.message
               })
           };
       }
   };
   ```

1. Cree un archivo .zip que contenga el archivo `index.mjs`:

   ```
   zip -r function.zip index.mjs
   ```

------
#### [ Java ]

**Para crear una función Java**

1. Cree un proyecto de Maven:

   ```
   mvn archetype:generate \
       -DgroupId=example \
       -DartifactId=lambda-secrets-demo \
       -DarchetypeArtifactId=maven-archetype-quickstart \
       -DarchetypeVersion=1.4 \
       -DinteractiveMode=false
   ```

1. Navegue hasta el directorio del proyecto:

   ```
   cd lambda-secrets-demo
   ```

1. Abra el archivo `pom.xml` y reemplace el contenido con lo siguiente:

   ```
   <project xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
       <modelVersion>4.0.0</modelVersion>
   
       <groupId>example</groupId>
       <artifactId>lambda-secrets-demo</artifactId>
       <version>1.0-SNAPSHOT</version>
   
       <properties>
           <maven.compiler.source>11</maven.compiler.source>
           <maven.compiler.target>11</maven.compiler.target>
       </properties>
   
       <dependencies>
           <dependency>
               <groupId>com.amazonaws</groupId>
               <artifactId>aws-lambda-java-core</artifactId>
               <version>1.2.1</version>
           </dependency>
       </dependencies>
   
       <build>
           <plugins>
               <plugin>
                   <groupId>org.apache.maven.plugins</groupId>
                   <artifactId>maven-shade-plugin</artifactId>
                   <version>3.2.4</version>
                   <executions>
                       <execution>
                           <phase>package</phase>
                           <goals>
                               <goal>shade</goal>
                           </goals>
                           <configuration>
                               <createDependencyReducedPom>false</createDependencyReducedPom>
                               <finalName>function</finalName>
                           </configuration>
                       </execution>
                   </executions>
               </plugin>
           </plugins>
       </build>
   </project>
   ```

1. Cambie el nombre del archivo `/lambda-secrets-demo/src/main/java/example/App.java` por `Hello.java` para que coincida con el nombre del controlador Java predeterminado de Lambda (`example.Hello::handleRequest`):

   ```
   mv src/main/java/example/App.java src/main/java/example/Hello.java
   ```

1. Abra el archivo `Hello.java` y reemplace el contenido con lo siguiente. Para `secretName`, use el nombre o el nombre de recurso de Amazon (ARN) de su secreto. 

   ```
   package example;
   
   import com.amazonaws.services.lambda.runtime.Context;
   import com.amazonaws.services.lambda.runtime.RequestHandler;
   import java.net.URI;
   import java.net.http.HttpClient;
   import java.net.http.HttpRequest;
   import java.net.http.HttpResponse;
   
   public class Hello implements RequestHandler<Object, String> {
       private final HttpClient client = HttpClient.newHttpClient();
   
       @Override
       public String handleRequest(Object input, Context context) {
           try {
               // Replace with the name or ARN of your secret
               String secretName = "arn:aws:secretsmanager:us-east-1:111122223333:secret:SECRET_NAME";
               String endpoint = "http://localhost:2773/secretsmanager/get?secretId=" + secretName;
   
               HttpRequest request = HttpRequest.newBuilder()
                   .uri(URI.create(endpoint))
                   .header("X-Aws-Parameters-Secrets-Token", System.getenv("AWS_SESSION_TOKEN"))
                   .GET()
                   .build();
   
               HttpResponse<String> response = client.send(request, 
                   HttpResponse.BodyHandlers.ofString());
   
               String secret = response.body();
               secret = secret.substring(secret.indexOf("SecretString") + 15);
               secret = secret.substring(0, secret.indexOf("\""));
   
               System.out.println("Retrieved secret: " + secret);
               return String.format(
                   "{\"statusCode\": %d, \"body\": \"%s\"}",
                   response.statusCode(), "Successfully retrieved secret"
               );
   
           } catch (Exception e) {
               e.printStackTrace();
               return String.format(
                   "{\"body\": \"Error retrieving secret: %s\"}", 
                   e.getMessage()
               );
           }
       }
   }
   ```

1. Elimine el directorio de prueba. Maven lo crea de forma predeterminada, pero no lo necesitamos para este ejemplo.

   ```
   rm -rf src/test
   ```

1. Compile el proyecto:

   ```
   mvn package
   ```

1. Descarga el archivo JAR (`target/function.jar`) para usarlo más adelante.

------

#### Creación de la función
<a name="lambda-secrets-manager-create"></a>

1. Abra la página de [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funciones) en la consola de Lambda.

1. Seleccione **Creación de función**.

1. Seleccione **Crear desde cero**.

1. En **Nombre de la función**, introduzca **secret-retrieval-demo**.

1. Elija el **tiempo de ejecución** que prefiera.

1. Elija **Crear función**.

**Cómo cargar el paquete de implementación**

1. En la pestaña **Código** de la función, elija **Cargar desde** y seleccione un **archivo .zip** (para Python y Node.js) o un **archivo .jar** (para Java).

1. Cargue el paquete de implementación que creó anteriormente.

1. Seleccione **Save**.

#### Adición de la extensión
<a name="lambda-secrets-manager-extension"></a>

**Cómo agregar la extensión de Lambda AWS Parameters and Secrets como una capa**

1. En la pestaña **Código** de la función, desplácese hacia abajo hasta **Capas**.

1. Elija **Add a layer (Añadir una capa)**.

1. Selecciona las **capas de AWS**.

1. Elija **AWS-Parameters-and-Secrets-Lambda-Extension**.

1. Seleccione la versión más reciente.

1. Elija **Agregar**.

#### Inclusión de permisos
<a name="lambda-secrets-manager-permissions"></a>

**Cómo agregar permisos de Secrets Manager a su rol de ejecución**

1. Elija la pestaña **Configuración** y, a continuación, elija **Permisos**.

1. En **Nombre del rol**, elija el enlace al rol de ejecución. Este enlace abre el rol en la consola de IAM.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/execution-role-console.png)

1. Seleccione **Agregar permisos** y, a continuación, **Crear política insertada**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/create-inline-policy.png)

1. Elija la pestaña **JSON** y añada la siguiente política. Para `Resource`, introduzca el ARN de su secreto.

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "secretsmanager:GetSecretValue",
               "Resource": "arn:aws:secretsmanager:us-east-1:111122223333:secret:SECRET_NAME"
           }
       ]
   }
   ```

------

1. Elija **Siguiente**.

1. Introduzca un nombre para la política.

1. Elija **Crear política**.

#### Prueba de la función
<a name="lambda-secrets-manager-test"></a>

**Para probar la función**

1. Vuelva a la consola de Lambda.

1. Seleccione la pestaña **Pruebas**.

1. Seleccione **Probar** Debería ver la siguiente respuesta:  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/execution-results-secret.png)

### Variables de entorno
<a name="lambda-secrets-manager-env-vars"></a>

La extensión de Lambda AWS Parameters and Secrets utiliza la siguiente configuración predeterminada. Puede anular esta configuración creando las [variables de entorno](configuration-envvars.md#create-environment-variables) correspondientes. Para ver la configuración actual de una función, configure `PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL` en `DEBUG`. La extensión registrará su información de configuración en los registros de CloudWatch al inicio de cada invocación de función.


| Opción | Predeterminado | Valores válidos | Variable de entorno | Details | 
| --- | --- | --- | --- | --- | 
| Puerto HTTP | 2773 | 1 a 65535 | PARAMETERS\$1SECRETS\$1EXTENSION\$1HTTP\$1PORT | Puerto para el servidor HTTP local | 
| Caché habilitada | TRUE | TRUE, FALSE | PARAMETERS\$1SECRETS\$1EXTENSION\$1CACHE\$1ENABLED | Activa o desactiva la caché | 
| Tamaño de caché | 1 000 | 0 a 1000 | PARAMETERS\$1SECRETS\$1EXTENSION\$1CACHE\$1SIZE | Configúrelo en 0 para deshabilitar el almacenamiento en caché | 
| TTL de Secrets Manager | 300 segundos | 0 a 300 segundos | SECRETS\$1MANAGER\$1TTL | Tiempo de vida de los secretos en caché. Configúrelo en 0 para deshabilitar el almacenamiento en caché. Esta variable se ignora si el valor para PARAMETERS\$1SECRETS\$1EXTENSION\$1CACHE\$1SIZE es 0. | 
| TTL del almacén de parámetros | 300 segundos | 0 a 300 segundos | SSM\$1PARAMETER\$1STORE\$1TTL | Tiempo de vida de los parámetros en caché. Configúrelo en 0 para deshabilitar el almacenamiento en caché. Esta variable se ignora si el valor para PARAMETERS\$1SECRETS\$1EXTENSION\$1CACHE\$1SIZE es 0. | 
| Nivel de registro | INFO | DEPURAR \$1 INFORMACIÓN \$1 ADVERTIR \$1 ERROR \$1 NINGUNO | PARAMETERS\$1SECRETS\$1EXTENSION\$1LOG\$1LEVEL | El nivel de detalle indicado en los registros de la extensión. | 
| Máximo de conexiones | 3 | 1 o más | PARAMETERS\$1SECRETS\$1EXTENSION\$1MAX\$1CONNECTIONS | Cantidad máxima de conexiones HTTP para las solicitudes al almacén de parámetros o Secrets Manager | 
| Tiempo de espera de Secrets Manager | 0 (sin tiempo de espera) | Todos los números enteros | SECRETS\$1MANAGER\$1TIMEOUT\$1MILLIS | Tiempo de espera para las solicitudes a Secrets Manager (en milisegundos) | 
| Tiempo de espera del almacén de parámetros | 0 (sin tiempo de espera) | Todos los números enteros | SSM\$1PARAMETER\$1STORE\$1TIMEOUT\$1MILLIS | Tiempo de espera para las solicitudes al almacén de parámetros (en milisegundos) | 

### Trabajo con rotación de secretos
<a name="lambda-secrets-manager-rotation"></a>

Si cambia los secretos con frecuencia, la duración predeterminada de la memoria caché de 300 segundos puede hacer que su función utilice secretos obsoletos. Tiene dos opciones para asegurarse de que su función utilice el valor secreto más reciente:
+ Reducir el TTL de la caché configurando la variable de entorno `SECRETS_MANAGER_TTL` en un valor inferior (en segundos). Por ejemplo, configúrelo en `60` garantiza que la función nunca utilice un secreto que tenga más de un minuto de antigüedad.
+ Usar las etiquetas de ensayo `AWSCURRENT` o `AWSPREVIOUS` de su solicitud secreta para asegurarse de obtener la versión específica que desea:

  ```
  secretsmanager/get?secretId=YOUR_SECRET_NAME&versionStage=AWSCURRENT
  ```

Elija el enfoque que mejor equilibre sus necesidades de rendimiento y actualización. Un TTL inferior significa llamadas más frecuentes a Secrets Manager, pero garantiza que trabaje con los valores secretos más recientes.

## Uso de la utilidad de parámetros de Powertools para AWS Lambda
<a name="lambda-secrets-manager-powertools-approach"></a>

La utilidad de parámetros de Powertools para AWS Lambda proporciona una interfaz unificada para la recuperación de secretos de varios proveedores, incluidos Secrets Manager, el almacén de parámetros y AppConfig. Gestiona el almacenamiento en caché y las transformaciones, y proporciona una experiencia de desarrollo más integrada en comparación con el enfoque de extensión.

### Ventajas de la utilidad de parámetros
<a name="lambda-secrets-manager-powertools-benefits"></a>
+ **Varios proveedores**: recupera parámetros de Secrets Manager, Parameter Store y AppConfig mediante la misma interfaz
+ **Transformaciones integradas**: análisis automático de JSON, decodificación de base64 y otras transformaciones de datos
+ **Almacenamiento en caché integrado**: almacenamiento en caché configurable con soporte TTL para reducir las llamadas a la API
+ **Seguridad de los tipos**: sólida compatibilidad con TypeScript y otros tiempos de ejecución compatibles
+ **Gestión de errores:** lógica de reintento y gestión de errores integrados

### Ejemplos de código
<a name="lambda-secrets-manager-powertools-examples"></a>

Los siguientes ejemplos muestran cómo recuperar secretos mediante la utilidad de parámetros en diferentes tiempos de ejecución:

**Python**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación de la utilidad de parámetros](https://docs.powertools.aws.dev/lambda/python/latest/utilities/parameters/).
Recuperación de secretos de Secrets Manager con Powertools para la utilidad de parámetros de AWS Lambda.  

```
from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities import parameters

logger = Logger()

def lambda_handler(event, context):
    try:
        # Get secret with caching (default TTL: 5 seconds)
        secret_value = parameters.get_secret("my-secret-name")
        
        # Get secret with custom TTL
        secret_with_ttl = parameters.get_secret("my-secret-name", max_age=300)
        
        # Get secret and transform JSON
        secret_json = parameters.get_secret("my-json-secret", transform="json")
        
        logger.info("Successfully retrieved secrets")
        
        return {
            'statusCode': 200,
            'body': 'Successfully retrieved secrets'
        }
        
    except Exception as e:
        logger.error(f"Error retrieving secret: {str(e)}")
        return {
            'statusCode': 500,
            'body': f'Error: {str(e)}'
        }
```

**TypeScript**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación de la utilidad de parámetros](https://docs.aws.amazon.com/powertools/typescript/2.1.1/utilities/parameters/).
Recuperación de secretos de Secrets Manager con Powertools para la utilidad de parámetros de AWS Lambda.  

```
import { Logger } from '@aws-lambda-powertools/logger';
import { getSecret } from '@aws-lambda-powertools/parameters/secrets';
import type { Context } from 'aws-lambda';

const logger = new Logger();

export const handler = async (event: any, context: Context) => {
    try {
        // Get secret with caching (default TTL: 5 seconds)
        const secretValue = await getSecret('my-secret-name');
        
        // Get secret with custom TTL
        const secretWithTtl = await getSecret('my-secret-name', { maxAge: 300 });
        
        // Get secret and transform JSON
        const secretJson = await getSecret('my-json-secret', { transform: 'json' });
        
        logger.info('Successfully retrieved secrets');
        
        return {
            statusCode: 200,
            body: 'Successfully retrieved secrets'
        };
        
    } catch (error) {
        logger.error('Error retrieving secret', { error });
        return {
            statusCode: 500,
            body: `Error: ${error}`
        };
    }
};
```

**Java**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación de la utilidad de parámetros](https://docs.powertools.aws.dev/lambda/java/latest/utilities/parameters/).
Recuperación de secretos de Secrets Manager con Powertools para la utilidad de parámetros de AWS Lambda.  

```
import software.amazon.lambda.powertools.logging.Logging;
import software.amazon.lambda.powertools.parameters.SecretsProvider;
import software.amazon.lambda.powertools.parameters.ParamManager;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class SecretHandler implements RequestHandler<Object, String> {
    
    private final SecretsProvider secretsProvider = ParamManager.getSecretsProvider();
    
    @Logging
    @Override
    public String handleRequest(Object input, Context context) {
        try {
            // Get secret with caching (default TTL: 5 seconds)
            String secretValue = secretsProvider.get("my-secret-name");
            
            // Get secret with custom TTL (300 seconds)
            String secretWithTtl = secretsProvider.withMaxAge(300).get("my-secret-name");
            
            // Get secret and transform JSON
            MySecret secretJson = secretsProvider.get("my-json-secret", MySecret.class);
            
            return "Successfully retrieved secrets";
            
        } catch (Exception e) {
            return "Error retrieving secret: " + e.getMessage();
        }
    }
    
    public static class MySecret {
        // Define your secret structure here
    }
}
```

**.NET**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación de la utilidad de parámetros](https://docs.aws.amazon.com/powertools/typescript/latest/features/parameters/).
Recuperación de secretos de Secrets Manager con Powertools para la utilidad de parámetros de AWS Lambda.  

```
using AWS.Lambda.Powertools.Logging;
using AWS.Lambda.Powertools.Parameters;
using Amazon.Lambda.Core;

[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

public class Function
{
    private readonly ISecretsProvider _secretsProvider;
    
    public Function()
    {
        _secretsProvider = ParametersManager.SecretsProvider;
    }
    
    [Logging]
    public async Task<string> FunctionHandler(object input, ILambdaContext context)
    {
        try
        {
            // Get secret with caching (default TTL: 5 seconds)
            var secretValue = await _secretsProvider.GetAsync("my-secret-name");
            
            // Get secret with custom TTL
            var secretWithTtl = await _secretsProvider.WithMaxAge(TimeSpan.FromMinutes(5))
                .GetAsync("my-secret-name");
            
            // Get secret and transform JSON
            var secretJson = await _secretsProvider.GetAsync<MySecret>("my-json-secret");
            
            return "Successfully retrieved secrets";
        }
        catch (Exception e)
        {
            return $"Error retrieving secret: {e.Message}";
        }
    }
    
    public class MySecret
    {
        // Define your secret structure here
    }
}
```

### Configuración y permisos
<a name="lambda-secrets-manager-powertools-setup"></a>

Para utilizar la utilidad de parámetros, debe realizar lo siguiente:

1. Instalar Powertools para AWS Lambda para su tiempo de ejecución. Para obtener más información, consulte [Powertools para AWS Lambda](powertools-for-lambda.md).

1. Agregar todos los permisos de IAM al rol de ejecución de la función. Consulte [Administrar permisos en AWS Lambda](lambda-permissions.md) para obtener más información.

1. Configurar los ajustes opcionales mediante [variables de entorno](configuration-envvars.md).

Los permisos de IAM obligatorios son los mismos que para el enfoque de la extensión. La utilidad gestionará automáticamente el almacenamiento en caché y las llamadas a la API a Secrets Manager según su configuración.

# Uso de Lambda con Amazon SQS
<a name="with-sqs"></a>

**nota**  
Si desea enviar datos a un destino que no sea una función de Lambda o enriquecer los datos antes de enviarlos, consulte [Amazon EventBridge Pipes](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html) (Canalizaciones de Amazon EventBridge).

Puede utilizar una función de Lambda para procesar mensajes en una cola de Amazon Simple Queue Service (Amazon SQS). Las [asignaciones de orígenes de eventos](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html) de Lambda son compatibles con [las colas estándar](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html) y [las colas de primero en entrar, primero en salir (FIFO)](invocation-eventsourcemapping.md). También puede usar el modo aprovisionado para asignar recursos de sondeo dedicados a las asignaciones de orígenes de eventos de Amazon SQS. La función de Lambda y la cola de Amazon SQS deben estar en la misma Región de AWS, aunque pueden estar en [diferentes Cuentas de AWS](with-sqs-cross-account-example.md).

Cuando se procesan mensajes de Amazon SQS, se debe implementar una lógica de respuesta por lotes parcial para evitar que se intente reprocesar los mensajes ya procesados correctamente cuando algunos mensajes de un lote fallan. La [utilidad de procesador por lotes](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) de Powertools para AWS Lambda simplifica esta implementación al gestionar de manera automática la lógica de respuesta parcial por lotes, lo que reduce el tiempo de desarrollo y mejora la fiabilidad.

**Topics**
+ [

## Descripción del comportamiento de sondeo y procesamiento por lotes para las asignaciones de orígenes de eventos de Amazon SQS
](#sqs-polling-behavior)
+ [

## Uso del modo aprovisionado con las asignaciones de orígenes de eventos de Amazon SQS
](#sqs-provisioned-mode)
+ [

## Configuración del modo aprovisionado para las asignación de orígenes de eventos de Amazon SQS
](#sqs-configuring-provisioned-mode)
+ [

## Ejemplo de evento de mensaje en cola estándar
](#example-standard-queue-message-event)
+ [

## Ejemplo de evento de mensajes de cola FIFO
](#sample-fifo-queues-message-event)
+ [

# Creación y configuración de una asignación de orígenes de eventos de Amazon SQS
](services-sqs-configure.md)
+ [

# Configuración del comportamiento de escalado para las asignaciones de orígenes de eventos de SQS
](services-sqs-scaling.md)
+ [

# Gestión de errores para un origen de eventos de SQS en Lambda
](services-sqs-errorhandling.md)
+ [

# Parámetros de Lambda para las asignaciones de origen de eventos de Amazon SQS
](services-sqs-parameters.md)
+ [

# Uso del filtrado de eventos con una fuente de eventos de Amazon SQS
](with-sqs-filtering.md)
+ [

# Tutorial: Uso de Lambda con Amazon SQS
](with-sqs-example.md)
+ [

# Tutorial: Uso de una cola entre cuentas de Amazon SQS como un origen de eventos
](with-sqs-cross-account-example.md)

## Descripción del comportamiento de sondeo y procesamiento por lotes para las asignaciones de orígenes de eventos de Amazon SQS
<a name="sqs-polling-behavior"></a>

Con las asignaciones de orígener de eventos de Amazon SQS, Lambda sondea la cola e invoca su función [sincrónicamente](invocation-sync.md) con un evento. Cada evento puede contener un lote de varios mensajes de la cola. Lambda recibe estos eventos lote por lote e invoca su función una vez por lote. Cuando la función procesa correctamente un lote, Lambda elimina sus mensajes de la cola.

Cuando Lambda lee un lote, los mensajes se mantienen en la cola, pero se ocultan durante el [tiempo de espera de visibilidad](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) de la cola. Cuando la función procesa correctamente todos los mensajes en el lote, Lambda elimina sus mensajes de la cola. De forma predeterminada, si la función detecta un error al procesar un lote, todos los mensajes de ese lote se vuelven a ver en la cola después de que expire el tiempo de visibilidad. Por este motivo, el código de su función debe ser capaz de procesar el mismo mensaje varias veces sin efectos secundarios no deseados.

**aviso**  
Las asignaciones de orígenes de eventos de Lambda procesan cada evento al menos una vez, y puede producirse un procesamiento duplicado de registros. Para evitar posibles problemas relacionados con la duplicación de eventos, le recomendamos encarecidamente que haga que el código de la función sea idempotente. Para obtener más información, consulte [¿Cómo puedo hacer que mi función de Lambda sea idempotente?](https://repost.aws/knowledge-center/lambda-function-idempotent) en el Centro de conocimientos de AWS.

Para evitar que Lambda procese un mensaje varias veces, puede configurar la asignación de orígenes de eventos para incluir los [errores de los elementos del lote](services-sqs-errorhandling.md#services-sqs-batchfailurereporting) en la respuesta de la función, o puede utilizar la acción [DeleteMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessage.html) de la API para eliminar los mensajes de la cola a medida que la función de Lambda los procese correctamente.

Para obtener más información sobre los parámetros de configuración que Lambda admite para asignaciones de orígenes de eventos de SQS, consulte [Creación de una asignación de orígenes de eventos](services-sqs-configure.md#events-sqs-eventsource).

## Uso del modo aprovisionado con las asignaciones de orígenes de eventos de Amazon SQS
<a name="sqs-provisioned-mode"></a>

Para las cargas de trabajo en las que necesite afinar el rendimiento de su asignación de orígenes de eventos, puede utilizar el modo aprovisionado. En el modo aprovisionado, usted define los límites mínimos y máximos para la cantidad de sondeos de eventos aprovisionados. Estos sondeos de eventos aprovisionados están dedicados a la asignación de orígenes de eventos y pueden gestionar los picos de mensajes inesperados mediante un ajuste de escalado automático adaptable. La asignación de orígenes de eventos de Amazon SQS configurada con el modo aprovisionado se escala 3 veces más rápido (hasta 1000 invocaciones simultáneas por minuto) y admite una concurrencia 16 veces mayor (hasta 20 000 invocaciones simultáneas) que la capacidad de asignación de orígenes de eventos predeterminada de Amazon SQS. Le recomendamos que utilice el modo aprovisionado para las cargas de trabajo impulsadas por eventos de Amazon SQS que tengan requisitos de rendimiento estrictos, como las empresas de servicios financieros que procesan fuentes de datos de mercado, las plataformas de comercio electrónico que ofrecen recomendaciones personalizadas en tiempo real y las empresas de juegos que administran las interacciones de los jugadores en directo. El uso del modo aprovisionado conlleva costos adicionales. Para obtener más información sobre precios, consulte [Precios de AWS Lambda](https://aws.amazon.com/lambda/pricing/).

Cada sondeador de eventos en modo aprovisionado puede gestionar hasta 1 MB/s de rendimiento, hasta 10 invocaciones simultáneas o hasta 10 llamadas a la API de sondeo de Amazon SQS por segundo. El rango de valores aceptados para el número mínimo de sondeadores de eventos (MinimumPollers) oscila entre 2 y 200, con el valor predeterminado de 2. El rango de valores aceptados para el número máximo de sondeadores de eventos (MaximumPollers) oscila entre 2 y 2000, con el valor predeterminado de 200. MaximumPollers debe ser mayor o igual que MinimumPollers.

### Determinación de los sondeadores de eventos necesarios
<a name="sqs-determining-event-pollers"></a>

Para estimar el número de sondeadores de eventos necesarios para garantizar un rendimiento óptimo del procesamiento de mensajes cuando se utiliza el modo aprovisionado para la ESM de SQS, recopile las siguientes métricas para su aplicación: picos de eventos de SQS por segundo que requieren un procesamiento de baja latencia, tamaño medio de la carga útil de los eventos de SQS, duración promedio de la función de Lambda y tamaño de lote configurado.

En primer lugar, puede estimar el número de eventos de SQS por segundo (EPS) que admite un sondeador de eventos para la carga de trabajo mediante la siguiente fórmula:

```
EPS per event poller = 
        minimum(
            ceiling(1024 / average event size in KB),
            ceiling(10 / average function duration in seconds) * batch size, 
            min(100, 10 * batch size)
                )
```

A continuación, puede calcular el número mínimo de sondeadores necesarios con la siguiente fórmula. Este cálculo garantiza un aprovisionamiento de capacidad suficiente para satisfacer sus necesidades de tráfico máximo.

```
Required event pollers = (Peak number of events per second in Queue) / EPS per event poller
```

Considere una carga de trabajo con un tamaño de lote predeterminado de 10, un tamaño promedio de eventos de 3 KB, una duración promedio de la función de 100 ms y el requisito de gestionar 1000 eventos por segundo. En este escenario, cada sondeador de eventos admitirá aproximadamente 100 eventos por segundo (EPS). Por lo tanto, debe establecer un mínimo de 10 sondeadores para gestionar adecuadamente los requisitos de tráfico máximo. Si su carga de trabajo tiene las mismas características, pero una duración promedio de la función de 1 segundo, cada sondeador solo admitirá 10 EPS, por lo que deberá configurar 100 sondeadores como mínimo para que admitan 1000 eventos por segundo con una latencia baja.

Recomendamos utilizar un tamaño de lote predeterminado de 10 o más para maximizar la eficiencia de los sondeadores de eventos en modo aprovisionado. Los tamaños de lote más altos permiten que cada sondeador procese más eventos por invocación, lo que mejora el rendimiento y la rentabilidad. Cuando planifique la capacidad del sondeador de eventos, tenga en cuenta los posibles picos de tráfico y considere la posibilidad de establecer el valor de minimumPollers ligeramente por encima del mínimo calculado para proporcionar un búfer. Además, supervise las características de su carga de trabajo a lo largo del tiempo, ya que los cambios en el tamaño de los mensajes, la duración de las funciones o los patrones de tráfico pueden requerir ajustes en la configuración del sondeador de eventos para mantener un rendimiento y una rentabilidad óptimos. Para planificar la capacidad de forma precisa, le recomendamos que pruebe su carga de trabajo específica para determinar el EPS real que puede generar cada sondeador de eventos.

## Configuración del modo aprovisionado para las asignación de orígenes de eventos de Amazon SQS
<a name="sqs-configuring-provisioned-mode"></a>

Puede configurar el modo aprovisionado para la asignación de orígenes de eventos de Amazon SQS mediante la consola o la API de Lambda.

**Cómo configurar el modo aprovisionado para una asignación de orígenes de eventos de Amazon SQS existente (consola)**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija la función con la asignación de orígenes de eventos de Amazon SQS para la que desee configurar el modo aprovisionado.

1. Elija **Configuración** y, a continuación, seleccione **Desencadenadores**.

1. Elija la asignación de orígenes de eventos de Amazon SQS para la que desee configurar el modo aprovisionado y, a continuación, seleccione **Editar**.

1. En **Configuración de la asignación de orígenes de eventos**, elija **Configurar el modo aprovisionado**.
   + En **Número mínimo de sondeos de eventos**, introduzca un valor entre 2 y 200. Si no especifica un valor, Lambda asigna el valor predeterminado de 2.
   + En **Número máximo de sondeos de eventos**, introduzca un valor entre 2 y 2000. Este valor debe ser mayor o igual que su valor para **Número mínimo de sondeos de eventos**. Si no especifica un valor, Lambda asigna el valor predeterminado de 200.

1. Seleccione **Save**.

Puede configurar el modo aprovisionado mediante programación con el objeto `ProvisionedPollerConfig` incluido en su `EventSourceMappingConfiguration`. Por ejemplo, el siguiente comando de la CLI `UpdateEventSourceMapping` configura un valor de `MinimumPollers` de 5 y un valor `MaximumPollers` de 100.

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --provisioned-poller-config '{"MinimumPollers": 5, "MaximumPollers": 100}'
```

Tras configurar el modo aprovisionado, puede observar el uso de los sondeos de eventos para su carga de trabajo supervisando la métrica `ProvisionedPollers`. Para obtener más información, consulte la métrica de la asignación de orígenes de eventos.

Para deshabilitar el modo aprovisionado y volver al modo predeterminado (bajo demanda), puede usar el siguiente comando de la CLI `UpdateEventSourceMapping`:

```
aws lambda update-event-source-mapping \
    --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \
    --provisioned-poller-config '{}'
```

**nota**  
El modo aprovisionado no se puede utilizar junto con el ajuste de concurrencia máxima. Cuando utiliza el modo aprovisionado, controla la máxima concurrencia mediante el número máximo de sondeadores de eventos.

Para obtener más información sobre la configuración del modo aprovisionado, consulte [Creación y configuración de una asignación de orígenes de eventos de Amazon SQS](services-sqs-configure.md).

## Ejemplo de evento de mensaje en cola estándar
<a name="example-standard-queue-message-event"></a>

**Example Evento de mensaje de Amazon SQS (cola estándar)**  

```
{
    "Records": [
        {
            "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
            "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
            "body": "Test message.",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1545082649183",
                "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                "ApproximateFirstReceiveTimestamp": "1545082649185"
            },
            "messageAttributes": {
                "myAttribute": {
                    "stringValue": "myValue", 
                    "stringListValues": [], 
                    "binaryListValues": [], 
                    "dataType": "String"
                }
            },
            "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue",
            "awsRegion": "us-east-2"
        },
        {
            "messageId": "2e1424d4-f796-459a-8184-9c92662be6da",
            "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
            "body": "Test message.",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1545082650636",
                "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                "ApproximateFirstReceiveTimestamp": "1545082650649"
            },
            "messageAttributes": {},
            "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue",
            "awsRegion": "us-east-2"
        }
    ]
}
```

De forma predeterminada, Lambda sondea hasta 10 mensajes en su cola a la vez y envía ese lote a la función. Para evitar invocar la función con un número pequeño de registros, puede configurar el origen del evento de modo que almacene en búfer registros hasta 5 minutos mediante la definición de una ventana de lote. Antes de invocar la función, Lambda continúa el sondeo de los mensajes de la cola estándar hasta que caduque la ventana de lotes, se alcance la [cuota de tamaño de carga de invocaciones](gettingstarted-limits.md) o se alcance el tamaño de lote máximo configurado.

Si utiliza un intervalo de lote y la cola de SQS contiene muy poco tráfico, Lambda puede esperar hasta 20 segundos antes de invocar la función. Esto sucederá incluso si establece un intervalo de lote inferior a 20 segundos. 

**nota**  
En Java, es posible que se produzcan errores de puntero nulo al deserializar JSON. Esto podría deberse a la forma en que el mapeador de objetos JSON convierte las mayúsculas/minúsculas de “Records” y “EventSourceARN”.

## Ejemplo de evento de mensajes de cola FIFO
<a name="sample-fifo-queues-message-event"></a>

Para las colas FIFO, los registros contienen atributos adicionales relacionados con la deduplicación y la secuenciación.

**Example Evento de mensaje de Amazon SQS (cola de FIFO)**  

```
{
    "Records": [
        {
            "messageId": "11d6ee51-4cc7-4302-9e22-7cd8afdaadf5",
            "receiptHandle": "AQEBBX8nesZEXmkhsmZeyIE8iQAMig7qw...",
            "body": "Test message.",
            "attributes": {
                "ApproximateReceiveCount": "1",
                "SentTimestamp": "1573251510774",
                "SequenceNumber": "18849496460467696128",
                "MessageGroupId": "1",
                "SenderId": "AIDAIO23YVJENQZJOL4VO",
                "MessageDeduplicationId": "1",
                "ApproximateFirstReceiveTimestamp": "1573251510774"
            },
            "messageAttributes": {},
            "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
            "eventSource": "aws:sqs",
            "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:fifo.fifo",
            "awsRegion": "us-east-2"
        }
    ]
}
```

# Creación y configuración de una asignación de orígenes de eventos de Amazon SQS
<a name="services-sqs-configure"></a>

Para procesar los mensajes de Amazon SQS con Lambda, configure la cola con los ajustes adecuados y, a continuación, cree una asignación de orígen de eventos de Lambda.

**Topics**
+ [

## Configurar una cola para utilizarla con Lambda
](#events-sqs-queueconfig)
+ [

## Configuración de permisos de rol de ejecución de Lambda
](#events-sqs-permissions)
+ [

## Creación de una asignación de orígenes de eventos
](#events-sqs-eventsource)

## Configurar una cola para utilizarla con Lambda
<a name="events-sqs-queueconfig"></a>

Si aún no tiene una cola de Amazon SQS, [cree una](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-create-queue.html) que sirva como origen de eventos para la función de Lambda. La función de Lambda y la cola de Amazon SQS deben estar en la misma Región de AWS, aunque pueden estar en [diferentes Cuentas de AWS](with-sqs-cross-account-example.md).

Para que su función tenga tiempo de procesar cada lote de registros, establezca el [tiempo de espera de visibilidad](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) de la cola de origen en al menos seis veces el [tiempo de espera que configure](configuration-timeout.md) en su función. El tiempo adicional permitirá a Lambda volver a intentar realizar los procesos en caso de que la función se vea limitada debido al procesamiento de un lote anterior.

**nota**  
El tiempo de espera de la función debe ser menor o igual que el tiempo de espera de visibilidad de la fila. Lambda valida este requisito al crear o actualizar una asignación de orígenes de eventos y devolverá un error si el tiempo de espera de la función supera el tiempo de espera de visibilidad de la fila.

De forma predeterminada, si Lambda detecta un error en cualquier momento del procesamiento de un lote, todos los mensajes de ese lote se vuelven a la cola. Tras el tiempo de [espera de visibilidad](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html), Lambda vuelve a ver los mensajes. Puede configurar la asignación de orígenes de orígenes de eventos para usar [respuestas de lote parciales](services-sqs-errorhandling.md#services-sqs-batchfailurereporting) para devolver solo los mensajes fallidos a la cola. Si su función no puede procesar un mensaje en repetidas ocasiones, Amazon SQS podrá enviar dicho mensaje a una [cola de mensajes fallidos](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html). Te recomendamos que establezcas `maxReceiveCount` la [política de redrive de la cola de origen en al menos](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html#policies-for-dead-letter-queues) 5. Esto le da a Lambda algunas oportunidades de volver a intentarlo antes de enviar los mensajes fallidos directamente a la cola de mensajes sin salida.

## Configuración de permisos de rol de ejecución de Lambda
<a name="events-sqs-permissions"></a>

La política administrada de AWS, [AWSLambdaSQSQueueExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaSQSQueueExecutionRole.html), contiene los permisos que Lambda necesita para poder leer de la cola de Amazon SQS. Puede [agregar esta política administrada](lambda-intro-execution-role.md) al rol de ejecución de la función.

De manera opcional, si utiliza una cola cifrada, también debe agregar el siguiente permiso a su rol de ejecución:
+ [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html)

## Creación de una asignación de orígenes de eventos
<a name="events-sqs-eventsource"></a>

Cree un mapeo de origen de eventos para indicar a Lambda que envíe elementos desde una cola a una función de Lambda. Puede crear varios mapeos de orígenes de eventos para procesar elementos de varias colas con una sola función. Cuando Lambda invoca la función objetivo, el evento puede contener múltiples elementos, dependiendo del *tamaño de lote* máximo configurable.

Para configurar la función para que lea desde Amazon SQS, adjunte la política administrada de AWS [AWSLambdaSQSQueueExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaSQSQueueExecutionRole.html) al rol de ejecución. A continuación, cree una asignación de orígenes de eventos de **SQS** desde la consola mediante los siguientes pasos.

**Cómo agregar permisos y crear un desencadenador**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de una función.

1. Elija la pestaña **Configuración** y, a continuación, elija **Permisos**.

1. En **Nombre del rol**, elija el enlace al rol de ejecución. Este enlace abre el rol en la consola de IAM.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/execution-role.png)

1. Elija **Agregar permisos** y luego **Adjuntar políticas**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/attach-policies.png)

1. En el campo de búsqueda, escriba `AWSLambdaSQSQueueExecutionRole`. Agregue esta política al rol de ejecución. Se trata de una política administrada de AWS que contiene los permisos que la función necesita para leer desde una cola de Amazon SQS. Para obtener más información acerca de esta política, consulte [AWSLambdaSQSQueueExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaSQSQueueExecutionRole.html) en la *Referencia de políticas administradas de AWS*.

1. Regrese a la función en la consola de Lambda. En **Function overview (Descripción general de la función)**, elija **Add trigger (Agregar desencadenador)**.  
![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/add-trigger.png)

1. Elija un tipo de desencadenador.

1. Configure las opciones requeridas y luego elija **Add** (Agregar).

Lambda admite las siguientes opciones de configuración para los orígenes de eventos de Amazon SQS:

**Cola de SQS**  
La cola de Amazon SQS desde la que leer registros. La función de Lambda y la cola de Amazon SQS deben estar en la misma Región de AWS, aunque pueden estar en [diferentes Cuentas de AWS](with-sqs-cross-account-example.md).

**Activar desencadenador**  
El estado de la asignación de origen de eventos. De forma predeterninada, la opción **Enable trigger** (Activar desencadenador) está seleccionada.

**Tamaño de lote**  
El número máximo de registros que se enviarán a la función en cada lote. Para una cola estándar, puede tratarse de hasta 10 000 registros. Para una cola FIFO, el máximo es 10. Para un tamaño de lote superior a 10, también debe establecer la ventana del lote (`MaximumBatchingWindowInSeconds`) a al menos 1 segundo.  
Configure el[ tiempo de espera de la función](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/configurations#timeouts) para que disponga de tiempo suficiente para procesar todo un lote de elementos. Si elementos tardan mucho tiempo en procesarse, elija un tamaño de lote más pequeño. Un tamaño de lote amplio puede mejorar la eficiencia para cargas de trabajo que son muy rápidas o tienen mucha administración. Si configura la [simultaneidad reservada](configuration-concurrency.md) en la función, establezca al menos cinco ejecuciones simultáneas para reducir la posibilidad de errores de limitación controlada cuando Lambda invoque la función.  
Lambda pasa todos los registros del lote a la función en una sola llamada, siempre y cuando el tamaño total de los eventos no exceda la [cuota de tamaño de carga de invocaciones](gettingstarted-limits.md) para la invocación sincrónica (6 MB). Tanto Lambda como Amazon SQS generan metadatos por cada registro. Estos metadatos adicionales se cuentan como el tamaño total de la carga útil y pueden hacer que el número total de registros enviados en un lote sea inferior al tamaño del lote configurado. Los campos de metadatos que Amazon SQS envía pueden tener una longitud variable. Para obtener más información acerca de los campos de metadatos de Amazon SQS, consulte la documentación de operación de la API [ReceiveMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) en la *Referencia de la API de Amazon Simple Queue Service*.

**Ventana del lote**  
La cantidad de tiempo máxima para recopilar registros antes de invocar la función, en segundos. Esto se aplica únicamente a las colas estándar.  
Si utiliza una ventana por lotes superior a 0 segundos, debe tener en cuenta el tiempo de procesamiento aumentado en el [tiempo de espera de visibilidad](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) de la cola. Recomendamos establecer el tiempo de espera de visibilidad de la cola hasta en seis veces el [tiempo de espera](configuration-timeout.md), más el valor de `MaximumBatchingWindowInSeconds`. Esto permite tiempo para que su función de Lambda procese cada lote de eventos y vuelva a intentarlo en caso de un error de limitación.  
Cuando los mensajes están disponibles, Lambda comienza a procesar los mensajes en lotes. Lambda comienza a procesar 5 lotes a la vez con 5 invocaciones simultáneas de la función. Si los mensajes siguen estando disponibles, Lambda agrega hasta 300 invocaciones simultáneas de la función por minuto, hasta un máximo de 1250 invocaciones simultáneas. Cuando se utiliza el modo aprovisionado, cada sondeador de eventos puede gestionar hasta 1 MB/s de rendimiento, hasta 10 invocaciones simultáneas o hasta 10 llamadas a la API de sondeo de Amazon SQS por segundo. Lambda escala el número de sondeadores de eventos entre el mínimo y el máximo configurados, y suma rápidamente hasta 1000 invocaciones simultáneas por minuto para proporcionar un procesamiento de baja latencia de los eventos de Amazon SQS. Usted controla el escalado y la concurrencia mediante estos ajustes de los sondeadores de eventos mínimos y máximos. Para obtener más información sobre el escalado de funciones y la concurrencia, consulte [Comprender el escalado de la función de Lambda](lambda-concurrency.md).  
Para procesar más mensajes, puede optimizar la función de Lambda para obtener un mayor rendimiento. Para obtener más información, consulte [Entender cómo escala AWS Lambda con las colas estándar de Amazon SQS](https://aws.amazon.com/blogs/compute/understanding-how-aws-lambda-scales-when-subscribed-to-amazon-sqs-queues/#:~:text=If there are more messages,messages from the SQS queue.).

**Criterios del filtro**  
Agregue criterios de filtrado para controlar qué eventos envía Lambda a su función para su procesamiento. Para obtener más información, consulte [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md).

**Simultaneidad máxima**  
Número máximo de funciones simultáneas que puede invocar el origen de eventos. No se puede usar con el modo apromovisionado habilitado. Para obtener más información, consulte [Configuración de la simultaneidad máxima para los orígenes de eventos de Amazon SQS](services-sqs-scaling.md#events-sqs-max-concurrency).

**Modo aprovisionado**  
Cuando está habilitado, asigna recursos de sondeo dedicados para la asignación de orígenes de eventos. Puede configurar el número mínimo (2-200) y máximo (2-2000) de sondeadores de eventos. Cada sondeador de eventos puede gestionar hasta 1 MB/s de rendimiento, hasta 10 invocaciones simultáneas o hasta 10 llamadas a la API de sondeo de Amazon SQS por segundo.  
Nota: No puede utilizar el modo Aprovisionado y la concurrencia máxima a la vez. Cuando el modo Aprovisionado esté habilitado, utilice la configuración máxima de sondeadores para controlar la concurrencia.

# Configuración del comportamiento de escalado para las asignaciones de orígenes de eventos de SQS
<a name="services-sqs-scaling"></a>

Puede controlar el comportamiento de escalado de las asignaciones de orígenes de eventos de Amazon SQS mediante la configuración de concurrencia máxima o la habilitación del modo aprovisionado. Estas opciones se excluyen mutuamente.

De forma predeterminada, Lambda escala automáticamente los sondeadores de eventos en función del volumen de los mensajes. Cuando habilita el modo aprovisionado, asigna un número mínimo y máximo de recursos de sondeo dedicados que permanecen preparados para gestionar los patrones de tráfico esperados. Esto le permite optimizar el rendimiento de la asignación de orígenes de eventos de dos maneras:
+ Modo estándar (predeterminado): Lambda administra automáticamente el escalado, a partir de un número reducido de sondeadores y con aumentos o reducciones según la carga de trabajo.
+ Modo aprovisionado: se configuran recursos de sondeo dedicados con límites mínimos y máximos, lo que permite un escalado 3 veces más rápido y una capacidad de procesamiento hasta 16 veces mayor.

Para las colas estándar, Lambda utiliza el [sondeo largo](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html#sqs-long-polling) para sondear una cola hasta que se active. Cuando los mensajes están disponibles, Lambda comienza a procesar cinco lotes a la vez con cinco invocaciones simultáneas de la función. Si los mensajes siguen disponibles, Lambda aumenta el número de procesos que son lotes de lectura hasta 300 invocaciones simultáneas más por minuto. El número máximo de invocaciones que una asignación de orígenes de eventos puede procesar simultáneamente es 1250. Cuando el tráfico es bajo, Lambda reduce el procesamiento a 5 invocaciones simultáneas y puede optimizarlo a tan solo 2 invocaciones simultáneas para reducir las llamadas a Amazon SQS y los costos correspondientes. Sin embargo, esta optimización no está disponible cuando se habilita la configuración de simultaneidad máxima.

Para colas FIFO, Lambda envía mensajes a su función en el orden en que los recibe. Cuando envíe un mensaje a una cola FIFO, especifique un [ID de grupo de mensajes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html). Amazon SQS garantiza que los mensajes del mismo grupo se entreguen a Lambda en orden. Cuando Lambda lee los mensajes en lotes, cada lote puede contener mensajes de más de un grupo, pero se mantiene el orden de los mensajes. Si la función devuelve un error, esta realiza todos los reintentos en los mensajes afectados antes de que Lambda reciba mensajes adicionales del mismo grupo.

Cuando se utiliza el modo aprovisionado, cada sondeador de eventos puede gestionar hasta 1 MB/s de rendimiento, hasta 10 invocaciones simultáneas o hasta 10 llamadas a la API de sondeo de Amazon SQS por segundo. Lambda escala el número de sondeadores de eventos entre el mínimo y el máximo configurados, y suma rápidamente hasta 1000 concurrencias por minuto para proporcionar un procesamiento coherente de baja latencia de los eventos de Amazon SQS. El uso del modo aprovisionado conlleva costos adicionales. Para obtener más información sobre precios, consulte [Precios de AWS Lambda](https://aws.amazon.com/lambda/pricing/). Cada sondeador de eventos utiliza [sondeos prolongados](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html) en la cola de SQS, con hasta 10 sondeos por segundo, lo que supone un costo por las solicitudes de la API de SQS. Para obtener más información, consulte [Precios de Amazon SQS](https://aws.amazon.com/sqs/pricing/ ). El escalado y la concurrencia se controlan mediante estas configuraciones mínima y máxima de los sondeadores de eventos, en lugar de usar la configuración de concurrencia máxima, ya que estas opciones no pueden usarse juntas.

**nota**  
No puede utilizar la configuración de concurrencia máxima y el modo aprovisionado al mismo tiempo. Cuando el modo aprovisionado está habilitado, puede controlar el escalado y la concurrencia de la asignación de orígenes de eventos de Amazon SQS mediante el número mínimo y máximo de sondeadores de eventos.

## Configuración de la simultaneidad máxima para los orígenes de eventos de Amazon SQS
<a name="events-sqs-max-concurrency"></a>

Puede utilizar la configuración de simultaneidad máxima para controlar el comportamiento de escalado de los orígenes de eventos de SQS. Tenga en cuenta que la concurrencia máxima no se puede utilizar con el modo aprovisionado habilitado. La configuración de la simultaneidad máxima limita el número de instancias simultáneas de la función que puede invocar un origen de eventos de Amazon SQS. La simultaneidad máxima es una configuración a nivel de origen de eventos. Si tiene varios orígenes de eventos de Amazon SQS asignación de orígenes de eventos, cada origen de eventos puede tener una configuración de simultaneidad máxima independiente. Puede utilizar la simultaneidad máxima para evitar que una cola utilice toda la [simultaneidad reservada](configuration-concurrency.md) de la función o el resto de la [cuota de simultaneidad de la cuenta](gettingstarted-limits.md). No hay ningún cargo por configurar la simultaneidad máxima en un origen de eventos de Amazon SQS.

Es importante destacar que la simultaneidad máxima y reservada son dos configuraciones independientes. No establezca una simultaneidad máxima superior a la reservada de la función. Si configura la simultaneidad máxima, asegúrese de que la simultaneidad reservada de la función es mayor o igual que la simultaneidad máxima total para todos los orígenes de eventos de Amazon SQS de la función. De lo contrario, Lambda podría limitar sus mensajes.

Si la cuota de simultaneidad de su cuenta se establece en el valor predeterminado (1000), puede escalarse una asignación de orígenes de eventos de Amazon SQS para invocar instancias de funciones hasta este valor, a menos que especifique una simultaneidad máxima.

Si recibe un aumento de la cuota de simultaneidad predeterminada de su cuenta, es posible que Lambda no pueda invocar instancias de funciones simultáneas hasta la nueva cuota. De forma predeterminada, Lambda puede escalar para invocar hasta 1250 instancias de funciones simultáneas para una asignación de orígenes de eventos de Amazon SQS. Si esto no es suficiente para su caso de uso, póngase en contacto con el servicio de asistencia de AWS para tratar un aumento de la simultaneidad de asignación de orígenes de eventos de Amazon SQS de su cuenta.

**nota**  
En el caso de las colas FIFO, las invocaciones simultáneas están limitadas por el número de [ID de grupos de mensajes](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html) (`messageGroupId`) o por la configuración de simultaneidad máxima, lo que sea inferior. Por ejemplo, si tiene seis ID de grupos de mensajes y la simultaneidad máxima está establecida en 10, la función puede tener un máximo de seis invocaciones simultáneas.

Puede configurar la simultaneidad máxima en la asignación de orígenes de eventos nuevos y existentes de Amazon SQS.

**Configure la simultaneidad máxima mediante la consola Lambda**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de una función.

1. En **Function overview** (Descripción general de las funciones), elija **SQS**. Esta abre la pestaña **Configuration** (Configuración).

1. Seleccione el activador de Amazon SQS y elija **Edit** (Editar).

1. En **Maximum concurrency** (Simultaneidad máxima), introduzca un número entre 2 y 1000. Para desactivar la simultaneidad máxima, deje la casilla vacía.

1. Seleccione **Save** (Guardar).

**Configure la simultaneidad máxima mediante la AWS Command Line Interface (AWS CLI)**  
Utilice el comando [asignación de orígenes de eventos](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) con la opción `--scaling-config`. Ejemplo:

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --scaling-config '{"MaximumConcurrency":5}'
```

Para desactivar la simultaneidad máxima, introduzca un valor vacío para `--scaling-config`:

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --scaling-config "{}"
```

**Configure la simultaneidad máxima mediante la API de Lambda**  
Utilice las acciones de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) o [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) con un objeto [ScalingConfig](https://docs.aws.amazon.com/lambda/latest/api/API_ScalingConfig.html).

# Gestión de errores para un origen de eventos de SQS en Lambda
<a name="services-sqs-errorhandling"></a>

Para gestionar los errores relacionados con un origen de eventos de SQS, Lambda utiliza automáticamente una estrategia de reintento con una estrategia de retroceso. También puede personalizar el comportamiento de la gestión de errores si configura la asignación de orígenes de eventos de SQS para que devuelva [respuestas parciales por lotes](#services-sqs-batchfailurereporting).

## Estrategia de retroceso para invocaciones fallidas
<a name="services-sqs-backoff-strategy"></a>

Cuando se produce un error en una invocación, Lambda intenta volver a intentar la invocación mientras implementa una estrategia de retraso. La estrategia de retroceso difiere ligeramente en función de si Lambda encontró el error debido a un error en el código de la función o a una limitación.
+  Si el **código de la función** provocó el error, Lambda dejará de procesar y volver a intentar la invocación. Mientras tanto, Lambda reduce de manera gradual el volumen de simultaneidad asignada a su asignación de orígenes de eventos de Amazon SQS. Cuando se agote el tiempo de espera de visibilidad de la cola, el mensaje volverá a aparecer en la cola. 
+ Si la invocación falla debido a la **limitación**, Lambda retrocede gradualmente los reintentos reduciendo la cantidad de simultaneidad asignada a la asignación de orígenes de eventos de Amazon SQS. Lambda sigue reintentando enviar el mensaje hasta que la marca de tiempo del mensaje supere el tiempo límite de visibilidad de la cola, momento en el que Lambda descarta el mensaje.

## Implementación de respuestas parciales por lotes
<a name="services-sqs-batchfailurereporting"></a>

Cuando la función Lambda detecta un error al procesar un lote, todos los mensajes de ese lote se vuelven a ver en la cola de forma predeterminada, incluidos los mensajes que Lambda procesó correctamente. Como resultado, la función puede terminar procesando el mismo mensaje varias veces.

Para evitar el reprocesamiento de todos los mensajes procesados con éxito en un lote con errores, puede configurar la asignación de orígenes de eventos para que solo se vean de nuevo los mensajes fallidos. Esto se denomina respuesta parcial por lotes. Para activar las respuestas parciales por lotes, especifique `ReportBatchItemFailures` en la acción [FunctionResponseTypes](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html#lambda-UpdateEventSourceMapping-request-FunctionResponseTypes) cuando configure la asignación de orígenes de eventos. Esto permite que la función devuelva un éxito parcial, lo que puede ayudar a reducir el número de reintentos innecesarios en los registros.

**nota**  
La [utilidad de procesador de lotes](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) de Powertools para AWS Lambda gestiona de manera automática toda la lógica de respuesta parcial del lote. Esta utilidad simplifica la implementación de los patrones de procesamiento por lotes y reduce el código personalizado que se necesita para gestionar de manera adecuada los errores de los artículos del lote. Está disponible para Python, Java, TypeScript y .NET.

Cuando `ReportBatchItemFailures` está activado, Lambda no [reduce verticalmente el sondeo de mensajes](#services-sqs-backoff-strategy) cuando fallan las invocaciones de las funciones. Utilice `ReportBatchItemFailures`, si espera que algunos mensajes fallen y no quiere que esos errores afecten a la velocidad de procesamiento de los mensajes.

**nota**  
Tenga en cuenta las siguientes consideraciones al utilizar las respuestas parciales por lotes:  
Si la función genera una excepción, todo el lote se considera un error completo.
Si utiliza esta característica con una cola FIFO, la función debe dejar de procesar los mensajes después del primer error y devolver todos los mensajes fallidos y sin procesar en `batchItemFailures`. Esto ayuda a preservar el orden de los mensajes en la cola.

**Para activar los informes parciales por lotes**

1. Revise las [Prácticas recomendadas para implementar las respuestas parciales por lotes](https://docs.aws.amazon.com/prescriptive-guidance/latest/lambda-event-filtering-partial-batch-responses-for-sqs/best-practices-partial-batch-responses.html).

1. Ejecute el siguiente comando para activar `ReportBatchItemFailures` para la función. Para recuperar el UUID de la asignación de orígenes de eventos, ejecute el comando [list-event-source-mappings](https://docs.aws.amazon.com/cli/latest/reference/lambda/list-event-source-mappings.html) de la AWS CLI.

   ```
   aws lambda update-event-source-mapping \
   --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
   --function-response-types "ReportBatchItemFailures"
   ```

1. Actualice el código de la función para detectar todas las excepciones y devolver los mensajes fallidos en una respuesta JSON `batchItemFailures`. La respuesta `batchItemFailures` debe incluir una lista de ID de mensajes, como valores JSON `itemIdentifier`.

   Supongamos que tiene un lote de cinco mensajes con ID de mensaje `id1`, `id2`, `id3`, `id4` y `id5`. Su función procesa correctamente `id1`, `id3` y `id5`. Para hacer que los mensajes `id2` y `id4` sean de nuevo visibles en la cola, la función debe devolver la siguiente respuesta: 

   ```
   { 
     "batchItemFailures": [ 
           {
               "itemIdentifier": "id2"
           },
           {
               "itemIdentifier": "id4"
           }
       ]
   }
   ```

   Estos son algunos ejemplos de código de función que devuelven la lista de IDs de mensajes fallidos del lote:

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Notificación de los errores de los elementos del lote de SQS con Lambda mediante .NET.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   using Amazon.Lambda.Core;
   using Amazon.Lambda.SQSEvents;
   
   // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
   [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
   namespace sqsSample;
   
   public class Function
   {
       public async Task<SQSBatchResponse> FunctionHandler(SQSEvent evnt, ILambdaContext context)
       {
           List<SQSBatchResponse.BatchItemFailure> batchItemFailures = new List<SQSBatchResponse.BatchItemFailure>();
           foreach(var message in evnt.Records)
           {
               try
               {
                   //process your message
                   await ProcessMessageAsync(message, context);
               }
               catch (System.Exception)
               {
                   //Add failed message identifier to the batchItemFailures list
                   batchItemFailures.Add(new SQSBatchResponse.BatchItemFailure{ItemIdentifier=message.MessageId}); 
               }
           }
           return new SQSBatchResponse(batchItemFailures);
       }
   
       private async Task ProcessMessageAsync(SQSEvent.SQSMessage message, ILambdaContext context)
       {
           if (String.IsNullOrEmpty(message.Body))
           {
               throw new Exception("No Body in SQS Message.");
           }
           context.Logger.LogInformation($"Processed message {message.Body}");
           // TODO: Do interesting work based on the new message
           await Task.CompletedTask;
       }
   }
   ```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Notificación de los errores de los elementos del lote de SQS con Lambda mediante Go.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   package main
   
   import (
   	"context"
   	"fmt"
   	"github.com/aws/aws-lambda-go/events"
   	"github.com/aws/aws-lambda-go/lambda"
   )
   
   func handler(ctx context.Context, sqsEvent events.SQSEvent) (map[string]interface{}, error) {
   	batchItemFailures := []map[string]interface{}{}
   
   	for _, message := range sqsEvent.Records {
   		if len(message.Body) > 0 {
   			// Your message processing condition here
   			fmt.Printf("Successfully processed message: %s\n", message.Body)
   		} else {
   			// Message processing failed
   			fmt.Printf("Failed to process message %s\n", message.MessageId)
   			batchItemFailures = append(batchItemFailures, map[string]interface{}{"itemIdentifier": message.MessageId})
   		}
   	}
   
   	sqsBatchResponse := map[string]interface{}{
   		"batchItemFailures": batchItemFailures,
   	}
   	return sqsBatchResponse, nil
   }
   
   func main() {
   	lambda.Start(handler)
   }
   ```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Notificación de los errores de los elementos del lote de SQS con Lambda mediante Java.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   import com.amazonaws.services.lambda.runtime.Context;
   import com.amazonaws.services.lambda.runtime.RequestHandler;
   import com.amazonaws.services.lambda.runtime.events.SQSEvent;
   import com.amazonaws.services.lambda.runtime.events.SQSBatchResponse;
    
   import java.util.ArrayList;
   import java.util.List;
    
   public class ProcessSQSMessageBatch implements RequestHandler<SQSEvent, SQSBatchResponse> {
       @Override
       public SQSBatchResponse handleRequest(SQSEvent sqsEvent, Context context) {
            List<SQSBatchResponse.BatchItemFailure> batchItemFailures = new ArrayList<SQSBatchResponse.BatchItemFailure>();
   
            for (SQSEvent.SQSMessage message : sqsEvent.getRecords()) {
                try {
                    //process your message
                } catch (Exception e) {
                    //Add failed message identifier to the batchItemFailures list
                    batchItemFailures.add(new SQSBatchResponse.BatchItemFailure(message.getMessageId()));
                }
            }
            return new SQSBatchResponse(batchItemFailures);
        }
   }
   ```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Notificación de los errores de los elementos del lote de SQS con Lambda mediante JavaScript.  

   ```
   // Node.js 20.x Lambda runtime, AWS SDK for Javascript V3
   export const handler = async (event, context) => {
       const batchItemFailures = [];
       for (const record of event.Records) {
           try {
               await processMessageAsync(record, context);
           } catch (error) {
               batchItemFailures.push({ itemIdentifier: record.messageId });
           }
       }
       return { batchItemFailures };
   };
   
   async function processMessageAsync(record, context) {
       if (record.body && record.body.includes("error")) {
           throw new Error("There is an error in the SQS Message.");
       }
       console.log(`Processed message: ${record.body}`);
   }
   ```
Notificación de los errores de los elementos del lote de SQS con Lambda mediante TypeScript.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   import { SQSEvent, SQSBatchResponse, Context, SQSBatchItemFailure, SQSRecord } from 'aws-lambda';
   
   export const handler = async (event: SQSEvent, context: Context): Promise<SQSBatchResponse> => {
       const batchItemFailures: SQSBatchItemFailure[] = [];
   
       for (const record of event.Records) {
           try {
               await processMessageAsync(record);
           } catch (error) {
               batchItemFailures.push({ itemIdentifier: record.messageId });
           }
       }
   
       return {batchItemFailures: batchItemFailures};
   };
   
   async function processMessageAsync(record: SQSRecord): Promise<void> {
       if (record.body && record.body.includes("error")) {
           throw new Error('There is an error in the SQS Message.');
       }
       console.log(`Processed message ${record.body}`);
   }
   ```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Notificación de los errores de los elementos del lote de SQS con Lambda mediante PHP.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   <?php
   
   use Bref\Context\Context;
   use Bref\Event\Sqs\SqsEvent;
   use Bref\Event\Sqs\SqsHandler;
   use Bref\Logger\StderrLogger;
   
   require __DIR__ . '/vendor/autoload.php';
   
   class Handler extends SqsHandler
   {
       private StderrLogger $logger;
       public function __construct(StderrLogger $logger)
       {
           $this->logger = $logger;
       }
   
       /**
        * @throws JsonException
        * @throws \Bref\Event\InvalidLambdaEvent
        */
       public function handleSqs(SqsEvent $event, Context $context): void
       {
           $this->logger->info("Processing SQS records");
           $records = $event->getRecords();
   
           foreach ($records as $record) {
               try {
                   // Assuming the SQS message is in JSON format
                   $message = json_decode($record->getBody(), true);
                   $this->logger->info(json_encode($message));
                   // TODO: Implement your custom processing logic here
               } catch (Exception $e) {
                   $this->logger->error($e->getMessage());
                   // failed processing the record
                   $this->markAsFailed($record);
               }
           }
           $totalRecords = count($records);
           $this->logger->info("Successfully processed $totalRecords SQS records");
       }
   }
   
   $logger = new StderrLogger();
   return new Handler($logger);
   ```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Notificación de los errores de los elementos del lote de SQS con Lambda mediante Python.  

   ```
   # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # SPDX-License-Identifier: Apache-2.0
   
   def lambda_handler(event, context):
       if event:
           batch_item_failures = []
           sqs_batch_response = {}
        
           for record in event["Records"]:
               try:
                   print(f"Processed message: {record['body']}")
               except Exception as e:
                   batch_item_failures.append({"itemIdentifier": record['messageId']})
           
           sqs_batch_response["batchItemFailures"] = batch_item_failures
           return sqs_batch_response
   ```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda-with-batch-item-handling). 
Notificación de los errores de los elementos del lote de SQS con Lambda mediante Ruby.  

   ```
   # Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   # SPDX-License-Identifier: Apache-2.0
   require 'json'
   
   def lambda_handler(event:, context:)
     if event
       batch_item_failures = []
       sqs_batch_response = {}
   
       event["Records"].each do |record|
         begin
           # process message
         rescue StandardError => e
           batch_item_failures << {"itemIdentifier" => record['messageId']}
         end
       end
   
       sqs_batch_response["batchItemFailures"] = batch_item_failures
       return sqs_batch_response
     end
   end
   ```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Notificación de los errores de los elementos del lote de SQS con Lambda mediante Rust.  

   ```
   // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
   // SPDX-License-Identifier: Apache-2.0
   use aws_lambda_events::{
       event::sqs::{SqsBatchResponse, SqsEvent},
       sqs::{BatchItemFailure, SqsMessage},
   };
   use lambda_runtime::{run, service_fn, Error, LambdaEvent};
   
   async fn process_record(_: &SqsMessage) -> Result<(), Error> {
       Err(Error::from("Error processing message"))
   }
   
   async fn function_handler(event: LambdaEvent<SqsEvent>) -> Result<SqsBatchResponse, Error> {
       let mut batch_item_failures = Vec::new();
       for record in event.payload.records {
           match process_record(&record).await {
               Ok(_) => (),
               Err(_) => batch_item_failures.push(BatchItemFailure {
                   item_identifier: record.message_id.unwrap(),
               }),
           }
       }
   
       Ok(SqsBatchResponse {
           batch_item_failures,
       })
   }
   
   #[tokio::main]
   async fn main() -> Result<(), Error> {
       run(service_fn(function_handler)).await
   }
   ```

------

Si los eventos fallidos no vuelven a la cola, consulte [¿Cómo soluciono los problemas de la función de Lambda SQS ReportBatchItemFailures?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-sqs-report-batch-item-failures/) en el Centro de conocimientos de AWS.

### Condiciones de éxito y fracaso
<a name="sqs-batchfailurereporting-conditions"></a>

Lambda trata un lote como un éxito completo si la función devuelve cualquiera de los siguientes elementos:
+ Una lista `batchItemFailures` vacía
+ Una lista `batchItemFailures` nula
+ Una `EventResponse` vacía
+ Una `EventResponse` nula

Lambda trata un lote como un error completo si la función devuelve cualquiera de los siguientes elementos:
+ Respuesta JSON no válida
+ Una cadena `itemIdentifier` vacía
+ Una nula `itemIdentifier`
+ Un `itemIdentifier` con un mal nombre de clave
+ Un valor `itemIdentifier` con un ID de mensaje que no existe

### Métricas de CloudWatch
<a name="sqs-batchfailurereporting-metrics"></a>

Para determinar si la función informa correctamente de los errores de elementos por lotes, puede monitorear las métricas Amazon SQS `NumberOfMessagesDeleted` y `ApproximateAgeOfOldestMessage` en Amazon CloudWatch.
+ `NumberOfMessagesDeleted` realiza un seguimiento del número de mensajes eliminados de la cola. Si cae a 0, es una señal de que la respuesta de la función no está devolviendo correctamente los mensajes fallidos.
+ `ApproximateAgeOfOldestMessage` hace un seguimiento de cuánto tiempo ha permanecido el mensaje más antiguo en la cola. Un aumento brusco de esta métrica puede indicar que la función no está devolviendo correctamente los mensajes fallidos.

### Uso de Powertools para el procesador por lotes de AWS Lambda
<a name="services-sqs-batchfailurereporting-powertools"></a>

La utilidad de procesamiento por lotes de Powertools para AWS Lambda gestiona de manera automática la lógica de respuesta parcial de los lotes, lo que reduce la complejidad de implementar la notificación de fallas en los lotes. Estos son algunos ejemplos del uso del procesador por lotes:

**Python**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/).
Procesamiento de mensajes de Amazon SQS con el procesador por lotes de AWS Lambda.  

```
import json
from aws_lambda_powertools import Logger
from aws_lambda_powertools.utilities.batch import BatchProcessor, EventType, process_partial_response
from aws_lambda_powertools.utilities.data_classes import SQSEvent
from aws_lambda_powertools.utilities.typing import LambdaContext

processor = BatchProcessor(event_type=EventType.SQS)
logger = Logger()

def record_handler(record):
    logger.info(record)
    # Your business logic here
    # Raise an exception to mark this record as failed
    
def lambda_handler(event, context: LambdaContext):
    return process_partial_response(
        event=event, 
        record_handler=record_handler, 
        processor=processor,
        context=context
    )
```

**TypeScript**  
Para ver ejemplos completos e instrucciones de configuración, consulte la [documentación del procesador por lotes](https://docs.aws.amazon.com/powertools/typescript/latest/features/batch/).
Procesamiento de mensajes de Amazon SQS con el procesador por lotes de AWS Lambda.  

```
import { BatchProcessor, EventType, processPartialResponse } from '@aws-lambda-powertools/batch';
import { Logger } from '@aws-lambda-powertools/logger';
import type { SQSEvent, Context } from 'aws-lambda';

const processor = new BatchProcessor(EventType.SQS);
const logger = new Logger();

const recordHandler = async (record: any): Promise<void> => {
    logger.info('Processing record', { record });
    // Your business logic here
    // Throw an error to mark this record as failed
};

export const handler = async (event: SQSEvent, context: Context) => {
    return processPartialResponse(event, recordHandler, processor, {
        context,
    });
};
```

# Parámetros de Lambda para las asignaciones de origen de eventos de Amazon SQS
<a name="services-sqs-parameters"></a>

Todos los tipos de origen de eventos Lambda comparten las mismas operaciones [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) y [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) de la API. Sin embargo, solo algunos de los parámetros se aplican a Amazon SQS.


| Parámetro | Obligatorio | Predeterminado | Notas | 
| --- | --- | --- | --- | 
|  BatchSize  |  N  |  10  |  Para colas estándar, el máximo es 10 000. Para colas FIFO, el máximo es 10.  | 
|  Habilitado  |  N  |  true  | none  | 
|  EventSourceArn  |  S  | N/A |  El ARN del flujo de datos o un consumidor de flujos  | 
|  FunctionName  |  S  | N/A  | none  | 
|  FilterCriteria  |  N  |  N/A   |  [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md)  | 
|  FunctionResponseTypes  |  N  | N/A  |  Para permitir que la función informe de errores específicos de un lote, incluya el valor `ReportBatchItemFailures` en `FunctionResponseTypes`. Para obtener más información, consulte [Implementación de respuestas parciales por lotes](services-sqs-errorhandling.md#services-sqs-batchfailurereporting).  | 
|  MaximumBatchingWindowInSeconds  |  N  |  0  | No se admite el intervalo de lotes para las colas FIFO | 
|  ProvisionedPollerConfig  |  N  |  N/A  |  Configura el número mínimo (2-200) y máximo (2-2000) de sondeadores de eventos dedicados para la asignación de orígenes de eventos de SQS. Cada sondeador de eventos puede gestionar hasta 1 MB/s de rendimiento y 10 invocaciones simultáneas.  | 
|  ScalingConfig  |  N  |  N/A   |  [Configuración de la simultaneidad máxima para los orígenes de eventos de Amazon SQS](services-sqs-scaling.md#events-sqs-max-concurrency)  | 

# Uso del filtrado de eventos con una fuente de eventos de Amazon SQS
<a name="with-sqs-filtering"></a>

Puede utilizar el filtrado de eventos para controlar qué registros de un flujo o una cola envía Lambda a su función. Para obtener información general sobre cómo funciona el filtrado de eventos, consulte [Controle qué eventos envía Lambda a la función](invocation-eventfiltering.md).

Esta sección se centra en el filtrado de eventos para las fuentes de eventos de Amazon SQS.

**nota**  
Las asignaciones de orígenes de eventos de Amazon SQS solo admiten el filtrado en la clave `body`.

**Topics**
+ [

## Conceptos básicos de filtrado de eventos de Amazon SQS
](#filtering-SQS)

## Conceptos básicos de filtrado de eventos de Amazon SQS
<a name="filtering-SQS"></a>

Supongamos que su cola de Amazon SQS contiene mensajes en el siguiente formato JSON.

```
{
    "RecordNumber": 1234,
    "TimeStamp": "yyyy-mm-ddThh:mm:ss",
    "RequestCode": "AAAA"
}
```

Un registro de ejemplo para esta cola tendría el siguiente aspecto.

```
{
    "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
    "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
    "body": "{\n "RecordNumber": 1234,\n "TimeStamp": "yyyy-mm-ddThh:mm:ss",\n "RequestCode": "AAAA"\n}",
    "attributes": {
        "ApproximateReceiveCount": "1",
        "SentTimestamp": "1545082649183",
        "SenderId": "AIDAIENQZJOLO23YVJ4VO",
        "ApproximateFirstReceiveTimestamp": "1545082649185"
        },
    "messageAttributes": {},
    "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
    "eventSource": "aws:sqs",
    "eventSourceARN": "arn:aws:sqs:us-west-2:123456789012:my-queue",
    "awsRegion": "us-west-2"
}
```

Para filtrar en función del contenido de los mensajes de Amazon SQS, utilice la clave `body` del registro de mensajes de Amazon SQS. Supongamos que desea procesar solo los registros en los que el `RequestCode` del mensaje de Amazon SQS sea “BBBB”. El objeto `FilterCriteria` sería el siguiente.

```
{
    "Filters": [
        {
            "Pattern": "{ \"body\" : { \"RequestCode\" : [ \"BBBB\" ] } }"
        }
    ]
}
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado. 

```
{
    "body": {
        "RequestCode": [ "BBBB" ]
        }
}
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "body" : { "RequestCode" : [ "BBBB" ] } }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:sqs:us-east-2:123456789012:my-queue \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"body\" : { \"RequestCode\" : [ \"BBBB\" ] } }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"body\" : { \"RequestCode\" : [ \"BBBB\" ] } }"}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "body" : { "RequestCode" : [ "BBBB" ] } }'
```

------

Supongamos que desea que su función procese solo los registros en los que `RecordNumber` sea un valor superior a 9999. El objeto `FilterCriteria` sería el siguiente.

```
{
    "Filters": [
        {
            "Pattern": "{ \"body\" : { \"RecordNumber\" : [ { \"numeric\": [ \">\", 9999 ] } ] } }"
        }
    ]
}
```

Para mayor claridad, este es el valor del `Pattern` del filtro ampliado en JSON no cifrado. 

```
{
    "body": {
        "RecordNumber": [
            {
                "numeric": [ ">", 9999 ]
            }
        ]
    }
}
```

Puede agregar el filtro mediante la consola, la AWS CLI o una plantilla de AWS SAM.

------
#### [ Console ]

Para agregar este filtro mediante la consola, siga las instrucciones que se indican en [Adjuntar criterios de filtro a una asignación de origen de eventos (consola)](invocation-eventfiltering.md#filtering-console) e ingrese la siguiente cadena para los **Criterios de filtro**.

```
{ "body" : { "RecordNumber" : [ { "numeric": [ ">", 9999 ] } ] } }
```

------
#### [ AWS CLI ]

Para crear una nueva asignación de orígenes de eventos con estos criterios de filtro mediante la AWS Command Line Interface (AWS CLI), ejecute el siguiente comando.

```
aws lambda create-event-source-mapping \
    --function-name my-function \
    --event-source-arn arn:aws:sqs:us-east-2:123456789012:my-queue \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"body\" : { \"RecordNumber\" : [ { \"numeric\": [ \">\", 9999 ] } ] } }"}]}'
```

Para agregar estos criterios de filtro a una asignación de orígenes de eventos existente, ejecute el siguiente comando.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"body\" : { \"RecordNumber\" : [ { \"numeric\": [ \">\", 9999 ] } ] } }"}]}'
```

------
#### [ AWS SAM ]

Para agregar este filtro mediante AWS SAM, agregue el siguiente fragmento a la plantilla YAML de su origen de eventos.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "body" : { "RecordNumber" : [ { "numeric": [ ">", 9999 ] } ] } }'
```

------

Para Amazon SQS, el cuerpo del mensaje puede ser cualquier cadena. No obstante, esto puede ser problemático si los `FilterCriteria` esperan que el formato JSON del `body` sea válido. La situación inversa también es problemática: si el cuerpo del mensaje entrante está en formato JSON, pero los criterios de filtro esperan que el `body` sea una cadena sin formato, puede producirse un comportamiento no deseado.

Para evitar este problema, asegúrese de que el formato del cuerpo de los `FilterCriteria` coincida con el formato esperado del `body` de los mensajes que recibe de la cola. Antes de filtrar los mensajes, Lambda evalúa automáticamente el formato del cuerpo del mensaje entrante y del patrón de filtro del `body`. Si no coincide, Lambda elimina el mensaje. En la siguiente tabla se resume esta evaluación:


| Formato del `body` del mensaje entrante | Formato del `body` del patrón de filtro | Acción resultante | 
| --- | --- | --- | 
|  Cadena sin formato  |  Cadena sin formato  |  Lambda filtra en función de los criterios de filtro.  | 
|  Cadena sin formato  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  Cadena sin formato  |  JSON válido  |  Lambda elimina el mensaje.  | 
|  JSON válido  |  Cadena sin formato  |  Lambda elimina el mensaje.  | 
|  JSON válido  |  Sin patrón de filtro para las propiedades de datos  |  Lambda filtra (solo en las demás propiedades de metadatos) en función de los criterios de filtro.  | 
|  JSON válido  |  JSON válido  |  Lambda filtra en función de los criterios de filtro.  | 

# Tutorial: Uso de Lambda con Amazon SQS
<a name="with-sqs-example"></a>

En este tutorial, creará una función de Lambda que consuma los mensajes de una cola de [Amazon Simple Queue Service (Amazon SQS)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html). La función de Lambda se ejecuta cada vez que se agrega un mensaje nuevo a la cola. La función escribe los mensajes en un flujo de Registros de Amazon CloudWatch. En el siguiente diagrama, se muestran los recursos de AWS que utiliza para completar el tutorial.

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/sqs_tut_resources.png)


Para completar este tutorial, lleve a cabo los siguientes pasos:

1. Cree una función de Lambda que escriba mensajes en Registros de CloudWatch.

1. Cree una cola de Amazon SQS.

1. Cree la asignación de orígenes de eventos de Lambda. La asignación de orígenes de eventos lee la cola de Amazon SQS e invoca la función de Lambda cuando se agrega un mensaje nuevo.

1. Para probar la configuración, agregue mensajes a la cola y supervise los resultados en Registros de CloudWatch.

## Requisitos previos
<a name="with-sqs-prepare"></a>

### Instala la AWS Command Line Interface
<a name="install_aws_cli"></a>

Si aún no ha instalado AWS Command Line Interface, siga los pasos que se indican en [Instalación o actualización de la versión más reciente de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalarlo.

El tutorial requiere un intérprete de comandos o un terminal de línea de comando para ejecutar los comandos. En Linux y macOS, use su administrador de intérprete de comandos y paquetes preferido.

**nota**  
En Windows, algunos comandos de la CLI de Bash que se utilizan habitualmente con Lambda (por ejemplo, `zip`) no son compatibles con los terminales integrados del sistema operativo. Para obtener una versión de Ubuntu y Bash integrada con Windows, [instale el subsistema de Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Creación del rol de ejecución
<a name="with-sqs-create-execution-role"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/sqs_tut_steps1.png)


Un [rol de ejecución](lambda-intro-execution-role.md) es un rol de AWS Identity and Access Management (IAM) que concede a la función de Lambda permiso para acceder a recursos y Servicios de AWS. Para permitir que la función lea elementos de Amazon SQS, adjunte la política de permisos **AWSLambdaSQSQueueExecutionRole**.

**Para crear un rol de ejecución y adjuntar una política de permisos de Amazon SQS**

1. Abra la [página Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Elija **Creación de rol**.

1. En **Tipo de entidad de confianza**, elija **Servicio de AWS**.

1. En **Caso de uso**, elija **Lambda**.

1. Elija **Siguiente**.

1. En el cuadro de búsqueda **Permisos de selección**, ingrese **AWSLambdaSQSQueueExecutionRole**.

1. Seleccione la política **AWSLambdaSQSQueueExecutionRole** y luego elija **Siguiente**.

1. En **Detalles del rol**, para **Nombre del rol**, ingrese **lambda-sqs-role**; luego elija **Crear rol**.

Tras crear la función, anote el nombre de recurso de Amazon (ARN) de la función de ejecución. Lo necesitará en pasos posteriores.

## Creación de la función
<a name="with-sqs-create-function"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/sqs_tut_steps2.png)


Cree una función de Lambda: que procese los mensajes de Amazon SQS. El código de función registra el cuerpo del mensaje de Amazon SQS en los Registros de CloudWatch.

En este tutorial, se utiliza el tiempo de ejecución de Node.js 24, pero también hemos proporcionado archivos de código de ejemplo en otros lenguajes de tiempo de ejecución. Puede seleccionar la pestaña del siguiente cuadro para ver el código del tiempo de ejecución que le interesa. El código JavaScript que usará en este paso está en el primer ejemplo que se muestra en la pestaña **JavaScript**.

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Uso de un evento de SQS con Lambda mediante .NET.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
﻿using Amazon.Lambda.Core;
using Amazon.Lambda.SQSEvents;


// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace SqsIntegrationSampleCode
{
    public async Task FunctionHandler(SQSEvent evnt, ILambdaContext context)
    {
        foreach (var message in evnt.Records)
        {
            await ProcessMessageAsync(message, context);
        }

        context.Logger.LogInformation("done");
    }

    private async Task ProcessMessageAsync(SQSEvent.SQSMessage message, ILambdaContext context)
    {
        try
        {
            context.Logger.LogInformation($"Processed message {message.Body}");

            // TODO: Do interesting work based on the new message
            await Task.CompletedTask;
        }
        catch (Exception e)
        {
            //You can use Dead Letter Queue to handle failures. By configuring a Lambda DLQ.
            context.Logger.LogError($"An error occurred");
            throw;
        }

    }
}
```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Uso de un evento de SQS con Lambda mediante Go.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package integration_sqs_to_lambda

import (
	"fmt"
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handler(event events.SQSEvent) error {
	for _, record := range event.Records {
		err := processMessage(record)
		if err != nil {
			return err
		}
	}
	fmt.Println("done")
	return nil
}

func processMessage(record events.SQSMessage) error {
	fmt.Printf("Processed message %s\n", record.Body)
	// TODO: Do interesting work based on the new message
	return nil
}

func main() {
	lambda.Start(handler)
}
```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Uso de un evento de SQS con Lambda mediante Java.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.SQSEvent;
import com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;

public class Function implements RequestHandler<SQSEvent, Void> {
    @Override
    public Void handleRequest(SQSEvent sqsEvent, Context context) {
        for (SQSMessage msg : sqsEvent.getRecords()) {
            processMessage(msg, context);
        }
        context.getLogger().log("done");
        return null;
    }

    private void processMessage(SQSMessage msg, Context context) {
        try {
            context.getLogger().log("Processed message " + msg.getBody());

            // TODO: Do interesting work based on the new message

        } catch (Exception e) {
            context.getLogger().log("An error occurred");
            throw e;
        }

    }
}
```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/blob/main/integration-sqs-to-lambda). 
Uso de un evento de SQS con Lambda mediante JavaScript.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
exports.handler = async (event, context) => {
  for (const message of event.Records) {
    await processMessageAsync(message);
  }
  console.info("done");
};

async function processMessageAsync(message) {
  try {
    console.log(`Processed message ${message.body}`);
    // TODO: Do interesting work based on the new message
    await Promise.resolve(1); //Placeholder for actual async work
  } catch (err) {
    console.error("An error occurred");
    throw err;
  }
}
```
Uso de un evento de SQS con Lambda mediante TypeScript.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { SQSEvent, Context, SQSHandler, SQSRecord } from "aws-lambda";

export const functionHandler: SQSHandler = async (
  event: SQSEvent,
  context: Context
): Promise<void> => {
  for (const message of event.Records) {
    await processMessageAsync(message);
  }
  console.info("done");
};

async function processMessageAsync(message: SQSRecord): Promise<any> {
  try {
    console.log(`Processed message ${message.body}`);
    // TODO: Do interesting work based on the new message
    await Promise.resolve(1); //Placeholder for actual async work
  } catch (err) {
    console.error("An error occurred");
    throw err;
  }
}
```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Uso de un evento de SQS con Lambda mediante PHP.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
<?php

# using bref/bref and bref/logger for simplicity

use Bref\Context\Context;
use Bref\Event\InvalidLambdaEvent;
use Bref\Event\Sqs\SqsEvent;
use Bref\Event\Sqs\SqsHandler;
use Bref\Logger\StderrLogger;

require __DIR__ . '/vendor/autoload.php';

class Handler extends SqsHandler
{
    private StderrLogger $logger;
    public function __construct(StderrLogger $logger)
    {
        $this->logger = $logger;
    }

    /**
     * @throws InvalidLambdaEvent
     */
    public function handleSqs(SqsEvent $event, Context $context): void
    {
        foreach ($event->getRecords() as $record) {
            $body = $record->getBody();
            // TODO: Do interesting work based on the new message
        }
    }
}

$logger = new StderrLogger();
return new Handler($logger);
```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Uso de un evento de SQS con Lambda mediante Python.  

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
def lambda_handler(event, context):
    for message in event['Records']:
        process_message(message)
    print("done")

def process_message(message):
    try:
        print(f"Processed message {message['body']}")
        # TODO: Do interesting work based on the new message
    except Exception as err:
        print("An error occurred")
        raise err
```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Uso de un evento de SQS con Lambda mediante Ruby.  

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
def lambda_handler(event:, context:)
  event['Records'].each do |message|
    process_message(message)
  end
  puts "done"
end

def process_message(message)
  begin
    puts "Processed message #{message['body']}"
    # TODO: Do interesting work based on the new message
  rescue StandardError => err
    puts "An error occurred"
    raise err
  end
end
```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Uso de un evento de SQS con Lambda mediante Rust.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use aws_lambda_events::event::sqs::SqsEvent;
use lambda_runtime::{run, service_fn, Error, LambdaEvent};

async fn function_handler(event: LambdaEvent<SqsEvent>) -> Result<(), Error> {
    event.payload.records.iter().for_each(|record| {
        // process the record
        tracing::info!("Message body: {}", record.body.as_deref().unwrap_or_default())
    });

    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        // disable printing the name of the module in every log line.
        .with_target(false)
        // disabling time is handy because CloudWatch will add the ingestion time.
        .without_time()
        .init();

    run(service_fn(function_handler)).await
}
```

------

**Para crear una función de Lambda Node.js.**

1. Cree un directorio para el proyecto y, a continuación, cambie a ese directorio.

   ```
   mkdir sqs-tutorial
   cd sqs-tutorial
   ```

1. Copie el código de muestra de JavaScript en un nuevo archivo con el nombre `index.js`.

1. Cree un paquete de implementación utilizando el siguiente comando `zip`.

   ```
   zip function.zip index.js
   ```

1. Cree una función de Lambda con el comando de AWS CLI [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html). Para el parámetro `role`, introduzca el ARN del rol de ejecución que creó anteriormente.
**nota**  
La función de Lambda y la cola de Amazon SQS deben estar en la misma Región de AWS.

   ```
   aws lambda create-function --function-name ProcessSQSRecord \
   --zip-file fileb://function.zip --handler index.handler --runtime nodejs24.x \
   --role arn:aws:iam::111122223333:role/lambda-sqs-role
   ```

## Prueba de la función
<a name="with-sqs-create-test-function"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/sqs_tut_steps3.png)


Invoque la función de Lambda manualmente con el comando `invoke` AWS CLI y un evento de Amazon SQS de muestra.

**Para invocar la función de Lambda con un evento de ejemplo**

1. Guarde el siguiente JSON como un archivo denominado `input.json`. Este JSON simula un evento que Amazon SQS podría enviar a la función de Lambda, donde `"body"` contiene el mensaje real de la cola. En este ejemplo, el mensaje es `"test"`.  
**Example Evento de Amazon SQS**  

   Se trata de un evento de prueba y no es necesario que cambie el mensaje o el número de cuenta.

   ```
   {
       "Records": [
           {
               "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
               "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
               "body": "test",
               "attributes": {
                   "ApproximateReceiveCount": "1",
                   "SentTimestamp": "1545082649183",
                   "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                   "ApproximateFirstReceiveTimestamp": "1545082649185"
               },
               "messageAttributes": {},
               "md5OfBody": "098f6bcd4621d373cade4e832627b4f6",
               "eventSource": "aws:sqs",
               "eventSourceARN": "arn:aws:sqs:us-east-1:111122223333:my-queue",
               "awsRegion": "us-east-1"
           }
       ]
   }
   ```

1. Ejecute el siguiente comando de AWS CLI [invoke](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/invoke.html). Este comando devuelve Registros de CloudWatch en la respuesta. Para obtener más información acerca de la recuperación de registros, consulte [Acceso a los registros con la AWS CLI](monitoring-cloudwatchlogs-view.md#monitoring-cloudwatchlogs-cli).

   ```
   aws lambda invoke --function-name ProcessSQSRecord --payload file://input.json out --log-type Tail \
   --query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
   ```

   La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 2*.

1. Encuentre el registro `INFO` en la respuesta. Aquí es donde la función de Lambda registra el cuerpo del mensaje. Debería ver registros con un aspecto similar al siguiente:

   ```
   2023-09-11T22:45:04.271Z	348529ce-2211-4222-9099-59d07d837b60	INFO	Processed message test
   2023-09-11T22:45:04.288Z	348529ce-2211-4222-9099-59d07d837b60	INFO	done
   ```

## Cree una cola de Amazon SQS.
<a name="with-sqs-configure-sqs"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/sqs_tut_steps4.png)


Cree una cola de Amazon SQS que la función de Lambda pueda utilizar como origen de eventos. La función de Lambda y la cola de Amazon SQS deben estar en la misma Región de AWS.

**Para crear una cola**

1. Abra la [consola de Amazon SQS](https://console.aws.amazon.com/sqs).

1. Elige **Crear cola**.

1. Escriba un nombre para la cola. Deje las configuraciones predeterminadas de todas las demás opciones.

1. Elige **Crear cola**.

Tras crear la cola, anote su ARN. Lo necesitará en el siguiente paso al asociar la cola a la función de Lambda.

## Configuración del origen de eventos
<a name="with-sqs-attach-notification-configuration"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/sqs_tut_steps5.png)


Conecte la cola de Amazon SQS a la función de Lambda mediante la creación de una [asignación de orígenes de eventos](invocation-eventsourcemapping.md). La asignación de orígenes de eventos lee la cola de Amazon SQS e invoca la función de Lambda cuando se agrega un mensaje nuevo.

Para crear una asignación entre la cola de Amazon SQS y la función de Lambda, ejecute el comando de AWS CLI [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html). Ejemplo:

```
aws lambda create-event-source-mapping --function-name ProcessSQSRecord  --batch-size 10 \
--event-source-arn arn:aws:sqs:us-east-1:111122223333:my-queue
```

Para obtener una lista de las asignaciones de orígenes de eventos, utilice el comando [list-event-source-mappings](https://awscli.amazonaws.com/v2/documentation/api/2.1.29/reference/lambda/list-event-source-mappings.html). Ejemplo:

```
aws lambda list-event-source-mappings --function-name ProcessSQSRecord
```

## Enviar un mensaje de prueba
<a name="with-sqs-test-message"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/sqs_tut_steps6.png)


**Para enviar un mensaje de Amazon SQS a la función de Lambda**

1. Abra la [consola de Amazon SQS](https://console.aws.amazon.com/sqs).

1. Elija la cola que creó anteriormente.

1. Seleccione **Enviar y recibir mensajes**.

1. En el **Cuerpo del mensaje**, ingrese un mensaje de prueba, como “este es un mensaje de prueba”.

1. Elija **Enviar mensaje**.

Lambda sondea la cola en busca de actualizaciones. Cuando hay un nuevo mensaje, Lambda invoca la función con estos nuevos datos de evento desde la cola. Si el controlador de la función vuelve sin excepciones, Lambda considera que el mensaje se procesó correctamente y empieza a leer nuevos mensajes en la cola. Después de procesar correctamente un mensaje, Lambda lo elimina automáticamente de la cola. Si el controlador genera una excepción, Lambda considera que el lote de mensajes no se procesó correctamente e invoca la función con el mismo lote de mensajes.

## Consulta de los Registros de CloudWatch
<a name="with-sqs-check-logs"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/sqs_tut_steps7.png)


**Para confirmar que la función procesó el mensaje**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija la función **ProcessSQSRecord**.

1. Elegir **Monitor**.

1. Seleccione **Ver Registros en CloudWatch**.

1. En la consola de CloudWatch, elija el **Flujo de registro** para la función.

1. Busque el registro `INFO`. Aquí es donde la función de Lambda registra el cuerpo del mensaje. Debería ver el mensaje que envió desde la cola de Amazon SQS. Ejemplo:

   ```
   2023-09-11T22:49:12.730Z b0c41e9c-0556-5a8b-af83-43e59efeec71 INFO Processed message this is a test message.
   ```

## Eliminación de sus recursos
<a name="cleanup"></a>

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

**Cómo eliminar el rol de ejecución**

1. Abra la página [Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione el rol de ejecución que creó.

1. Elija **Eliminar**.

1. Si desea continuar, escriba el nombre del rol en el campo de entrada de texto y elija **Delete** (Eliminar).

**Cómo eliminar la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que ha creado.

1. Elija **Acciones**, **Eliminar**.

1. Escriba **confirm** en el campo de entrada de texto y elija **Delete** (Eliminar).

**Para eliminar la cola de Amazon SQS**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de Amazon SQS en [https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/).

1. Seleccione la cola que ha creado.

1. Elija **Eliminar**.

1. Introduzca **confirm** en el campo de entrada de texto.

1. Elija **Eliminar**.

# Tutorial: Uso de una cola entre cuentas de Amazon SQS como un origen de eventos
<a name="with-sqs-cross-account-example"></a>

En este tutorial, creará una función de Lambda que consuma los mensajes de una cola de Amazon Simple Queue Service (Amazon SQS) en una cuenta de AWS diferente. Este tutorial incluye dos cuentas de AWS: la **Cuenta A** hace referencia a la cuenta que contiene la función de Lambda y la **Cuenta B** hace referencia a la cuenta que contiene la cola de Amazon SQS.

## Requisitos previos
<a name="with-sqs-cross-account-prepare"></a>

### Instala la AWS Command Line Interface
<a name="install_aws_cli"></a>

Si aún no ha instalado AWS Command Line Interface, siga los pasos que se indican en [Instalación o actualización de la versión más reciente de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalarlo.

El tutorial requiere un intérprete de comandos o un terminal de línea de comando para ejecutar los comandos. En Linux y macOS, use su administrador de intérprete de comandos y paquetes preferido.

**nota**  
En Windows, algunos comandos de la CLI de Bash que se utilizan habitualmente con Lambda (por ejemplo, `zip`) no son compatibles con los terminales integrados del sistema operativo. Para obtener una versión de Ubuntu y Bash integrada con Windows, [instale el subsistema de Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Creación del rol de ejecución (Cuenta A)
<a name="with-sqs-cross-account-create-execution-role"></a>

En la **Cuenta A**, cree un [rol de ejecución](lambda-intro-execution-role.md) que conceda permiso a la función para acceder a los recursos necesarios de AWS.

**Para crear un rol de ejecución**

1. Abra la [página de Roles](https://console.aws.amazon.com/iam/home#/roles) (Roles) en la consola de AWS Identity and Access Management (IAM).

1. Elija **Crear rol**.

1. Cree un rol con las propiedades siguientes.
   + **Trusted entity (Entidad de confianza** – **AWS Lambda**
   + **Permisos**: **AWSLambdaSQSQueueExecutionRole**
   + **Role name (Nombre de rol** – **cross-account-lambda-sqs-role**

La política **AWSLambdaSQSQueueExecutionRole** tiene los permisos que la función necesita para leer elementos de Amazon SQS y escribir registros en Amazon CloudWatch Logs.

## Creación de la función (Cuenta A)
<a name="with-sqs-cross-account-create-function"></a>

En la **Cuenta A**, cree una función de Lambda que procese los mensajes de Amazon SQS. La función de Lambda y la cola de Amazon SQS deben estar en la misma Región de AWS.

El siguiente ejemplo de código Node.js escribe cada mensaje en un registro de Registros de CloudWatch.

**Example index.mjs**  

```
export const handler = async function(event, context) {
  event.Records.forEach(record => {
    const { body } = record;
    console.log(body);
  });
  return {};
}
```

**Cómo crear la función**
**nota**  
Al seguir estos pasos, se crea una función de Node.js. Para otros lenguajes, los pasos son similares, pero algunos detalles son diferentes.

1. Guarde el código de ejemplo como un archivo denominado `index.mjs`.

1. Cree un paquete de implementación.

   ```
   zip function.zip index.mjs
   ```

1. Cree la función mediante el comando `create-function` de la AWS Command Line Interface (AWS CLI). Sustituya `arn:aws:iam::111122223333:role/cross-account-lambda-sqs-role` por el ARN del rol de ejecución que ha creado anteriormente.

   ```
   aws lambda create-function --function-name CrossAccountSQSExample \
   --zip-file fileb://function.zip --handler index.handler --runtime nodejs24.x \
   --role arn:aws:iam::111122223333:role/cross-account-lambda-sqs-role
   ```

## Prueba de la función (Cuenta A)
<a name="with-sqs-cross-account-create-test-function"></a>

En la **Cuenta A**, pruebe la función de Lambda de forma manual mediante el comando `invoke` de la AWS CLI y un evento de Amazon SQS de muestra.

Si el controlador vuelve normalmente sin excepciones, Lambda considera que el mensaje se procesó de forma correcta y empieza a leer mensajes nuevos en la cola. Después de procesar correctamente un mensaje, Lambda lo elimina automáticamente de la cola. Si el controlador genera una excepción, Lambda considera que el lote de mensajes no se procesó correctamente e invoca la función con el mismo lote de mensajes.

1. Guarde el siguiente JSON como un archivo denominado `input.txt`.

   ```
   {
       "Records": [
           {
               "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
               "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
               "body": "test",
               "attributes": {
                   "ApproximateReceiveCount": "1",
                   "SentTimestamp": "1545082649183",
                   "SenderId": "AIDAIENQZJOLO23YVJ4VO",
                   "ApproximateFirstReceiveTimestamp": "1545082649185"
               },
               "messageAttributes": {},
               "md5OfBody": "098f6bcd4621d373cade4e832627b4f6",
               "eventSource": "aws:sqs",
               "eventSourceARN": "arn:aws:sqs:us-east-1:111122223333:example-queue",
               "awsRegion": "us-east-1"
           }
       ]
   }
   ```

   El JSON anterior simula un evento que Amazon SQS podría enviar a la función de Lambda, donde `"body"` contiene el mensaje real de la cola.

1. Ejecute el siguiente comando AWS CLI de la `invoke`.

   ```
   aws lambda invoke --function-name CrossAccountSQSExample \
   --cli-binary-format raw-in-base64-out \
   --payload file://input.txt outputfile.txt
   ```

   La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 2*.

1. Verifique la salida en el archivo `outputfile.txt`.

## Creación de una cola de Amazon SQS (Cuenta B)
<a name="with-sqs-cross-account-configure-sqs"></a>

En la **Cuenta B**, cree una cola de Amazon SQS que la función de Lambda en la **Cuenta A** pueda utilizar como un origen de eventos. La función de Lambda y la cola de Amazon SQS deben estar en la misma Región de AWS.

**Para crear una cola**

1. Abra la [consola de Amazon SQS](https://console.aws.amazon.com/sqs).

1. Elige **Crear cola**.

1. Cree una cola con las siguientes propiedades.
   + **Type** (Tipo): **estándar**
   + **Name** (Nombre): **LambdaCrossAccountQueue**
   + **Configuration** (Configuración): conserve la configuración predeterminada.
   + **Access policy** (Política de acceso): elija **Advanced** (Avanzada). Pegue la siguiente política JSON. Reemplace los siguientes valores:
     + `111122223333`: ID de la **cuenta A** de la Cuenta de AWS
     + `444455556666`: ID de la **cuenta B** de la Cuenta de AWS

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

****  

     ```
     {
         "Version":"2012-10-17",		 	 	 
         "Id": "Queue1_Policy_UUID",
         "Statement": [
             {
                 "Sid": "Queue1_AllActions",
                 "Effect": "Allow",
                 "Principal": {
                     "AWS": [
                         "arn:aws:iam::111122223333:role/cross-account-lambda-sqs-role"
                     ]
                 },
                 "Action": "sqs:*",
                 "Resource": "arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue"
             }
         ]
     }
     ```

------

     Esta política concede al rol de ejecución de Lambda en la **Cuenta A** los permisos para consumir mensajes de esta cola de Amazon SQS.

1. Después de crear la cola, registre su Nombre de recurso de Amazon (ARN). Lo necesitará en el siguiente paso al asociar la cola a la función de Lambda.

## Configuración del origen de eventos (Cuenta A)
<a name="with-sqs-cross-account-event-source"></a>

En la **Cuenta A**, cree una asignación de orígenes de eventos entre la cola de Amazon SQS en la **Cuenta B** y la función de Lambda al ejecutar el siguiente comando `create-event-source-mapping` de la AWS CLI. Sustituya `arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue` por el ARN de la cola de Amazon SQS que creó en el paso anterior.

```
aws lambda create-event-source-mapping --function-name CrossAccountSQSExample --batch-size 10 \
--event-source-arn arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue
```

Para obtener una lista de asignaciones de orígenes de eventos, ejecute el siguiente comando.

```
aws lambda list-event-source-mappings --function-name CrossAccountSQSExample \
--event-source-arn arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue
```

## Prueba de la configuración
<a name="with-sqs-final-integration-test-no-iam"></a>

Ahora puede probar la configuración de la siguiente manera:

1. En la **Cuenta B**, abra la [consola de Amazon SQS](https://console.aws.amazon.com/sqs).

1. Elija **LambdaCrossAccountQueue**, que creó anteriormente.

1. Seleccione **Send and receive messages (Enviar y recibir mensajes)**.

1. En **Message body** (Cuerpo del mensaje), ingrese un mensaje de prueba.

1. Elija **Enviar mensaje**.

La función de Lambda en la **Cuenta A** debería recibir el mensaje. Lambda continuará sondeando la cola en busca de actualizaciones. Cuando hay un nuevo mensaje, Lambda invoca la función con estos nuevos datos de evento desde la cola. La función se ejecuta y crea registros en Amazon CloudWatch. Puede ver los registros en la [consola de CloudWatch](https://console.aws.amazon.com/cloudwatch).

## Eliminación de sus recursos
<a name="cleanup"></a>

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

En la **Cuenta A**, limpie el rol de ejecución y la función de Lambda.

**Cómo eliminar el rol de ejecución**

1. Abra la página [Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione el rol de ejecución que creó.

1. Elija **Eliminar**.

1. Si desea continuar, escriba el nombre del rol en el campo de entrada de texto y elija **Delete** (Eliminar).

**Cómo eliminar la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que ha creado.

1. Elija **Acciones**, **Eliminar**.

1. Escriba **confirm** en el campo de entrada de texto y elija **Delete** (Eliminar).

En la **Cuenta B**, limpie la cola de Amazon SQS.

**Para eliminar la cola de Amazon SQS**

1. Inicie sesión en la Consola de administración de AWS y abra la consola de Amazon SQS en [https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/).

1. Seleccione la cola que ha creado.

1. Elija **Eliminar**.

1. Introduzca **confirm** en el campo de entrada de texto.

1. Elija **Eliminar**.

# Orquestación de funciones de Lambda con Step Functions
<a name="with-step-functions"></a>

AWS Step Functions proporciona una orquestación visual del flujo de trabajo para coordinar las funciones de Lambda con otros servicios de AWS. Con integraciones nativas para más de 220 servicios de AWS y una infraestructura totalmente administrada que no requiere mantenimiento, Step Functions es ideal cuando necesita un diseño visual del flujo de trabajo e integraciones de servicios totalmente administradas.

Para la orquestación mediante lenguajes de programación estándar dentro de Lambda, donde la lógica del flujo de trabajo convive con la lógica empresarial, considere las [funciones duraderas de Lambda](durable-functions.md). Para obtener ayuda para elegir entre estas opciones, consulte [Funciones duraderas o Step Functions](durable-step-functions.md).

Por ejemplo, para procesar un pedido, puede ser necesario validar los detalles del pedido, comprobar los niveles de inventario, procesar el pago y generar una factura. Escriba funciones de Lambda independientes para cada tarea y utilice Step Functions para administrar el flujo de trabajo. Step Functions coordina el flujo de datos entre sus funciones y gestiona los errores de cada paso. Esta separación hace que sus flujos de trabajo sean más fáciles de visualizar, modificar y mantener a medida que se vuelven más complejos.

## Cuándo usar Step Functions con Lambda
<a name="when-to-use-step-functions"></a>

Los siguientes escenarios son ejemplos claros de cuándo Step Functions resulta particularmente adecuado para orquestar aplicaciones basadas en Lambda.
+ [Procesamiento secuencial](#sequential-processing)
+ [Gestión de errores complejos](#complex-error-handling)
+ [Flujos de trabajo condicionales y aprobaciones humanas](#conditional-workflows-human-approvals)
+ [Procesamiento paralelo](#parallel-processing)

### Procesamiento secuencial
<a name="sequential-processing"></a>

El procesamiento secuencial es cuando una tarea debe completarse antes de que pueda comenzar la siguiente. Por ejemplo, en un sistema de procesamiento de pedidos, el procesamiento de pagos no puede comenzar hasta que se complete la validación del pedido, y la generación de facturas debe esperar a la confirmación del pago. Escriba funciones de Lambda independientes para cada tarea y utilice Step Functions para gestionar la secuencia y gestionar el flujo de datos entre las funciones.

#### Ejemplo de antipatrón
<a name="anti-pattern-sequential"></a>

Una sola función de Lambda administra todo el flujo de trabajo de procesamiento de pedidos mediante las siguientes acciones:
+ Invocar otras funciones de Lambda en secuencia
+ Analizar y validar las respuestas de cada función
+ Implementar la lógica de recuperación y gestión de errores
+ Administrar el flujo de datos entre funciones

#### Método recomendado
<a name="recommended-sequential"></a>

Use dos funciones de Lambda: una para validar el pedido y otra para procesar el pago. Step Functions coordina estas funciones mediante las siguientes acciones:
+ Ejecutar las tareas en la secuencia correcta
+ Pasar datos entre funciones
+ Implementar la gestión de errores en cada paso
+ Utilizar los estados [Elección](https://docs.aws.amazon.com/step-functions/latest/dg/state-choice.html) para garantizar que solo se proceda al pago de los pedidos válidos

**Example gráfico del flujo de trabajo**  

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/sequential_workflow.png)


**nota**  
**Alternativa que prioriza el código:** para el procesamiento secuencial con puntos de control y reintentos basados en código, consulte los [pasos de las funciones duraderas de Lambda.](durable-basic-concepts.md)

### Gestión de errores complejos
<a name="complex-error-handling"></a>

Mientras que Lambda proporciona [capacidades de reintento para invocaciones asíncronas y asignaciones de orígenes de eventos](invocation-retries.md), Step Functions ofrece una gestión de errores más sofisticada para flujos de trabajo complejos. Puede [configurar los reintentos automáticos](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html#error-handling-retrying-after-an-error) con un retroceso exponencial y establecer diferentes políticas de reintentos para los distintos tipos de errores. Cuando se agoten los reintentos, use `Catch` para enrutar los errores a un [estado alternativo](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html#error-handling-fallback-states). Esto resulta especialmente útil cuando se necesita una gestión de errores de flujo de trabajo que coordine múltiples funciones y servicios.

Para obtener más información sobre cómo gestionar errores de la función de Lambda en una máquina de estados, consulte [Handling errors](https://catalog.workshops.aws/stepfunctions/handling-errors) en *The AWS Step Functions Workshop*.

#### Ejemplo de antipatrón
<a name="anti-pattern-error-handling"></a>

Una sola función de Lambda gestiona todo lo siguiente:
+ Intenta llamar a un servicio de procesamiento de pagos.
+ Si el servicio de pago no está disponible, la función espera y lo vuelve a intentar más tarde.
+ Implementa un retroceso exponencial personalizado para el tiempo de espera.
+ Después de que todos los intentos fallen, captura el error y elige otro flujo.

#### Método recomendado
<a name="recommended-error-handling"></a>

Usa una sola función de Lambda centrada únicamente en el procesamiento de pagos. Step Functions administra la gestión de errores mediante las siguientes acciones:
+ [Reintentar automáticamente las tareas fallidas con periodos de retroceso configurables](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html#error-handling-retrying-after-an-error)
+ Aplicar diferentes políticas de reintento en función de los tipos de errores
+ Enrutar los diferentes tipos de errores a los estados de reserva adecuados
+ Mantener el estado y el historial de la gestión de errores

**Example gráfico del flujo de trabajo**  

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/error_handling_workflow.png)


**nota**  
**Alternativa que prioriza el código:** las funciones duraderas proporcionan una gestión de errores de tipo try-catch con estrategias de reintento configurables. Consulte [Gestión de errores en funciones duraderas](durable-execution-sdk-retries.md).

### Flujos de trabajo condicionales y aprobaciones humanas
<a name="conditional-workflows-human-approvals"></a>

Utilice el [estado Elección](https://docs.aws.amazon.com/step-functions/latest/dg/state-choice.html) de Step Functions para enrutar los flujos de trabajo en función del resultado de la función y el [sufijo waitForTaskToken](https://docs.aws.amazon.com/step-functions/latest/dg/connect-to-resource.html#connect-wait-token) para pausar los flujos de trabajo para decisiones humanas. Por ejemplo, para procesar una solicitud de aumento del límite de crédito, utilice una función de Lambda para evaluar los factores de riesgo. A continuación, utilice Step Functions para dirigir las solicitudes de alto riesgo a la aprobación manual y las solicitudes de bajo riesgo a la aprobación automática.

Para implementar un ejemplo de flujo de trabajo que utilice un patrón de integración de tokens de tarea de devolución de llamada, consulte [Callback with Task Token](https://catalog.workshops.aws/stepfunctions/integrating-services/3-callback-token) en *The AWS Step Functions Workshop*. 

#### Ejemplo de antipatrón
<a name="anti-pattern-conditional"></a>

Una sola función de Lambda administra un flujo de trabajo de aprobación complejo mediante las siguientes acciones:
+ Implementar una lógica condicional anidada para evaluar las solicitudes de crédito
+ Invocar diferentes funciones de aprobación según los importes de las solicitudes
+ Administrar múltiples vías de aprobación y puntos de decisión
+ Hacer un seguimiento del estado de las aprobaciones pendientes
+ Implementar una lógica de tiempo de espera y notificación para las aprobaciones

#### Método recomendado
<a name="recommended-conditional"></a>

Use tres funciones de Lambda: una para evaluar el riesgo de cada solicitud, otra para aprobar las solicitudes de bajo riesgo y otra para dirigir las solicitudes de alto riesgo a un administrador para que las revise. Step Functions administra el flujo de trabajo mediante las siguientes acciones:
+ Usar estados [Elección](https://docs.aws.amazon.com/step-functions/latest/dg/state-choice.html) para enrutar las solicitudes en función del importe y el nivel de riesgo
+ Pausar la ejecución mientras se espera la aprobación humana
+ Administrar los tiempos de espera de las aprobaciones pendientes
+ Proporcionar visibilidad sobre el estado actual de cada solicitud

**Example gráfico del flujo de trabajo**  

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/conditional_workflow.png)


**nota**  
**Alternativa que prioriza el código:** las funciones duraderas admiten devoluciones de llamadas para flujos de trabajo con intervención humana. Consulte [Devoluciones de llamadas en funciones duraderas](durable-execution-sdk.md).

### Procesamiento paralelo
<a name="parallel-processing"></a>

Step Functions ofrece tres formas de gestionar el procesamiento en paralelo:
+ El [estado En paralelo](https://docs.aws.amazon.com/step-functions/latest/dg/state-parallel.html) ejecuta varias ramas de su flujo de trabajo simultáneamente. Úselo cuando tenga que ejecutar diferentes funciones en paralelo, como generar miniaturas mientras extrae metadatos de imágenes.
+ El [estado Mapa en línea](https://docs.aws.amazon.com/step-functions/latest/dg/state-map-inline.html) procesa matrices de datos con hasta 40 iteraciones simultáneas. Úselo para conjuntos de datos pequeños y medianos en los que tenga que efectuar la misma operación en cada elemento.
+ El [estado Mapa distribuido](https://docs.aws.amazon.com/step-functions/latest/dg/state-map-distributed.html) gestiona el procesamiento en paralelo a gran escala con hasta 10 000 ejecuciones simultáneas y es compatible con matrices JSON y orígenes de datos de Amazon Simple Storage Service (Amazon S3). Úselo cuando procese conjuntos de datos de gran tamaño o cuando necesite una mayor simultaneidad.

#### Ejemplo de antipatrón
<a name="anti-pattern-parallel"></a>

Una sola función de Lambda intenta administrar el procesamiento en paralelo mediante las siguientes acciones:
+ Invocar simultáneamente varias funciones de procesamiento de imágenes
+ Implementar una lógica de ejecución en paralelo personalizada
+ Administrar los tiempos de espera y la gestión de errores para cada tarea en paralelo
+ Recopilar y agregar los resultados de todas las funciones

#### Método recomendado
<a name="recommended-parallel"></a>

Use tres funciones de Lambda: una para crear una imagen en miniatura, otra para agregar una marca de agua y otra para extraer los metadatos. Step Functions administra estas funciones mediante las siguientes acciones:
+ Ejecutar todas las funciones simultáneamente con el estado [En paralelo](https://docs.aws.amazon.com/step-functions/latest/dg/state-parallel.html)
+ Recopilar los resultados de cada función en una matriz ordenada
+ Administrar los tiempos de espera y la gestión de errores en todas las ejecuciones en paralelo
+ Continuar solo cuando se completen todas las ramas en paralelo

**Example gráfico del flujo de trabajo**  

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/parallel_workflow.png)


**nota**  
**Alternativa que prioriza el código:** las funciones duraderas proporcionan operaciones `parallel()` y `map()`. Consulte [Ejecución en paralelo](durable-execution-sdk.md).

## Cuándo no usar Step Functions con Lambda
<a name="when-not-to-use"></a>

No todas las aplicaciones basadas en Lambda se benefician del uso de Step Functions. Tenga en cuenta estos escenarios al elegir la arquitectura de su aplicación.
+ [Aplicaciones sencillas](#simple-applications)
+ [Procesamiento de datos complejos](#complex-data-processing)
+ [cargas de trabajo con un uso intensivo de la CPU](#cpu-intensive)

### Aplicaciones sencillas
<a name="simple-applications"></a>

**nota**  
Para los flujos de trabajo que no requieren un diseño visual ni amplias integraciones de servicios, [las funciones duraderas de Lambda](durable-functions.md) pueden ser una alternativa más sencilla que mantiene la lógica del flujo de trabajo en el código dentro de Lambda.

Para las aplicaciones que no requieren una orquestación compleja, el uso de Step Functions puede agregar una complejidad innecesaria. Por ejemplo, si simplemente procesa mensajes de una cola de Amazon SQS o responde a eventos de Amazon EventBridge, puede configurar estos servicios para que invoquen sus funciones de Lambda directamente. Del mismo modo, si la aplicación consta de solo una o dos funciones de Lambda con una gestión de errores sencilla, la invocación directa de Lambda o las arquitecturas basadas en eventos podrían ser más sencillas de implementar y mantener.

### Procesamiento de datos complejos
<a name="complex-data-processing"></a>

Puede usar el estado [Mapa distribuido](https://docs.aws.amazon.com/step-functions/latest/dg/state-map-distributed.html) de Step Functions para procesar simultáneamente grandes conjuntos de datos de Amazon S3 con funciones de Lambda. Esto resulta eficaz para muchas cargas de trabajo en paralelo a gran escala, incluido el procesamiento de datos semiestructurados, como archivos JSON o CSV. Sin embargo, para transformaciones de datos más complejas o análisis avanzados, tenga en cuenta estas alternativas:
+ **Canalizaciones de transformación de datos**: use AWS Glue para trabajos de ETL que procesan datos estructurados o semiestructurados de varios orígenes. AWS Glue es particularmente útil cuando se necesitan capacidades integradas de administración de catálogos de datos y esquemas.
+ **Análisis de datos:** use Amazon EMR para análisis de datos a escala de petabytes, especialmente cuando necesite herramientas Apache Hadoop de ecosistema o para cargas de trabajo de machine learning que superen los límites de [memoria](configuration-memory.md) de Lambda.

### cargas de trabajo con un uso intensivo de la CPU
<a name="cpu-intensive"></a>

Si bien Step Functions puede orquestar tareas con un uso intensivo de la CPU, es posible que las funciones de Lambda no sean adecuadas para estas cargas de trabajo debido a sus recursos de CPU limitados. Para operaciones de computación intensiva dentro de sus flujos de trabajo, tenga en cuenta estas alternativas:
+ **Orquestación de contenedores:** utilice Step Functions para administrar las tareas de Amazon Elastic Container Service (Amazon ECS) a fin de obtener recursos de computación más coherentes y escalables.
+ **Procesamiento por lotes:** integre AWS Batch con Step Functions para administrar trabajos por lotes que requieren un uso sostenido de la CPU.

# Invocación de una función de Lambda con eventos por lotes de Amazon S3
<a name="services-s3-batch"></a>

Puede utilizar las operaciones por lotes de Amazon S3 para invocar una función de Lambda en un conjunto grande de objetos de Amazon S3. Amazon S3 realiza un seguimiento del progreso de las operaciones por lotes, envía notificaciones y almacena un informe de finalización que muestra el estado de cada acción. 

Para ejecutar una operación por lotes, debe crear un [trabajo de operaciones por lotes](https://docs.aws.amazon.com/AmazonS3/latest/dev/batch-ops-operations.html) de Amazon S3. Cuando se crea el trabajo, se proporciona un manifiesto (la lista de objetos) y se configura la acción a realizar en esos objetos. 

Cuando se inicia el trabajo por lotes, Amazon S3 invoca la función de Lambda [sincrónicamente](invocation-sync.md) para cada objeto del manifiesto. El parámetro de evento incluye los nombres del bucket y del objeto. 

En el ejemplo siguiente se muestra el evento que Amazon S3 envía a la función de Lambda de un objeto denominado **customerImage1.jpg** en el bucket **amzn-s3-demo-bucket**.

**Example Evento de solicitud por lotes de Amazon S3**  

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

Su función de Lambda debe devolver un objeto JSON con los campos tal como se muestran en el siguiente ejemplo. Puede copiar el parámetro `invocationId` y `taskId` desde el parámetro de evento. Puede devolver una cadena en el `resultString`. Amazon S3 guarda los valores `resultString` en el informe de finalización. 

**Example Respuesta de solicitud por lotes de Amazon S3**  

```
{
  "invocationSchemaVersion": "1.0",
  "treatMissingKeysAs" : "PermanentFailure",
  "invocationId" : "YXNkbGZqYWRmaiBhc2RmdW9hZHNmZGpmaGFzbGtkaGZza2RmaAo",
  "results": [
    {
      "taskId": "dGFza2lkZ29lc2hlcmUK",
      "resultCode": "Succeeded",
      "resultString": "[\"Alice\", \"Bob\"]"
    }
  ]
}
```

## Invocación de una función de Lambda desde operaciones por lotes de Amazon S3
<a name="invoking"></a>

Puede invocar la función de Lambda con el ARN de una función no calificada o calificada. Si desea utilizar la misma versión de una función para todo el trabajo por lotes, configure una versión de función específica en el parámetro `FunctionARN` cuando cree el trabajo. Si configura un alias o el calificador \$1LATEST, el trabajo por lotes comienza inmediatamente a llamar a la nueva versión de la función si el alias o \$1LATEST se actualizan durante la ejecución del trabajo. 

Tenga en cuenta que no puede reutilizar una función basada en eventos de Amazon S3 existente para operaciones por lotes. Esto se debe a que la operación por lotes de Amazon S3 pasa un parámetro de evento diferente a la función de Lambda y espera un mensaje de retorno con una estructura JSON específica.

En la [política basada en recursos](access-control-resource-based.md) que cree para el trabajo por lotes de Amazon S3, asegúrese de establecer permisos para que el trabajo invoque su función de Lambda.

En el [rol de ejecución](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-iam-role-policies.html) de la función, establezca una política de confianza para que Amazon S3 asuma el rol cuando ejecute la función.

Si su función utiliza SDK de AWS para administrar recursos de Amazon S3, debe agregar permisos de Amazon S3 a la función de ejecución. 

Cuando se ejecuta el trabajo, Amazon S3 inicia varias instancias de función para procesar los objetos de Amazon S3 en paralelo, hasta el [límite de simultaneidad](lambda-concurrency.md) de la función. Amazon S3 limita el aumento inicial de instancias para evitar un costo excesivo para trabajos más pequeños. 

Si la función de Lambda devuelve un código de respuesta `TemporaryFailure`, Amazon S3 reintenta la operación. 

Para obtener más información acerca de las operaciones por lotes de Amazon S3, consulte [Administrar operaciones por lotes](https://docs.aws.amazon.com/AmazonS3/latest/dev/batch-ops.html) en la *Guía para desarrolladores de Amazon S3*. 

Para obtener un ejemplo de cómo utilizar una función Lambda en operaciones por lotes de Amazon S3, consulte [Invocación de una función de Lambda desde las operaciones por lotes de Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/dev/batch-ops-invoke-lambda.html) en la *Guía para desarrolladores de Amazon S3*. 

# Invocar las funciones de Lambda usando las notificaciones de Amazon SNS
<a name="with-sns"></a>

Puede utilizar una función de Lambda para procesar notificaciones de Amazon Simple Notification Service (Amazon SNS). Amazon SNS admite funciones de Lambda como destino para los mensajes enviados a un tema. Puede suscribir la función a temas de la misma cuenta o de otras cuentas de AWS. Para ver un tutorial detallado, consulte [Tutorial: Uso de AWS Lambda con Amazon Simple Notification Service](with-sns-example.md).

Lambda admite desencadenadores de SNS únicamente para temas de SNS estándar. Los temas FIFO no son compatibles.

Lambda procesa los mensajes SNS de forma asíncrona poniendo los mensajes en cola y gestionando los reintentos. Si Amazon SNS no puede conectar con Lambda o se rechaza el mensaje, Amazon SNS lo vuelve a intentar a intervalos cada vez mayores durante varias horas. Para conocer los detalles, consulte [Fiabilidad](https://aws.amazon.com/sns/faqs/#Reliability) en las preguntas frecuentes de Amazon SNS.

**aviso**  
Las invocaciones asíncronas de Lambda procesan cada evento al menos una vez; puede producirse un procesamiento duplicado de registros. Para evitar posibles problemas relacionados con la duplicación de eventos, le recomendamos encarecidamente que haga que el código de la función sea idempotente. Para obtener más información, consulte [¿Cómo puedo hacer que mi función de Lambda sea idempotente?](https://repost.aws/knowledge-center/lambda-function-idempotent) en el Centro de conocimientos de AWS.

## Utilidad de idempotencia de Powertools para AWS Lambda
<a name="services-sns-powertools-idempotency"></a>

La utilidad de idempotencia de Powertools para AWS Lambda hace que sus funciones de Lambda sean idempotentes. Está disponible para Python, TypeScript, Java y .NET. Para obtener más información, consulte [Utilidad de idempotencia](https://docs.powertools.aws.dev/lambda/python/latest/utilities/idempotency/) en la documentación de *Powertools para Lambda AWS(Python), [Utilidad de idempotencia](https://docs.aws.amazon.com/powertools/typescript/2.1.1/utilities/idempotency/) en la documentación de *Powertools para Lambda AWS(TypeScript), [Utilidad de idempotencia](https://docs.powertools.aws.dev/lambda/java/latest/utilities/idempotency/) en la documentación de *Powertools para Lambda AWS(Java) y [Utilidad de idempotencia](https://docs.powertools.aws.dev/lambda/dotnet/utilities/idempotency/) en la documentación de *Powertools para Lambda AWS(.NET). ****

**Topics**
+ [

## Utilidad de idempotencia de Powertools para AWS Lambda
](#services-sns-powertools-idempotency)
+ [

## Adición de un desencadenador de temas de Amazon SNS para una función de Lambda mediante la consola
](#sns-trigger-console)
+ [

## Adición manual de un desencadenador de temas de Amazon SNS para una función de Lambda
](#sns-trigger-manual)
+ [

## Ejemplo de forma de evento SNS
](#sns-sample-event)
+ [

# Tutorial: Uso de AWS Lambda con Amazon Simple Notification Service
](with-sns-example.md)

## Adición de un desencadenador de temas de Amazon SNS para una función de Lambda mediante la consola
<a name="sns-trigger-console"></a>

Para agregar un tema de SNS como desencadenador de una función de Lambda, la forma más sencilla es utilizar la consola de Lambda. Al agregar el desencadenador a través de la consola, Lambda configura automáticamente los permisos y suscripciones necesarios para empezar a recibir eventos del tema de SNS.

**Cómo agregar un tema de SNS como desencadenador de una función de Lambda (consola)**

1. Abra la página de [Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija el nombre de una función a la que desee agregarle el desencadenador.

1. Elija **Configuración** y, a continuación, seleccione **Desencadenadores**.

1. Elija **Add trigger (Añadir disparador)**.

1. En **Configuración del desencadenador**, seleccione **SNS** de la lista desplegable.

1. Para el **tema de SNS**, elija el tema de SNS al que desee suscribirse.

## Adición manual de un desencadenador de temas de Amazon SNS para una función de Lambda
<a name="sns-trigger-manual"></a>

Para configurar manualmente un desencadenador de SNS para una función de Lambda, debe completar los siguientes pasos:
+ Defina una política basada en recursos para la función de modo que SNS pueda invocarla.
+ Suscriba la función de Lambda al tema de Amazon SNS.
**nota**  
Si su tema de SNS y su función de Lambda están en cuentas de AWS diferentes, también debe conceder permisos adicionales para permitir las suscripciones multicuenta al tema de SNS. Para obtener más información, consulte [Conceder permiso entre cuentas para la suscripción a Amazon SNS](with-sns-example.md#with-sns-subscription-grant-permission).

Puede usar el AWS Command Line Interface (AWS CLI) para completar estos dos pasos. En primer lugar, para definir una política basada en recursos para una función de Lambda que permita las invocaciones de SNS, utilice el siguiente comando de la AWS CLI. Asegúrese de sustituir el valor de `--function-name` por el nombre de la función de Lambda y el valor de `--source-arn` por el ARN del tema de SNS.

```
aws lambda add-permission --function-name example-function \
    --source-arn arn:aws:sns:us-east-1:123456789012:sns-topic-for-lambda \
    --statement-id function-with-sns --action "lambda:InvokeFunction" \
    --principal sns.amazonaws.com
```

Utilice el siguiente comando AWS CLI para suscribir la función al tema SNS. Sustituya el valor de `--topic-arn` por el ARN del tema de SNS y el valor de `--notification-endpoint` por el ARN de la función de Lambda.

```
aws sns subscribe --protocol lambda \
    --region us-east-1 \
    --topic-arn arn:aws:sns:us-east-1:123456789012:sns-topic-for-lambda \
    --notification-endpoint arn:aws:lambda:us-east-1:123456789012:function:example-function
```

## Ejemplo de forma de evento SNS
<a name="sns-sample-event"></a>

Amazon SNS invoca la función [de forma asíncrona](invocation-async.md) con un evento que contiene un mensaje y metadatos.

**Example Evento de mensajes de Amazon SNS**  

```
{
  "Records": [
    {
      "EventVersion": "1.0",
      "EventSubscriptionArn": "arn:aws:sns:us-east-1:123456789012:sns-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
      "EventSource": "aws:sns",
      "Sns": {
        "SignatureVersion": "1",
        "Timestamp": "2019-01-02T12:45:07.000Z",
        "Signature": "tcc6faL2yUC6dgZdmrwh1Y4cGa/ebXEkAi6RibDsvpi+tE/1+82j...65r==",
        "SigningCertURL": "https://sns.us-east-1.amazonaws.com/SimpleNotificationService-ac565b8b1a6c5d002d285f9598aa1d9b.pem",
        "MessageId": "95df01b4-ee98-5cb9-9903-4c221d41eb5e",
        "Message": "Hello from SNS!",
        "MessageAttributes": {
          "Test": {
            "Type": "String",
            "Value": "TestString"
          },
          "TestBinary": {
            "Type": "Binary",
            "Value": "TestBinary"
          }
        },
        "Type": "Notification",
        "UnsubscribeUrl": "https://sns.us-east-1.amazonaws.com/?Action=Unsubscribe&amp;SubscriptionArn=arn:aws:sns:us-east-1:123456789012:test-lambda:21be56ed-a058-49f5-8c98-aedd2564c486",
        "TopicArn":"arn:aws:sns:us-east-1:123456789012:sns-lambda",
        "Subject": "TestInvoke"
      }
    }
  ]
}
```

# Tutorial: Uso de AWS Lambda con Amazon Simple Notification Service
<a name="with-sns-example"></a>

En este tutorial, utilizará una función de Lambda en una Cuenta de AWS para suscribirse a un tema de Amazon Simple Notification Service (Amazon SNS) en una Cuenta de AWS independiente. Cuando publica mensajes en su tema de Amazon SNS, la función de Lambda lee el contenido del mensaje y lo envía a Registros de Amazon CloudWatch. Para completar este tutorial, debe usar la AWS Command Line Interface (AWS CLI).

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-sns-tutorial/sns_tut_resources.png)


Para completar este tutorial, lleve a cabo los siguientes pasos:
+ En la **cuenta A**, cree un tema de Amazon SNS.
+ En la **cuenta B**, cree una función de Lambda que lea los mensajes del tema.
+ En la **cuenta B**, cree una suscripción al tema.
+ Publique los mensajes en el tema de Amazon SNS en la **cuenta A** y confirme que la función de Lambda de la **cuenta B** los envíe a Registros de CloudWatch.

Al completar estos pasos, aprenderá a configurar un tema de Amazon SNS para invocar una función de Lambda. También aprenderá a crear una política de AWS Identity and Access Management (IAM) que conceda permiso a un recurso de otra Cuenta de AWS para invocar Lambda.

En el tutorial, utiliza dos Cuentas de AWS independientes. Los comandos de AWS CLI ilustran esto mediante dos perfiles con nombre llamados `accountA` y `accountB`, cada uno configurado para usarse con una Cuenta de AWS diferente. A fin de aprender a configurar AWS CLI para usar diferentes perfiles, consulte [Opciones de los archivos de configuración y credenciales](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) en la *Guía del usuario de la versión 2 de la AWS Command Line Interface*. Asegúrese de configurar la misma Región de AWS predeterminada para ambos perfiles.

Si los perfiles de AWS CLI que crea para las dos Cuentas de AWS utilizan nombres distintos, o si usa el perfil predeterminado y un perfil con nombre, modifique los comandos de AWS CLI en los siguientes pasos según sea necesario.

## Requisitos previos
<a name="with-sns-prereqs"></a>

### Instala la AWS Command Line Interface
<a name="install_aws_cli"></a>

Si aún no ha instalado AWS Command Line Interface, siga los pasos que se indican en [Instalación o actualización de la versión más reciente de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalarlo.

El tutorial requiere un intérprete de comandos o un terminal de línea de comando para ejecutar los comandos. En Linux y macOS, use su administrador de intérprete de comandos y paquetes preferido.

**nota**  
En Windows, algunos comandos de la CLI de Bash que se utilizan habitualmente con Lambda (por ejemplo, `zip`) no son compatibles con los terminales integrados del sistema operativo. Para obtener una versión de Ubuntu y Bash integrada con Windows, [instale el subsistema de Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Creación de un tema de Amazon SNS (cuenta A)
<a name="with-sns-create-topic"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_1.png)


**Para crear el tema**
+ En la **cuenta A**, cree un tema estándar de Amazon SNS mediante el siguiente comando de AWS CLI.

  ```
  aws sns create-topic --name sns-topic-for-lambda --profile accountA
  ```

  Debería ver un resultado similar a este.

  ```
  {
      "TopicArn": "arn:aws:sns:us-west-2:123456789012:sns-topic-for-lambda"
  }
  ```

  Anote el Nombre de recurso de Amazon (ARN) del tema. Lo necesitará más adelante en el tutorial cuando agregue permisos a la función de Lambda para suscribirse al tema.

## Creación de un rol de ejecución de función (cuenta B)
<a name="with-sns-example-create-iam-role"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_2.png)


Un rol de ejecución es un rol de IAM que concede a la función de Lambda permiso para acceder a servicios y recursos de Servicios de AWS. Antes de crear la función en la **cuenta B**, cree un rol que conceda a la función permisos básicos para escribir registros en Registros de CloudWatch. Agregaremos los permisos para leer el tema de Amazon SNS en un paso posterior.

**Para crear un rol de ejecución**

1. En la **cuenta B**, abra la [página de roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione **Crear rol**.

1. En **Tipo de entidad de confianza**, elija **Servicio de AWS**.

1. En **Caso de uso**, elija **Lambda**.

1. Elija **Siguiente**.

1. Siga estos pasos para agregar una política de permisos básicos al rol:

   1. En el cuadro de búsqueda **Permisos de selección**, ingrese **AWSLambdaBasicExecutionRole**.

   1. Elija **Siguiente**.

1. Siga estos pasos para finalizar la creación del rol:

   1. En **Detalles del rol**, escriba **lambda-sns-role** en **Nombre de rol**.

   1. Seleccione **Crear rol**.

## Creación de una función de Lambda (cuenta B)
<a name="with-sns-example-create-test-function"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_3.png)


Cree una función de Lambda que procese los mensajes de Amazon SNS. El código de función registra el contenido de los mensajes de cada entrada en los Registros de Amazon CloudWatch.

En este tutorial, se utiliza el tiempo de ejecución de Node.js 24, pero también hemos proporcionado archivos de código de ejemplo en otros lenguajes de tiempo de ejecución. Puede seleccionar la pestaña del siguiente cuadro para ver el código del tiempo de ejecución que le interesa. El código JavaScript que usará en este paso está en el primer ejemplo que se muestra en la pestaña **JavaScript**.

------
#### [ .NET ]

**SDK para .NET**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Uso de un evento de SNS con Lambda mediante .NET  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
using Amazon.Lambda.Core;
using Amazon.Lambda.SNSEvents;


// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace SnsIntegration;

public class Function
{
    public async Task FunctionHandler(SNSEvent evnt, ILambdaContext context)
    {
        foreach (var record in evnt.Records)
        {
            await ProcessRecordAsync(record, context);
        }
        context.Logger.LogInformation("done");
    }

    private async Task ProcessRecordAsync(SNSEvent.SNSRecord record, ILambdaContext context)
    {
        try
        {
            context.Logger.LogInformation($"Processed record {record.Sns.Message}");

            // TODO: Do interesting work based on the new message
            await Task.CompletedTask;
        }
        catch (Exception e)
        {
            //You can use Dead Letter Queue to handle failures. By configuring a Lambda DLQ.
            context.Logger.LogError($"An error occurred");
            throw;
        }
    }
}
```

------
#### [ Go ]

**SDK para Go V2**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Uso de un evento de SNS con Lambda mediante Go  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package main

import (
	"context"
	"fmt"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func handler(ctx context.Context, snsEvent events.SNSEvent) {
	for _, record := range snsEvent.Records {
		processMessage(record)
	}
	fmt.Println("done")
}

func processMessage(record events.SNSEventRecord) {
	message := record.SNS.Message
	fmt.Printf("Processed message: %s\n", message)
	// TODO: Process your record here
}

func main() {
	lambda.Start(handler)
}
```

------
#### [ Java ]

**SDK para Java 2.x**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Uso de un evento de SNS con Lambda mediante Java.  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package example;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.SNSEvent;
import com.amazonaws.services.lambda.runtime.events.SNSEvent.SNSRecord;


import java.util.Iterator;
import java.util.List;

public class SNSEventHandler implements RequestHandler<SNSEvent, Boolean> {
    LambdaLogger logger;

    @Override
    public Boolean handleRequest(SNSEvent event, Context context) {
        logger = context.getLogger();
        List<SNSRecord> records = event.getRecords();
        if (!records.isEmpty()) {
            Iterator<SNSRecord> recordsIter = records.iterator();
            while (recordsIter.hasNext()) {
                processRecord(recordsIter.next());
            }
        }
        return Boolean.TRUE;
    }

    public void processRecord(SNSRecord record) {
        try {
            String message = record.getSNS().getMessage();
            logger.log("message: " + message);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
```

------
#### [ JavaScript ]

**SDK para JavaScript (v3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/blob/main/integration-sns-to-lambda). 
Uso de un evento de SNS con Lambda mediante JavaScript  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
exports.handler = async (event, context) => {
  for (const record of event.Records) {
    await processMessageAsync(record);
  }
  console.info("done");
};

async function processMessageAsync(record) {
  try {
    const message = JSON.stringify(record.Sns.Message);
    console.log(`Processed message ${message}`);
    await Promise.resolve(1); //Placeholder for actual async work
  } catch (err) {
    console.error("An error occurred");
    throw err;
  }
}
```
Uso de un evento de SNS con Lambda mediante TypeScript  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
import { SNSEvent, Context, SNSHandler, SNSEventRecord } from "aws-lambda";

export const functionHandler: SNSHandler = async (
  event: SNSEvent,
  context: Context
): Promise<void> => {
  for (const record of event.Records) {
    await processMessageAsync(record);
  }
  console.info("done");
};

async function processMessageAsync(record: SNSEventRecord): Promise<any> {
  try {
    const message: string = JSON.stringify(record.Sns.Message);
    console.log(`Processed message ${message}`);
    await Promise.resolve(1); //Placeholder for actual async work
  } catch (err) {
    console.error("An error occurred");
    throw err;
  }
}
```

------
#### [ PHP ]

**SDK para PHP**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Uso de un evento de SNS con Lambda mediante PHP  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
<?php

/* 
Since native PHP support for AWS Lambda is not available, we are utilizing Bref's PHP functions runtime for AWS Lambda.
For more information on Bref's PHP runtime for Lambda, refer to: https://bref.sh/docs/runtimes/function

Another approach would be to create a custom runtime. 
A practical example can be found here: https://aws.amazon.com/blogs/apn/aws-lambda-custom-runtime-for-php-a-practical-example/
*/

// Additional composer packages may be required when using Bref or any other PHP functions runtime.
// require __DIR__ . '/vendor/autoload.php';

use Bref\Context\Context;
use Bref\Event\Sns\SnsEvent;
use Bref\Event\Sns\SnsHandler;

class Handler extends SnsHandler
{
    public function handleSns(SnsEvent $event, Context $context): void
    {
        foreach ($event->getRecords() as $record) {
            $message = $record->getMessage();

            // TODO: Implement your custom processing logic here
            // Any exception thrown will be logged and the invocation will be marked as failed

            echo "Processed Message: $message" . PHP_EOL;
        }
    }
}

return new Handler();
```

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

**SDK para Python (Boto3)**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Uso de un evento de SNS con Lambda mediante Python  

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
def lambda_handler(event, context):
    for record in event['Records']:
        process_message(record)
    print("done")

def process_message(record):
    try:
        message = record['Sns']['Message']
        print(f"Processed message {message}")
        # TODO; Process your record here
        
    except Exception as e:
        print("An error occurred")
        raise e
```

------
#### [ Ruby ]

**SDK para Ruby**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Uso de un evento de SNS con Lambda mediante Ruby  

```
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0
def lambda_handler(event:, context:)
  event['Records'].map { |record| process_message(record) }
end

def process_message(record)
  message = record['Sns']['Message']
  puts("Processing message: #{message}")
rescue StandardError => e
  puts("Error processing message: #{e}")
  raise
end
```

------
#### [ Rust ]

**SDK para Rust**  
 Hay más en GitHub. Busque el ejemplo completo y aprenda a configurar y ejecutar en el repositorio de [ejemplos de tecnología sin servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Uso de un evento de SNS con Lambda mediante Rust  

```
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use aws_lambda_events::event::sns::SnsEvent;
use aws_lambda_events::sns::SnsRecord;
use lambda_runtime::{run, service_fn, Error, LambdaEvent};
use tracing::info;

// Built with the following dependencies:
//  aws_lambda_events = { version = "0.10.0", default-features = false, features = ["sns"] }
//  lambda_runtime = "0.8.1"
//  tokio = { version = "1", features = ["macros"] }
//  tracing = { version = "0.1", features = ["log"] }
//  tracing-subscriber = { version = "0.3", default-features = false, features = ["fmt"] }

async fn function_handler(event: LambdaEvent<SnsEvent>) -> Result<(), Error> {
    for event in event.payload.records {
        process_record(&event)?;
    }
    
    Ok(())
}

fn process_record(record: &SnsRecord) -> Result<(), Error> {
    info!("Processing SNS Message: {}", record.sns.message);

    // Implement your record handling code here.

    Ok(())
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        .with_target(false)
        .without_time()
        .init();

    run(service_fn(function_handler)).await
}
```

------

**Cómo crear la función**

1. Cree un directorio para el proyecto y, a continuación, cambie a ese directorio.

   ```
   mkdir sns-tutorial
   cd sns-tutorial
   ```

1. Copie el código de muestra de JavaScript en un nuevo archivo con el nombre `index.js`.

1. Cree un paquete de implementación utilizando el siguiente comando `zip`.

   ```
   zip function.zip index.js
   ```

1. Ejecute el siguiente comando de AWS CLI para crear la función de Lambda en la **cuenta B**.

   ```
   aws lambda create-function --function-name Function-With-SNS \
       --zip-file fileb://function.zip --handler index.handler --runtime nodejs24.x \
       --role arn:aws:iam::<AccountB_ID>:role/lambda-sns-role  \
       --timeout 60 --profile accountB
   ```

   Debería ver un resultado similar a este.

   ```
   {
       "FunctionName": "Function-With-SNS",
       "FunctionArn": "arn:aws:lambda:us-west-2:123456789012:function:Function-With-SNS",
       "Runtime": "nodejs24.x",
       "Role": "arn:aws:iam::123456789012:role/lambda_basic_role",
       "Handler": "index.handler",
       ...
       "RuntimeVersionConfig": {
           "RuntimeVersionArn": "arn:aws:lambda:us-west-2::runtime:7d5f06b69c951da8a48b926ce280a9daf2e8bb1a74fc4a2672580c787d608206"
       }
   }
   ```

1. Registre el Nombre de recurso de Amazon (ARN) de la función. Lo necesitará más adelante en el tutorial cuando agregue permisos para permitir a Amazon SNS que invoque la función.

## Adición de permisos a la función (cuenta B)
<a name="with-sns-create-function-permissions"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_4.png)


Para que Amazon SNS invoque la función, debe concederle permiso en una instrucción de una [política basada en recursos](access-control-resource-based.md). Para agregar esta instrucción, utilice el comando `add-permission` de AWS CLI.

**Para conceder permiso a Amazon SNS para invocar la función**
+ En la **cuenta B**, ejecute el siguiente comando de AWS CLI mediante el ARN del tema de Amazon SNS que registró anteriormente.

  ```
  aws lambda add-permission --function-name Function-With-SNS \
      --source-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \
      --statement-id function-with-sns --action "lambda:InvokeFunction" \
      --principal sns.amazonaws.com --profile accountB
  ```

  Debería ver un resultado similar a este.

  ```
  {
      "Statement": "{\"Condition\":{\"ArnLike\":{\"AWS:SourceArn\":
        \"arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda\"}},
        \"Action\":[\"lambda:InvokeFunction\"],
        \"Resource\":\"arn:aws:lambda:us-east-1:<AccountB_ID>:function:Function-With-SNS\",
        \"Effect\":\"Allow\",\"Principal\":{\"Service\":\"sns.amazonaws.com\"},
        \"Sid\":\"function-with-sns\"}"
  }
  ```

**nota**  
Si la cuenta con el tema de Amazon SNS está alojada en una [Región de AWS con suscripción](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-regions.html), debe especificar la región en la entidad principal. Por ejemplo, si trabaja con un tema de Amazon SNS en la región de Asia-Pacífico (Hong Kong), debe especificar `sns.ap-east-1.amazonaws.com` en lugar de `sns.amazonaws.com` para la entidad principal. 

## Concesión de permiso entre cuentas para la suscripción a Amazon SNS (cuenta A)
<a name="with-sns-subscription-grant-permission"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_5.png)


Para que su función de Lambda de la **cuenta B** se suscriba al tema de Amazon SNS que creó en la **cuenta A**, tiene que conceder permiso a la **cuenta B** para suscribirse al tema. Utilice el comando `add-permission` de AWS CLI para conceder este permiso. 

**Para conceder permiso para que la cuenta B se suscriba al tema**
+ En la **cuenta A**, ejecute el siguiente comando de AWS CLI. Utilice el ARN del tema de Amazon SNS que registró anteriormente.

  ```
  aws sns add-permission --label lambda-access --aws-account-id <AccountB_ID> \
      --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \  
      --action-name Subscribe ListSubscriptionsByTopic --profile accountA
  ```

## Creación de una suscripción (cuenta B)
<a name="with-sns-create-subscription"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_6.png)


En la **cuenta B**, ahora puede suscribir su función de Lambda al tema de Amazon SNS que creó al principio del tutorial en la **cuenta A**. Cuando se envía un mensaje a este tema (`sns-topic-for-lambda`), Amazon SNS invoca su función de Lambda `Function-With-SNS` en la **cuenta B**. 

**Para crear una suscripción**
+ En la **cuenta B**, ejecute el siguiente comando de AWS CLI. Use la región predeterminada en la que creó el tema y los ARN del tema y la función de Lambda.

  ```
  aws sns subscribe --protocol lambda \
      --region us-east-1 \
      --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \
      --notification-endpoint arn:aws:lambda:us-east-1:<AccountB_ID>:function:Function-With-SNS \
      --profile accountB
  ```

  Debería ver un resultado similar a este.

  ```
  {
      "SubscriptionArn": "arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx"
  }
  ```

## Publicación de mensajes en el tema (cuenta A y cuenta B)
<a name="with-sns-publish-message"></a>

![\[\]](http://docs.aws.amazon.com/es_es/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_7.png)


Ahora que su función de Lambda de la **cuenta B** se ha suscrito a su tema de Amazon SNS en la **cuenta A**, es hora de probar la configuración mediante la publicación de mensajes en el tema. Para confirmar que Amazon SNS ha invocado la función de Lambda, utilice Registros de CloudWatch para ver la salida de la función.

**Para publicar un mensaje en el tema y ver la salida de la función**

1. Escriba `Hello World` en un archivo de texto y guárdelo como `message.txt`.

1. Desde el mismo directorio en el que guardó el archivo de texto, ejecute el siguiente comando de AWS CLI en la **cuenta A**. Use el ARN de su propio tema.

   ```
   aws sns publish --message file://message.txt --subject Test \
       --topic-arn arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda \
       --profile accountA
   ```

   Esto devolverá un ID de mensaje con un identificador único que indica que Amazon SNS ha aceptado el mensaje. Posteriormente, Amazon SNS intentará entregar el mensaje a los suscriptores del tema. Para confirmar que Amazon SNS ha invocado la función de Lambda, utilice Registros de CloudWatch para ver la salida de la función:

1. En la **cuenta B**, abra la página [Grupos de registro](https://console.aws.amazon.com/cloudwatch/home#logsV2:log-groups) de la consola de Amazon CloudWatch.

1. Elija el grupo de registro para la función (`/aws/lambda/Function-With-SNS`).

1. Elija el flujo de registros más reciente.

1. Si la función se ha invocado correctamente, verá una salida similar a la siguiente en la que se muestra el contenido del mensaje que publicó en el tema.

   ```
   2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO Processed message Hello World
   2023-07-31T21:42:51.250Z c1cba6b8-ade9-4380-aa32-d1a225da0e48 INFO done
   ```

## Eliminación de sus recursos
<a name="cleanup"></a>

A menos que desee conservar los recursos que creó para este tutorial, puede eliminarlos ahora. Si elimina los recursos de AWS que ya no utiliza, evitará gastos innecesarios en su Cuenta de AWS.

En la **cuenta A**, limpie el tema de Amazon SNS.

**Para eliminar el tema de Amazon SNS**

1. Abra la página [Topics (Temas)](https://console.aws.amazon.com//sns/home#topics:) en la consola de Amazon SNS.

1. Seleccione el tema que creó.

1. Elija **Eliminar**.

1. Introduzca **delete me** en el campo de entrada de texto.

1. Elija **Eliminar**.

En la **cuenta B**, limpie el rol de ejecución, la función de Lambda y la suscripción de Amazon SNS.

**Cómo eliminar el rol de ejecución**

1. Abra la página [Roles](https://console.aws.amazon.com/iam/home#/roles) en la consola de IAM.

1. Seleccione el rol de ejecución que creó.

1. Elija **Eliminar**.

1. Si desea continuar, escriba el nombre del rol en el campo de entrada de texto y elija **Delete** (Eliminar).

**Cómo eliminar la función de Lambda**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Seleccione la función que ha creado.

1. Elija **Acciones**, **Eliminar**.

1. Escriba **confirm** en el campo de entrada de texto y elija **Delete** (Eliminar).

**Para eliminar la suscripción a Amazon SNS**

1. Abra la página [Suscriptions (Suscripciones)](https://console.aws.amazon.com//sns/home#subscriptions:) en la consola de Amazon SNS.

1. Seleccione la suscripción que creó.

1. Elija **Delete (Eliminar)**, **Delete (Eliminar)**.