

# Invocando o Lambda com eventos de outros serviços da AWS
<a name="lambda-services"></a>

Alguns Serviços da AWS podem invocar diretamente as funções do Lambda usando *gatilhos*. Esses serviços enviam eventos para o Lambda, e a função é invocada imediatamente quando o evento especificado ocorre. Os acionadores são adequados para eventos discretos e processamento em tempo real. Quando você [cria um acionador usando o console do Lambda](#lambda-invocation-trigger), o console interage com o serviço da AWS correspondente para configurar a notificação de eventos nesse serviço. Na verdade, o acionador é armazenado e gerenciado pelo serviço que gera os eventos, não pelo Lambda.

Os eventos são dados estruturados em formato JSON. A estrutura JSON varia dependendo do serviço que a gera e do tipo de evento, mas todos eles contêm os dados que a função precisa para processar o evento.

Uma função pode ter vários gatilhos. Cada acionador atua como um cliente ao invocar a função de forma independente, e cada evento que o Lambda transmite para a função tem dados de somente um acionador. O Lambda converte o documento do evento em um objeto e o transmite ao manipulador da função.

Dependendo do serviço, a invocação conduzida por eventos pode ser [síncrona](invocation-sync.md) ou [assíncrona](invocation-async.md).
+ Para a invocação síncrona, o serviço que gera o evento aguarda a resposta da sua função. Esse serviço define os dados que a função precisa retornar na resposta. O serviço controla a estratégia de erro, como se deve tentar novamente em erros.
+ Para a invocação assíncrona, o Lambda coloca o evento em filas antes de transmiti-lo para a função. Quando o Lambda coloca o evento em fila, ele envia imediatamente uma resposta bem-sucedida para o serviço que gerou o evento. Depois que a função processa o evento, o Lambda não retorna uma resposta ao serviço de geração de eventos.

## Criar um acionador
<a name="lambda-invocation-trigger"></a>

A maneira mais fácil de criar um acionador é usar o console do Lambda. Quando você cria um acionador usando o console, o Lambda adiciona automaticamente as permissões necessárias à [política baseada em recursos](access-control-resource-based.md) da função.

**Para criar um acionador usando o console do Lambda**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Selecione a função para a qual deseja criar um acionador.

1. No painel **Visão geral da função**, escolha **Adicionar gatilho**.

1. Selecione o serviço da AWS no qual deseja invocar a função.

1. Preencha as opções no painel **Configuração de acionador** e escolha **Adicionar**. Dependendo do AWS service (Serviço da AWS) que você escolher para invocar a função, as opções de configuração do acionador serão diferentes.

## Serviços que podem invocar funções do Lambda
<a name="listing-of-services-and-links-to-more-information"></a>

A tabela a seguir lista os serviços que podem invocar funções do Lambda.


****  

| Serviço | Método de invocação | 
| --- | --- | 
|  [Amazon Managed Streaming for Apache Kafka](with-msk.md)  |  [Mapeamento de origem de evento](invocation-eventsourcemapping.md)  | 
|  [Apache Kafka autogerenciado](with-kafka.md)  |  [Mapeamento de origem de evento](invocation-eventsourcemapping.md)  | 
|  [Amazon API Gateway](services-apigateway.md)  |  Conduzido por eventos; invocação síncrona  | 
|  [AWS CloudFormation](services-cloudformation.md)  |  Conduzido por eventos; invocação assíncrona  | 
|  [Amazon CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#LambdaFunctionExample)  |  Conduzido por eventos; invocação assíncrona  | 
|  [AWS CodeCommit](https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-notify-lambda-cc.html)  |  Conduzido por eventos; invocação assíncrona  | 
|  [AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/actions-invoke-lambda-function.html)  |  Conduzido por eventos; invocação assíncrona  | 
|  [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-events.html)  |  Conduzido por eventos; invocação síncrona  | 
|  [AWS Config](governance-config.md)  |  Conduzido por eventos; invocação assíncrona  | 
|  [Amazon Connect](https://docs.aws.amazon.com/connect/latest/adminguide/connect-lambda-functions.html)  |  Conduzido por eventos; invocação síncrona  | 
|  [Amazon DocumentDB](with-documentdb.md)  |  [Mapeamento de origem de evento](invocation-eventsourcemapping.md)  | 
|  [Amazon DynamoDB](with-ddb.md)  |  [Mapeamento de origem de evento](invocation-eventsourcemapping.md)  | 
|  [Elastic Load Balancing (Application Load Balancer)](services-alb.md)  |  Conduzido por eventos; invocação síncrona  | 
|  [Amazon EventBridge (CloudWatch Events)](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html)  |  Acionado por evento; invocação assíncrona (barramentos de eventos), invocação síncrona ou assíncrona (canais e agendas)  | 
|  [AWS IoT](services-iot.md)  |  Conduzido por eventos; invocação assíncrona  | 
|  [Amazon Kinesis](with-kinesis.md)  |  [Mapeamento de origem de evento](invocation-eventsourcemapping.md)  | 
|  [Amazon Data Firehose](https://docs.aws.amazon.com/firehose/latest/dev/data-transformation.html)  |  Conduzido por eventos; invocação síncrona  | 
|  [Amazon Lex](https://docs.aws.amazon.com/lexv2/latest/dg/lambda.html)  |  Conduzido por eventos; invocação síncrona  | 
|  [Amazon MQ](with-mq.md)  |  [Mapeamento de origem de evento](invocation-eventsourcemapping.md)  | 
|  [Amazon Simple Email Service](https://docs.aws.amazon.com/ses/latest/dg/receiving-email-action-lambda.html)  |  Conduzido por eventos; invocação assíncrona  | 
|  [Amazon Simple Notification Service](with-sns.md)  |  Conduzido por eventos; invocação assíncrona  | 
|  [Amazon Simple Queue Service](with-sqs.md)  |  [Mapeamento de origem de evento](invocation-eventsourcemapping.md)  | 
|  [Amazon Simple Storage Service (Amazon S3)](with-s3.md)  |  Conduzido por eventos; invocação assíncrona  | 
|  [Amazon Simple Storage Service Batch](services-s3-batch.md)  |  Conduzido por eventos; invocação síncrona  | 
|  [Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotate-secrets_lambda.html)  |  Rodízio de segredos  | 
|  [AWS Step Functions](https://docs.aws.amazon.com/step-functions/latest/dg/connect-lambda.html)  |  Invocação síncrona ou assíncrona, acionada por evento  | 
|  [Amazon VPC Lattice](https://docs.aws.amazon.com/vpc-lattice/latest/ug/lambda-functions.html)  |  Conduzido por eventos; invocação síncrona  | 

# Usar o Lambda com o Apache Kafka
<a name="with-kafka-esm"></a>

O Lambda suporta[Apache Kafka](https://kafka.apache.org/)como um[Origem do evento](invocation-eventsourcemapping.md). O Apache Kafka é uma plataforma de streaming de eventos de código aberto, desenvolvida para processar pipelines de dados e aplicações de streaming de alto throughput em tempo real. Há duas maneiras principais de usar o Lambda com o Apache Kafka:
+ [Usar o Lambda com o Amazon MSK](with-msk.md): o Amazon Managed Streaming for Apache Kafka (Amazon MSK) é um serviço totalmente gerenciado pela AWS. O Amazon MSK ajuda a automatizar o gerenciamento da infraestrutura do Kafka, incluindo provisionamento, aplicação de patches e escalação.
+ [Usar o Lambda com o Apache Kafka autogerenciado](with-kafka.md): na terminologia da AWS, um cluster autogerenciado inclui os clusters do Kafka não hospedados pela AWS. Por exemplo, ainda é possível usar o Lambda com um cluster do Kafka hospedado em um provedor de nuvem que não seja a AWS, como o [Confluent Cloud](https://www.confluent.io/confluent-cloud/) ou o [Redpanda](https://www.redpanda.com/).

Ao decidir entre o Amazon MSK e o Apache Kafka autogerenciado, considere as necessidades operacionais e os requisitos de controle. O Amazon MSK será a melhor opção se quiser que a AWS ajude você a gerenciar rapidamente uma configuração do Kafka escalável e pronta para produção com o mínimo de sobrecarga operacional. Ele simplifica a segurança, o monitoramento e a alta disponibilidade, ajudando você a se concentrar no desenvolvimento de aplicações, e não no gerenciamento da infraestrutura. Por outro lado, o Apache Kafka autogerenciado é mais adequado para casos de uso executados em ambientes não hospedados pela AWS, incluindo clusters on-premises.

**Topics**
+ [Usar o Lambda com o Amazon MSK](with-msk.md)
+ [Usar o Lambda com o Apache Kafka autogerenciado](with-kafka.md)
+ [Modos de escalabilidade de sondagem de eventos do Apache Kafka no Lambda](kafka-scaling-modes.md)
+ [Posições iniciais de sondagem e fluxo do Apache Kafka no Lambda](kafka-starting-positions.md)
+ [ID de grupo de consumidores personalizável no Lambda](kafka-consumer-group-id.md)
+ [Filtrar as origens dos eventos do Amazon MSK e do Apache Kafka autogerenciado](kafka-filtering.md)
+ [Usar registros de esquema com origens de eventos do Kafka no Lambda](services-consume-kafka-events.md)
+ [Processamento de baixa latência para fontes de eventos do Kafka](with-kafka-low-latency.md)
+ [Configuração dos controles de tratamento de erros para origens de eventos do Kafka](kafka-retry-configurations.md)
+ [Capturar lotes descartados para uma origem do evento do Amazon MSK e do Apache Kafka autogerenciado](kafka-on-failure.md)
+ [Uso de um tópico do Kafka como destino em caso de falha](kafka-on-failure-destination.md)
+ [Registro do mapeamento da origem do evento do Kafka](esm-logging.md)
+ [Solução de problemas de erros do mapeamento da origem do evento do Kafka](with-kafka-troubleshoot.md)

# Usar o Lambda com o Amazon MSK
<a name="with-msk"></a>

O [Amazon Managed Streaming for Apache Kafka (Amazon MSK)](https://docs.aws.amazon.com/msk/latest/developerguide/what-is-msk.html) é um serviço totalmente gerenciado que você pode usar para criar e executar aplicações que usam o Apache Kafka para processar dados de streaming. O Amazon MSK simplifica a configuração, o dimensionamento e o gerenciamento de clusters do Kafka. O Amazon MSK também facilita a configuração da aplicação para várias zonas de disponibilidade e para segurança com o AWS Identity and Access Management (IAM).

Este capítulo explica como usar um cluster do Amazon MSK como origem de eventos para a função do Lambda. O processo geral de integração do Amazon MSK com o Lambda envolve as seguintes etapas:

1. **[Configuração do cluster e da rede](with-msk-cluster-network.md)**: primeiro, configure o [cluster do Amazon MSK](https://docs.aws.amazon.com/msk/latest/developerguide/what-is-msk.html). Isso inclui a configuração da rede correta para permitir que o Lambda acesse o cluster.

1. **[Configuração do mapeamento da origem do evento](with-msk-configure.md)**: depois, crie o recurso de [mapeamento da origem do evento](invocation-eventsourcemapping.md) de que o Lambda precisa para se conectar ao cluster Amazon MSK à função com segurança.

1. **[Configuração da função e das permissões](with-msk-permissions.md)**: por fim, certifique-se de que a função esteja configurada corretamente e tenha as permissões exigidas em seu [perfil de execução](lambda-intro-execution-role.md).

**nota**  
Agora é possível criar e gerenciar seus mapeamentos da origem do evento do Amazon MSK diretamente do console do Lambda ou do Amazon MSK. Ambos os consoles oferecem a opção de lidar automaticamente com a configuração das permissões necessárias do perfil de execução do Lambda para um processo de configuração mais simplificado.

Para obter exemplos de como configurar uma integração do Lambda com um cluster do Amazon MSK, consulte [Tutorial: Usar um mapeamento de origem do evento do Amazon MSK para invocar uma função do 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/) no AWS Compute Blog e [Amazon MSK Lambda Integration](https://amazonmsk-labs.workshop.aws/en/msklambda.html) no Amazon MSK Labs.

**Topics**
+ [Evento de exemplo](#msk-sample-event)
+ [Configurar o cluster do Amazon MSK e a rede do Amazon VPC para o Lambda](with-msk-cluster-network.md)
+ [Configuração de permissões do Lambda para mapeamentos da origem do evento do Amazon MSK](with-msk-permissions.md)
+ [Configurar as origens de eventos do Amazon MSK para o Lambda](with-msk-configure.md)
+ [Tutorial: Usar um mapeamento de origem do evento do Amazon MSK para invocar uma função do Lambda](services-msk-tutorial.md)

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

O Lambda envia o lote de mensagens no parâmetro de evento quando ele chama sua função. O payload do evento contém uma matriz de mensagens. Cada item de array contém detalhes do tópico do Amazon MSK e do identificador de partição, juntamente com um carimbo de data/hora e uma mensagem codificada em 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
                  ]
               }
            ]
         }
      ]
   }
}
```

# Configurar o cluster do Amazon MSK e a rede do Amazon VPC para o Lambda
<a name="with-msk-cluster-network"></a>

Para conectar a função do AWS Lambda ao cluster do Amazon MSK, é preciso configurar corretamente o cluster e a [Amazon Virtual Private Cloud (VPC)](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html) em que ele reside. Esta página descreve como configurar o cluster e a VPC. Se o cluster e a VPC já estiverem configurados corretamente, consulte [Configurar as origens de eventos do Amazon MSK para o Lambda](with-msk-configure.md) para configurar o mapeamento da origem do evento.

**Topics**
+ [Visão geral dos requisitos de configuração de rede para integrações entre o Lambda e o MSK](#msk-network-requirements)
+ [Configurar um gateway NAT para uma origem de eventos do MSK](#msk-nat-gateway)
+ [Configurar endpoints AWS PrivateLink para uma origem de eventos do MSK](#msk-vpc-privatelink)

## Visão geral dos requisitos de configuração de rede para integrações entre o Lambda e o MSK
<a name="msk-network-requirements"></a>

A configuração de rede necessária para uma integração entre o Lambda e o MSK depende da arquitetura de rede da aplicação. Há três recursos principais envolvidos nessa integração: o cluster do Amazon MSK, a função do Lambda e o mapeamento da origem do evento do Lambda. Cada um desses recursos reside em uma VPC diferente:
+ O cluster do Amazon MSK normalmente reside em uma sub-rede privada de uma VPC que você gerencia.
+ A função do Lambda reside em uma VPC gerenciada pela AWS e cujo proprietário é o Lambda.
+ O mapeamento da origem do evento do Lambda reside em outra VPC gerenciada pela AWS, cujo proprietário é o Lambda, em separado da VPC que contém a função.

O [mapeamento da origem do evento](invocation-eventsourcemapping.md) é o recurso intermediário entre o cluster do MSK e a função do Lambda. O mapeamento da origem do evento tem duas tarefas principais. Primeiro, ele pesquisa novas mensagens no cluster do MSK. Depois, ele invoca a função do Lambda com essas mensagens. Como esses três recursos estão em VPCs diferentes, as operações de pesquisa e invocação exigem chamadas de rede entre VPCs.

Os requisitos de configuração de rede para o mapeamento da origem do evento variam conforme o uso do [modo provisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode) ou do modo sob demanda, conforme indicado no seguinte diagrama:

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


A maneira como o mapeamento da origem do evento do Lambda pesquisa novas mensagens no cluster do MSK é igual em ambos os modos. Para estabelecer uma conexão entre o mapeamento da origem do evento e o cluster do MSK, o Lambda cria uma [ENI de hiperplano](configuration-vpc.md#configuration-vpc-enis) (ou reutiliza uma existente, se disponível) em a sub-rede privada para estabelecer uma conexão segura. Como ilustrado no diagrama, essa ENI de hiperplano usa a configuração de sub-rede e de grupo de segurança do seu cluster do MSK, não da função do Lambda.

Após pesquisar a mensagem do cluster, a maneira como o Lambda invoca a função é diferente em cada modo:
+ No modo provisionado, o Lambda processa automaticamente a conexão entre a VPC do mapeamento da origem do evento e a VPC da função. Assim, não é preciso nenhum componente de rede adicional para invocar a função.
+ No modo sob demanda, o mapeamento da origem do evento do Lambda invoca a função por um caminho através da VPC gerenciada pelo cliente. Por isso, você precisa configurar um [gateway NAT](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) na sub-rede pública da VPC ou endpoints [AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/what-is-privatelink.html) na sub-rede privada da VPC que forneçam acesso ao Lambda, ao [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html) e, opcionalmente, ao [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). A configuração correta dessas opções permite uma conexão entre a sua VPC e a VPC de runtime gerenciada pelo Lambda, que é necessária para invocar a função.

Um gateway NAT permite que recursos na sub-rede privada acessem a Internet pública. Usar essa configuração significa que o tráfego atravessa a Internet antes da invocação da função do Lambda. Os endpoints AWS PrivateLink permitem que as sub-redes privadas se conectem com segurança aos serviços da AWS ou a outros recursos da VPC privada sem atravessar a Internet pública. Consulte [Configurar um gateway NAT para uma origem de eventos do MSK](#msk-nat-gateway) ou [Configurar endpoints AWS PrivateLink para uma origem de eventos do MSK](#msk-vpc-privatelink) para obter detalhes sobre como configurar esses recursos.

Até agora, o pressuposto é que o cluster do MSK reside em uma sub-rede privada dentro da VPC, que é o caso mais comum. Porém, mesmo que o cluster do MSK esteja em uma sub-rede pública dentro da VPC, você deve configurar endpoints AWS PrivateLink para permitir uma conexão segura. A tabela a seguir resume os requisitos de configuração de rede com base em como você configura o cluster do MSK e o mapeamento da origem do evento do Lambda:


| Localização do cluster do MSK (em VPC gerenciada pelo cliente) | Modo de escalação do mapeamento da origem do evento do Lambda | Configuração de rede exigida | 
| --- | --- | --- | 
|  Sub-rede privada  |  Modo sob demanda  |  Gateway NAT (na sub-rede pública da VPC) ou endpoints AWS PrivateLink (na sub-rede privada da VPC) para permitir o acesso ao Lambda, ao AWS STS e, opcionalmente, ao Secrets Manager.  | 
|  Sub-rede pública  |  Modo sob demanda  |  Endpoints AWS PrivateLink (na sub-rede pública da VPC) para permitir o acesso ao Lambda, ao AWS STS e, opcionalmente, ao Secrets Manager.  | 
|  Sub-rede privada  |  Modo provisionado  |  Nenhum  | 
|  Sub-rede pública  |  Modo provisionado  |  Nenhum  | 

Além disso, os grupos de segurança associados ao cluster do MSK devem permitir tráfego nas portas corretas. Configure as seguintes regras de grupo de segurança:
+ **Regras de entrada**: permitir todo o tráfego na porta padrão do agente. A porta que o MSK usa depende do tipo de autenticação no cluster: `9098` para autenticação do IAM, `9096` para SASL/SCRAM e `9094` para TLS. Como alternativa, é possível usar uma regra de grupo de segurança autorreferenciada para permitir o acesso de instâncias dentro do mesmo grupo de segurança.
+ **Regras de saída**: permitir todo o tráfego na porta `443` para destinos externos se a função precisar se comunicar com outros serviços da AWS. Como alternativa, você também pode usar uma regra de grupo de segurança autorreferenciada para limitar o acesso ao agente se não precisar se comunicar com outros serviços da AWS.
+ **Regras de entrada para o endpoint da Amazon VPC**: caso você esteja usando um endpoint da Amazon VPC, o grupo de segurança associado ao endpoint deve permitir tráfego de entrada na porta `443` vindo do grupo de segurança do cluster.

## Configurar um gateway NAT para uma origem de eventos do MSK
<a name="msk-nat-gateway"></a>

Você pode configurar um gateway NAT para permitir que o mapeamento da origem do evento pesquise mensagens do cluster e invoque a função por um caminho via VPC. Isso é necessário apenas se o mapeamento da origem do evento usar o modo sob demanda e o cluster residir em uma sub-rede privada da VPC. Se o cluster residir em uma sub-rede pública da VPC ou se o mapeamento da origem do evento usar o modo provisionado, não será necessário configurar um gateway NAT.

Um [gateway NAT](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) permite que os recursos de uma sub-rede privada acessem a Internet pública. Se você precisar de conectividade privada com o Lambda, consulte [Configurar endpoints AWS PrivateLink para uma origem de eventos do MSK](#msk-vpc-privatelink).

Depois de configurar o gateway NAT, configure as tabelas de rotas apropriadas. Isso permite que o tráfego da sub-rede privada seja roteado para a Internet pública via gateway NAT.

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


As etapas a seguir guiam você pela configuração de um gateway NAT usando o console. Repita essas etapas conforme necessário para cada zona de disponibilidade (AZ).

**Para configurar um gateway NAT e o roteamento adequado (console)**

1. Siga as etapas em [Criar um gateway NAT](https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-working-with.html), observando o seguinte:
   + Os gateways NAT sempre devem residir em uma sub-rede pública. Crie gateways NAT com [conectividade pública](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html).
   + Se o cluster do MSK for replicado em várias AZs, crie apenas um gateway NAT por AZ. Por exemplo, em cada AZ, a VPC deve ter uma sub-rede privada contendo o cluster e uma sub-rede pública contendo o gateway NAT. Para uma configuração com três AZs, você terá três sub-redes privadas, três sub-redes públicas e três gateways NAT.

1. Depois de criar o gateway NAT, abra o console da [Amazon VPC](https://console.aws.amazon.com/vpc/) e escolha **Tabelas de rotas** no menu à esquerda.

1. Escolha **Create Route Table (Criar tabela de rotas)**.

1. Associe essa tabela de rotas à VPC que contém o cluster do MSK. Opcionalmente, insira um nome para a tabela de rotas.

1. Escolha **Create Route Table (Criar tabela de rotas)**.

1. Escolha a tabela de rotas que acabou de criar.

1. Na guia **Associações da sub-rede** selecione **Editar associações da sub-rede**.
   + Associe essa tabela de rotas à sub-rede privada que contém o cluster do MSK.

1. Escolha **Edit routes (Editar rotas)**.

1. Selecione **Adicionar rota**:

   1. Em **Destination (Destino)**, selecione `0.0.0.0/0`.

   1. Em **Destino**, escolha **Gateway NAT**.

   1. Na caixa de pesquisa, escolha o gateway NAT que você criou na etapa 1. Esse deve ser o gateway NAT da mesma AZ que a sub-rede privada que contém o cluster do MSK (a sub-rede privada que você associou a essa tabela de rotas na etapa 6).

1. Escolha **Salvar alterações**.

## Configurar endpoints AWS PrivateLink para uma origem de eventos do MSK
<a name="msk-vpc-privatelink"></a>

Você pode configurar endpoints AWS PrivateLink para pesquisar mensagens do cluster e invocar a função por um caminho via VPC. Esses endpoints devem permitir que o cluster do MSK acesse o seguinte:
+ O serviço Lambda
+ O [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html)
+ Opcionalmente, o serviço [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html). Isso será necessário se o segredo exigido para autenticação do cluster estiver armazenado no Secrets Manager.

A configuração dos endpoints PrivateLink será necessária apenas se o mapeamento da origem do evento usar o modo sob demanda. Se o mapeamento da origem do evento usar o modo provisionado, o Lambda estabelecerá as conexões necessárias para você.

Os endpoints PrivateLink permitem acesso privado seguro aos serviços da AWS por AWS PrivateLink. Como alternativa, para configurar um gateway NAT para conceder ao cluster do MSK acesso à Internet pública, consulte [Configurar um gateway NAT para uma origem de eventos do MSK](#msk-nat-gateway).

Após a configuração dos endpoints da VPC, o cluster do MSK deverá ter acesso direto e privado ao Lambda, ao STS e, opcionalmente, ao Secrets Manager.

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


As etapas a seguir guiam você pela configuração de um endpoint PrivateLink usando o console. Repita essas etapas conforme necessário para cada endpoint (Lambda, STS, Secrets Manager).

**Para configurar um endpoints PrivateLink da VPC (console)**

1. Abra o [console da Amazon VPC](https://console.aws.amazon.com/vpc/) e escolha **Endpoints ** no menu à esquerda.

1. Escolha **Criar endpoint**.

1. Opcionalmente, insira um nome para o endpoint.

1. Em **Tipo**, escolha **Serviços da AWS**.

1. Em **Serviços**, comece a digitar o nome do serviço. Por exemplo, para criar um endpoint para se conectar ao Lambda, digite `lambda` na caixa de pesquisa.

1. Nos resultados, você deve ver o endpoint do serviço na região atual. Por exemplo, na região Leste dos EUA (Norte da Virgínia), você deve ver `com.amazonaws.us-east-2.lambda`. Selecione este serviço.

1. Em **Configurações de rede**, selecione a VPC que contém o cluster do MSK.

1. Em **Sub-redes**, selecione as AZs em que seu cluster do MSK está.
   + Para cada AZ, em **ID da sub-rede**, escolha a sub-rede privada que contém o cluster do MSK.

1. Em **grupos de segurança** selecione o grupo de segurança associado ao cluster do MSK.

1. Escolha **Criar endpoint**.

Por padrão, os endpoints da Amazon VPC têm políticas do IAM abertas que permitem amplo acesso aos recursos. A prática recomendada é restringir essas políticas para executar as ações necessárias usando esse endpoint. Por exemplo, para o endpoint do Secrets Manager, você pode modificar a política para que permita apenas que o perfil de execução da função acesse o segredo.

**Example Política de endpoint da VPC: endpoint do 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 os endpoints do AWS STS e do Lambda, você pode restringir a entidade principal chamadora à entidade principal do serviço Lambda. Porém, certifique-se de usar `"Resource": "*"` nessas políticas.

**Example Política de endpoint da VPC: endpoint do AWS STS**  

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

**Example Política de endpoint da VPC: endpoint do Lambda**  

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

# Configuração de permissões do Lambda para mapeamentos da origem do evento do Amazon MSK
<a name="with-msk-permissions"></a>

Além de acessar o cluster do Amazon MSK, a função e o mapeamento da origem do evento precisam de permissões para realizar várias ações de API do Amazon MSK. Adicione essas permissões ao [perfil de execução](lambda-intro-execution-role.md) da função. Se os usuários precisarem de acesso, adicione as permissões necessárias à política de identidades para o usuário ou o perfil.

A política gerenciada [AWSLambdaMSKExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaMSKExecutionRole.html) contém as permissões mínimas necessárias para mapeamentos da origem do evento do Lambda do Amazon MSK. Para simplificar o processo de permissões, é possível:
+ Anexe a política gerenciada [AWSLambdaMSKExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaMSKExecutionRole.html) ao seu perfil de execução.
+ Deixe que o console do Lambda gere as permissões para você. Quando você [cria um mapeamento da origem do evento do Amazon MSK no console](msk-esm-create.md#msk-console), o Lambda avalia seu perfil de execução e alerta você caso alguma permissão esteja faltando. Escolha **Gerar permissões** para atualizar automaticamente seu perfil de execução. Isso não funciona se você criou ou modificou manualmente suas políticas de perfil de execução, ou se as políticas estiverem anexadas a vários perfis. Observe que permissões adicionais ainda podem ser necessárias em seu perfil de execução ao usar recursos avançados, como [Destino em caso de falha](kafka-on-failure.md) ou [Registro de esquemas do AWS Glue](services-consume-kafka-events.md).

**Topics**
+ [Permissões obrigatórias](#msk-required-permissions)
+ [Permissões opcionais.](#msk-optional-permissions)

## Permissões obrigatórias
<a name="msk-required-permissions"></a>

O perfil de execução da função do Lambda deve ter as permissões exigidas para mapeamentos da origem do evento do Amazon MSK a seguir. Essas permissões estão incluídas na política [AWSLambdaMSKExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaMSKExecutionRole.html).

### Permissões do CloudWatch Logs
<a name="msk-basic-permissions"></a>

As permissões a seguir permitem que o Lambda crie e armazene logs no Amazon CloudWatch Logs.
+ [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)

### Permissões de cluster do MSK
<a name="msk-cluster-permissions"></a>

As permissões a seguir permitem que o Lambda acesse o cluster do Amazon por você:
+ [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 usar [kafka:DescribeClusterV2](https://docs.aws.amazon.com/MSK/2.0/APIReference/v2-clusters-clusterarn.html) em vez de [kafka:DescribeCluster](https://docs.aws.amazon.com/msk/1.0/apireference/clusters-clusterarn.html). A permissão v2 funciona com clusters do Amazon MSK provisionados e com tecnologia sem servidor. Você só precisará de uma dessas permissões na sua política.

### Permissões da VPC
<a name="msk-vpc-permissions"></a>

As permissões a seguir permitem que o Lambda crie e gerencie interfaces de rede ao se conectar ao seu cluster do 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)

## Permissões opcionais.
<a name="msk-optional-permissions"></a>

 Sua função do Lambda também pode precisar dessas permissões para: 
+ Acesse clusters do Amazon MSK entre contas. Para mapeamentos da origem do evento entre contas, você precisará de [kafka:DescribeVpcConnection](https://docs.aws.amazon.com/msk/1.0/apireference/vpc-connection-arn.html) no perfil de execução. Uma entidade principal do IAM que crie um mapeamento da origem do evento entre contas precisa de [kafka:ListVpcConnections](https://docs.aws.amazon.com/msk/1.0/apireference/vpc-connections.html).
+ Acesse o segredo SCRAM, se estiver usando [autenticação SASL/SCRAM](msk-cluster-auth.md#msk-sasl-scram). Com isso, a função pode usar um nome de usuário e uma senha para se conectar ao Kafka.
+ Descreva seu segredo do Secrets Manager, se estiver usando SASL/SCRAM ou [autenticação mTLS](msk-cluster-auth.md#msk-mtls). Com isso, a função pode recuperar as credenciais ou os certificados necessários para conexões seguras.
+ Acesse sua chave gerenciada pelo cliente do AWS KMS, se o seu segredo do AWS Secrets Manager estiver criptografado com uma chave gerenciada pelo cliente do AWS KMS.
+ Acesse os segredos do registro de esquemas se estiver usando um registro de esquema com autenticação:
  + Para o AWS Glue Schema Registry: sua função precisa das permissões `glue:GetRegistry` e `glue:GetSchemaVersion`. Elas permitem que a função pesquise e use as regras de formato de mensagens armazenadas no AWS Glue.
  + Para o [Confluent Schema Registry](https://docs.confluent.io/platform/current/schema-registry/security/index.html) com `BASIC_AUTH` ou `CLIENT_CERTIFICATE_TLS_AUTH`: a função precisa da permissão `secretsmanager:GetSecretValue` para o segredo que contém credenciais de autenticação. Com isso, a função pode recuperar o nome de usuário/senha ou os certificados necessários para acessar o Confluent Schema Registry.
  + Para certificados de CA privados: a função precisa da permissão secretsmanager:GetSecretValue para o segredo que contém o certificado. Com isso, a função pode verificar a identidade dos registros de esquema que usam certificados personalizados.
+ Acesse grupos de consumidores do cluster do Kafka e mensagens de sondagem do tópico se você estiver usando a autenticação do IAM para o mapeamento da origem do evento.

 Eles correspondem às seguintes permissões necessárias: 
+ [kafka:ListScramSecrets](https://docs.aws.amazon.com/msk/1.0/apireference/clusters-clusterarn-scram-secrets.html): permite a listagem de segredos SCRAM para autenticação do Kafka
+ [secretsmanager:GetSecretValue](https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html): permite a recuperação de segredos do Secrets Manager
+ [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html): permite a descriptografia de dados criptografados usando o AWS KMS
+ [glue:GetRegistry](https://docs.aws.amazon.com/glue/latest/webapi/API_GetRegistry.html): permite o acesso ao AWS Glue Schema Registry
+ [glue:GetSchemaVersion](https://docs.aws.amazon.com/glue/latest/webapi/API_GetSchemaVersion.html): permite a recuperação de versões específicas de esquema do AWS Glue Schema Registry
+ [kafka-cluster:Connect](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): concede permissão para se conectar e se autenticar no cluster.
+ [kafka-cluster:AlterGroup](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): concede permissão para entrar em grupos de um cluster, equivalente a READ GROUP ACL do Apache Kafka.
+ [kafka-cluster:DescribeGroup](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): concede permissão para descrever os grupos de um cluster, equivalente à ACL DESCRIBE GROUP do Apache Kafka.
+ [kafka-cluster:DescribeTopic](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): concede permissão para descrever os grupos de um cluster, equivalente à ACL DESCRIBE TOPIC do Apache Kafka.
+ [kafka-cluster:ReadData](https://docs.aws.amazon.com/service-authorization/latest/reference/list_apachekafkaapisforamazonmskclusters.html): concede permissão para ler dados dos tópicos de um cluster, equivalente a READ TOPIC ACL do Apache Kafka.

 Além disso, se quiser enviar registros cuja invocação não teve êxito para um destino em caso de falha, você precisará das seguintes permissões, dependendo do tipo de destino: 
+ Para destinos do Amazon SQS: [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html): permite enviar mensagens a uma fila do Amazon SQS
+ Para destinos do Amazon SNS: [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html): permite publicar mensagens em um tópico do Amazon SNS
+ Para destinos de buckets do Amazon S3: [s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) e [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBucket.html): permite escrever e listar objetos em um bucket do Amazon S3

Para solução de problemas de erros comuns de autenticação e de autorização, consulte [Solução de problemas de erros do mapeamento da origem do evento do Kafka](with-kafka-troubleshoot.md).

# Configurar as origens de eventos do Amazon MSK para o Lambda
<a name="with-msk-configure"></a>

Para usar um cluster do Amazon MSK como origem de eventos para a função do Lambda, você cria [um mapeamento da origem do evento](invocation-eventsourcemapping.md) que conecta os dois recursos. Esta página descreve como criar um mapeamento da origem do evento para o Amazon MSK.

Esta página pressupõe que você já configurou adequadamente o cluster do MSK e a [Amazon Virtual Private Cloud (VPC)](https://docs.aws.amazon.com/vpc/latest/userguide/what-is-amazon-vpc.html) em que ele reside. Se você precisar configurar o cluster ou a VPC, consulte [Configurar o cluster do Amazon MSK e a rede do Amazon VPC para o Lambda](with-msk-cluster-network.md). Para configurar o comportamento de novas tentativas para tratamento de erros, consulte [Configuração dos controles de tratamento de erros para origens de eventos do Kafka](kafka-retry-configurations.md).

**Topics**
+ [Usar um cluster do Amazon MSK como uma origem de eventos](#msk-esm-overview)
+ [Configuração de métodos de autenticação de cluster do Amazon MSK no Lambda](msk-cluster-auth.md)
+ [Criar um mapeamento da origem do evento do Lambda para uma origem de evento do Amazon MSK](msk-esm-create.md)
+ [Criar mapeamentos da origem do evento entre contas no Lambda](msk-cross-account.md)
+ [Parâmetros de configuração de origem do evento do Amazon MSK no Lambda](msk-esm-parameters.md)

## Usar um cluster do Amazon MSK como uma origem de eventos
<a name="msk-esm-overview"></a>

Quando você adiciona seu cluster do Apache Kafka ou do Amazon MSK como um gatilho para a função do Lambda, o cluster é usado como uma [origem de eventos](invocation-eventsourcemapping.md).

O Lambda lê os dados de eventos dos tópicos do Kafka que você especifica como `Topics` em uma solicitação de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) com base na [posição inicial](kafka-starting-positions.md) especificada. Após o processamento bem-sucedido, seu tópico do Kafka é confirmado no cluster do Kafka.

O Lambda lê as mensagens sequencialmente para cada partição de tópico do Kafka. Uma única carga do Lambda pode conter mensagens de várias partições. Quando mais registros ficam disponíveis, o Lambda continua processando os registros em lotes, com base no valor de BatchSize especificado na solicitação de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html), até a função estar atualizada com o tópico.

Depois que o Lambda processa cada lote, ele confirma os deslocamentos das mensagens nesse lote. Se sua função retorna um erro para qualquer uma das mensagens em um lote, o Lambda tenta novamente todo o lote de mensagens até que o processamento seja bem-sucedido ou as mensagens expiram. É possível enviar registros que apresentaram falha em todas as tentativas a um destino em caso de falha para processamento posterior.

**nota**  
Embora as funções do Lambda normalmente tenham um limite máximo de tempo de 15 minutos, os mapeamentos da origem dos eventos para o Amazon MSK, o Apache Kafka autogerenciado, o Amazon DocumentDB e o Amazon MQ para ActiveMQ e RabbitMQ são compatíveis somente com funções com limites máximos de tempo limite de 14 minutos.

# Configuração de métodos de autenticação de cluster do Amazon MSK no Lambda
<a name="msk-cluster-auth"></a>

O Lambda precisa de permissão para acessar o cluster do Amazon MSK, recuperar registros e realizar outras tarefas. O Amazon MSK é compatível com vários métodos de autenticação com o cluster do MSK.

**Topics**
+ [Acesso não autenticado](#msk-unauthenticated)
+ [Autenticação SASL/SCRAM](#msk-sasl-scram)
+ [Autenticação TLS mútua](#msk-mtls)
+ [Autenticação do IAM](#msk-iam-auth)
+ [Como o Lambda escolhe um operador de bootstrap](#msk-bootstrap-brokers)

## Acesso não autenticado
<a name="msk-unauthenticated"></a>

Se nenhum cliente acessar o cluster pela Internet, você poderá usar o acesso não autenticado.

## Autenticação SASL/SCRAM
<a name="msk-sasl-scram"></a>

O Lambda é compatível com autenticação [Simple Authentication and Security Layer/Salted Challenge Response Authentication Mechanism (SASL/SCRAM)](https://docs.aws.amazon.com/msk/latest/developerguide/msk-password-tutorial.html), com a função de hash SHA-512 e com a criptografia de Transport Layer Security (TLS). Para que o Lambda se conecte ao cluster, armazene as credenciais de autenticação (nome de usuário e senha) em um segredo do Secrets Manager e referencie esse segredo quando configurar o mapeamento da origem do evento.

Para obter mais informações sobre o uso do Secrets Manager, consulte [Sign-in credentials authentication with Secrets Manager](https://docs.aws.amazon.com/msk/latest/developerguide/msk-password.html) no *Amazon Managed Streaming for Apache Kafka Developer Guide*.

**nota**  
O Amazon MSK não oferece suporte a autenticação SASL/PLAIN.

## Autenticação TLS mútua
<a name="msk-mtls"></a>

O Mutual TLS (mTLS) fornece autenticação bidirecional entre o cliente e o servidor. O cliente envia um certificado ao servidor para que o servidor verifique o cliente. O servidor também envia um certificado para o cliente para que ele verifique o servidor.

Para integrações do Amazon MSK com o Lambda, o cluster do MSK atua como servidor e o Lambda atua como cliente.
+ Para que o Lambda verifique o cluster do MSK, você configura um certificado de cliente como um segredo no Secrets Manager e referencia esse certificado na configuração do mapeamento da origem do evento. O certificado do servidor deve ser assinado por uma autoridade de certificação (CA) no armazenamento de confiança da .
+ O cluster do MSK também envia um certificado de servidor ao Lambda. O certificado do servidor deve ser assinado por uma autoridade de certificação (CA) no armazenamento de confiança da AWS.

O Amazon MSK não é compatível com certificados de servidor auto-assinados. Todos os agentes no Amazon MSK usam [certificados públicos](https://docs.aws.amazon.com/msk/latest/developerguide/msk-encryption.html) assinados por [CAs do Amazon Trust Services](https://www.amazontrust.com/repository/), em que o Lambda confia por padrão.

### Configurar o segredo de mTLS
<a name="mtls-auth-secret"></a>

O segredo CLIENT\$1CERTIFICATE\$1TLS\$1AUTH requer um campo de certificado e um campo de chave privada. Para uma chave privada criptografada, o segredo requer uma senha de chave privada. Tanto o certificado como a chave privada devem estar no formato PEM.

**nota**  
O Lambda oferece suporte a algoritmos de criptografia de chave privada [PBES1](https://datatracker.ietf.org/doc/html/rfc2898/#section-6.1) (mas não PBES2).

O campo certificate (certificado) deve conter uma lista de certificados, começando pelo certificado do cliente, seguido por quaisquer certificados intermediários e terminando com o certificado raiz. Cada certificado deve iniciar em uma nova linha com a seguinte estrutura:

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

O Secrets Manager oferece suporte a segredos de até 65.536 bytes, que é espaço suficiente para cadeias de certificados longas.

A chave privada deve estar no formato [PKCS \$18](https://datatracker.ietf.org/doc/html/rfc5208), com a seguinte estrutura:

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

Para uma chave privada criptografada, use a seguinte estrutura:

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

O exemplo a seguir exibe o conteúdo de um segredo para autenticação mTLS usando uma chave privada criptografada. Para uma chave privada criptografada, inclua a senha da chave privada no segredo.

```
{
 "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 obter mais informações sobre o mTLS para Amazon MSK e instruções para gerar um certificado de cliente, consulte [Mutual TLS client authentication for Amazon MSK](https://docs.aws.amazon.com/msk/latest/developerguide/msk-authentication.html) no *Amazon Managed Streaming for Apache Kafka Developer Guide*.

## Autenticação do IAM
<a name="msk-iam-auth"></a>

É possível usar o AWS Identity and Access Management (IAM) para autenticar a identidade dos clientes que se conectam ao cluster do MSK. Com a autenticação do IAM, o Lambda depende das permissões do [perfil de execução](lambda-intro-execution-role.md) da função para se conectar ao cluster, recuperar registros e realizar outras ações necessárias. Para ver um exemplo de política com as permissões necessárias, consulte [Create authorization policies for the IAM role](https://docs.aws.amazon.com/msk/latest/developerguide/create-iam-access-control-policies.html) no *Amazon Managed Streaming for Apache Kafka Developer Guide*.

Se a autenticação do IAM estiver ativa no cluster do MSK e você não fornecer um segredo, o Lambda usará automaticamente a autenticação do IAM por padrão.

Para obter mais informações sobre a autenticação do IAM no Amazon MSK, consulte [IAM access control](https://docs.aws.amazon.com/msk/latest/developerguide/iam-access-control.html).

## Como o Lambda escolhe um operador de bootstrap
<a name="msk-bootstrap-brokers"></a>

O Lambda escolhe um [operador de bootstrap](https://docs.aws.amazon.com/msk/latest/developerguide/msk-get-bootstrap-brokers.html) com base nos métodos de autenticação disponíveis no cluster e dependendo de você fornecer um segredo para autenticação. Se você fornecer um segredo para mTLS ou SASL/SCRAM, o Lambda escolherá esse método de autenticação automaticamente. Se você não fornecer um segredo, o Lambda selecionará o método de autenticação mais forte que estiver ativo no seu cluster. Veja a seguir a ordem de prioridade na qual o Lambda seleciona um operador, da autenticação mais forte para a mais fraca:
+ mTLs (segredo fornecido para mTLs)
+ SASL/SCRAM (segredo fornecido para SASL/SCRAM)
+ SASL IAM (nenhum segredo fornecido, e a autenticação do IAM está ativa)
+ TLS não autenticado (nenhum segredo fornecido, e a autenticação do IAM não está ativa)
+ Texto simples (nenhum segredo fornecido, e a autenticação do IAM e o TLS não autenticado não estão ativos)

**nota**  
Se o Lambda não conseguir se conectar ao tipo de operador mais seguro, o Lambda não tentará se conectar a um tipo de operador diferente (mais fraco). Se quiser que o Lambda escolha um tipo de operador mais fraco, desative todos os métodos de autenticação mais fortes no seu cluster.

# Criar um mapeamento da origem do evento do Lambda para uma origem de evento do Amazon MSK
<a name="msk-esm-create"></a>

Para criar um mapeamento da origem do evento, você pode usar o console do Lambda, a [AWS Command Line Interface (CLI)](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) ou um [SDK da AWS](https://aws.amazon.com/getting-started/tools-sdks/).

**nota**  
Quando você cria o mapeamento da origem do evento, o Lambda cria uma [ENI de hiperplano](configuration-vpc.md#configuration-vpc-enis) na sub-rede privada que contém o cluster do MSK, permitindo que o Lambda estabeleça uma conexão segura. Essa ENI de hiperplano permite usar a configuração de sub-rede e grupo de segurança do cluster MSK, não a função do Lambda.

As etapas do console a seguir adicionam um cluster do Amazon MSK como acionador da função do Lambda. Nos bastidores, isso cria um recurso de mapeamento da origem do evento.

**Para adicionar um acionador do Amazon MSK à sua função do Lambda (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) no console do Lambda.

1. Escolha o nome da função do Lambda à qual você deseja adicionar um acionador. do Amazon MSK.

1. Em **Visão geral da função**, escolha **Adicionar gatilho**.

1. Em **Configuração do acionador**, escolha **MSK**.

1. Para especificar os detalhes do cluster do Kafka, faça o seguinte:

   1. Em **Cluster do MSK**, selecione seu cluster.

   1. Em **Nome do tópico**, insira o nome do tópico do Kafka do qual as mensagens serão consumidas.

   1. Em **ID do grupo de consumidores**, insira o ID de um grupo de consumidores do Kafka para ingressar, se aplicável. Para obter mais informações, consulte [ID de grupo de consumidores personalizável no Lambda](kafka-consumer-group-id.md).

1. Em **Autenticação de cluster**, faça as configurações necessárias. Para obter mais informações sobre autenticação de cluster, consulte [Configuração de métodos de autenticação de cluster do Amazon MSK no Lambda](msk-cluster-auth.md).
   + Ative a opção **Usar autenticação** se quiser que o Lambda realize a autenticação com o cluster MSK quando estabelecer uma conexão. A autenticação é recomendada.
   + Se você usar autenticação, em **Método de autenticação**, escolha o método de autenticação a ser usado.
   + Se você usar autenticação, em **Chave do Secrets Manager**, escolha a chave do Secrets Manager que contém as credenciais de autenticação necessárias para acessar o cluster.

1. Em **Configuração do agente de sondagem de eventos**, faça as configurações necessárias.
   + Escolha **Ativar acionador** para habilitar o acionador imediatamente após a criação.
   + Escolha se deseja **Configurar o modo provisionado** para o mapeamento da origem do evento. Para obter mais informações, consulte [Modos de escalabilidade de sondagem de eventos do Apache Kafka no Lambda](kafka-scaling-modes.md).
     + Se você configurar o modo provisionado, insira um valor para **Mínimo de agentes de sondagem de eventos**, um valor para **Máximo de agentes de sondagem de eventos** e um valor opcional para PollerGroupName para especificar o agrupamento de vários ESMs na mesma VPC de origem dos eventos.
   + Em **Posição inicial**, escolha como quer que o Lambda comece a ler o fluxo. Para obter mais informações, consulte [Posições iniciais de sondagem e fluxo do Apache Kafka no Lambda](kafka-starting-positions.md).

1. Em **Processamento em lotes**, faça as configurações necessárias. Para obter mais informações sobre processamento em lotes, consulte [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

   1. Em **Batch size** (Tamanho do lote), insira o número máximo de mensagens a serem recebidas em um único lote.

   1. Em **Janela de lotes**, insira o número máximo de segundos que o Lambda leva coletando registros antes de invocar a função.

1. Em **Filtragem**, faça as configurações necessárias. Para obter mais informações sobre filtragem, consulte [Filtrar as origens dos eventos do Amazon MSK e do Apache Kafka autogerenciado](kafka-filtering.md).
   + Em **Critérios de filtro**, adicione as definições de critérios de filtro para definir se um evento deve ou não ser processado.

1. Em **Tratamento de falhas**, faça as configurações necessárias. Para obter mais informações sobre tratamento de falhas, consulte [Capturar lotes descartados para uma origem do evento do Amazon MSK e do Apache Kafka autogerenciado](kafka-on-failure.md).
   + Em **Destino em caso de falha**, especifique o ARN do destino em caso de falha.

1. Em **Tags**, insira as tags a serem associadas a esse mapeamento da origem do evento.

1. Para criar o acionador, selecione **Add** (Adicionar).

Também é possível criar o mapeamento da origem do evento usando a AWS CLI com o comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html). O exemplo a seguir cria um mapeamento da origem do evento para mapear a função do Lambda `my-msk-function` para o tópico `AWSKafkaTopic`, começando pela mensagem `LATEST`. Esse comando também usa o objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html) para instruir o Lambda a usar a autenticação [SASL/SCRAM](msk-cluster-auth.md#msk-sasl-scram) quando se conectar ao cluster.

```
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"}]'
```

Se o cluster usar a [autenticação mTLS](msk-cluster-auth.md#msk-mtls), inclua um objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html) que especifique a `CLIENT_CERTIFICATE_TLS_AUTH` e o ARN de uma chave do Secrets Manager. Isso é mostrado no seguinte 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"}]'
```

Quando o cluster usa a [autenticação do IAM](msk-cluster-auth.md#msk-iam-auth), você não precisa de um objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html). Isso é mostrado no seguinte 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
```

# Criar mapeamentos da origem do evento entre contas no Lambda
<a name="msk-cross-account"></a>

É possível usar a [conectividade privada com várias VPCs](https://docs.aws.amazon.com/msk/latest/developerguide/aws-access-mult-vpc.html) para conectar uma função do Lambda a um cluster DO MSK provisionado em outra Conta da AWS. A conectividade com várias VPCs usa AWS PrivateLink, que mantém todo o tráfego na rede da AWS.

**nota**  
Não é possível criar mapeamentos da origem do evento entre contas para clusters do MSK sem servidor.

Para criar um mapeamento da origem de eventos entre contas, primeiro você precisa [configurar a conectividade com várias VPCs](https://docs.aws.amazon.com/msk/latest/developerguide/aws-access-mult-vpc.html#mvpc-cluster-owner-action-turn-on) para o cluster do MSK. Ao criar o mapeamento da origem de eventos, use o ARN da conexão VPC gerenciada, em vez do ARN do cluster, conforme mostrado nos exemplos a seguir. A operação [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) também difere dependendo do tipo de autenticação usado pelo cluster do MSK.

**Example : criar um mapeamento da origem de eventos entre contas para o cluster que usa autenticação do IAM**  
Quando o cluster usa a [autenticação baseada em perfil do IAM](msk-cluster-auth.md#msk-iam-auth), você não precisa de um objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html). Exemplo:  

```
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 : criar um mapeamento da origem de eventos entre contas para o cluster que usa autenticação SASL/SCRAM**  
Se o cluster usar [autenticação SASL/SCRAM](msk-cluster-auth.md#msk-sasl-scram), você precisa incluir um objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html) que especifique `SASL_SCRAM_512_AUTH` e um ARN secreto do Secrets Manager.  
Há duas maneiras de usar segredos para mapeamentos da origem do evento entre contas do Amazon MSK com autenticação SASL/SCRAM:  
+ Crie um segredo na conta da função do Lambda e sincronize-o com o segredo do cluster. [Crie uma rotação](https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets.html) para manter os dois segredos sincronizados. Essa opção permite controlar o segredo pela conta da função.
+ Use o segredo associado ao cluster do MSK. Esse segredo deve permitir o acesso entre contas à conta da função do Lambda. Para obter mais informações, consulte [Permissões para segredos do AWS Secrets Manager para usuários em uma conta 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 : criar um mapeamento da origem de eventos entre contas para o cluster que usa autenticação mTLS**  
Se o cluster usar [autenticação mTLS](msk-cluster-auth.md#msk-mtls), você precisa incluir um objeto [SourceAccessConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_SourceAccessConfiguration.html) que especifique `CLIENT_CERTIFICATE_TLS_AUTH` e um ARN secreto do Secrets Manager. O segredo pode ser armazenado na conta do cluster ou na conta da função do 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"}]'
```

# Parâmetros de configuração de origem do evento do Amazon MSK no Lambda
<a name="msk-esm-parameters"></a>

Todos os tipos de origem de evento Lambda compartilham o mesmo[CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html)e[UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html)Operações de API do. Porém, apenas alguns dos parâmetros se aplicam ao Amazon MSK, como mostra a tabela a seguir.


| Parâmetro | Obrigatório | Padrão | Observações | 
| --- | --- | --- | --- | 
|  AmazonManagedKafkaEventSourceConfig  |  N  |  Contém o campo ConsumerGroupId, que assume, por padrão, um valor exclusivo.  |  Pode definir apenas em Criar  | 
|  BatchSize  |  N  |  100  |  Máximo: 10.000.  | 
|  DestinationConfig  |  N  |  N/D  |  [Capturar lotes descartados para uma origem do evento do Amazon MSK e do Apache Kafka autogerenciado](kafka-on-failure.md)  | 
|  Habilitado  |  N  |  Verdadeiro  |    | 
|  BisectBatchOnFunctionError  |  N  |  Falso  |  [Configuração dos controles de tratamento de erros para origens de eventos do Kafka](kafka-retry-configurations.md)  | 
|  FunctionResponseTypes  |  N  |  N/D  |  [Configuração dos controles de tratamento de erros para origens de eventos do Kafka](kafka-retry-configurations.md)  | 
|  MaximumRecordAgeInSeconds  |  N  |  -1 (infinito)  |  [Configuração dos controles de tratamento de erros para origens de eventos do Kafka](kafka-retry-configurations.md)  | 
|  MaximumRetryAttempts  |  N  |  -1 (infinito)  |  [Configuração dos controles de tratamento de erros para origens de eventos do Kafka](kafka-retry-configurations.md)  | 
|  EventSourceArn  |  S  | N/D |  Pode definir apenas em Criar  | 
|  FilterCriteria  |  N  |  N/D  |  [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md)  | 
|  FunctionName  |  S  |  N/D  |    | 
|  KMSKeyArn  |  N  |  N/D  |  [Criptografia de critérios de filtro](invocation-eventfiltering.md#filter-criteria-encryption)  | 
|  MaximumBatchingWindowInSeconds  |  N  |  500 ms  |  [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching)  | 
|  ProvisionedPollersConfig  |  N  |  `MinimumPollers`: o valor padrão será 1 se não for especificado. `MaximumPollers`: o valor padrão será 200 se não for especificado. `PollerGroupName`: N/D  |  [Modo provisionado](kafka-scaling-modes.md#kafka-provisioned-mode)  | 
|  SourceAccessConfigurations  |  N  |  Sem credenciais do  |  Credenciais de autenticação SASL/SCRAM ou CLIENT\$1CERTIFICATE\$1TLS\$1AUTH (MutualTLS) para a fonte do evento  | 
|  StartingPosition  |  S  | N/D |  AT\$1TIMESTAMP, TRIM\$1HORIZON, ou LATEST Pode definir apenas em Criar  | 
|  StartingPositionTimestamp  |  N  |  N/D  |  Obrigatório se StartingPosition estiver definido como AT\$1TIMESTAMP  | 
|  Tags  |  N  |  N/D  |  [Uso de tags em mapeamentos da origem do evento](tags-esm.md)  | 
|  Tópicos  |  S  | N/D |  Nome do tópico do Kafka Pode definir apenas em Criar  | 

**nota**  
Quando você especifica um `PollerGroupName`, vários ESMs dentro da mesma Amazon VPC podem compartilhar a capacidade da unidade de sondagem de evento (EPU). É possível usar essa opção para otimizar os custos do modo provisionado para seus ESMs. Requisitos para o agrupamento de ESM:  
Os ESMs devem estar na mesma Amazon VPC
Máximo de 100 ESMs por grupo de agentes de sondagem
O máximo agregado de agentes de sondagem em todos os ESMs em um grupo não pode exceder a 2.000
É possível atualizar o `PollerGroupName` para mover um ESM para um grupo diferente ou remover um ESM de um grupo configurando `PollerGroupName` como uma string vazia (“”).

# Tutorial: Usar um mapeamento de origem do evento do Amazon MSK para invocar uma função do Lambda
<a name="services-msk-tutorial"></a>

Neste tutorial, você fará o seguinte:
+ Criar uma função do Lambda na mesma conta da AWS que um cluster do Amazon MSK existente.
+ Configurar a rede e a autenticação para que o Lambda se comunique com o Amazon MSK.
+ Configurar um mapeamento de origem do evento do Amazon MSK do Lambda, o qual executa sua função do Lambda quando os eventos aparecem no tópico.

Depois de concluir essas etapas, quando os eventos forem enviados para o Amazon MSK, você poderá configurar uma função do Lambda para processar esses eventos automaticamente com seu próprio código do Lambda personalizado.

 **O que você pode fazer com esse recurso?** 

**Exemplo de solução: use um mapeamento de origem de evento do MSK para fornecer pontuações ao vivo para seus clientes.**

Considere o seguinte cenário: sua empresa hospeda uma aplicação Web em que seus clientes podem ver informações sobre eventos ao vivo, como competições esportivas. As atualizações de informações do jogo são fornecidas à sua equipe por meio de um tópico do Kafka no Amazon MSK. Você deseja criar uma solução que consuma atualizações do tópico do MSK para fornecer uma visão atualizada do evento ao vivo aos clientes dentro de uma aplicação desenvolvida por você. Você optou pela seguinte abordagem de design: suas aplicações clientes se comunicarão com um backend sem servidor hospedado na AWS. Os clientes se conectarão por meio de sessões de websocket usando a API de WebSocket do Amazon API Gateway.

Nessa solução, você precisa de um componente que leia eventos do MSK, execute uma lógica personalizada para preparar esses eventos para a camada de aplicação e, em seguida, encaminhe essas informações para a API do API Gateway. É possível implementar esse componente com o AWS Lambda, fornecendo sua lógica personalizada em uma função do Lambda e, em seguida, chamando-a com um mapeamento de origem de eventos do Amazon MSK do AWS Lambda.

Para obter mais informações sobre a implementação de soluções usando a API de WebSocket do Amazon API Gateway, consulte os [tutoriais da API de WebSocket](https://docs.aws.amazon.com/apigateway/latest/developerguide/websocket-api-chat-app.html) na documentação do API Gateway.

## Pré-requisitos
<a name="w2aad101c23c15c35c19"></a>

Uma conta da AWS com os seguintes recursos pré-configurados:

**Para cumprir esses pré-requisitos, recomendamos seguir a seção [Conceitos básicos do uso do Amazon MSK](https://docs.aws.amazon.com//msk/latest/developerguide/getting-started.html) na documentação do Amazon MSK.**
+ Um cluster do Amazon MSK. Consulte [Criar um cluster do Amazon MSK](https://docs.aws.amazon.com//msk/latest/developerguide/create-cluster.html) em *Conceitos básicos do uso do Amazon MSK*.
+ A seguinte configuração:
  + Certifique-se de que a **autenticação baseada em perfis do IAM** esteja **habilitada** nas configurações de segurança do cluster. Isso melhora sua segurança ao limitar sua função do Lambda para acessar somente os recursos necessários do Amazon MSK. Esse comportamento é habilitado por padrão em todos os novos clusters do Amazon MSK.
  + Certifique-se de que o **acesso público** esteja desativado nas configurações de rede do cluster. Restringir o acesso do cluster do Amazon MSK à Internet melhora sua segurança ao limitar o número de intermediários que lidam com seus dados. Esse comportamento é habilitado por padrão em todos os novos clusters do Amazon MSK.
+ Um tópico do Kafka no cluster do Amazon MSK para usar nesta solução. Consulte [Criar um tópico](https://docs.aws.amazon.com//msk/latest/developerguide/create-topic.html) em *Conceitos básicos do uso do Amazon MSK*.
+ Um host administrativo do Kafka configurado para recuperar informações do cluster do Kafka e enviar eventos do Kafka para seu tópico para teste, como uma instância do Amazon EC2 com a CLI de administração do Kafka e a biblioteca do IAM do Amazon MSK instalada. Consulte [Criar uma máquina cliente](https://docs.aws.amazon.com//msk/latest/developerguide/create-client-machine.html) em *Conceitos básicos do uso do Amazon MSK*.

Depois de configurar esses recursos, reúna as seguintes informações da sua conta da AWS para confirmar que está tudo pronto para continuar.
+ O nome do cluster do Amazon MSK. Essas informações podem ser encontradas no console do Amazon MSK.
+ O UUID do cluster, parte do ARN do seu cluster do Amazon MSK, o qual pode ser encontrado no console do Amazon MSK. Siga os procedimentos em [Listar clusters](https://docs.aws.amazon.com/msk/latest/developerguide/msk-list-clusters.html) na documentação do Amazon MSK para encontrar essas informações.
+ Os grupos de segurança associados ao cluster do Amazon MSK. Essas informações podem ser encontradas no console do Amazon MSK. Nas etapas a seguir, faça referência a elas como *clusterSecurityGroups*.
+ O ID da Amazon VPC contendo seu cluster do Amazon MSK. É possível encontrar essas informações identificando sub-redes associadas ao seu cluster do Amazon MSK no console do Amazon MSK e, em seguida, identificando a Amazon VPC associada à sub-rede no console da Amazon VPC.
+ O nome do tópico do Kafka usado na solução. É possível encontrar essas informações chamando o cluster do Amazon MSK com a CLI de `topics` do Kafka no host administrativo do Kafka. Para obter mais informações sobre a CLI de tópicos, consulte [Adicionar e remover tópicos](https://kafka.apache.org/documentation/#basic_ops_add_topic) na documentação do Kafka.
+ O nome de um grupo de consumidores para seu tópico do Kafka, adequado para uso por sua função do Lambda. Esse grupo pode ser criado automaticamente pelo Lambda, então não é necessário criá-lo com a CLI do Kafka. Se você precisar gerenciar seus grupos de consumidores, para saber mais sobre a CLI de grupos de consumidores, consulte [Gerenciar grupos de consumidores](https://kafka.apache.org/documentation/#basic_ops_consumer_group) na documentação do Kafka.

As seguintes permissões em sua conta da AWS:
+ Permissão para criar e gerenciar uma função do Lambda
+ Permissão para criar políticas do IAM e associá-las à sua função do Lambda.
+ Permissão para criar endpoints da Amazon VPC e alterar a configuração de rede na Amazon VPC que hospeda seu cluster do Amazon MSK.

### Instalar o AWS Command Line Interface
<a name="install_aws_cli"></a>

Se você ainda não instalou a AWS Command Line Interface, siga as etapas em [Instalar ou atualizar a versão mais recente da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalá-la.

O tutorial requer um terminal de linha de comando ou um shell para executar os comandos. No Linux e no macOS, use o gerenciador de pacotes e de shell de sua preferência.

**nota**  
No Windows, alguns comandos da CLI do Bash que você costuma usar com o Lambda (como `zip`) não são compatíveis com os terminais integrados do sistema operacional. Para obter uma versão do Ubuntu com o Bash integrada no Windows, [instale o Subsistema do Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Configurar a conectividade de rede para que o Lambda se comunique com o Amazon MSK
<a name="w2aad101c23c15c35c21"></a>

 Use AWS PrivateLink para conectar o Lambda e o Amazon MSK. Isso pode ser feito com a criação de endpoints da Amazon VPC de interface no console do Amazon VPC. Para obter mais informações sobre a configuração de rede, consulte [Configurar o cluster do Amazon MSK e a rede do Amazon VPC para o Lambda](with-msk-cluster-network.md). 

Quando um mapeamento de origem de evento do Amazon MSK é executado em nome de uma função do Lambda, ele assume o perfil de execução da função do Lambda. Essa função do IAM autoriza o mapeamento a acessar recursos protegidos pelo IAM, como seu cluster do Amazon MSK. Embora os componentes compartilhem uma função de execução, o mapeamento do Amazon MSK e sua função do Lambda têm requisitos de conectividade separados para suas respectivas tarefas, conforme mostrado no diagrama a seguir.

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


Seu mapeamento da origem do evento pertence ao seu grupo de segurança do cluster do Amazon MSK. Nesta etapa de rede, crie endpoints do Amazon VPC da VPC do cluster do Amazon MSK para conectar o mapeamento da origem do evento aos serviços do Lambda e STS. Proteja esses endpoints para aceitar tráfego do seu grupo de segurança de cluster do Amazon MSK. Em seguida, ajuste os grupos de segurança do cluster do Amazon MSK para permitir que o mapeamento da origem do evento se comunique com o cluster do Amazon MSK.

 É possível configurar as etapas a seguir usando o Console de gerenciamento da AWS.

**Para configurar os endpoints da Amazon VPC de interface para conectar o Lambda e o Amazon MSK**

1. Crie um grupo de segurança para os endpoints da Amazon VPC de interface, *endpointSecurityGroup*, que permite tráfego TCP de entrada na porta 443 proveniente de *clusterSecurityGroups*. Siga o procedimento em [Criar um grupo de segurança](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/working-with-security-groups.html#creating-security-group) na documentação do Amazon EC2 para criar um grupo de segurança. Em seguida, siga o procedimento em [Adicionar regras a um grupo de segurança](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/working-with-security-groups.html#adding-security-group-rule) na documentação do Amazon EC2 para adicionar as regras apropriadas. 

   **Crie um grupo de segurança com as seguintes informações:**

   Ao adicionar suas regras de entrada, crie uma regra para cada grupo de segurança em *clusterSecurityGroups*. Para cada regra:
   + Em **Tipo**, selecione **HTTPS**.
   + Em **Origem**, selecione um dos *clusterSecurityGroups*.

1.  Crie um endpoint conectando o serviço do Lambda à Amazon VPC contendo seu cluster do Amazon MSK. Siga o procedimento em [Criar um endpoint de interface](https://docs.aws.amazon.com//vpc/latest/privatelink/create-interface-endpoint.html).

   **Crie um endpoint de interface com as seguintes informações:**
   + Em **Nome do serviço**, selecione `com.amazonaws.regionName.lambda`, onde *regionName* hospeda sua função do Lambda.
   + Para **VPC**, selecione a Amazon VPC que contém seu cluster do Amazon MSK.
   + Em **Grupos de segurança**, selecione o *endpointSecurityGroup* que você criou anteriormente.
   + Para **Sub-redes**, selecione as sub-redes que hospedam seu cluster do Amazon MSK.
   + Para **Política**, forneça o documento de política a seguir, que protege o endpoint para uso pela entidade principal do serviço do Lambda para a ação `lambda:InvokeFunction`.

     ```
     {
         "Statement": [
             {
                 "Action": "lambda:InvokeFunction",
                 "Effect": "Allow",
                 "Principal": {
                     "Service": [
                         "lambda.amazonaws.com"
                     ]
                 },
                 "Resource": "*"
             }
         ]
     }
     ```
   + Certifique-se de que a opção **Habilitar nome de DNS** permaneça selecionada.

1.  Crie um endpoint conectando o serviço do AWS STS à Amazon VPC que contém seu cluster do Amazon MSK. Siga o procedimento em [Criar um endpoint de interface](https://docs.aws.amazon.com//vpc/latest/privatelink/create-interface-endpoint.html).

   **Crie um endpoint de interface com as seguintes informações:**
   + Em **Nome do serviço**, selecione AWS STS.
   + Para **VPC**, selecione a Amazon VPC que contém seu cluster do Amazon MSK.
   + Em **Grupos de segurança**, selecione *endpointSecurityGroup*.
   + Para **Sub-redes**, selecione as sub-redes que hospedam seu cluster do Amazon MSK.
   + Para **Política**, forneça o documento de política a seguir, que protege o endpoint para uso pela entidade principal do serviço do Lambda para a ação `sts:AssumeRole`.

     ```
     {
         "Statement": [
             {
                 "Action": "sts:AssumeRole",
                 "Effect": "Allow",
                 "Principal": {
                     "Service": [
                         "lambda.amazonaws.com"
                     ]
                 },
                 "Resource": "*"
             }
         ]
     }
     ```
   + Certifique-se de que a opção **Habilitar nome de DNS** permaneça selecionada.

1. Para cada grupo de segurança associado ao seu cluster do Amazon MSK, ou seja, em *clusterSecurityGroups*, permita o seguinte:
   + Permita todo o tráfego TCP de entrada e saída na porta 9098 para todos os *clusterSecurityGroups*, inclusive dentro dele mesmo.
   + Permita todo o tráfego TCP de saída na porta 443.

   Parte desse tráfego é permitido por regras padrão do grupo de segurança. Portanto, se seu cluster estiver vinculado a um único grupo de segurança e esse grupo tiver regras padrão, regras adicionais não serão necessárias. Para adicionar regras do grupo de segurança, siga o procedimento em [Adicionar regras a um grupo de segurança](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/working-with-security-groups.html#adding-security-group-rule) na documentação do Amazon EC2.

   **Adicione regras aos seus grupos de segurança com as seguintes informações:**
   + Para cada regra de entrada ou regra de saída para a porta 9098, forneça
     + Em **Tipo**, selecione **TCP personalizado**.
     + Em **Intervalo de portas**, forneça 9098.
     + Em **Origem**, forneça um dos *clusterSecurityGroups*.
   + Para cada regra de entrada da porta 443, em **Tipo**, selecione **HTTPS**.

## Crie um perfil do IAM para que o Lambda leia seu tópico do Amazon MSK
<a name="w2aad101c23c15c35c23"></a>

Identifique os requisitos de autenticação para que o Lambda leia seu tópico do Amazon MSK e, em seguida, defina-os em uma política. Crie uma função, *lambdaAuthRole*, que autorize o Lambda a usar essas permissões. Autorize ações no seu cluster Amazon MSK usando ações do IAM do `kafka-cluster`. Em seguida, autorize o Lambda a realizar as ações do Amazon MSK `kafka` e do Amazon EC2 necessárias para descobrir e se conectar ao seu cluster do Amazon MSK, bem como as ações do CloudWatch para que o Lambda possa registrar em log o que fez.

**Para descrever os requisitos de autenticação para que o Lambda leia a partir do Amazon MSK**

1. Escreva um documento de política do IAM (um documento JSON), *clusterAuthPolicy*, que permita que o Lambda leia seu tópico do Kafka no seu cluster do Amazon MSK usando seu grupo de consumidores do Kafka. O Lambda exige que um grupo de consumidores do Kafka seja definido durante a leitura.

   Altere o modelo a seguir para se alinhar aos seus pré-requisitos:

------
#### [ 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 obter mais informações, consulte : [Configuração de permissões do Lambda para mapeamentos da origem do evento do Amazon MSK](with-msk-permissions.md). Ao redigir sua política:
   + Substitua *us-east-1* e *111122223333* por Região da AWS e por Conta da AWS de seu cluster Amazon MSK.
   + Em *mskClusterName*, forneça o nome do seu cluster do Amazon MSK.
   + Em *cluster-uuid*, forneça o UUID no ARN para seu cluster do Amazon MSK.
   + Em *mskTopicName*, forneça o nome do seu tópico do Kafka.
   + Em *mskGroupName*, forneça o nome do seu grupo de consumidores do Kafka.

1. Identifique as permissões do Amazon MSK, do Amazon EC2 e do CloudWatch necessárias para que o Lambda descubra e conecte seu cluster Amazon MSK e registre esses eventos no log.

   A política gerenciada `AWSLambdaMSKExecutionRole` define de forma permissiva as permissões necessárias. Use-a nas etapas a seguir.

   Em um ambiente de produção, avalie `AWSLambdaMSKExecutionRole` para restringir sua política de perfil de execução com base no princípio do privilégio mínimo e, em seguida, escreva uma política para seu perfil que substitua essa política gerenciada.

Para obter detalhes sobre a linguagem de políticas do IAM, consulte a [Documentação do IAM](https://docs.aws.amazon.com//iam/).

Agora que você escreveu seu documento de política, crie uma política do IAM para poder anexá-la ao seu perfil. É possível fazer isso usando o console com o procedimento a seguir.

**Para criar uma política do IAM a partir do seu documento de política**

1. Faça login no Console de gerenciamento da AWS e abra o console do IAM em [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

1. No painel de navegação à esquerda, escolha **Políticas**. 

1. Escolha **Criar política**.

1. Na seção **Editor de políticas**, escolha a opção **JSON**.

1. Cole *clusterAuthPolicy*.

1. Quando terminar de adicionar as permissões à política, escolha **Avançar**.

1. Na página **Revisar e criar**, digite um **nome de política** e uma **descrição** (opcional) para a política que você está criando. Revise **Permissões definidas nessa política** para ver as permissões que são concedidas pela política.

1. Escolha **Criar política** para salvar sua nova política.

Para obter mais informações, consulte [Criar políticas do IAM](https://docs.aws.amazon.com//IAM/latest/UserGuide/access_policies_create.html) na documentação do IAM.

Agora que você tem as políticas apropriadas do IAM, crie uma perfil e anexe-o a ela. É possível fazer isso usando o console com o procedimento a seguir.

**Como criar uma função de execução no console do IAM**

1. Abra a página [Roles (Funções)](https://console.aws.amazon.com/iam/home#/roles) no console do IAM.

1. Selecione **Create role** (Criar função).

1. Em **Tipo de entidade confiável**, selecione **Serviço da AWS**.

1. Em **Use case** (Caso de uso), escolha **Lambda**.

1. Escolha **Próximo**.

1. Selecione as políticas a seguir:
   + *clusterAuthPolicy*
   + `AWSLambdaMSKExecutionRole`

1. Escolha **Próximo**.

1. Em **Nome do perfil**, insira *lambdaAuthRole* e, em seguida, escolha **Criar perfil**.

Para obter mais informações, consulte [Definir permissões de uma função do Lambda com um perfil de execução](lambda-intro-execution-role.md).

## Crie uma função do Lambda para ler do seu tópico do Amazon MSK
<a name="w2aad101c23c15c35c25"></a>

Crie uma função do Lambda configurada para usar seu perfil do IAM. É possível criar sua função do Lambda usando o console.

**Para criar uma função do Lambda usando sua configuração de autenticação**

1.  Abra o console do Lambda e selecione **Criar função** no cabeçalho. 

1. Selecione **Criar do zero**.

1. Em **Nome da função**, forneça um nome apropriado de sua escolha.

1. Em **Runtime**, escolha a versão **Mais recente com suporte** do `Node.js` para usar o código fornecido neste tutorial.

1. Escolha **Alterar perfil de execução padrão**.

1. Selecione **Usar perfil existente**.

1. Em **Perfil existente**, selecione *lambdaAuthRole*.

Em um ambiente de produção, geralmente é necessário adicionar mais políticas ao perfil de execução da sua função do Lambda para processar de forma significativa seus eventos do Amazon MSK. Para obter mais informações sobre como adicionar políticas ao seu perfil, consulte [Adicionar ou remover permissões de identidade](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_manage-attach-detach.html#add-policies-console) na documentação do IAM.

## Criar um mapeamento da origem do evento para sua função do Lambda
<a name="w2aad101c23c15c35c27"></a>

Seu mapeamento de origem de eventos do Amazon MSK fornece ao serviço do Lambda as informações necessárias para invocar seu Lambda quando eventos apropriados do Amazon MSK ocorrem. É possível criar um mapeamento do Amazon MSK usando o console. Crie um acionador do Lambda e, em seguida, o mapeamento de origem de eventos será configurado automaticamente.

**Para criar um acionador do Lambda (e mapeamento de origem de eventos)**

1. Navegue até a página de visão geral da sua função do Lambda.

1. Na seção de visão geral da função, selecione **Adicionar acionador** no canto inferior esquerdo.

1. No menu suspenso **Selecionar uma origem**, selecione **Amazon MSK**.

1. Não defina a **autenticação**.

1. Em **Cluster do MSK**, selecione o nome do seu cluster.

1. Em **Tamanho do lote**, insira 1. Essa etapa facilita o teste desse recurso, mas não é um valor ideal em ambientes de produção.

1. Em **Nome do tópico**, forneça o nome do seu tópico do Kafka.

1. Para **ID do grupo de consumidores**, forneça o ID do seu grupo de consumidores do Kafka.

## Atualize a função do Lambda para ler seus dados de streaming
<a name="w2aad101c23c15c35c29"></a>

 O Lambda fornece informações sobre eventos do Kafka por meio do parâmetro de método de evento. Para obter um exemplo de estrutura de um evento do Amazon MSK, consulte [Evento de exemplo](with-msk.md#msk-sample-event). Depois de entender como interpretar os eventos do Amazon MSK encaminhados pelo Lambda, você pode alterar o código da função do Lambda para usar as informações fornecidas por eles. 

 Forneça o seguinte código à sua função do Lambda para registrar em log o conteúdo de um evento do Amazon MSK do Lambda para fins de teste: 

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumir um evento do Amazon MSK com o Lambda usando .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumo de um evento do Amazon MSK com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumir um evento do Amazon MSK com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumir um evento do Amazon MSK com o Lambda usando 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)
      }) 
    }
}
```
Consumir um evento do Amazon MSK com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumo de um evento do Amazon MSK com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumir um evento do Amazon MSK com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumir um evento do Amazon MSK com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-msk-to-lambda). 
Consumo de um evento do Amazon MSK com o Lambda usando o 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
}
```

------

É possível fornecer código de função para o Lambda usando o console.

**Para atualizar o código da função usando o editor de código do console**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda e selecione a função.

1. Selecione a guia **Código**.

1. No painel **Código-fonte**, selecione o arquivo de código-fonte e edite-o no editor de código integrado.

1. Na seção **DEPLOY**, escolha **Implantar** para atualizar o código da função:  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

## Teste sua função do Lambda para verificar se ela está conectada ao seu tópico do Amazon MSK
<a name="w2aad101c23c15c35c31"></a>

Agora você pode verificar se seu Lambda está sendo invocado pela origem do evento inspecionando os logs de eventos do CloudWatch.

**Para verificar se sua função do Lambda está sendo invocada**

1. Use seu host de administração do Kafka para gerar eventos do Kafka usando a CLI do `kafka-console-producer`. Para obter mais informações, consulte [Escrever alguns eventos no tópico na](https://kafka.apache.org/documentation/#quickstart_send) documentação do Kafka. Envie eventos suficientes para preencher o lote definido pelo tamanho do lote para seu mapeamento de origem de eventos definido na etapa anterior, caso contrário, o Lambda aguardará a invocação de mais informações.

1. Se sua função for executada, o Lambda escreverá o que aconteceu com o CloudWatch. No console, navegue até a página de detalhes da função do Lambda.

1. Selecione a guia **Configuration** (Configuração).

1. Na barra lateral, selecione **Ferramentas de monitoramento e operações**.

1. Identifique o **Grupo de logs do CloudWatch** em **Configuração de log**. O grupo de logs deve começar com `/aws/lambda`. Escolha o link para o grupo de logs.

1. No console do CloudWatch, inspecione os **Eventos de logs** em busca dos eventos de log que o Lambda enviou para o fluxo de logs. Identifique se há eventos de log contendo a mensagem do seu evento do Kafka, como na imagem a seguir. Se houver, você conectou com êxito uma função do Lambda ao Amazon MSK com um mapeamento de origem de eventos do Lambda.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/msk_tut_log.png)

# Usar o Lambda com o Apache Kafka autogerenciado
<a name="with-kafka"></a>

Este tópico descreve como usar o Lambda com um cluster Kafka autogerenciado. Na terminologia da AWS, um cluster autogerenciado inclui clusters do Kafka não hospedados pela AWS. Por exemplo, você pode hospedar seu cluster do Kafka com um provedor de nuvem, como [Confluent Cloud](https://www.confluent.io/confluent-cloud/) ou [Redpanda](https://www.redpanda.com/).

Este capítulo explica como usar um cluster do Apache Kafka autogerenciado como origem do evento para a função do Lambda. O processo geral de integração do Apache Kafka autogerenciado com o Lambda envolve as seguintes etapas:

1. **[Configuração de cluster e rede](with-kafka-cluster-network.md)**: primeiro, configure seu cluster do Apache Kafka autogerenciado com a configuração de rede correta para permitir que o Lambda acesse seu cluster.

1. **[Configuração do mapeamento da origem do evento](with-kafka-configure.md)**: depois, crie o recurso de [mapeamento da origem do evento](invocation-eventsourcemapping.md) de que o Lambda precisa para se conectar ao cluster Apache Kafka à função com segurança.

1. **[Configuração da função e das permissões](with-kafka-permissions.md)**: por fim, certifique-se de que a função esteja configurada corretamente e tenha as permissões exigidas em seu [perfil de execução](lambda-intro-execution-role.md).

O Apache Kafka como uma fonte de eventos opera de forma semelhante ao uso do Amazon Simple Queue Service (Amazon SQS) ou do Amazon Kinesis. O Lambda pesquisa internamente por novas mensagens da origem do evento e, em seguida, chama de forma síncrona a função do Lambda de destino. O Lambda lê as mensagens em lotes e fornece estas para a sua função como uma carga de eventos. O tamanho máximo do lote é configurável (o padrão é 100 mensagens). Para obter mais informações, consulte [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

Para otimizar o throughput do mapeamento da origem de eventos do Apache Kafka autogerenciado, configure o modo provisionado. No modo provisionado, você pode definir o número mínimo e máximo de agentes de sondagem de eventos alocados para o mapeamento da origem de eventos. Isso pode melhorar a capacidade do mapeamento da origem de eventos para lidar com picos inesperados de mensagens. Para obter mais informações, consulte [ modo provisionado](kafka-scaling-modes.md#kafka-provisioned-mode).

**Atenção**  
Os mapeamentos da origem do evento do Lambda processam cada evento ao menos uma vez, podendo haver o processamento duplicado de registros. Para evitar possíveis problemas relacionados a eventos duplicados, é altamente recomendável tornar o código da função idempotente. Para saber mais, consulte [Como tornar minha função do Lambda idempotente](https://repost.aws/knowledge-center/lambda-function-idempotent) no Centro de Conhecimentos da AWS.

Para fontes de eventos baseadas em Kafka, o Lambda oferece suporte a parâmetros de controle de processamento, como janelas de lotes e tamanho do lote. Para obter mais informações, consulte [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

Para obter um exemplo de como usar o Kafka autogerenciado como uma fonte de eventos, consulte [Usar o Apache Kafka auto-hospedado como uma fonte de eventos para o AWS Lambda](https://aws.amazon.com/blogs/compute/using-self-hosted-apache-kafka-as-an-event-source-for-aws-lambda/) no Blog de computação da AWS.

**Topics**
+ [Evento de exemplo](#smaa-sample-event)
+ [Configurar o cluster do Apache Kafka autogerenciado e a rede do Lambda](with-kafka-cluster-network.md)
+ [Configurar as permissões do perfil de execução do Lambda](with-kafka-permissions.md)
+ [Configurar origens de eventos do Apache Kafka autogerenciado para o Lambda](with-kafka-configure.md)

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

O Lambda envia o lote de mensagens no parâmetro de evento quando ele invoca sua função do Lambda. O payload do evento contém uma matriz de mensagens. Cada item da matriz contém detalhes do tópico do Kafka e do identificador de partição do Kafka, juntamente com um carimbo de data/hora e uma mensagem codificada em 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
                  ]
               }
            ]
         }
      ]
   }
}
```

# Configurar o cluster do Apache Kafka autogerenciado e a rede do Lambda
<a name="with-kafka-cluster-network"></a>

Para conectar a função do Lambda ao cluster do Apache Kafka autogerenciado, é preciso configurar corretamente o cluster e a rede em que ele reside. Esta página descreve como configurar o cluster e a rede. Se o cluster e a rede já estiverem configurados corretamente, consulte [Configurar origens de eventos do Apache Kafka autogerenciado para o Lambda](with-kafka-configure.md) para configurar o mapeamento da origem do evento.

**Topics**
+ [Configuração do cluster do Apache Kafka autogerenciado](#kafka-cluster-setup)
+ [Configuração da segurança de rede](#services-kafka-vpc-config)

## Configuração do cluster do Apache Kafka autogerenciado
<a name="kafka-cluster-setup"></a>

Você pode hospedar seu cluster do Apache Kafka autogerenciado com provedores de nuvem, como [Confluent Cloud](https://www.confluent.io/confluent-cloud/) ou [Redpanda](https://www.redpanda.com/), ou executá-lo em sua própria infraestrutura. Certifique-se de que seu cluster esteja devidamente configurado e acessível a partir da rede à qual seu mapeamento da origem do evento Lambda se conectará.

## Configuração da segurança de rede
<a name="services-kafka-vpc-config"></a>

Para conceder ao Lambda acesso total ao Apache Kafka autogerenciado por meio do mapeamento da origem do evento, seu cluster deve usar um endpoint público (endereço IP público) ou você deve fornecer acesso à Amazon VPC na qual o cluster foi criado.

Ao usar o Apache Kafka autogerenciado com o Lambda, recomendamos a criação de [endpoints de VPC do AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html) para conceder acesso da sua função aos recursos na sua Amazon VPC.

**nota**  
Os endpoints de VPC do AWS PrivateLink são necessários para funções com mapeamentos da origem de eventos que usam o modo padrão (sob demanda) para pesquisadores de eventos. Se o mapeamento da origem do evento usa o [modo provisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode), você não precisa configurar endpoints de VPC do AWS PrivateLink.

Crie um endpoint para fornecer acesso aos seguintes recursos:
+  Lambda: crie um endpoint para a entidade principal de serviço do Lambda. 
+  AWS STS: crie um endpoint para o AWS STS com a finalidade de possibilitar que uma entidade principal de serviço assuma um perfil em seu nome. 
+  Secrets Manager: caso o seu cluster use o Secrets Manager para armazenar credenciais, crie um endpoint específico para o Secrets Manager. 

Como alternativa, configure um gateway NAT em cada sub-rede pública da Amazon VPC. Para obter mais informações, consulte [Habilitar o acesso à Internet para funções do Lambda conectadas à VPC](configuration-vpc-internet.md).

Ao criar um mapeamento da origem do evento para o Apache Kafka autogerenciado, o Lambda verifica se as interfaces de rede elástica (ENIs) já estão presentes nas sub-redes e nos grupos de segurança configurados para a Amazon VPC. Se o Lambda encontrar ENIs existentes, ele tentará reutilizá-las. Caso contrário, o Lambda criará novas ENIs para se conectar à origem do evento e invocar sua função.

**nota**  
As funções do Lambda sempre são executadas em VPCs de propriedade do serviço Lambda. A configuração de VPC da sua função não afetará o mapeamento da origem do evento. Somente a configuração de rede da origem dos eventos determina como o Lambda estabelece conexão com a origem dos eventos.

Configure os grupos de segurança para a Amazon VPC que contém o cluster. Por padrão, o Apache Kafka autogerenciado usa a seguinte porta: `9092`.
+ Regras de entrada: permitem todo o tráfego na porta padrão do agente para o grupo de segurança associado à origem dos eventos. Como alternativa, é possível usar uma regra de grupo de segurança autorreferenciada para permitir o acesso de instâncias dentro do mesmo grupo de segurança.
+ Regras de saída: permitir todo o tráfego na porta `443` para destinos externos se sua função precisar se comunicar com serviços da AWS. Como alternativa, você também poderá usar uma regra de grupo de segurança autorreferenciada para limitar o acesso ao operador se não precisar se comunicar com outros serviços AWS.
+ Regras de entrada para o endpoint da Amazon VPC: caso você esteja usando um endpoint da Amazon VPC, o grupo de segurança associado ao endpoint da Amazon VPC deve permitir o tráfego de entrada na porta `443` usando o grupo de segurança do cluster.

Caso o cluster use autenticação, é possível restringir a política de endpoint para o endpoint do Secrets Manager. Para chamar a API do Secrets Manager, o Lambda usa seu perfil de função, e não a entidade principal de serviço do Lambda.

**Example Política de endpoint da VPC: endpoint do 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"
          }
      ]
  }
```

Quando você usa os endpoints da Amazon VPC, a AWS roteia suas chamadas de API para invocar sua função usando a interface de rede elástica (ENI) do endpoint. A entidade principal do serviço Lambda precisa chamar `lambda:InvokeFunction` para quaisquer perfis e funções que usem essas ENIs.

Por padrão, os endpoints da Amazon VPC têm políticas do IAM abertas que permitem amplo acesso aos recursos. A prática recomendada é restringir essas políticas para executar as ações necessárias usando esse endpoint. Para garantir que seu mapeamento da origem do evento seja capaz de invocar sua função do Lambda, a política de endpoint da VPC deve permitir que a entidade principal do serviço Lambda chame `sts:AssumeRole` e `lambda:InvokeFunction`. A restrição de suas políticas de endpoint da VPC para permitir apenas chamadas de API originadas em sua organização impedirá o funcionamento adequado do mapeamento da origem do evento; portanto, `"Resource": "*"` é necessário nessas políticas.

O seguinte exemplo de políticas de endpoint da VPC mostra como conceder o acesso necessário à entidade principal do serviço Lambda para os endpoints do AWS STS e Lambda.

**Example Política de endpoint da VPC: endpoint do AWS STS**  

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

**Example Política de endpoint da VPC: endpoint do Lambda**  

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

# Configurar as permissões do perfil de execução do Lambda
<a name="with-kafka-permissions"></a>

Além de [acessar seu cluster autogerenciado do Kafka](kafka-cluster-auth.md), sua função do Lambda necessita de permissões para executar várias ações da API. Adicione essas permissões à [função de execução](lambda-intro-execution-role.md) da função. Se os usuários precisarem acessar alguma ação da API, adicione as permissões necessárias à política de identidade para o usuário ou a função do AWS Identity and Access Management (IAM).

**Topics**
+ [Permissões de função do Lambda necessárias](#smaa-api-actions-required)
+ [Permissões de função do Lambda opcionais](#smaa-api-actions-optional)
+ [Adicionar permissões à sua função de execução](#smaa-permissions-add-policy)
+ [Conceder acesso aos usuários com uma política do IAM](#smaa-permissions-add-users)

## Permissões de função do Lambda necessárias
<a name="smaa-api-actions-required"></a>

Para criar e armazenar logs em um grupo de logs do Amazon CloudWatch Logs, sua função Lambda deve ter as seguintes permissões na função de execução:
+ [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)

## Permissões de função do Lambda opcionais
<a name="smaa-api-actions-optional"></a>

Sua função Lambda também pode precisar dessas permissões para:
+ Descreva o segredo do Secrets Manager.
+ Acessar a chave gerenciada pelo cliente AWS Key Management Service (AWS KMS)
+ Acesse sua Amazon VPC.
+ Enviar registros de invocações com falha para um destino

### Secrets Manager e permissões do AWS KMS
<a name="smaa-api-actions-secrets"></a>

Conforme o tipo de controle de acesso que você está configurando para seus agentes do Kafka, sua função Lambda poderá precisar de permissão para acessar seu segredo do Secrets Manager ou descriptografar sua chave do AWS KMS gerenciada pelo cliente. Para acessar esses recursos, a função de execução da função precisa ter as seguintes permissões:
+ [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)

### Permissões da VPC
<a name="smaa-api-actions-vpc"></a>

Se somente usuários dentro de uma VPC puderem acessar seu cluster do Apache Kafka autogerenciado, a função Lambda deverá ter permissão para acessar seus recursos da Amazon VPC. Esses recursos incluem sua VPC, sub-redes, security groups e interfaces de rede. Para acessar esses recursos, a função de execução da função precisa ter as seguintes permissões:
+ [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)

## Adicionar permissões à sua função de execução
<a name="smaa-permissions-add-policy"></a>

Para acessar outros serviços da AWS que seu cluster autogerenciado do Apache Kafka usa, o Lambda utiliza as políticas de permissão que você define na [função de execução](lambda-intro-execution-role.md) da função do Lambda.

Por padrão, o Lambda não pode executar as ações obrigatórias ou opcionais para um cluster do Apache Kafka autogerenciado. Você deve criar e definir essas ações em uma [política de confiança do IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_update-role-trust-policy.html) para seu perfil de execução. Este exemplo mostra como criar uma política que permita que o Lambda acesse seus recursos da Amazon VPC.

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

****  

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

------

## Conceder acesso aos usuários com uma política do IAM
<a name="smaa-permissions-add-users"></a>

Por padrão, usuários e perfis não têm permissão para executar [operações de API de origem de eventos](invocation-eventsourcemapping.md#event-source-mapping-api). Para conceder acesso a usuários de sua organização ou conta, crie ou atualize uma política baseada em identidades. Para obter mais informações, consulte [Controlar o acesso aos recursos da AWS usando políticas](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_controlling.html) no *Manual do usuário do IAM*.

Para solução de problemas de erros comuns de autenticação e de autorização, consulte [Solução de problemas de erros do mapeamento da origem do evento do Kafka](with-kafka-troubleshoot.md).

# Configurar origens de eventos do Apache Kafka autogerenciado para o Lambda
<a name="with-kafka-configure"></a>

Para usar um cluster do Apache Kafka autogerenciado como origem de eventos para a função do Lambda, você deve criar um [mapeamento da origem do evento](invocation-eventsourcemapping.md) que conecta os dois recursos. Esta página descreve como criar um mapeamento da origem do evento para o Apache Kafka autogerenciado.

Esta página pressupõe que você já configurou adequadamente o cluster do Kafka e em que ele reside. Se você precisar configurar seu cluster ou sua rede, consulte [Configurar o cluster do Apache Kafka autogerenciado e a rede do Lambda](with-kafka-cluster-network.md).

**Topics**
+ [Como usar um cluster do Apache Kafka autogerenciado como uma origem do evento](#kafka-esm-overview)
+ [Configurar métodos de autenticação de cluster no Lambda](kafka-cluster-auth.md)
+ [Criar um mapeamento da origem do evento do Lambda para uma origem de evento do Apache Kafka autogerenciado](kafka-esm-create.md)
+ [Todos os parâmetros de configuração da origem do evento do Apache Kafka autogerenciado no Lambda](kafka-esm-parameters.md)

## Como usar um cluster do Apache Kafka autogerenciado como uma origem do evento
<a name="kafka-esm-overview"></a>

Quando você adiciona seu cluster do Apache Kafka ou do Amazon MSK como um gatilho para a função do Lambda, o cluster é usado como uma [origem de eventos](invocation-eventsourcemapping.md).

O Lambda lê os dados de eventos dos tópicos do Kafka que você especifica como `Topics` em uma solicitação de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) com base na [posição inicial](kafka-starting-positions.md) especificada. Após o processamento bem-sucedido, seu tópico do Kafka é confirmado no cluster do Kafka.

O Lambda lê as mensagens sequencialmente para cada partição de tópico do Kafka. Uma única carga do Lambda pode conter mensagens de várias partições. Quando mais registros ficam disponíveis, o Lambda continua processando os registros em lotes, com base no valor de BatchSize especificado na solicitação de [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html), até a função estar atualizada com o tópico.

Depois que o Lambda processa cada lote, ele confirma os deslocamentos das mensagens nesse lote. Se sua função retorna um erro para qualquer uma das mensagens em um lote, o Lambda tenta novamente todo o lote de mensagens até que o processamento seja bem-sucedido ou as mensagens expiram. É possível enviar registros que apresentaram falha em todas as tentativas a um destino em caso de falha para processamento posterior.

**nota**  
Embora as funções do Lambda normalmente tenham um limite máximo de tempo de 15 minutos, os mapeamentos da origem dos eventos para o Amazon MSK, o Apache Kafka autogerenciado, o Amazon DocumentDB e o Amazon MQ para ActiveMQ e RabbitMQ são compatíveis somente com funções com limites máximos de tempo limite de 14 minutos.

# Configurar métodos de autenticação de cluster no Lambda
<a name="kafka-cluster-auth"></a>

O Lambda suporta vários métodos para autenticar com seu cluster Apache Kafka autogerenciado. Configure o cluster Kafka para utilizar um dos métodos de autenticação compatíveis. Para obter mais informações sobre a segurança do Kafka, consulte a seção [Segurança](http://kafka.apache.org/documentation.html#security) da documentação do Kafka.

## Autenticação SASL/SCRAM
<a name="smaa-auth-sasl"></a>

O Lambda oferece suporte à autenticação Simple Authentication e Security Layer/Salted Challenge Response Authentication Mechanism (SASL/SCRAM) com criptografia (`SASL_SSL`) Transport Layer Security (TLS). O Lambda envia as credenciais criptografadas para autenticar com o cluster. O Lambda não oferece suporte a SASL/SCRAM com texto simples (`SASL_PLAINTEXT`). Para obter mais informações sobre a autenticação do SASL/SCRAM, consulte [RFC 5802](https://tools.ietf.org/html/rfc5802).

O Lambda também oferece suporte à autenticação SASL/PLAIN. Como esse mecanismo usa credenciais de texto não criptografado, a conexão com o servidor deve usar criptografia TLS para garantir que as credenciais sejam protegidas.

Para a autenticação SASL, armazene as credenciais de login como um segredo no AWS Secrets Manager. Para obter mais informações sobre o uso do Secrets Manager, consulte [Create an AWS Secrets Manager secret](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html) no *AWS Secrets Manager User Guide*.

**Importante**  
Para usar o Secrets Manager para autenticação, os segredos devem estar armazenados na mesma região da AWS que sua função do Lambda.

## Autenticação TLS mútua
<a name="smaa-auth-mtls"></a>

O TLS mútuo (mTLS) fornece autenticação bidirecional entre o cliente e o servidor. O cliente envia um certificado ao servidor para que o servidor verifique o cliente, e o servidor envia um certificado ao cliente para que o cliente verifique o servidor. 

No Apache Kafka autogerenciado, o Lambda atua como cliente. Você configura um certificado de cliente (como um segredo no Secrets Manager) para autenticar o Lambda com os agentes do Kafka. O certificado do cliente deve ser assinado por uma autoridade de certificação no armazenamento de confiança do servidor.

O cluster do Kafka envia um certificado de servidor ao Lambda para autenticar os agentes do Kafka com o Lambda. O certificado do servidor pode ser um certificado CA público ou um certificado de CA privado/autoassinado. O certificado CA público deve ser assinado por uma autoridade de certificação (CA) que esteja no repositório de confiança do Lambda. Para um certificado CA privado/autoassinado, configure o certificado CA raiz do servidor (como um segredo no Secrets Manager). O Lambda usa o certificado raiz para verificar os agentes do Kafka.

Para obter mais informações sobre o 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) (Introdução à autenticação TLS mútua para o Amazon MSK como fonte de eventos).

## Configurar o segredo do certificado do cliente
<a name="smaa-auth-secret"></a>

O segredo CLIENT\$1CERTIFICATE\$1TLS\$1AUTH requer um campo de certificado e um campo de chave privada. Para uma chave privada criptografada, o segredo requer uma senha de chave privada. Tanto o certificado como a chave privada devem estar no formato PEM.

**nota**  
O Lambda oferece suporte a algoritmos de criptografia de chave privada [PBES1](https://datatracker.ietf.org/doc/html/rfc2898/#section-6.1) (mas não PBES2).

O campo certificate (certificado) deve conter uma lista de certificados, começando pelo certificado do cliente, seguido por quaisquer certificados intermediários e terminando com o certificado raiz. Cada certificado deve iniciar em uma nova linha com a seguinte estrutura:

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

O Secrets Manager oferece suporte a segredos de até 65.536 bytes, que é espaço suficiente para cadeias de certificados longas.

A chave privada deve estar no formato [PKCS \$18](https://datatracker.ietf.org/doc/html/rfc5208), com a seguinte estrutura:

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

Para uma chave privada criptografada, use a seguinte estrutura:

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

O exemplo a seguir exibe o conteúdo de um segredo para autenticação mTLS usando uma chave privada criptografada. Para uma chave privada criptografada, inclua a senha de chave privada no segredo.

```
{"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-----"
}
```

## Configurar o segredo do certificado CA raiz do servidor
<a name="smaa-auth-ca-cert"></a>

Crie esse segredo se seus agentes do Kafka usarem criptografia TLS com certificados assinados por uma CA privada. É possível usar criptografia TLS para autenticação de VPC, SASL/SCRAM, SASL/PLAIN ou mTLS.

O segredo do certificado CA raiz do servidor requer um campo que contenha o certificado CA raiz do agente do Kafka no formato PEM. O exemplo a seguir exibe a estrutura do segredo.

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

# Criar um mapeamento da origem do evento do Lambda para uma origem de evento do Apache Kafka autogerenciado
<a name="kafka-esm-create"></a>

Para criar um mapeamento da origem do evento, você pode usar o console do Lambda, a [AWS Command Line Interface (CLI)](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) ou um [SDK da AWS](https://aws.amazon.com/getting-started/tools-sdks/).

As etapas do console a seguir adicionam um cluster do Apache Kafka autogerenciado como acionador da função do Lambda. Nos bastidores, isso cria um recurso de mapeamento da origem do evento.

## Pré-requisitos
<a name="kafka-esm-prereqs"></a>
+ Um cluster Apache Kafka autogerenciado. O Lambda é compatível com o Apache Kafka versão 0.10.1.0 e posteriores.
+ Uma [função de execução](lambda-intro-execution-role.md) com permissão para acessar os recursos da AWS que o cluster do Kafka autogerenciado usa.

## Adicionando um cluster Kafka autogerenciado (console)
<a name="kafka-esm-console"></a>

Siga estas etapas para adicionar seu cluster autogerenciado do Apache Kafka e um tópico do Kafka como um acionador para sua função do Lambda.

**Para adicionar um acionador do Apache Kafka à sua função do Lambda (console)**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Escolha o nome da função do Lambda.

1. Em **Visão geral da função**, escolha **Adicionar gatilho**.

1. Em **Trigger configuration** (Configuração do acionador), faça o seguinte:

   1. Selecione o tipo de acionadro **Apache Kafka**.

   1. Para **Servidores de bootstrap**, insira o endereço de host e par de portas de um corretor Kafka em seu cluster e escolha **Adicionar**. Repita para cada agente da Kafka no cluster.

   1. Em **Nome do tópico**, insira o nome do tópico do Kafka usado para armazenar registros no cluster.

   1. Se você configurar o modo provisionado, insira um valor para **Mínimo de agentes de sondagem de eventos**, um valor para **Máximo de agentes de sondagem de eventos** e um valor opcional para PollerGroupName para especificar o agrupamento de vários ESMs na mesma VPC de origem dos eventos.

   1. (Opcional) Em **Tamanho do lote**, insira o número máximo de registros a serem recebidos em um único lote.

   1. Em **Batch window** (Janela de lote), insira o tempo máximo em segundos usado pelo Lambda para coletar os registros antes de invocar a função.

   1. (Opcional) em **Consumer group ID** (ID do grupo de consumidores), insira o ID de um grupo de consumidores do Kafka no qual ingressar.

   1. (Opcional) Em **Posição inicial**, escolha **Mais recente** para começar a realizar a leitura do fluxo a partir do registro mais recente, **Horizonte de corte** para começar no registro mais antigo disponível ou **No timestamp** para especificar um timestamp para começar a realizar a leitura.

   1. (Opcional) Em **VPC**, escolha a Amazon VPC para seu cluster do Kafka. Em seguida, escolha **VPC subnets** (Sub-redes da VPC) e **VPC security groups** (Grupos de segurança da VPC).

      Essa configuração será necessária se apenas os usuários da VPC acessarem seus agentes.

      

   1. (Opcional) Em **Authentication** (Autenticação), escolha **Add** (Adicionar) e faça o seguinte:

      1. Escolha o protocolo de acesso ou a autenticação dos agentes do Kafka no cluster.
         + Se o agente do Kafka usar autenticação SASL/PLAIN, escolha **BASIC\$1AUTH**.
         + Se seu agente usar autenticação SASL/SCRAM, escolha um dos protocolos **SASL\$1SCRAM**.
         + Se estiver configurando a autenticação mTLS, escolha o protocolo **CLIENT\$1CERTIFICATE\$1TLS\$1AUTH**.

      1. Para a autenticação SASL/SCRAM ou mTLS, escolha a chave secreta do Secrets Manager que contém as credenciais de seu cluster do Kafka.

   1. (Opcional) Em **Encryption** (Criptografia), escolha o segredo do Secrets Manager que contém o certificado CA raiz que seus agentes do Kafka usam para criptografia TLS, se seus agentes do Kafka usarem certificados assinados por uma CA privada.

      Essa configuração se aplica à criptografia TLS para SASL/SCRAM ou SASL/PLAIN e à autenticação MTLs.

   1. Para criar o gatilho em um estado desativado para teste (recomendado), desmarque **Ativar gatilho**. Ou, para habilitar o gatilho imediatamente, selecione **Ativar gatilho**.

1. Para criar o acionador, selecione **Add** (Adicionar).

## Adicionando um cluster Kafka autogerenciado (AWS CLI)
<a name="kafka-esm-cli"></a>

Use os comandos de exemplo da AWS CLI a seguir para criar e visualizar um acionador autogerenciado do Apache Kafka para sua função do Lambda.

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

Se usuários do Kafka acessarem seus agentes do Kafka pela Internet, especifique o segredo do Secrets Manager criado para autenticação SASL/SCRAM. O exemplo a seguir usa o comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) da AWS CLI para mapear uma função do Lambda chamada `my-kafka-function` em um tópico do Kafka chamado `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"]}}'
```

### Usar uma VPC
<a name="kafka-esm-cli-create-vpc"></a>

Se apenas os usuários do Kafka em sua VPC acessarem seus agentes do Kafka, você deverá especificar sua VPC, suas sub-redes e seu grupo de segurança da VPC. O exemplo a seguir usa o comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) da AWS CLI para mapear uma função do Lambda chamada `my-kafka-function` em um tópico do Kafka chamado `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"]}}'
```

### Visualizar o status usando a AWS CLI
<a name="kafka-esm-cli-view"></a>

O exemplo a seguir usa o comando [get-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-event-source-mapping.html) da AWS CLI para descrever o status do mapeamento da origem do evento que você criou.

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

# Todos os parâmetros de configuração da origem do evento do Apache Kafka autogerenciado no Lambda
<a name="kafka-esm-parameters"></a>

Todos os tipos de origem de evento Lambda compartilham o mesmo[CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html)e[UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html)Operações de API do. Porém, apenas alguns dos parâmetros se aplicam ao Apache Kafka autogerenciado, como mostra a tabela a seguir.


| Parâmetro | Obrigatório | Padrão | Observações | 
| --- | --- | --- | --- | 
|  BatchSize  |  N  |  100  |  Máximo: 10.000.  | 
|  DestinationConfig  |  N  |  N/D  |  [Capturar lotes descartados para uma origem do evento do Amazon MSK e do Apache Kafka autogerenciado](kafka-on-failure.md)  | 
|  Habilitado  |  N  |  Verdadeiro  |  | 
|  FilterCriteria  |  N  |  N/D  |  [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md)  | 
|  FunctionName  |  S  |  N/D  |    | 
|  KMSKeyArn  |  N  |  N/D  |  [Criptografia de critérios de filtro](invocation-eventfiltering.md#filter-criteria-encryption)  | 
|  MaximumBatchingWindowInSeconds  |  N  |  500 ms  |  [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching)  | 
|  ProvisionedPollersConfig  |  N  |  `MinimumPollers`: o valor padrão será 1 se não for especificado. `MaximumPollers`: o valor padrão será 200 se não for especificado. `PollerGroupName`: N/D  |  [Modo provisionado](kafka-scaling-modes.md#kafka-provisioned-mode)  | 
|  SelfManageDeventSource  |  S  | N/D |  Lista de corretores Kafka. Pode definir apenas em Criar  | 
|  SelfManagedKafkaEventSourceConfig  |  N  |  Contém o campo ConsumerGroupId que assume por padrão um valor exclusivo.  |  Pode definir apenas em Criar  | 
|  SourceAccessConfigurations  |  N  |  Nenhuma credencial  |  Informações da VPC ou credenciais de autenticação para o cluster   Para SASL\$1PLAIN, defina como BASIC\$1AUTH  | 
|  StartingPosition  |  S  |  N/D  |  AT\$1TIMESTAMP, TRIM\$1HORIZON, ou LATEST Pode definir apenas em Criar  | 
|  StartingPositionTimestamp  |  N  |  N/D  |  Obrigatório se StartingPosition estiver definido como AT\$1TIMESTAMP  | 
|  Tags  |  N  |  N/D  |  [Uso de tags em mapeamentos da origem do evento](tags-esm.md)  | 
|  Tópicos  |  S  |  N/D  |  Nome do tópico Pode definir apenas em Criar  | 

**nota**  
Quando você especifica um `PollerGroupName`, vários ESMs dentro da mesma Amazon VPC podem compartilhar a capacidade da unidade de sondagem de evento (EPU). É possível usar essa opção para otimizar os custos do modo provisionado para seus ESMs. Requisitos para o agrupamento de ESM:  
Os ESMs devem estar na mesma Amazon VPC
Máximo de 100 ESMs por grupo de agentes de sondagem
O máximo agregado de agentes de sondagem em todos os ESMs em um grupo não pode exceder a 2.000
É possível atualizar o `PollerGroupName` para mover um ESM para um grupo diferente ou remover um ESM de um grupo configurando `PollerGroupName` como uma string vazia (“”).

# Modos de escalabilidade de sondagem de eventos do Apache Kafka no Lambda
<a name="kafka-scaling-modes"></a>

É possível escolher entre dois modos de escalabilidade de sondagem de eventos para o mapeamento da origem do evento do Apache Kafka autogerenciado:
+ [Modo sob demanda (padrão)](#kafka-default-mode)
+ [Modo provisionado](#kafka-provisioned-mode)

## Modo sob demanda (padrão)
<a name="kafka-default-mode"></a>

Quando você cria inicialmente uma origem do evento do Kafka, o Lambda aloca um número padrão de sondagem de eventos para processar todas as partições no tópico do Kafka. O Lambda aumenta ou diminui automaticamente o número de [agentes de sondagem de eventos](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode) com base na carga de mensagens.

A cada um minuto, o Lambda avalia o atraso de deslocamento de todas as partições do tópico. Se o atraso de deslocamento for muito alto, a partição está recebendo mensagens mais rápido do que o Lambda pode processá-las. Se necessário, o Lambda adiciona ou remove os agentes de sondagem de eventos do tópico. Esse processo de ajuste de escala automático para adicionar ou remover agentes de sondagem de eventos ocorre em até três minutos após a avaliação.

Se a função do Lambda de destino sofrer um controle de utilização, o Lambda reduzirá o número de agentes de sondagem de eventos. Essa ação reduz a workload na função, reduzindo o número de mensagens que os agentes de sondagem de eventos podem recuperar e enviar para a função.

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

Para workloads em que você precisa ajustar o throughput do mapeamento da origem de eventos, você pode usar o modo provisionado. No modo provisionado, você define limites mínimos e máximos para a quantidade de agentes de sondagem de eventos provisionados. Esses agentes de sondagem de eventos provisionados são dedicados ao mapeamento da origem do evento e podem lidar com picos inesperados de mensagens por meio do ajuste de escala automático responsivo. Recomendamos que você use o modo provisionado para workloads do Kafka que tenham requisitos rigorosos de performance.

No Lambda, um agente de sondagem de eventos é uma unidade computacional com recursos de throughput que variam de acordo com o tipo da origem do evento. Para o Amazon MSK e o Apache Kafka autogerenciado, cada agente de sondagem de eventos pode lidar com até 5 MB/seg de throughput, ou até 5 invocações simultâneas. Por exemplo, se sua origem de eventos produzir uma carga útil média de 1 MB e a duração média de sua função for de 1 segundo, um único agente de sondagem de eventos do Kafka poderá oferecer suporte a um throughput de 5 MB/seg e 5 invocações do Lambda simultâneas (supondo que não haja transformação da carga útil). Para o Amazon SQS, cada agente de sondagem de eventos pode lidar com até 1 MB/s de throughput, ou até 10 invocações simultâneas. O uso do modo provisionado incorre em custos adicionais com base no uso do agente de sondagem de eventos. Para obter detalhes de preço, consulte [Definição de preço do AWS Lambda](https://aws.amazon.com/lambda/pricing/).

**nota**  
Ao usar o modo provisionado, você não precisa criar endpoints da VPC do AWS PrivateLink nem conceder as permissões associadas como parte da sua configuração de rede.

No modo provisionado, o intervalo de valores aceitos para o número mínimo de agentes de sondagem de eventos (`MinimumPollers`) está entre 1 e 200, inclusive. O intervalo de valores aceitos para o número máximo de agentes de sondagem de eventos (`MaximumPollers`) está entre 1 e 2.000, inclusive. O valor de `MaximumPollers` deve ser maior que ou igual ao valor de `MinimumPollers`. Além disso, para manter o processamento ordenado nas partições, o Lambda limita o valor de `MaximumPollers` ao número de partições no tópico.

Para obter mais detalhes sobre como escolher valores mínimo e máximo apropriados de agentes de sondagem de eventos, consulte [Práticas recomendadas](#kafka-provisioned-mode-bp).

É possível configurar o modo provisionado para o mapeamento da origem do evento do Kafka usando o console ou a API do Lambda.

**Para configurar o modo provisionado para um mapeamento da origem do evento existente (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha a função com o mapeamento da origem do evento para a qual você deseja configurar o modo provisionado.

1. Escolha **Configuração** e, em seguida, escolha **Acionadores**.

1. Escolha o mapeamento da origem do evento para o qual você deseja configurar o modo provisionado e selecione **Editar**.

1. Em **Modo provisionado**, selecione **Configurar**.
   + Para **Agentes de sondagem de eventos mínimos**, insira um valor entre 1 e 200. Se você não especificar um valor, o Lambda vai atribuir o valor padrão de 1.
   + Para **Agentes de sondagem de eventos máximos**, insira um valor entre 1 e 2.000. Esse valor deve ser maior ou igual ao seu valor para **Agentes de sondagem de eventos mínimos**. Se você não especificar um valor, o Lambda vai atribuir o valor padrão de 200.

1. Escolha **Salvar**.

É possível configurar o modo provisionado programaticamente usando o objeto [ProvisionedPollerConfig](https://docs.aws.amazon.com/lambda/latest/api/API_ProvisionedPollerConfig.html) em seu [ EventSourceMappingConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_EventSourceMappingConfiguration.html). Por exemplo, o comando da CLI [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) a seguir configura um valor de 5 para `MinimumPollers` e um valor de 100 para `MaximumPollers`.

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

Depois de configurar o modo provisionado, você pode observar o uso de agentes de sondagem de eventos para sua workload monitorando a métrica `ProvisionedPollers`. Para obter mais informações, consulte [Métricas de mapeamento da origem do evento](monitoring-metrics-types.md#event-source-mapping-metrics).

Para desativar o modo provisionado e retornar ao modo padrão (sob demanda), você pode usar o seguinte comando da 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 '{}'
```

## Atributos avançados de tratamento de erros e performance
<a name="services-kafka-advanced-features"></a>

Para mapeamentos da origem do evento do Kafka com o modo provisionado habilitado, é possível configurar atributos adicionais para melhorar a performance e o tratamento de erros:
+ [Configurações de novas tentativas](kafka-retry-configurations.md): controle como o Lambda lida com registros falhados com o máximo de tentativas, limites de idade de registro, divisão de lotes e respostas de lote parciais.
+ [Destinos do Kafka em caso de falha](kafka-on-failure-destination.md): envie registros com falha para um tópico do Kafka para processamento ou análise posterior.

## Práticas recomendadas e considerações ao usar o modo provisionado
<a name="kafka-provisioned-mode-bp"></a>

A configuração ideal de agentes de sondagem de eventos mínimos e máximos para o mapeamento da origem de eventos depende dos requisitos de performance da sua aplicação. Recomendamos que você inicie por um mínimo padrão de agentes de sondagem de eventos para definir o perfil de performance básico. Ajuste sua configuração com base nos padrões de processamento de mensagens observados e no perfil de performance desejado.

Para workloads com tráfego intenso e necessidades rigorosas de performance, aumente o número mínimo de agentes de sondagem de eventos para lidar com picos repentinos de mensagens. Para determinar os agentes de sondagem de eventos mínimos necessários, considere as mensagens de sua workload por segundo e o tamanho médio da carga útil e use a capacidade de throughput de um único agente de sondagem de eventos (até 5 MBps) como referência.

Para manter o processamento ordenado em uma partição, o Lambda limita o máximo de agentes de sondagem de eventos ao número de partições no tópico. Além disso, o número máximo de agentes de sondagem de eventos para os quais o mapeamento da origem de eventos pode ser escalado depende das configurações de simultaneidade da função.

Ao ativar o modo provisionado, atualize suas configurações de rede para remover os endpoints de VPC do AWS PrivateLink e as permissões associadas.

## Otimização de custos para o modo provisionado
<a name="kafka-cost-optimization"></a>

### Definição de preços do modo provisionado
<a name="kafka-provisioned-pricing"></a>

O modo provisionado é cobrado com base nos agentes de sondagem de eventos mínimos provisionados e nos agentes de sondagem de eventos consumidos durante o escalonamento automático. As cobranças são calculadas usando uma unidade de cobrança chamada unidade de sondagem de evento (EPU). Você paga pelo número e pela duração das EPUs usadas, medidas em horas da unidade de sondagem de eventos. É possível usar o modo provisionado com um único ESM para aplicações sensíveis à performance ou agrupar vários ESMs na mesma VPC para compartilhar a capacidade e os custos da EPU. Vamos nos aprofundar em dois recursos que ajudam você a otimizar seus custos do modo provisionado. Para obter detalhes da definição de preços, consulte [Definição de preços do AWS Lambda](https://aws.amazon.com/lambda/pricing/).

### Utilização aprimorada da EPU
<a name="kafka-enhanced-epu-utilization"></a>

Cada EPU oferece suporte à capacidade de throughput de até 20 MB/s para sondagem de eventos e a um padrão de 10 agentes de sondagem de eventos. Quando você cria um modo provisionado para o Kafka ESM definindo um mínimo e um máximo de agentes de sondagem, ele usa o número mínimo de agentes de sondagem para provisionar EPUs com base no padrão de 10 agentes de sondagem de eventos por EPU. No entanto, cada agente de sondagem de eventos pode ser escalado de forma independente para oferecer suporte a até 5 MB/s de capacidade de throughput, o que pode exigir menor densidade de agentes de sondagem de eventos em uma EPU específica e acionar a escalabilidade das EPUs. O número de agentes de sondagem de eventos alocados em uma EPU depende da capacidade computacional consumida por cada agente de sondagem de eventos. Essa abordagem de utilização aprimorada da EPU permite que os agentes de sondagem de eventos com requisitos de throughput variados utilizem a capacidade da EPU de forma eficaz, reduzindo os custos de todos os ESMs.

### Agrupamento de ESM
<a name="kafka-esm-grouping-cost"></a>

Para otimizar ainda mais os custos do modo provisionado, é possível agrupar vários ESMs de Kafka para compartilhar a capacidade da EPU. Com o agrupamento de ESM e a utilização aprimorada da EPU, é possível reduzir os custos do modo provisionado em até 90% para workloads de baixo throughput em comparação com a execução no modo ESM único. Todos os ESMs que exigem menos de 1 capacidade de EPU se beneficiarão do agrupamento de ESM. Esses ESMs normalmente exigem poucos agentes de sondagem de eventos mínimos para atender às suas necessidades de throughput. Esse recurso permitirá que você adote o modo provisionado para todas as suas workloads do Kafka e se beneficie de atributos como validação de esquema, filtragem de eventos Avro/Protobuf, invocações de baixa latência e tratamento aprimorado de erros, disponíveis somente no modo provisionado.

Quando você configura o parâmetro `PollerGroupName` com o mesmo valor para vários ESMs dentro da mesma Amazon VPC, esses ESMs compartilham recursos de EPU em vez de cada um exigir capacidade de EPU dedicada. É possível agrupar até 100 ESMs por grupo de agentes de sondagem e agregar o máximo de agentes de sondagem em todos os ESMs em um grupo que não pode exceder 2.000.

#### Para configurar o agrupamento de ESM (console)
<a name="kafka-esm-grouping-console-cost"></a>

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha a função.

1. Escolha **Configuração** e, em seguida, escolha **Acionadores**.

1. Ao criar um novo mapeamento da origem do evento do Kafka ou editar um existente, selecione **Configurar** no **Modo provisionado**.

1. Para **Agentes de sondagem de eventos mínimos**, insira um valor entre 1 e 200.

1. Para **Agentes de sondagem de eventos máximos**, insira um valor entre 1 e 2.000.

1. Em **Nome do grupo de agentes de sondagem**, insira um identificador para o grupo. Use o mesmo nome para outros ESMs que você deseje agrupar.

1. Escolha **Salvar**.

#### Para configurar o agrupamento de ESM (AWS CLI)
<a name="kafka-esm-grouping-cli-cost"></a>

O exemplo a seguir cria um ESM com um grupo de agentes de sondagem chamado `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 adicionar outro ESM ao mesmo grupo (compartilhando a capacidade de EPU), use o mesmo 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**  
É possível atualizar o `PollerGroupName` para mover um ESM para um grupo diferente ou remover um ESM de um grupo passando uma string vazia (“”) para `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": ""
  }'
```

#### Considerações sobre as estratégias de agrupamento
<a name="kafka-grouping-strategy-considerations"></a>
+ **Limite da aplicação**: agrupe os ESMs que pertencem às mesmas aplicações ou serviços para melhor alocação e gerenciamento de custos. Considere usar convenções de nomenclatura como `app-name-environment` (por exemplo, `order-processor-prod`).
+ **Padrão de tráfego**: evite agrupar ESMs com alto throughput e padrões de tráfego com rajadas, pois isso pode levar à contenção de recursos.
+ **Raio de explosão**: considere o impacto se a infraestrutura compartilhada tiver problemas. Todos os ESMs do mesmo grupo são afetados por limitações de recursos compartilhados. Para workloads de missão crítica, talvez você queira usar grupos separados ou ESMs dedicados.

#### Exemplo de otimização de custos
<a name="kafka-cost-optimization-example"></a>

Considere um cenário em que você tenha 10 ESMs, cada um configurado com 1 agente de sondagem de eventos e throughput abaixo de 2 MB/s:

**Sem agrupamento:**
+ Cada ESM exige sua própria EPU
+ Total de EPUs necessárias: 10
+ Custo por EPU: 0,185 USD/hora na região Leste dos EUA (Norte da Virgínia)
+ Custo mensal da EPU (720 horas): 10 × 720 × 0,185 USD = 1.332 USD

**Com agrupamento:**
+ Todos os 10 ESMs compartilham a capacidade da EPU
+ 10 agentes de sondagem de eventos cabem em 1 EPU (com o novo suporte de 10 agentes de sondagem por EPU)
+ Total de EPUs necessárias: 1
+ Custo mensal da EPU (720 horas): 1 × 720 × 0,185 USD = 133,20 USD
+ **Economia de custos: 90%** (economia de 1.198,80 USD por mês)

# Posições iniciais de sondagem e fluxo do Apache Kafka no Lambda
<a name="kafka-starting-positions"></a>

O [ parâmetro StartingPosition](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-StartingPosition) informa ao Lambda quando começar a ler as mensagens do fluxo do Amazon MSK ou do Apache Kafka autogerenciado. Existem três opções à escolha:
+ **Mais recente**: o Lambda começa a ler imediatamente depois do registro mais recente no tópico do Kafka.
+ **Horizonte de corte**: o Lambda começa a ler o tópico a partir do último registro não cortado do tópico do Kafka. Esse registro também é o mais antigo do tópico.
+ **No timestamp**: o Lambda começa a ler a partir de uma posição definida por um timestamp, em segundos de hora Unix. Use o [parâmetro StartingPositionTimestamp](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-StartingPositionTimestamp) para especificar o timestamp.

A pesquisa de fluxo durante a criação ou atualização de um mapeamento da origem do evento acaba sendo consistente:
+ Durante a criação do mapeamento da origem do evento, pode levar alguns minutos para a sondagem de eventos do fluxo iniciar.
+ Durante as atualizações do mapeamento da origem do evento, a pesquisa de eventos de fluxo pode levar até 90 minutos para parar e recomeçar.

Esse comportamento significa que, se você especificar `LATEST` como posição inicial do fluxo, o mapeamento da origem do evento poderá ignorar alguns eventos durante a criação ou a atualização. Para garantir que nenhum evento seja ignorado, especifique `TRIM_HORIZON` ou `AT_TIMESTAMP`.

# ID de grupo de consumidores personalizável no Lambda
<a name="kafka-consumer-group-id"></a>

Ao configurar o Amazon MSK ou o Apache Kafka autogerenciado como uma origem do evento, você pode especificar o ID de um [grupo de consumidores](https://developer.confluent.io/learn-more/kafka-on-the-go/consumer-groups/). Esse ID de grupo de consumidores é um identificador existente para o grupo de consumidores do Kafka no qual você deseja que a função do Lambda ingresse. Você pode usar esse recurso para migrar facilmente qualquer configuração de processamento em andamento de registros do Kafka de outros consumidores para o Lambda.

O Kafka distribui mensagens para todos os consumidores de um grupo de consumidores. Se você especificar o ID de um grupo de consumidores que tenha outros consumidores ativos, o Lambda receberá apenas uma parte das mensagens do tópico do Kafka. Se você quiser que o Lambda lide com todas as mensagens do tópico, desative todos os outros consumidores desse grupo de consumidores.

Além disso, se você especificar o ID de um grupo de consumidores e o Kafka encontrar um grupo de consumidores válido já existente com o mesmo ID, o Lambda ignorará a [StartingPosition](kafka-starting-positions.md) no mapeamento da origem do evento. Em vez disso, o Lambda começará a processar registros de acordo com o deslocamento confirmado do grupo de consumidores. Se você especificar um ID de grupo de consumidores e o Kafka não conseguir encontrar um grupo de consumidores existente, o Lambda configurará a origem de eventos com a especificada `StartingPosition`.

O ID do grupo de consumidores que você especificar deverá ser exclusivo entre todas as origens de eventos do Kafka. Após criar um mapeamento de origem de eventos do Kafka com o ID do grupo de consumidores especificado, você não poderá atualizar esse valor.

# Filtrar as origens dos eventos do Amazon MSK e do Apache Kafka autogerenciado
<a name="kafka-filtering"></a>

É possível usar filtragem de eventos para controlar quais registros de um stream ou fila que o Lambda enviará para a função. Para obter informações gerais sobre como a filtragem de eventos funciona, consulte [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md).

**nota**  
Mapeamentos da origem do evento do Amazon MSK e do Apache Kafka autogerenciado somente são compatíveis com filtragem na chave `value`.

**Topics**
+ [Fundamentos de filtragem de eventos do Kafka](#filtering-kafka)

## Fundamentos de filtragem de eventos do Kafka
<a name="filtering-kafka"></a>

Suponha que um produtor esteja escrevendo mensagens para um tópico no cluster do Kafka em um formato válido JSON ou como strings de texto simples. Um exemplo de registro seria semelhante ao a seguir, com a mensagem convertida em uma string codificada em Base64 no campo `value`.

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

Suponha que o produtor do Apache Kafka esteja escrevendo mensagens para o tópico no formato JSON a seguir.

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

É possível usar a chave `value` para filtrar registros. Suponha que você queira filtrar somente os registros onde `device_ID` comece com as letras AB. O objeto `FilterCriteria` seria como a seguir.

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

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples.

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

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

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

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

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

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

Para adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

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

------

Com o Kafka, você também pode filtrar registros quando a mensagem é uma string de texto simples. Suponha que você queira ignorar as mensagens em que a string seja “erro”. O objeto `FilterCriteria` seria como a seguir.

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

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples.

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

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

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

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

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

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

Para adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

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

------

As mensagens do Kafka devem ser strings codificadas em UTF-8, sejam em texto simples ou no formato JSON. Isso porque o Lambda decodifica as matrizes de bytes do Kafka em UTF-8 antes de aplicar os critérios do filtro. Se as mensagens usarem outra codificação, como UTF-16 ou ASCII, ou se o formato da mensagem não corresponder ao formato dos `FilterCriteria`, o Lambda processará somente os filtros de metadados. A tabela a seguir resume o comportamento específico:


| Formato do da mensagem recebida | Formato padrão de filtro para propriedades de mensagem | Ação resultante | 
| --- | --- | --- | 
|  String simples  |  String simples  |  Filtros do Lambda com base em seus critérios de filtro.  | 
|  String simples  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  String simples  |  JSON válido  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  JSON válido  |  String simples  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  JSON válido  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  JSON válido  |  JSON válido  |  Filtros do Lambda com base em seus critérios de filtro.  | 
|  String não codificada em UTF-8  |  JSON, string de texto simples ou nenhum padrão  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 

# Usar registros de esquema com origens de eventos do Kafka no Lambda
<a name="services-consume-kafka-events"></a>

 Registros de esquema ajudam a definir e gerenciar esquemas de fluxos de dados. O esquema define a estrutura e o formato de um registro de dados. No contexto de mapeamentos de origens de eventos do Kafka, é possível configurar um registro de esquema para validar a estrutura e o formato das mensagens do Kafka em relação a esquemas predefinidos antes que estas cheguem à sua função do Lambda. Isso acrescenta uma camada de governança de dados à sua aplicação e permite gerenciar formatos de dados com eficiência, garantir a conformidade do esquema e otimizar os custos por meio da filtragem de eventos. 

 Embora esse recurso funciona com todas as linguagens de programação, considere os seguintes pontos importantes: 
+ O Powertools para Lambda fornece suporte específico para Java, Python e TypeScript, mantendo a consistência com padrões de desenvolvimento existentes do Kafka e possibilitando o acesso direto a objetos de negócios sem um código de desserialização personalizado
+ Esse recurso está disponível apenas para mapeamentos de origens de eventos que usam o modo provisionado. O registro de esquema não oferece suporte a mapeamentos de origens de eventos no modo sob demanda. Se estiver usando o modo provisionado e tiver um registro de esquema configurado, você não poderá mudar para o modo sob demanda, a não ser que remova primeiro a configuração desse registro de esquema. Para obter mais informações, consulte . [Modo provisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode)
+ É possível configurar apenas um registro de esquema por mapeamento de origem do evento (ESM). Usar um registro de esquema com uma origem de evento do Kafka tem o potencial de aumentar o uso da Event Poller Unit (EPU) do Lambda, que é uma dimensão de preço para o modo Provisionado. 

**Topics**
+ [Opções para registros de esquema](#services-consume-kafka-events-options)
+ [Como o Lambda realiza a validação do esquema para mensagens do Kafka](#services-consume-kafka-events-how)
+ [Configurar um registro do esquema do Kafka](#services-consume-kafka-events-config)
+ [Filtragem para Avro e Protobuf](#services-consume-kafka-events-filtering)
+ [Formatos de cargas úteis e comportamento de desserialização](#services-consume-kafka-events-payload)
+ [Trabalhar com dados desserializados em funções do Lambda](#services-consume-kafka-events-payload-examples)
+ [Métodos de autenticação do registro de esquema](#services-consume-kafka-events-auth)
+ [Tratamento de erros e solução de problemas de registro de esquema](#services-consume-kafka-events-troubleshooting)

## Opções para registros de esquema
<a name="services-consume-kafka-events-options"></a>

 O Lambda é compatível com as seguintes opções de registros de esquema: 
+ [AWS Glue Registro de esquemas do](https://docs.aws.amazon.com/glue/latest/dg/schema-registry.html)
+ [Confluent Cloud Schema Registry](https://docs.confluent.io/platform/current/schema-registry/index.html)
+ [Confluent Schema Registry autogerenciado](https://docs.confluent.io/platform/current/schema-registry/index.html)

 Seu registro de esquema é compatível com a validação de mensagens nos seguintes formatos de dados: 
+ Apache Avro
+ Buffers de protocolo (Protobuf)
+ Esquema JSON (JSON-SE)

 Para utilizar um registro de esquema, verifique primeiro se o mapeamento da origem do evento está no modo provisionado. Quando você utiliza um registro de esquema, o Lambda adiciona metadados sobre o esquema à carga útil. Para obter mais informações, consulte [Formatos de carga útil e comportamento de desserialização](#services-consume-kafka-events-payload). 

## Como o Lambda realiza a validação do esquema para mensagens do Kafka
<a name="services-consume-kafka-events-how"></a>

 Quando você configura um registro de esquema, o Lambda realiza as seguintes etapas para cada mensagem do Kafka: 

1. O Lambda faz a sondagem do registro do Kafka do seu cluster.

1. O Lambda valida os atributos de mensagem selecionados no registro em relação a um esquema específico no registro de esquema.
   + Se o esquema associado à mensagem não for encontrado no registro, o Lambda enviará a mensagem a uma DLQ com o código do motivo `SCHEMA_NOT_FOUND`.

1. O Lambda desserializa a mensagem de acordo com a configuração do registro do esquema para validar a mensagem. Se a filtragem de eventos estiver configurada, o Lambda realizará a filtragem com base nos critérios de filtros configurados.
   + Se a desserialização falhar, o Lambda enviará a mensagem a uma DLQ com o código do motivo `DESERIALIZATION_ERROR`. Se não houver uma DLQ configurada, o Lambda descartará a mensagem.

1. Se a mensagem for validada pelo registro do esquema e não for filtrada por seus critérios de filtro, o Lambda invocará sua função com a mensagem.

 O objetivo desse recurso é validar mensagens que já foram produzidas usando clientes Kafka integrados a um registro de esquema. Recomendamos configurar seus produtores do Kafka para funcionarem com seu registro de esquema a fim de criar mensagens formatadas corretamente. 

## Configurar um registro do esquema do Kafka
<a name="services-consume-kafka-events-config"></a>

 As seguintes etapas do console adicionam uma configuração de registro do esquema do Kafka ao seu mapeamento da origem do evento. 

**Para adicionar uma configuração de registro do esquema do Kafka ao mapeamento da origem do evento (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) no console do Lambda.

1. Escolher **configuração**.

1. Escolha **Gatilhos**.

1. Selecione o mapeamento da origem do evento do Kafka para o qual você deseja configurar um registro de esquema e, em seguida, escolha **Editar**.

1. Em **Configuração do agente de sondagem de eventos**, escolha **Configurar registro de esquema**. Seu mapeamento da origem do evento deve estar no modo provisionado para você ver essa opção.

1. Em **URI do registro do esquema**, insira o ARN do registro de esquema AWS Glue ou o URL HTTPS do Confluent Cloud Schema Registry ou do Registro Confluent Schema Registry autogerenciado.

1. As etapas de configuração abaixo instruem o Lambda a acessar seu registro de esquema. Para obter mais informações, consulte [Métodos de autenticação do registro de esquema](#services-consume-kafka-events-auth).
   + Em **Tipo de configuração de acesso**, escolha o tipo de autenticação usado pelo Lambda para acessar seu registro de esquema.
   + Em **URI de configuração de acesso**, insira o ARN do segredo do Secrets Manager para autenticação com seu registro de esquema, se aplicável. Certifique-se de que o [perfil de execução](with-msk-permissions.md) da sua função contenha as permissões corretas.

1. O campo **Criptografia** apenas será aplicável se o registro do esquema for assinado por uma autoridade de certificação (CA) privada ou por uma autoridade de certificação (CA) que não esteja no repositório confiável do Lambda. Se aplicável, forneça a chave do segredo que contém o certificado da CA privada usado pelo registro de esquema para criptografia TLS.

1. Para **Formato do registro de eventos**, escolha como você deseja que o Lambda forneça os registros da sua função após a validação do esquema. Para obter mais informações, consulte [Exemplos de formatos de carga útil](#services-consume-kafka-events-payload).
   + Se você escolher **JSON**, o Lambda fornecerá os atributos selecionados no atributo de validação do esquema abaixo, no formato JSON padrão. Para os atributos não selecionados, o Lambda os fornece como estão.
   + Se você escolher **SOURCE**, o Lambda fornecerá os atributos selecionados no atributo de validação de esquema abaixo, no formato JSON padrão.

1. Para **Atributo de validação de esquema**, selecione os atributos de mensagens que você deseja que o Lambda valide e desserialize usando seu registro de esquema. É necessário selecionar pelo menos uma das opções **KEY** ou **VALUE**. Se você escolheu o JSON para o formato de registro de eventos, o Lambda também desserializa os atributos de mensagem selecionados antes de os enviar para sua função. Para obter mais informações, consulte [Formatos de carga útil e comportamento de desserialização](#services-consume-kafka-events-payload).

1. Escolha **Salvar**.

 Você também pode usar a API do Lambda para criar ou atualizar seu mapeamento de origem do evento com uma configuração de registro de esquema. Os exemplos a seguir demonstram como configurar um registro do esquema AWS Glue ou Confluent Schema Registry usando o AWS CLI, que corresponde às operações de API [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) e [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) na *Referência de APIs do AWS Lambda*: 

**Importante**  
Se estiver atualizando qualquer campo de configuração do registro do esquema usando a API AWS CLI ou `update-event-source-mapping`, você deverá atualizar todos os campos da configuração do registro de esquema.

------
#### [ 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 remover uma configuração de registro de esquema do mapeamento da origem do evento, é possível usar o comando da CLI [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) na *Referência a APIs do AWS Lambda*.

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

------

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

 Ao usar os formatos Avro ou Protobuf com um registro de esquema, você pode aplicar a filtragem de eventos à sua função do Lambda. Os padrões de filtro são aplicados à representação JSON clássica desserializada dos dados após a validação do esquema. Por exemplo, com um esquema Avro definindo detalhes de produtos, incluindo preço, você pode filtrar mensagens com base no valor de preço: 

**nota**  
 Ao ser desserializado, o Avro é convertido em JSON padrão, o que significa que não pode ser reconvertido diretamente em um objeto Avro. Se precisar converter em um objeto Avro, use o formato SOURCE em vez disso.   
 Para desserialização do Protobuf, os nomes dos campos no JSON resultante correspondem aos definidos no seu esquema, em vez de serem convertidos em camel case, como o Protobuf normalmente faz. Lembre-se disso ao criar padrões de filtragem. 

```
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\"] } }"
            }
        ]
    }'
```

 Neste exemplo, o padrão de filtro analisa o objeto `value`, combinando as mensagens no `field_1` com `"value1"` e no `field_2` com `"value2"`. Os critérios do filtro são avaliados em relação aos dados desserializados depois que o Lambda converte a mensagem do formato Avro em JSON. 

 Para obter informações mais detalhadas sobre a filtragem de eventos, consulte [Filtragem de eventos do Lambda](invocation-eventfiltering.md). 

## Formatos de cargas úteis e comportamento de desserialização
<a name="services-consume-kafka-events-payload"></a>

 Ao usar um registro de esquema, o Lambda entrega a carga útil final para sua função em um formato semelhante à [carga útil do evento regular](with-msk.md#msk-sample-event), com alguns campos adicionais. Os campos adicionais dependem do parâmetro `SchemaValidationConfigs`. Para cada atributo selecionado para validação (chave ou valor), o Lambda adiciona os metadados do esquema correspondentes à carga útil. 

**nota**  
Você deve atualizar [aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events) para a versão 3.16.0 ou superior para usar campos de metadados de esquema.

 Por exemplo, se você validar o campo `value`, o Lambda adicionará um campo chamado `valueSchemaMetadata` à sua carga útil. Da mesma forma, para o campo `key`, o Lambda adiciona um campo chamado `keySchemaMetadata`. Esses metadados contêm informações sobre o formato dos dados e o ID do esquema usado para validação: 

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

 O parâmetro `EventRecordFormat` pode ser definido como `JSON` ou `SOURCE`, o que determina como o Lambda lida com dados validados pelo esquema antes de os entregar à função. Cada opção oferece diferentes recursos de processamento: 
+ `JSON`: o Lambda desserializa os atributos validados no formato JSON padrão, preparando os dados para uso direto em linguagens com suporte nativo para JSON. Esse formato é ideal quando não é necessário preservar o formato binário original ou trabalhar com classes geradas.
+ `SOURCE`: o Lambda preserva o formato binário original dos dados como uma string codificada em Base64, possibilitando a conversão direta em objetos Avro ou Protobuf. Esse formato é essencial ao trabalhar com linguagens de tipagem forte ou quando você precisa manter todos os recursos de esquemas Avro ou Protobuf.

Com base nessas características de formato e considerações específicas de linguagem, recomendamos os seguintes formatos:


**Formatos recomendados com base na linguagem de programação**  

| Linguagem | Avro | Protobuf | JSON | 
| --- | --- | --- | --- | 
| Java | SOURCE | SOURCE | SOURCE | 
| Python | JSON | JSON | JSON | 
| NodeJS | JSON | JSON | JSON | 
| .NET | SOURCE | SOURCE | SOURCE | 
| Outros | JSON | JSON | JSON | 

As seções a seguir descrevem esses formatos em detalhes e fornecem exemplos de cargas úteis para cada um.

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

 Se você escolher `JSON` como `EventRecordFormat`, o Lambda validará e desserializará os atributos da mensagem selecionados no campo `SchemaValidationConfigs` (os atributos `key` e/ou `value`). O Lambda fornece esses atributos selecionados como strings codificadas em base64 da sua representação JSON padrão na sua função. 

**nota**  
 Ao ser desserializado, o Avro é convertido em JSON padrão, o que significa que não pode ser reconvertido diretamente em um objeto Avro. Se precisar converter em um objeto Avro, use o formato SOURCE em vez disso.   
 Para desserialização do Protobuf, os nomes dos campos no JSON resultante correspondem aos definidos no seu esquema, em vez de serem convertidos em camel case, como o Protobuf normalmente faz. Lembre-se disso ao criar padrões de filtragem. 

 O seguinte exemplo mostra uma carga útil, supondo que você escolha `JSON` como `EventRecordFormat`, e os atributos `key` e `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
                  ]
               }
            ]
         }
      ]
   }
}
```

 Neste exemplo: 
+ Tanto `key` quanto `value` são strings codificadas em base64 da sua representação JSON após a desserialização.
+ O Lambda inclui metadados de esquema para ambos os atributos em `keySchemaMetadata` e `valueSchemaMetadata`.
+ Sua função pode decodificar as strings `key` e `value` para acessar os dados JSON desserializados.

 O formato JSON é recomendado para linguagens sem tipo forte, como Python ou Node.js. Essas linguagens têm suporte nativo para converter JSON em objetos. 

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

 Se você escolher `SOURCE` como `EventRecordFormat`, o Lambda ainda validará o registro em relação ao registro de esquema, mas entregará os dados binários originais para sua função sem desserialização. Esses dados binários são fornecidos como uma string codificada em Base64 dos dados de bytes originais, com metadados anexados pelo produtor removidos. Como resultado, é possível converter diretamente os dados binários brutos em objetos Avro e Protobuf dentro do código da função. Recomendamos o uso do Powertools para AWS Lambda, que desserializará os dados binários brutos e fornecerá objetos Avro e Protobuf diretamente. 

 Por exemplo, se você configurar o Lambda para validar os atributos `key` e `value`, mas usar o formato `SOURCE`, sua função receberá uma carga útil como esta: 

```
{
    "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
                        ]
                    }
                ]
            }
        ]
    }
}
```

 Neste exemplo: 
+ Tanto `key` quanto `value` contêm os dados binários originais como strings codificadas em Base64.
+ Sua função precisa lidar com a desserialização usando as bibliotecas apropriadas.

 É recomendável escolher `SOURCE` para `EventRecordFormat` se você estiver usando objetos gerados pelo Avro ou pelo Protobuf, especialmente com funções Java. Isso porque o Java é uma linguagem com tipagem forte e requer desserializadores específicos para os formatos Avro e Protobuf. No código da função, você pode usar sua biblioteca Avro ou Protobuf preferida para desserializar os dados. 

## Trabalhar com dados desserializados em funções do Lambda
<a name="services-consume-kafka-events-payload-examples"></a>

O Powertools para AWS Lambda ajuda a desserializar registros do Kafka no código da função com base no formato em uso. Esse utilitário simplifica o trabalho com registros do Kafka, manipulando a conversão dos dados e fornecendo objetos prontos para uso.

 Para usar o Powertools para AWS Lambda em uma função, você precisa adicionar o Powertools para AWS Lambda como uma camada ou incluí-lo como uma dependência ao criar sua função do Lambda. Para obter instruções de configuração e mais informações, consulte a documentação do Powertools para AWS Lambda para sua linguagem preferida: 
+ [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**  
Ao trabalhar com a integração de registros de esquemas, você pode escolher o formato `SOURCE` ou `JSON`. Cada opção oferece suporte a diferentes formatos de serialização, conforme mostrado a seguir:  


| Formato | Suporte | 
| --- | --- | 
|  SOURCE  |  Avro e Protobuf (usando a integração de registro de esquema do Lambda)  | 
|  JSON  |  Dados JSON  | 

 Ao usar o formato `SOURCE` ou `JSON`, você pode usar o Powertools para AWS para ajudar a desserializar os dados no código da função. Estes são alguns exemplos de como lidar com diferentes formatos de dados: 

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

Exemplo 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";
    }

}
```

Exemplo do 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}")
```

Exemplo com 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,
        },
    }
);
```

Exemplo com .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 ]

Exemplo 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";
    }

}
```

Exemplo do 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}")
```

Exemplo com 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,
        },
    }
);
```

Exemplo com .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 ]

Exemplo 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";
    }
}
```

Exemplo do 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}")
```

Exemplo com 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',
        },
    }
);
```

Exemplo com .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 autenticação do registro de esquema
<a name="services-consume-kafka-events-auth"></a>

 Para usar um registro de esquema, o Lambda precisa ser capaz de acessá-lo com segurança. Se estiver trabalhando com um registro de esquema do AWS Glue, o Lambda depende da autenticação do IAM. Isso significa que a [função de execução](lambda-intro-execution-role.md) da função deve ter as seguintes permissões para acessar o registro do AWS Glue: 
+ [GetRegistry](https://docs.aws.amazon.com/glue/latest/webapi/API_GetRegistry.html) na *Referência à API da Web do AWS Glue*
+ [GetSchemaVersion](https://docs.aws.amazon.com/glue/latest/webapi/API_GetSchemaVersion.html) na *Referência à API da Web do AWS Glue*

Exemplo de política do IAM necessária: 

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

****  

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

------

**nota**  
 Para registros de esquema do AWS Glue, se você fornecer `AccessConfigs` para um registro do AWS Glue, o Lambda retornará uma exceção de validação. 

Se você estiver trabalhando com um registro de esquema Confluent, poderá escolher um dos três métodos de autenticação compatíveis para o parâmetro `Type` do objeto [KafkaSchemaRegistryAccessConfig](https://docs.aws.amazon.com/lambda/latest/api/API_KafkaSchemaRegistryAccessConfig):
+ **BASIC\$1AUTH**: o Lambda usa nome de usuário e a senha ou a autenticação de chave de API e o segredo de API para acessar seu registro. Se você escolher essa opção, forneça o ARN do Secrets Manager contendo suas credenciais no campo de URI.
+ **CLIENT\$1CERTIFICATE\$1TLS\$1AUTH**: o Lambda usa autenticação mútua TLS com certificados de cliente. Para usar essa opção, o Lambda precisa acessar o certificado e a chave privada. Forneça o ARN do Secrets Manager contendo essas credenciais no campo de URI.
+ **NO\$1AUTH**: o certificado de CA pública deve ser assinado por uma autoridade de certificação (CA) que esteja no repositório de confiança do Lambda. Para um certificado de CA privada/autoassinado, configure o certificado de CA raiz do servidor. Para usar essa opção, omita o parâmetro `AccessConfigs`.

 Além disso, se o Lambda precisar acessar um certificado de CA privada para verificar o certificado TLS do registro de esquema, escolha `SERVER_ROOT_CA_CERT` como `Type` e forneça o ARN do Secrets Manager ao certificado no campo de URI. 

**nota**  
 Para configurar a opção `SERVER_ROOT_CA_CERT` no console, forneça o ARN do segredo contendo o certificado no campo **Criptografia**. 

 A configuração de autenticação para o registro de esquema é separada de qualquer autenticação que você tenha configurado para o cluster Kafka. É necessário configurar os dois separadamente, mesmo que eles usem métodos de autenticação semelhantes. 

## Tratamento de erros e solução de problemas de registro de esquema
<a name="services-consume-kafka-events-troubleshooting"></a>

Ao usar um registro de esquema com a sua origem de evento do Amazon MSK, você pode se deparar com vários erros. Esta seção fornece orientação sobre problemas comuns e como resolvê-los.

### Erros de configuração
<a name="consume-kafka-events-troubleshooting-configuration-errors"></a>

Esses erros ocorrem ao configurar o registro de esquema.

Modo provisionado necessário  
**Mensagem de erro:** `SchemaRegistryConfig is only available for Provisioned Mode. To configure Schema Registry, please enable Provisioned Mode by specifying MinimumPollers in ProvisionedPollerConfig.`  
**Resolução:** habilite o modo provisionado para o mapeamento da origem do evento configurando o parâmetro `MinimumPollers` em `ProvisionedPollerConfig`.

URL de registro de esquema inválido  
**Mensagem de erro:** `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.`  
**Resolução:** forneça um URL HTTPS válido para o Confluent Schema Registry ou um ARN válido para o AWS Glue Schema Registry.

Formato de registro de evento inválido ou ausente  
**Mensagem de erro:** `EventRecordFormat is a required field for SchemaRegistryConfig. Please provide one of supported format types: SOURCE, JSON.`  
**Resolução:** especifique SOURCE ou JSON como o EventRecordFormat na configuração do registro de esquema.

Atributos de validação duplicados  
**Mensagem de erro:** `Duplicate KEY/VALUE Attribute in SchemaValidationConfigs. SchemaValidationConfigs must contain at most one KEY/VALUE Attribute.`  
**Resolução:** remova os atributos KEY ou VALUE duplicados dos seus SchemaValidationConfigs. Cada tipo de atributo somente pode aparecer uma vez.

Configuração de validação ausente  
**Mensagem de erro:** `SchemaValidationConfigs is a required field for SchemaRegistryConfig.`  
**Resolução:** adicione SchemaValidationConfigs à sua configuração, especificando pelo menos um atributo de validação (KEY ou VALUE).

### Erros de acesso e permissões
<a name="consume-kafka-events-troubleshooting-access-errors"></a>

Esses erros ocorrem quando o Lambda não consegue acessar o registro de esquema devido a problemas de permissão ou autenticação.

Acesso ao Registro do esquema do AWS Glue negado  
**Mensagem de erro:** `Cannot access Glue Schema with provided role. Please ensure the provided role can perform the GetRegistry and GetSchemaVersion Actions on your schema.`  
**Resolução:** adicione as permissões necessárias (`glue:GetRegistry` e `glue:GetSchemaVersion`) ao perfil de execução da sua função.

Acesso ao Confluent Schema Registry negado  
**Mensagem de erro:** `Cannot access Confluent Schema with the provided access configuration.`  
**Resolução:** verifique se as suas credenciais de autenticação (armazenadas no Secrets Manager) estão corretas e se têm as permissões necessárias para acessar o registro de esquema.

Registro de esquemas do AWS Glue entre contas  
**Mensagem de erro:** `Cross-account Glue Schema Registry ARN not supported.`  
**Resolução:** use um Registro de esquema do AWS Glue que esteja na mesma conta da AWS da sua função do Lambda.

Registro de esquema do AWS Glue entre regiões  
**Mensagem de erro:** `Cross-region Glue Schema Registry ARN not supported.`  
**Resolução:** use um Registro de esquema do AWS Glue que esteja na mesma região da sua função do Lambda.

Problemas de acesso a segredos  
**Mensagem de erro:** `Lambda received InvalidRequestException from Secrets Manager.`  
**Resolução:** verifique se o perfil de execução da função tem permissão para acessar o segredo e se o este não está criptografado com uma chave padrão do AWS KMS ao acessar de uma conta diferente.

### Erros de conexão
<a name="consume-kafka-events-troubleshooting-connection-errors"></a>

Esses erros ocorrem quando o Lambda não consegue estabelecer uma conexão com o registro de esquema.

Problemas de conectividade com a VPC  
**Mensagem de erro:** `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.`  
**Resolução:** configure sua rede VPC para permitir conexões com o registro de esquema usando um AWS PrivateLink, um gateway NAT ou emparelhamento de VPCs.

Falha do handshake TLS  
**Mensagem de erro:** `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.`  
**Resolução:** verifique se seus certificados de CA e certificados de cliente (para mTLS) estão corretos e configurados corretamente no Secrets Manager.

Controle de utilização  
**Mensagem de erro:** `Receiving throttling errors when accessing the schema registry. Please increase API TPS limits for your schema registry.`  
**Resolução:** aumente os limites de taxas de API para o registro de esquema ou reduza a taxa de solicitações provenientes da sua aplicação.

Erros de registro do esquema autogerenciado  
**Mensagem de erro:** `Lambda received an internal server an unexpected error from the provided self-managed schema registry.`  
**Resolução:** verifique a integridade e a configuração do seu servidor de registro de esquema autogerenciado.

# Processamento de baixa latência para fontes de eventos do Kafka
<a name="with-kafka-low-latency"></a>

O AWS Lambda oferece suporte nativo ao processamento de eventos de baixa latência para aplicações que exigem latências consistentes de ponta a ponta de menos de 100 milissegundos. Esta página fornece detalhes de configuração e recomendações para permitir fluxos de trabalho de baixa latência.

## Habilite o processamento de baixa latência
<a name="enable-low-latency"></a>

Para habilitar o processamento de baixa latência em um mapeamento da origem do eventos do Kafka, é necessária a seguinte configuração básica: 
+ Habilite o modo provisionado. Para obter mais informações, consulte [Modo provisionado](kafka-scaling-modes.md#kafka-provisioned-mode).
+ Defina o parâmetro do mapeamento da origem do evento `MaximumBatchingWindowInSeconds` como 0. Para obter mais informações, consulte [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

## Ajuste o ESM do Kafka de baixa latência
<a name="recommendations-low-latency"></a>

Considere as recomendações a seguir para otimizar seu mapeamento da origem do evento do Kafka para baixa latência:

### Configuração do modo provisionado
<a name="recommendations-pollers"></a>

No modo provisionado do mapeamento da origem do evento do Kafka, o Lambda permite ajustar o throughput do mapeamento da origem do evento configurando um número mínimo e máximo de recursos chamados **sondagens de eventos**. Uma sondagem de eventos (ou **uma sondagem**) representa um recurso computacional que sustenta um mapeamento da origem do evento no modo provisionado e aloca um throughput de até 5 MB/s. Cada sondagem de eventos suporta até 5 invocações simultâneas do Lambda.

Para determinar a configuração ideal da sondagem para sua aplicação, considere sua taxa de ingestão máxima e os requisitos de processamento. Vamos dar uma olhada em um exemplo simplificado:

Com um tamanho de lote de 20 registros e uma duração média da função de destino de 50 ms, cada sondagem pode lidar com 2.000 registros por segundo, sujeitos ao limite de 5 MB/s. Isso é calculado como: (20 registros × 1000ms/50ms) × 5 invocações simultâneas do Lambda. Portanto, se a taxa de ingestão máxima desejada for de 20.000 registros por segundo, você precisará de pelo menos 10 sondagens de eventos.

**nota**  
Recomendamos provisionar as sondagens de eventos adicionais como buffer para evitar que a operação consistente atinja a capacidade máxima.

O modo provisionado dimensiona automaticamente suas sondagens de eventos com base nos padrões de tráfego dentro das **sondagens de eventos** mínimas e máximas configuradas, o que pode acionar o rebalanceamento e, portanto, introduzir latência adicional. Você pode desabilitar o ajuste de escala automático ao configurar o mesmo valor para o mínimo e máximo de **sondagem de eventos**.

### Considerações adicionais
<a name="additional-considerations-low-latency"></a>

Algumas das considerações adicionais incluem:
+ As partidas a frio da invocação da função de destino do Lambda podem potencialmente aumentar a latência de ponta a ponta. Para reduzir esse risco, considere habilitar a [simultaneidade provisionada](provisioned-concurrency.md) ou o [SnapStart](snapstart.md) na função de destino do mapeamento da origem do evento. Além disso, otimize a alocação de memória de sua função para garantir execuções consistentes e ideais.
+ Quando `MaximumBatchingWindowInSeconds` for definido como 0, o Lambda processará imediatamente todos os registros disponíveis sem esperar para preencher o tamanho completo do lote. Por exemplo, se o tamanho do lote estiver definido para 1.000 registros, mas apenas 100 registros estiverem disponíveis, o Lambda processará esses 100 registros imediatamente, em vez de esperar que os 1.000 registros completos se acumulem.

**Importante**  
A configuração ideal para processamento de baixa latência varia significativamente com base na workload específica. Enfatizamos a recomendação de testar diferentes configurações com sua workload real para determinar as melhores configurações para seu caso de uso. 

# Configuração dos controles de tratamento de erros para origens de eventos do Kafka
<a name="kafka-retry-configurations"></a>

É possível configurar como o Lambda lida com erros e novas tentativas para os mapeamentos da origem do evento do Kafka. Essas configurações ajudam você a controlar como o Lambda processa registros com falha e gerencia o comportamento de novas tentativas.

## Configurações disponíveis de novas tentativas
<a name="kafka-retry-options"></a>

As configurações de novas tentativas a seguir estão disponíveis para origens de eventos do Amazon MSK e do Kafka autogerenciado:
+ **Máximo de novas tentativas**: o número máximo de vezes que o Lambda tenta novamente quando a função retorna um erro. Isso não conta a tentativa inicial de invocação. O valor padrão é -1 (infinito). Quando você configura tanto [tentativas infinitas](kafka-on-failure-destination.md) quanto um destino em caso de falha, o Lambda aplica automaticamente um máximo de 10 tentativas de repetição.
+ **Idade máxima do registro**: a idade máxima de um registro que o Lambda envia para sua função. O valor padrão é -1 (infinito).
+ **Dividir lote em caso de erro**: quando a sua função retorna um erro, o lote é dividido em dois lotes menores e cada um é tentado novamente em separado. Isso ajuda a isolar registros problemáticos.
+ **Resposta em lote parcial**: permite que sua função retorne informações sobre quais registros em um lote falharam no processamento, para que o Lambda possa repetir somente os registros com falha.

## Configuração dos controles de tratamento de erro (console)
<a name="kafka-retry-console"></a>

É possível configurar o comportamento de novas tentativas ao criar ou atualizar um mapeamento da origem do evento do Kafka no console do Lambda.

**Para configurar o comportamento de novas tentativas para uma origem de eventos do Kafka (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha o nome da sua função.

1. Execute um destes procedimentos:
   + Para adicionar um novo acionador do Kafka, em **Visão geral da função**, escolha **Adicionar acionador**.
   + Para modificar um acionador existente do Kafka, escolha o acionador e, em seguida, escolha **Editar**.

1. Em **Configuração do agente de sondagem de eventos**, selecione o modo provisionado para configurar os controles de tratamento de erros:

   1. Em **Novas tentativas**, insira o número máximo de novas tentativas (0-10000, ou -1 para infinito).

   1. Em **Idade máxima do registro**, insira a idade máxima em segundos (60-604800, ou -1 para infinito).

   1. Para habilitar a divisão dos lotes quando ocorrerem erros, selecione **Dividir lote em caso de erro**.

   1. Para habilitar a resposta em lote parcial, selecione **ReportBatchItemFailures**.

1. Escolha **Adicionar** ou **Salvar**.

## Configuração do comportamento de novas tentativas (AWS CLI)
<a name="kafka-retry-cli"></a>

Use os comandos da AWS CLI a seguir para configurar o comportamento de novas tentativas para seus mapeamentos da origem do evento do Kafka.

### Criação de um mapeamento da origem do evento com novas tentativas
<a name="kafka-retry-cli-create"></a>

O exemplo a seguir cria um mapeamento da origem do evento do Kafka autogerenciado com controles de tratamento de erros:

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

Para origens de eventos do 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"
```

### Atualização das configurações de novas tentativas
<a name="kafka-retry-cli-update"></a>

Use o comando `update-event-source-mapping` para modificar as configurações de novas tentativas de um mapeamento da origem do evento 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>

A resposta em lote parcial, também conhecida como ReportBatchItemFailures, é um atributo fundamental para o tratamento de erros na integração do Lambda com origens do Kafka. Sem esse atributo, quando ocorre um erro em um dos itens de um lote, isso resulta no reprocessamento de todas as mensagens desse lote. Com a resposta em lote parcial habilitada e implementada, o manipulador retorna identificadores somente para as mensagens com falha, permitindo que o Lambda tente novamente apenas esses itens específicos. Isso fornece maior controle sobre como os lotes contendo mensagens com falha são processados.

Para relatar erros de lote, você usará este esquema JSON:

```
{
  "batchItemFailures": [
    {
      "itemIdentifier": {
        "partition": "topic-partition_number",
        "offset": 100
      }
    },
    ...
  ]
}
```

**Importante**  
Se você retornar um JSON vazio válido ou nulo, o mapeamento da origem do evento considerará um lote como processado com êxito. Qualquer topic-partition\$1number ou deslocamento inválido retornado que não esteja presente no evento invocado será tratado como falha, e todo o lote será testado novamente.

Os exemplos de código a seguir mostram como implementar uma resposta parcial em lote para funções do Lambda que recebem eventos de origens do Kafka. A função relata as falhas do item em lote na resposta, sinalizando para o Lambda tentar novamente essas mensagens posteriormente.

Aqui está uma implementação do manipulador do Lambda em Python que mostra essa abordagem:

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

Aqui está uma versão em 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 };
```

# Capturar lotes descartados para uma origem do evento do Amazon MSK e do Apache Kafka autogerenciado
<a name="kafka-on-failure"></a>

Para reter registros de invocações de mapeamento da origem do evento com falha, adicione um destino ao mapeamento da origem de eventos da função. Cada registro enviado ao destino é um documento JSON que contém metadados sobre a invocação que falhou. Para destinos do Amazon S3, o Lambda também envia todo o registro da invocação junto com os metadados. É possível configurar qualquer tópico do Amazon SNS, fila do Amazon SQS, bucket do Amazon S3 ou Kafka como destino.

Com destinos do Amazon S3, você pode usar o recurso [Notificações de eventos do Amazon S3](https://docs.aws.amazon.com/) para receber notificações quando objetos forem carregados no bucket do S3 de destino. Também é possível configurar as notificações de eventos do S3 para invocar outra função do Lambda para realizar o processamento automatizado em lotes com falha.

Sua função de execução deve ter permissões para o destino:
+ **Para um destino do SQS:** [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)
+ **Para um destino do SNS:** [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)
+ **Para um destino do S3:** [s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) e [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/ListObjectsV2.html)
+ **Para um destino do Kafka**: [kafka-cluster:WriteData](https://docs.aws.amazon.com/msk/latest/developerguide/kafka-actions.html)

É possível configurar um tópico do Kafka como um destino do Kafka em caso de falha para os seus mapeamentos da origem do evento do Kafka. Quando o Lambda não consegue processar registros após exaurir as novas tentativas ou quando os registros excedem a idade máxima, o Lambda envia os registros com falha para o tópico especificado do Kafka para processamento posterior. Consulte [Uso de um tópico do Kafka como destino em caso de falha](kafka-on-failure-destination.md).

Você deve implantar um endpoint da VPC para o serviço de destino em caso de falha dentro da VPC do cluster do Kafka.

Além disso, se você configurou uma chave do KMS no seu destino, o Lambda precisará das seguintes permissões, dependendo do tipo de destino:
+ Se você habilitou a criptografia com sua própria chave do KMS para um destino do S3, [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) é necessário. Se a chave do KMS e o destino do bucket do S3 estiverem em uma conta diferente da função do Lambda e do perfil de execução, configure a chave do KMS para confiar no perfil de execução para permitir kms:GenerateDataKey.
+ Se você habilitou a criptografia com sua própria chave do KMS para um destino do SQS, [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) e [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) são necessários. Se a chave do KMS e o destino da fila do SQS estiverem em uma conta diferente da função do Lambda e do perfil de execução, configure a chave do KMS para confiar no perfil de execução para permitir kms:Decrypt, kms:GenerateDataKey, [kms:DescribeKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_DescribeKey.html) e [kms:ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html).
+ Se você habilitou a criptografia com sua própria chave do KMS para um destino do SNS, [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html) e [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html) são necessários. Se a chave do KMS e o destino do tópico do SNS estiverem em uma conta diferente da função do Lambda e do perfil de execução, configure a chave do KMS para confiar no perfil de execução para permitir kms:Decrypt, kms:GenerateDataKey, [kms:DescribeKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_DescribeKey.html) e [kms:ReEncrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_ReEncrypt.html).

## Configurar destinos em caso de falha para um mapeamento da origem do evento do Kafka
<a name="kafka-onfailure-destination"></a>

Para configurar um destino em caso de falha usando o console, siga estas etapas:

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha uma função.

1. Em **Function overview (Visão geral da função)**, escolha **Add destination (Adicionar destino)**.

1. Em **Origem**, escolha **Invocação do mapeamento da origem do evento**.

1. Em **Mapeamento da origem do evento**, escolha uma origem de eventos configurada para essa função.

1. Em **Condição**, selecione **Em caso de falha**. Para invocações de mapeamento da origem de eventos, essa é a única condição aceita.

1. Em **Tipo de destino**, escolha o tipo de destino para o qual o Lambda envia registros de invocação.

1. Em **Destination (Destino)**, escolha um recurso.

1. Escolha **Salvar**.

Também é possível configurar um destino em caso de falha usando a AWS CLI. Por exemplo, o seguinte comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) adiciona um mapeamento de origem de eventos com um destino SQS em caso de falha 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"}}'
```

O seguinte comando [update-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) adiciona um destino S3 em caso de falha à origem de eventos associada à entrada `uuid`:

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--destination-config '{"OnFailure": {"Destination": "arn:aws:s3:::dest-bucket"}}'
```

Para remover um destino, forneça uma string vazia como argumento para o parâmetro `destination-config`:

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--destination-config '{"OnFailure": {"Destination": ""}}'
```

### Práticas recomendadas de segurança para destinos do Amazon S3
<a name="kafka-s3-destination-security"></a>

Excluir um bucket do S3 configurado como destino sem remover o destino da configuração da sua função pode criar um risco de segurança. Se outro usuário souber o nome do seu bucket de destino, ele poderá recriar o bucket na Conta da AWS dele. Registros de invocações com falha serão enviados para o bucket do usuário, potencialmente expondo dados da sua função.

**Atenção**  
Para garantir que os registros de invocação da sua função não possam ser enviados para um bucket do S3 em outra Conta da AWS, adicione uma condição ao perfil de execução da função que limite as permissões `s3:PutObject` aos buckets na sua conta. 

O exemplo a seguir mostra uma política do IAM que limita as permissões `s3:PutObject` da função aos bucket da conta. Essa política também dá ao Lambda a permissão `s3:ListBucket` necessária para usar um bucket do 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 adicionar uma política de permissões ao perfil de execução da função usando o Console de gerenciamento da AWS ou a AWS CLI, consulte as instruções nos seguintes procedimentos:

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

**Para adicionar uma política de permissões ao perfil de execução de uma função (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Selecione a função do Lambda cujo perfil de execução você queira modificar.

1. Na guia **Configuração**, escolha **Permissões**.

1. Na guia **Perfil de execução**, selecione o **Nome do perfil** da função para abrir a página do console do IAM do perfil.

1. Adicione uma política de permissões ao perfil da seguinte maneira:

   1. No painel **Políticas de permissões**, escolha **Adicionar permissões** e **Criar política em linha**.

   1. No **Editor de políticas**, selecione **JSON**.

   1. Cole a política que você deseja adicionar no editor (substituindo o JSON existente) e escolha **Próximo**.

   1. No campo **Detalhes da política**, insira o **Nome da política**.

   1. Escolha **Criar política**.

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

**Para adicionar uma política de permissões ao perfil de execução de uma função (CLI)**

1. Crie um documento de política de JSON com as permissões necessárias e salve-o em um diretório local.

1. Use o comando da CLI `put-role-policy` do IAM para adicionar permissões ao perfil de execução da função. Execute o comando a seguir no diretório em que você salvou seu documento de política de JSON e substitua o nome do perfil, o nome da política e o documento da política pelos seus próprios valores.

   ```
   aws iam put-role-policy \
   --role-name my_lambda_role \
   --policy-name LambdaS3DestinationPolicy \
   --policy-document file://my_policy.json
   ```

------

### Exemplo de registro de invocação do SNS e do SQS
<a name="kafka-sns-sqs-destinations"></a>

O exemplo a seguir mostra o que é enviado pelo Lambda para o destino de tópico do SNS ou de fila do SQS em caso de falha na invocação da origem de eventos do Kafka. Cada uma das chaves abaixo de `recordsInfo` contém o tópico e a partição do Kafka separados por um hífen. Por exemplo, para a chave `"Topic-0"`, `Topic` é o tópico do Kafka, e `0` é a partição. Para cada tópico e partição, você pode usar os dados de desvios e do carimbo de data/hora para encontrar os registros de invocação originais.

```
{
    "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",
            }
        }
    }
}
```

### Exemplo de registro de invocação de destino S3
<a name="kafka-s3-destinations"></a>

Para destinos do S3, o Lambda envia todo o registro da invocação junto com os metadados para o destino. O exemplo a seguir mostra o que é enviado pelo Lambda para o destino de bucket do S3 em caso de falha na invocação da origem de eventos do Kafka. Além de todos os campos do exemplo anterior para destinos do SQS e do SNS, o campo `payload` contém o registro de invocação original como uma string JSON com 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
}
```

**dica**  
Recomendamos habilitar o versionamento do S3 no bucket de destino.

# Uso de um tópico do Kafka como destino em caso de falha
<a name="kafka-on-failure-destination"></a>

É possível configurar um tópico do Kafka como um destino do Kafka em caso de falha para os seus mapeamentos da origem do evento do Kafka. Quando o Lambda não consegue processar registros após exaurir as novas tentativas ou quando os registros excedem a idade máxima, o Lambda envia os registros com falha para o tópico especificado do Kafka para processamento posterior. Quando você configura tanto [tentativas infinitas](kafka-retry-configurations.md) quanto um destino em caso de falha, o Lambda aplica automaticamente um máximo de 10 tentativas de repetição.

## Como funciona um destino do Kafka em caso de falha
<a name="kafka-ofd-overview"></a>

Quando você configura um tópico do Kafka como um destino em caso de falha, o Lambda atua como produtor do Kafka e grava registros com falha no tópico de destino. Isso cria um padrão de tópico de mensagem não entregue (DLT) em sua infraestrutura do Kafka.
+ **Mesmo requisito do cluster**: o tópico de destino deve existir no mesmo cluster do Kafka que seus tópicos de origem.
+ **Conteúdo real do registro**: os destinos do Kafka recebem os registros reais com falha junto com os metadados da falha.
+ **Prevenção de recursão**: o Lambda evita loops infinitos bloqueando configurações em que os tópicos de origem e destino são os mesmos.

## Configuração de um destino do Kafka em caso de falha
<a name="kafka-ofd-configure"></a>

É possível configurar um tópico do Kafka como um destino em caso de falha ao criar ou atualizar um mapeamento da origem do evento do Kafka.

### Configuração de um destino do Kafka (console)
<a name="kafka-ofd-console"></a>

**Para configurar um tópico do Kafka como um destino em caso de falha (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha o nome da sua função.

1. Execute um destes procedimentos:
   + Para adicionar um novo acionador do Kafka, em **Visão geral da função**, escolha **Adicionar acionador**.
   + Para modificar um acionador existente do Kafka, escolha o acionador e, em seguida, escolha **Editar**.

1. Em **Configurações adicionais**, para **Destino em caso de falha**, escolha **Tópico do Kafka**.

1. Em **Nome do tópico**, insira o nome do tópico do Kafka para o qual os registros que falharem serão enviados.

1. Escolha **Adicionar** ou **Salvar**.

### Configuração de um destino do Kafka (AWS CLI)
<a name="kafka-ofd-cli"></a>

Use o prefixo `kafka://` para especificar um tópico do Kafka como destino em caso de falha.

#### Criação de um mapeamento da origem do evento com destino do Kafka
<a name="kafka-ofd-cli-create"></a>

O exemplo a seguir cria um mapeamento da origem do evento do Amazon MSK com um tópico do Kafka como destino em caso de falha:

```
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"}}'
```

Para o Kafka autogerenciado, use a mesma sintaxe:

```
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"}}'
```

#### Atualização de um destino do Kafka
<a name="kafka-ofd-cli-update"></a>

Use o comando `update-event-source-mapping` para adicionar ou modificar um destino do 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 um destino do Kafka
<a name="kafka-ofd-record-format"></a>

Quando o Lambda envia registros com falha para um tópico do Kafka, cada mensagem contém metadados sobre a falha e o conteúdo real do registro.

### Metadados com falha
<a name="kafka-ofd-metadata"></a>

Os metadados incluem informações sobre por que o registro falhou e detalhes sobre o 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=="
        }
      ]
    }
  }
}
```

### Comportamento das chaves de partição
<a name="kafka-ofd-partitioning"></a>

O Lambda usa a mesma chave de partição do registro original ao produzir para o tópico de destino. Se o registro original não tiver chave, o Lambda usará o particionamento round-robin padrão do Kafka em todas as partições disponíveis no tópico de destino.

## Requisitos e limitações
<a name="kafka-ofd-requirements"></a>
+ **Modo provisionado obrigatório**: um destino em caso de falha do Kafka só está disponível para mapeamentos da origem do evento com o modo provisionado habilitado.
+ **Mesmo cluster apenas**: o tópico de destino deve existir no mesmo cluster do Kafka que seus tópicos de origem.
+ **Permissões de tópico**: o mapeamento da origem do evento deve ter permissões de gravação no tópico de destino. Exemplo:

  ```
  {
      "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": "*"
          }
      ]
  }
  ```
+ **Sem recursão**: o nome do tópico de destino não pode ser o mesmo de nenhum dos nomes dos tópicos de origem.

# Registro do mapeamento da origem do evento do Kafka
<a name="esm-logging"></a>

Você pode configurar o registro em nível de sistema para seus mapeamentos da origem de eventos do Kafka a fim de habilitar e filtrar os logs do sistema que os agentes de sondagem de eventos Lambda enviam para o CloudWatch. 

Esse recurso está disponível apenas para mapeamentos de origens de eventos do Kafka e com o [Modo provisionado](https://docs.aws.amazon.com/lambda/latest/dg/kafka-scaling-modes.html#kafka-provisioned-mode).

Para fazer o mapeamento da origem do evento com a configuração de registro, você também pode verificar os logs do sistema a partir de consultas de logs pré-criadas na guia **Monitor** da página Console **Lambda** > **Recursos adicionais** > **mapeamentos da origem do evento** agora.

## Como funciona o registro em log
<a name="esm-logging-overview"></a>

Quando você define a configuração de registro com o nível de log em seu mapeamento da origem do evento, o agente de sondagem de eventos do Lambda envia os logs correspondentes (logs do sistema de mapeamento da origem do evento).

O mapeamento da origem do evento reutiliza o mesmo [destino de log](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-logs.html#configuring-log-destinations) com a função do Lambda. Certifique-se de que a função do Lambda tenha as permissões de registro em log necessárias.

O mapeamento da origem do evento terá seu próprio fluxo de logs, com a data e o UUID do mapeamento da origem do evento como nome do fluxo de logs, como `2020/01/01/12345678-1234-1234-1234-12345678901`.

Para logs do sistema de mapeamento da origem do evento, você pode escolher entre os níveis de log a seguir.


| Nível de log | Usage | 
| --- | --- | 
| DEBUG (mais detalhes) | Informações detalhadas sobre o progresso do processamento da origem do evento | 
| INFORMAÇÕES | Mensagens sobre a operação normal do mapeamento da origem do evento | 
| WARN (menos detalhes) | Mensagens sobre possíveis avisos e erros que podem levar a um comportamento inesperado | 

Quando você seleciona um nível de log, o agente de sondagem de eventos do Lambda envia logs desse nível, e de níveis inferiores. Por exemplo, se você definir o nível de log do sistema de mapeamento da origem do evento como INFO, o agente de sondagem de eventos não enviará saídas de log no nível DEBUG.

## Configurar o registro em log da
<a name="esm-logging-configure"></a>

É possível definir a configuração de registro em log ao criar ou atualizar um mapeamento da origem do evento do Kafka.

### Configurar o registro em log (console)
<a name="esm-logging-console"></a>

**Para configurar o registro em log (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha o nome da sua função.

1. Execute um destes procedimentos:
   + Para adicionar um novo acionador do Kafka, em **Visão geral da função**, escolha **Adicionar acionador**.
   + Para modificar um acionador existente do Kafka, escolha o acionador e, em seguida, escolha **Editar**.

1. Em **Configuração do agente de sondagem de eventos**, para o **Modo provisionado**, ative a caixa de seleção **Configurar**. A configuração do **Nível de log** deve aparecer.

1.  Clique na lista suspensa **Nível de log** e selecione um nível para o mapeamento da origem do evento.

1. Escolha **Adicionar** ou **Salvar** na parte inferior para criar ou atualizar o mapeamento da origem do evento.

### Configurar o registro em log (AWS CLI)
<a name="esm-logging-cli"></a>

#### Criar um mapeamento da origem do evento com o registro em log
<a name="esm-logging-cli-create"></a>

O exemplo a seguir cria um mapeamento da origem do evento do Amazon MSK com configuração de registro em log:

```
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"}'
```

Para o Kafka autogerenciado, use a mesma sintaxe:

```
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"}'
```

#### Atualizar a configuração do registro em log
<a name="esm-logging-cli-update"></a>

Use o comando `update-event-source-mapping` para adicionar ou modificar a configuração do registro em log:

```
aws lambda update-event-source-mapping \
  --uuid 12345678-1234-1234-1234-123456789012 \
  --logging-config '{"SystemLogLevel":"WARN"}'
```

## Formato de registro para um log do sistema de mapeamento da origem do evento do Kafka
<a name="esm-logging-record-format"></a>

Quando o agente de sondagem de eventos do Lambda envia o log, cada respectiva entrada contém metadados gerais de mapeamento da origem do evento e o conteúdo específico do evento.

### Registro em log WARN
<a name="esm-logging-warn-record"></a>

O registro WARN contém erros ou avisos do agente de sondagem de eventos e é emitido quando o evento ocorre. Por exemplo:

```
{
    "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 em log INFO
<a name="esm-logging-info-record"></a>

O registro INFO contém configurações de cliente consumidor do Kafka em cada agente de sondagem de eventos e é emitido no caso de um consumidor ser criado ou alterado. Por exemplo:

```
{
    "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 em log DEBUG
<a name="esm-logging-debug-record"></a>

O log DEBUG contém as informações relacionadas aos deslocamentos do Kafka no processamento do mapeamento da origem do evento, e as informações de deslocamento são emitidas por minuto. Por exemplo:

```
{
    "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
    }
}
```

# Solução de problemas de erros do mapeamento da origem do evento do Kafka
<a name="with-kafka-troubleshoot"></a>

Os tópicos a seguir fornecem orientação para a solução de erros e problemas que você pode encontrar usando o Amazon MSK ou o Apache Kafka autogerenciado no Lambda.

Para obter mais ajuda com a solução de problemas, visite o [Centro de Conhecimento da AWS](https://repost.aws/knowledge-center#AWS_Lambda).

## Erros de autenticação e autorização
<a name="kafka-permissions-errors"></a>

Se alguma das permissões necessárias para consumir dados do cluster do Kafka estiver ausente, o Lambda exibirá uma das mensagens a seguir de erro no mapeamento da fonte de eventos em **LastProcessingResult**.

**Topics**
+ [O cluster falhou ao autorizar o Lambda](#kafka-authorize-errors)
+ [SASL authentication failed (Falha na autenticação SASL)](#kafka-sasl-errors)
+ [Server failed to authenticate Lambda (Falha ao autenticar o Lambda no servidor)](#kafka-mtls-errors-server)
+ [Lambda failed to authenticate server (Falha ao autenticar o servidor no Lambda)](#kafka-mtls-errors-lambda)
+ [Provided certificate or private key is invalid (O certificado ou a chave privada fornecida é inválida)](#kafka-key-errors)

### O cluster falhou ao autorizar o Lambda
<a name="kafka-authorize-errors"></a>

Para SASL/SCRAM ou mTLS, esse erro indica que o usuário fornecido não tem todas estas permissões da lista de controle de acesso (ACL) do Kafka necessárias:
+ Cluster DescribeConfigs
+ Descrever grupo
+ Ler grupo
+ Descrever tópico
+ Ler tópico

Ao criar ACLs do Kafka com as permissões necessárias do `kafka-cluster`, especifique o tópico e o grupo como recursos. O nome do tópico deve corresponder ao tópico no mapeamento da fonte de eventos. O nome do grupo deve corresponder ao UUID do mapeamento da fonte de eventos.

Depois de adicionar as permissões necessárias à função de execução, poderá levar vários minutos para que as alterações entrem em vigor.

A seguir está um exemplo de log no nível do sistema ESM após ativar a [Configuração de registro](esm-logging.md) para esse 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"
    }
}
```

### SASL authentication failed (Falha na autenticação SASL)
<a name="kafka-sasl-errors"></a>

Em SASL/SCRAM ou SASL/PLAIN, esse erro indica que as credenciais de login fornecidas não são válidas.

Para controle de acesso do IAM, o perfil de execução não tem a permissão `kafka-cluster:Connect` para o cluster. Adicione essa permissão à função e especifique o nome do recurso da Amazon (ARN) do cluster como recurso.

É possível que esse erro ocorra de modo intermitente. O cluster rejeitará conexões depois que o número de conexões de TCP exceder a cota de serviço. O Lambda recua e tenta novamente até que uma conexão seja bem-sucedida. Depois que o Lambda se conecta ao cluster e sonda por registros, o último resultado de processamento é alterado para `OK`.

A seguir está um exemplo de log no nível do sistema ESM após ativar a [Configuração de registro](esm-logging.md) para esse problema ao usar a autenticação 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"
    }
}
```

### Server failed to authenticate Lambda (Falha ao autenticar o Lambda no servidor)
<a name="kafka-mtls-errors-server"></a>

Esse erro indica que o agente do Kafka não conseguiu autenticar o Lambda. Esse erro pode ocorrer por estes motivos:
+ Você não forneceu um certificado de cliente para autenticação mTLS.
+ Você forneceu um certificado de cliente, mas os agentes do Kafka não estão configurados para usar a autenticação mTLS.
+ Um certificado de cliente não é confiável para os agentes do Kafka.

### Lambda failed to authenticate server (Falha ao autenticar o servidor no Lambda)
<a name="kafka-mtls-errors-lambda"></a>

Esse erro indica que o Lambda não conseguiu autenticar o agente do Kafka. Esse erro pode ocorrer por estes motivos:
+ Para Apache Kafka autogerenciado: os agentes do Kafka usam certificados autoassinados ou uma CA privada, mas não fornecem o certificado CA raiz do servidor.
+ Para Apache Kafka autogerenciado: o certificado CA raiz do servidor não corresponde à CA raiz que assinou o certificado do agente.
+ A validação do nome de host falhou porque o certificado do agente não contém o nome DNS ou o endereço IP do agente como nome alternativo do assunto.

### Provided certificate or private key is invalid (O certificado ou a chave privada fornecida é inválida)
<a name="kafka-key-errors"></a>

Esse erro indica que o consumidor do Kafka não pôde usar o certificado fornecido ou a chave privada. Verifique se o certificado e a chave usam o formato PEM e que a criptografia de chave privada usa um algoritmo PBES1.

A seguir está um exemplo de log no nível do sistema ESM após ativar a [Configuração de registro](esm-logging.md) para esse 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"
    }
}
```

## Erros de rede e conectividade
<a name="kafka-network-errors"></a>

Problemas de configuração de rede podem impedir que o Lambda se conecte ao seu cluster Kafka. Os tópicos a seguir descrevem erros comuns relacionados à rede.

**Topics**
+ [Tempo limite de conexão devido à configuração do grupo de segurança](#kafka-security-group-errors)
+ [Os endpoints do agente do Kafka não podem ser resolvidos](#kafka-cluster-deleted-errors)

### Tempo limite de conexão devido à configuração do grupo de segurança
<a name="kafka-security-group-errors"></a>

Se o grupo de segurança associado ao seu cluster Kafka não permitir tráfego de entrada de si mesmo, o Lambda não poderá se conectar ao cluster. Certifique-se de que as regras de entrada do grupo de segurança permitam o tráfego do próprio grupo de segurança nas portas do agente do Kafka.

A seguir está um exemplo de log no nível do sistema ESM após ativar a [Configuração de registro](esm-logging.md) para esse 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"
    }
}
```

Você também pode verificar o log de informações do consumidor do Kafka para verificar a conexão e a configuração da rede. O campo `brokerEndpoints` mostra os endereços do agente do Kafka, `securityProtocol` e `saslMechanism` (se aplicável) mostram o método de autenticação e o campo `networkConfig` mostra os endereços IP, o bloco CIDR da sub-rede e os grupos de segurança usados pelo mapeamento da origem do evento. Verifique se os grupos de segurança listados permitem o tráfego de entrada necessário:

```
{
    "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"
            ]
        }
    }
}
```

### Os endpoints do agente do Kafka não podem ser resolvidos
<a name="kafka-cluster-deleted-errors"></a>

Esse erro indica que o cluster do Kafka não existe ou foi excluído. Verifique se o cluster especificado no mapeamento da origem do evento existe e está em um estado ativo.

A seguir está um exemplo de log no nível do sistema ESM após ativar a [Configuração de registro](esm-logging.md) para esse 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"
    }
}
```

## Erros de mapeamento da fonte de eventos
<a name="services-event-errors"></a>

Quando você adicionar seu cluster do Apache Kafka como uma [fonte de eventos](invocation-eventsourcemapping.md) para sua função do Lambda, se ela encontrar um erro, o consumidor do Kafka interrompe o processamento de registros. Os consumidores de uma partição de tópico são aqueles que se inscrevem, leem e processam seus registros. Seus outros consumidores do Kafka podem continuar processando registros, desde que não encontrem o mesmo erro.

Para determinar a causa de um consumidor parado, verifique o campo `StateTransitionReason` na resposta do `EventSourceMapping`. A lista a seguir descreve os erros de origem do evento que você pode receber:

**`ESM_CONFIG_NOT_VALID`**  
A configuração do mapeamento da fonte de eventos não é válida.

**`EVENT_SOURCE_AUTHN_ERROR`**  
O Lambda não conseguiu autenticar a fonte de eventos.

**`EVENT_SOURCE_AUTHZ_ERROR`**  
O Lambda não tem as permissões necessárias para acessar a fonte de eventos.

**`FUNCTION_CONFIG_NOT_VALID`**  
A configuração da função não é válida.

**nota**  
Se os registros de eventos do Lambda excederem o limite de tamanho permitido de 6 MB, eles poderão ficar sem processamento.

# Invocar uma função do Lambda usando um endpoint do Amazon API Gateway
<a name="services-apigateway"></a>

É possível criar uma API da Web com um endpoint HTTP para a função do Lambda usando o Amazon API Gateway. O API Gateway fornece ferramentas para criar e documentar APIs da Web que direcionam as solicitações HTTP para as funções do Lambda. É possível proteger o acesso à sua API com controles de autenticação e autorização. Suas APIs podem veicular o tráfego pela Internet ou podem ser acessadas somente dentro da VPC.

**dica**  
O Lambda fornece duas maneiras de invocar uma função por meio de um endpoint HTTP: API Gateway e URLs de funções do Lambda. Se não tiver certeza de qual é o melhor método para seu caso de uso, consulte [Seleção de um método para invocar a função do Lambda usando uma solicitação HTTP](apig-http-invoke-decision.md).

Os recursos em sua API definem um ou mais métodos, como GET ou POST. Os métodos têm uma integração que direciona solicitações para uma função do Lambda ou outro tipo de integração. É possível definir cada recurso e método individualmente ou usar tipos especiais de recurso e método para corresponder todas as solicitações que se enquadram em um padrão. Um [recurso proxy](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html) captura todos os caminhos abaixo de um recurso. O método `ANY` captura todos os métodos HTTP.

**Topics**
+ [Escolher um tipo de API](#services-apigateway-apitypes)
+ [Adicionar um endpoint público à sua função do Lambda](#apigateway-add)
+ [Integração de proxy](#apigateway-proxy)
+ [Formato de eventos](#apigateway-example-event)
+ [Formato de resposta](#apigateway-types-transforms)
+ [Permissões](#apigateway-permissions)
+ [Aplicação de exemplo](#services-apigateway-samples)
+ [O manipulador de eventos do Powertools para AWS Lambda](#services-apigateway-powertools)
+ [Tutorial: Uso do Lambda com API Gateway](services-apigateway-tutorial.md)
+ [Tratamento de erros do Lambda com uma API do API Gateway](services-apigateway-errors.md)
+ [Seleção de um método para invocar a função do Lambda usando uma solicitação HTTP](apig-http-invoke-decision.md)

## Escolher um tipo de API
<a name="services-apigateway-apitypes"></a>

O API Gateway é compatível com três tipos de API que invocam as funções do Lambda:
+ [API HTTP](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html): uma API RESTful leve e de baixa latência.
+ [API REST](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html): uma API RESTful personalizável e com muitos recursos.
+ [API de WebSocket](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html): uma API da Web que mantém conexões persistentes com clientes para uma comunicação duplex completa.

As APIs HTTP e REST são ambas APIs RESTful que processam solicitações de HTTP e retornam respostas. As APIs HTTP são mais recentes e são criadas com a versão 2 da API do API Gateway. Os recursos abaixo são novos para APIs HTTP:

**Recursos da API HTTP**
+ **Implantações automáticas**: quando você modifica rotas ou integrações, as alterações são implantadas automaticamente em estágios com implantação automática habilitada.
+ **Estágio padrão**: você pode criar um estágio padrão (`$default`) para veicular solicitações no caminho raiz do URL da API. Para estágios nomeados, você deve incluir o nome do estágio no início do caminho.
+ **Configuração de CORS**: você pode configurar sua API para adicionar cabeçalhos CORS às respostas de saída em vez de adicioná-las manualmente no código da função.

As APIs REST são APIs RESTful clássicas às quais o API Gateway oferece suporte desde o lançamento. As APIs REST têm atualmente mais recursos de personalização, integração e gerenciamento.

**Recursos da API REST**
+ **Tipos de integração**: APIs REST são compatíveis com integrações personalizadas do Lambda. Com uma integração personalizada, você pode enviar apenas o corpo da solicitação para a função ou aplicar um modelo de transformação ao corpo da solicitação antes de enviá-la para a função.
+ **Controle de acesso**: as APIs REST oferecem suporte a mais opções de autenticação e autorização.
+ **Monitoramento e rastreamento**: as APIs REST oferecem suporte ao monitoramento do AWS X-Ray e a outras opções de log.

Para obter uma comparação detalhada, consulte [Escolher entre APIs HTTP e REST](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-vs-rest.html) no *Guia do desenvolvedor do API Gateway*.

As APIs WebSocket também usam a API do API Gateway versão 2 e oferecem suporte a um conjunto de recursos semelhante. Use uma API WebSocket para aplicativos que se beneficiam de uma conexão persistente entre o cliente e a API. As APIs WebSocket oferecem uma comunicação duplex completa, o que significa que tanto o cliente quanto a API podem enviar mensagens continuamente sem esperar por uma resposta.

As APIs HTTP oferecem suporte a um formato de evento simplificado (versão 2.0). Para obter um exemplo de um evento de API HTTP, consulte [Criação integrações de proxy AWS Lambda para APIs HTTP no API Gateway](https://docs.aws.amazon.com//apigateway/latest/developerguide/http-api-develop-integrations-lambda.html).

Para obter mais informações, consulte [Criar integrações de proxy do AWS Lambda para APIs HTTP no API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html).

## Adicionar um endpoint público à sua função do Lambda
<a name="apigateway-add"></a>

**Como adicionar um endpoint público à sua função do Lambda**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha uma função.

1. Em **Visão geral da função**, escolha **Adicionar gatilho**.

1. Selecione **API Gateway**.

1. Escolher **Create an API** (Criar uma API) ou **Use an existing API** (Usar uma API existente).

   1. **New API** (Nova API): para **API type** (Tipo de API), escolha **HTTP API**. Para obter mais informações, consulte [Escolher um tipo de API](#services-apigateway-apitypes).

   1. **Existing API**: selecione a API na lista suspensa ou insira seu ID (por exemplo, r3pmxmplak).

1. Em **Security (Segurança)**, escolha **Open (Abrir)**.

1. Escolha **Adicionar**.

## Integração de proxy
<a name="apigateway-proxy"></a>

As APIs do API Gateway são compostas por estágios, recursos, métodos e integrações. O estágio e o recurso determinam o caminho do endpoint:

**Formato do caminho da API**
+ `/prod/`: o estágio e o recurso raiz de `prod`.
+ `/prod/user`: o estágio de `prod` e o recurso de `user`.
+ `/dev/{proxy+}`: qualquer rota no estágio de `dev`.
+ `/`: (APIs HTTP) o estágio padrão e o recurso raiz.

Uma integração do Lambda mapeia uma combinação de caminho e método de HTTP para uma função do Lambda. É possível configurar o API Gateway para transmitir o corpo da solicitação de HTTP no estado em que se encontra (integração personalizada) ou para encapsular o corpo da solicitação em um documento que inclui todas as informações de solicitação, inclusive cabeçalhos, recursos, caminho e método.

Para obter mais informações, consulte [Integrações de proxy do Lambda no 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>

O Amazon API Gateway invoca sua função [de modo síncrono](invocation-sync.md) com um evento que contém uma representação JSON da solicitação de HTTP. Para uma integração personalizada, o evento é o corpo da solicitação. Para uma integração de proxy, o evento tem uma estrutura definida. Para ver um exemplo de um evento de proxy de uma API REST do API Gateway, consulte [Formato de entrada de uma função do Lambda para integração de proxy](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-input-format) no *Guia do desenvolvedor do API Gateway*.

## Formato de resposta
<a name="apigateway-types-transforms"></a>

O API Gateway aguarda uma resposta de sua função e retransmite o resultado para o chamador. Para uma integração personalizada, defina uma resposta de integração e uma resposta de método para converter a saída da função em uma resposta de HTTP. Para uma integração de proxy, a função deve responder com uma representação da resposta em um formato específico.

O exemplo abaixo mostra um objeto de resposta de uma função Node.js. O objeto de resposta representa uma resposta de HTTP bem-sucedida que contém um documento JSON.

**Example index.mjs: objeto de resposta de integração 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}"
    }
```

O runtime do Lambda serializa o objeto de resposta em JSON e o envia para a API. A API analisa a resposta e a utiliza para criar uma resposta de HTTP que, então, é enviada para o cliente que fez a solicitação original.

**Example Resposta 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
  }
```

## Permissões
<a name="apigateway-permissions"></a>

O Amazon API Gateway recebe permissão para invocar sua função por meio da [política baseada em recursos](access-control-resource-based.md) da função. É possível conceder permissão de invocar a uma API inteira ou conceder acesso limitado a um estágio, recurso ou método.

Ao adicionar uma API à sua função usando o console do Lambda, o console do API Gateway ou em um modelo de AWS SAM, a política baseada em recursos da função é atualizada automaticamente. Veja abaixo um exemplo de política de função.

**Example política de função**    
****  

```
{
  "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/"
        }
      }
    }
  ]
}
```

É possível gerenciar manualmente as permissões da política de função com as seguintes operações da 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 permissão de invocação a uma API existente, use o comando `add-permission`. Exemplo:

```
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/"
```

A seguinte saída deverá ser mostrada:

```
{
    "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**  
Se a sua função e a API estiverem em Regiões da AWS diferentes, o identificador de região no ARN de origem deverá corresponder à região da função, e não à região da API. Quando o API Gateway invoca uma função, ele usa um ARN de recurso baseado no ARN da API, mas modificado para corresponder à região da função.

O ARN de origem no exemplo concede permissão a uma integração no método GET do recurso raiz no estágio padrão de uma API com o ID `mnh1xmpli7`. É possível usar um asterisco no ARN de origem para conceder permissões a vários estágios, métodos ou recursos.

**Padrões de recursos**
+ `mnh1xmpli7/*/GET/*`: método GET em todos os recursos, em todos os estágios.
+ `mnh1xmpli7/prod/ANY/user`: método ANY no recurso `user` no estágio `prod`.
+ `mnh1xmpli7/*/*/*`: qualquer método em todos os recursos, em todos os estágios.

Para obter detalhes sobre como exibir a política e remover instruções, consulte [Visualizar políticas do IAM baseadas em recurso no Lambda](access-control-resource-based.md).

## Aplicação de exemplo
<a name="services-apigateway-samples"></a>

O aplicativo de exemplo de [API Gateway com Node.js](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/nodejs-apig) inclui uma função com um modelo do AWS SAM que cria uma API REST com o rastreamento do AWS X-Ray habilitado. Ele também inclui scripts para implantar, invocar a função, testar a API e fazer a limpeza.

## O manipulador de eventos do Powertools para AWS Lambda
<a name="services-apigateway-powertools"></a>

O manipulador de eventos do kit de ferramentas Powertools para AWS Lambda fornece roteamento, middleware, configuração CORS, geração de especificações da OpenAPI, validação de solicitações, tratamento de erros e outros recursos úteis ao escrever funções do Lambda invocadas por um endpoint do API Gateway (HTTP ou REST). O utilitário de manipulador de eventos está disponível para Python e TypeScript/JavaScript. Para obter mais informações, consulte a [API REST do manipulador de eventos](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/) na documentação do *Powertools para AWS Lambda (Python)* e a [API HTTP do manipulador de eventos na documentação do *Powertools para AWS Lambda (TypeScript)*. ](https://docs.aws.amazon.com/powertools/typescript/latest/features/event-handler/http/)

### 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 do Lambda com API Gateway
<a name="services-apigateway-tutorial"></a>

Neste tutorial, você criará uma API REST que será usada para invocar uma função do Lambda usando uma solicitação HTTP. A função do Lambda executará operações de criação, leitura, atualização e exclusão (CRUD) em uma tabela do DynamoDB. Essa função será fornecida aqui para fins de demonstração, mas você aprenderá a configurar uma API REST do API Gateway que pode invocar qualquer função do Lambda.

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


O uso do API Gateway fornece aos usuários um endpoint HTTP seguro para invocar a função do Lambda e pode ajudar a gerenciar grandes volumes de chamadas para a função, ao realizar o controle de utilização do tráfego e validar e autorizar as chamadas de API automaticamente. O API Gateway também oferece controles de segurança flexíveis usando o AWS Identity and Access Management (IAM) e o Amazon Cognito. Isso é útil para casos de uso em que é necessária uma autorização prévia para as chamadas em sua aplicação.

**dica**  
O Lambda fornece duas maneiras de invocar uma função por meio de um endpoint HTTP: API Gateway e URLs de funções do Lambda. Se não tiver certeza de qual é o melhor método para seu caso de uso, consulte [Seleção de um método para invocar a função do Lambda usando uma solicitação HTTP](apig-http-invoke-decision.md).

Para concluir este tutorial, você passará pelos estágios a seguir:

1. Criação e configuração de uma função do Lambda em Python ou em Node.js para a execução de operações em uma tabela do DynamoDB.

1. Criação de uma API REST no API Gateway para conexão com a função do Lambda.

1. Criação de uma tabela do DynamoDB e realização de teste com a função do Lambda no console.

1. Implantação da API e realização de teste da configuração completa usando curl em um terminal.

Ao concluir esses estágios, você aprenderá a usar o API Gateway para criar um endpoint HTTP que pode invocar uma função do Lambda com segurança em qualquer escala. Você também aprenderá como implantar a API e testá-la no console, além de como enviar uma solicitação HTTP usando um terminal.

## Criação de uma política de permissões
<a name="services-apigateway-tutorial-policy"></a>

Antes de ser possível criar uma [função de execução](lambda-intro-execution-role.md) para a função do Lambda, primeiro é necessário criar uma política de permissões para fornecer à sua função permissão para acessar os recursos da AWS necessários. Para este tutorial, a política permitirá que o Lambda execute operações de CRUD em uma tabela do DynamoDB e grave no Amazon CloudWatch Logs.

**Para criar a política**

1. Abra a [página Policies](https://console.aws.amazon.com/iam/home#/policies) (Políticas) do console do IAM.

1. Escolha **Create Policy**.

1. Escolha a guia **JSON** e cole a política personalizada a seguir no 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. Escolha **Próximo: tags**.

1. Selecione **Próximo: revisar**.

1. No campo **Política de revisão**, em **Nome** da política, insira **lambda-apigateway-policy**.

1. Escolha **Criar política**.

## Criar uma função de execução
<a name="services-apigateway-tutorial-role"></a>

Um [perfil de execução](lambda-intro-execution-role.md) é um perfil do AWS Identity and Access Management (IAM) que concede a uma função do Lambda permissão para acessar recursos e Serviços da AWS. Para permitir que a função execute operações em uma tabela do DynamoDB, vincule a política de permissões criada na etapa anterior.

**Para criar um perfil de execução e vincular a política de permissões personalizada**

1. Abra a página [Funções](https://console.aws.amazon.com/iam/home#/roles) no console do IAM.

1. Selecione **Criar perfil**.

1. Para o tipo de entidade confiável, escolha **Serviço da AWS** e, em seguida, para o caso de uso, selecione **Lambda**.

1. Escolha **Próximo**.

1. Na caixa de pesquisa de política, insira **lambda-apigateway-policy**.

1. Nos resultados da pesquisa, selecione a política que você criou (`lambda-apigateway-policy`) e, depois, escolha **Next** (Avançar).

1. Em **Role details** (Detalhes do perfil), para **Role name** (Nome do perfil), insira **lambda-apigateway-role** e, em seguida, escolha **Create role** (Criar perfil).

## Criar a função do Lambda
<a name="services-apigateway-tutorial-function"></a>

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda e escolha **Criar função**.

1. Escolha **Criar do zero**.

1. Em **Function name** (Nome da função), insira `LambdaFunctionOverHttps`.

1. Em **Runtime**, escolha o runtime Node.js ou Python mais recente.

1. Em **Permissions** (Permissões), expanda **Change default execution role** (Alterar função de execução padrão).

1. Escolha **Usar um perfil existente** e selecione o perfil **lambda-apigateway-role** que você criou anteriormente.

1. Escolha a opção **Criar função**.

1. No painel **Código-fonte**, substitua o código padrão pelo código Node.js ou Python a seguir.

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

   A configuração `region` deve corresponder à Região da AWS na qual que você implanta a função e [cria a tabela do 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**  
Neste exemplo, o nome da tabela do DynamoDB está definido como uma variável em seu código da função. Em uma aplicação real, a prática recomendada é transferir esse parâmetro como uma variável de ambiente e evitar codificar o nome da tabela. Para obter mais informações, consulte [Usar variáveis de ambiente do AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html).

1. Na seção **DEPLOY**, escolha **Implantar** para atualizar o código da função:  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

## Testar a função
<a name="services-apigateway-tutorial-test-function"></a>

Antes de integrar a função com o API Gateway, confirme se a implantação da função ocorreu com êxito. Use o console do Lambda para enviar um evento de teste para a função.

1. Na página do console do Lambda da função, escolha a guia **Testar**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/test-tab.png)

1. Role para baixo até a seção **JSON do evento** e substitua o evento padrão pelo que se segue. Esse evento corresponde à estrutura esperada pela função do Lambda.

   ```
   {
       "operation": "echo",
       "payload": {
           "somekey1": "somevalue1",
           "somekey2": "somevalue2"
       }
   }
   ```

1. Escolha **Testar**.

1. Em **Execução da função: êxito**, expanda **Detalhes**. Você deverá ver a resposta a seguir:

   ```
   {
     "somekey1": "somevalue1",
     "somekey2": "somevalue2"
   }
   ```

## Criar uma API REST usando o API Gateway
<a name="services-apigateway-tutorial-api"></a>

Nesta etapa, você cria a API REST do API Gateway que usará para invocar a função do Lambda.

**Para criar a API**

1. Abra o [console do API Gateway](https://console.aws.amazon.com/apigateway).

1. Selecione **Create API** (Criar API).

1. Na caixa do **API REST**, escolha **Construir**.

1. Em **Detalhes da API**, deixe a opção **Nova API** selecionada e, em **Nome da API**, insira**DynamoDBOperations**.

1. Selecione **Criar API**.

## Criação de um recurso na API REST
<a name="services-apigateway-tutorial-resource"></a>

Para adicionar um método HTTP à API, primeiro é necessário criar um recurso no qual esse método possa operar. Aqui você cria o recurso para gerenciar a tabela do DynamoDB.

**Para criar o recurso**

1. No [Console do Gateway da API](https://console.aws.amazon.com/apigateway), na página **Recursos** da API, escolha **Criar recurso**.

1. Em **Detalhes do recurso**, em **Nome do recurso**, insira **DynamoDBManager**.

1. Escolha **Create Resource** (Criar recurso).

## Criação de um método HTTP POST
<a name="services-apigateway-tutorial-method"></a>

Nesta etapa, você cria um método (`POST`) para o recurso `DynamoDBManager`. Você vincula esse método `POST` à função do Lambda para que, quando o método receber uma solicitação HTTP, o API Gateway invoque sua função do Lambda.

**nota**  
 Para a finalidade deste tutorial, um método HTTP (`POST`) será usado para invocar uma única função do Lambda que executa todas as operações em sua tabela do DynamoDB. Em uma aplicação real, a prática recomendada é usar diferentes funções do Lambda e métodos HTTP para cada operação. Para obter mais informações, consulte [The Lambda monolith](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/monolith) no Serverless Land. 

**Para criar o método POST**

1. Na página **Recursos** da API, certifique-se de que o recurso `/DynamoDBManager` esteja realçado. Em seguida, no painel **Métodos**, escolha **Criar método**.

1. Em **Tipo de método**, escolha **POST**.

1. Em **Tipo de integração**, mantenha a opção **Função do Lambda** selecionada.

1. Em **Função do Lambda**, escolha o nome do recurso da Amazon (ARN) para sua função (`LambdaFunctionOverHttps`).

1. Escolha **Criar método**.

## Criar uma tabela do DynamoDB
<a name="services-apigateway-tutorial-table"></a>

Crie uma tabela do DynamoDB em branco na qual a função do Lambda executará as operações de CRUD.

**Para criar uma tabela do DynamoDB**

1. Abra a [página Tables (Tabelas) no console do DynamoDB](https://console.aws.amazon.com/dynamodbv2#tables).

1. Escolha **Criar tabela**.

1. Em **Detalhes da tabela**, faça o seguinte:

   1. Em **Table name** (Nome da tabela), insira **lambda-apigateway**.

   1. Para a **Chave de partição**, insira **id** e mantenha o tipo de dados definido como **String**.

1. Em **Table settings** (Configurações da tabela), mantenha **Default settings** (Configurações padrões).

1. Escolha **Criar tabela**.

## Teste da integração do API Gateway, do Lambda e do DynamoDB
<a name="services-apigateway-tutorial-test-setup"></a>

Agora está tudo pronto para que ocorra o teste da integração do método de API do API Gateway com a função do Lambda e a tabela do DynamoDB. Ao usar o console do API Gateway, você envia solicitações diretamente para o método `POST` usando a função de teste do console. Nesta etapa, primeiro você usa uma operação `create` para adicionar um novo item à tabela do DynamoDB e, em seguida, usa uma operação `update` para modificar o item.

**Teste 1: para criar um novo item na tabela do DynamoDB**

1. No [API Gateway console](https://console.aws.amazon.com/apigateway) (Console do API Gateway), escolha a sua API (`DynamoDBOperations`).

1. No recurso `DynamoDBManager`, escolha o método **POST**.

1. Selecione a guia **Testar**. Talvez seja necessário selecionar o botão de seta para a direita para mostrar a guia.

1. Em **Método de teste**, mantenha as opções **Strings de consulta** e **Cabeçalhos** vazias. Em **Corpo da solicitação**, cole o seguinte JSON:

   ```
   {
     "operation": "create",
     "payload": {
       "Item": {
         "id": "1234ABCD",
         "number": 5
       }
     }
   }
   ```

1. Escolha **Testar**.

   Os resultados que são exibidos quando o teste é concluído devem mostrar status `200`. Esse código de status indica que a operação `create` ocorreu com êxito.

    Para confirmar, verifique se a tabela do DynamoDB passou a conter o novo item.

1. Abra a [página Tables](https://console.aws.amazon.com/dynamodbv2#tables) (Tabelas) do console do DynamoDB e escolha a tabela `lambda-apigateway`.

1. Escolha **Explore table items** (Explorar itens da tabela). No painel **Itens retornados**, você verá um item com o **id** `1234ABCD` e o **número** `5`. Exemplo:  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/items-returned.png)

**Teste 2: para atualizar o item na tabela do DynamoDB**

1. No [Console do API Gateway](https://console.aws.amazon.com/apigateway), retorne para a guia **Teste** do seu método POST.

1. Em **Método de teste**, mantenha as opções **Strings de consulta** e **Cabeçalhos** vazias. Em **Corpo da solicitação**, cole o seguinte JSON:

   ```
   {
       "operation": "update",
       "payload": {
           "Key": {
               "id": "1234ABCD"
           },
           "UpdateExpression": "SET #num = :newNum",
           "ExpressionAttributeNames": {
               "#num": "number"
           },
           "ExpressionAttributeValues": {
               ":newNum": 10
           }
       }
   }
   ```

1. Escolha **Testar**.

   Os resultados que são exibidos quando o teste é concluído devem mostrar status `200`. Esse código de status indica que a operação `update` ocorreu com êxito.

    Para confirmar, verifique se o item na tabela do DynamoDB foi modificado.

1. Abra a [página Tables](https://console.aws.amazon.com/dynamodbv2#tables) (Tabelas) do console do DynamoDB e escolha a tabela `lambda-apigateway`.

1. Escolha **Explore table items** (Explorar itens da tabela). No painel **Itens retornados**, você verá um item com o **id** `1234ABCD` e o **número** `10`.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/items-returned-2.png)

## Implantar a API
<a name="services-apigateway-tutorial-deploy-api"></a>

Para que um cliente chame a API, você deve criar uma implantação e um estágio associado. Um estágio representa um snapshot da API, incluindo seus métodos e integrações.

**Para implantar a API**

1. Abra a página **APIs** do [API Gateway console](https://console.aws.amazon.com/apigateway) (Console do API Gateway) e escolha a API `DynamoDBOperations`.

1. Na página **Recursos** da sua API, escolha **Implantar API**.

1. Em **Estágio**, escolha **\$1Novo estágio\$1** e, em seguida, em **Nome do estágio**, insira **test**.

1. Escolha **Implantar**.

1. No painel **Detalhes do estágio** copie o **URL de invocação**. Você usará isso na próxima etapa para invocar a função usando uma solicitação HTTP.

## Uso de curl para invocar a função usando solicitações HTTP
<a name="services-apigateway-tutorial-invoke-function"></a>

Agora é possível invocar a função do Lambda ao emitir uma solicitação HTTP para a API. Nesta etapa, você criará um novo item na tabela do DynamoDB e realizará as operações de leitura, atualização e exclusão nesses itens.

**Para criar um item na tabela do DynamoDB usando curl**

1. Abra um terminal ou prompt de comando em sua máquina local e execute o seguinte comando `curl` usando o URL de invocação que você copiou na etapa anterior. Este comando usa as seguintes opções:
   + `-H`: adiciona um cabeçalho à solicitação. Aqui, especifica o tipo de conteúdo como JSON.
   + `-d`: envia dados no corpo da solicitação. Essa opção usa um método HTTP POST por padrão.

------
#### [ 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}}}'
   ```

------

   Se a operação foi bem-sucedida, você deverá ver uma resposta retornada com um código 200 de status de HTTP.

1. Também é possível usar o console do DynamoDB para confirmar que o item novo está na sua tabela fazendo o seguinte:

   1. Abra a [página Tables](https://console.aws.amazon.com/dynamodbv2#tables) (Tabelas) do console do DynamoDB e escolha a tabela `lambda-apigateway`.

   1. Escolha **Explore table items** (Explorar itens da tabela). No painel **Itens retornados**, você verá um item com o **id** `5678EFGH` e o **número** `15`.

**Para ler o item na tabela do DynamoDB usando curl**
+ No seu terminal ou prompt de comando, execute o seguinte comando `curl` para ler o valor do item que você acabou de criar. Use seu próprio URL de invocação.

------
#### [ 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\"}}}'
  ```

------

  Você deve ver uma saída como uma das seguintes, dependendo de ter escolhido o código da função em Node.js ou em 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 atualizar o item na tabela do DynamoDB usando curl**

1. No seu terminal ou prompt de comando, execute o seguinte comando `curl` para atualizar o item que você acabou de criar ao alterar o valor `number`. Use seu próprio URL de invocação.

------
#### [ 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 o valor de `number` para p item foi atualizado, execute outro comando de leitura:

------
#### [ 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 excluir o item na tabela do DynamoDB usando curl**

1. No seu terminal ou prompt de comando, execute o seguinte comando `curl` para excluir o item que você acabou de criar. Use seu próprio URL de invocação.

------
#### [ 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 se a operação de exclusão ocorreu com êxito. No painel **Itens retornados** da página **Explorar itens** do console do DynamoDB, verifique se o item com o **id** `5678EFGH` não está mais na tabela.

## Limpeza dos recursos (opcional)
<a name="cleanup"></a>

Agora você pode excluir os recursos criados para este tutorial, a menos que queira mantê-los. Excluindo os recursos da AWS que você não está mais usando, você evita cobranças desnecessárias em sua Conta da AWS.

**Como excluir a função do Lambda**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Selecione a função que você criou.

1. Selecione **Ações**, **Excluir**.

1. Digite **confirm** no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir a função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione a função de execução que você criou.

1. Escolha **Excluir**.

1. Insira o nome do perfil no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir a API**

1. Abra a [página APIs](https://console.aws.amazon.com/apigateway/main/apis) do console do API Gateway.

1. Selecione a API que você criou.

1. Selecione **Ações**, **Excluir**.

1. Escolha **Excluir**.

**Para excluir uma tabela do DynamoDB**

1. Abra a [página Tables](https://console.aws.amazon.com//dynamodb/home#tables:) (Tabelas) no console do DynamoDB.

1. Selecione a tabela que você criou.

1. Escolha **Excluir**.

1. Digite **delete** na caixa de texto.

1. Selecione **Delete table** (Excluir tabela).

# Tratamento de erros do Lambda com uma API do API Gateway
<a name="services-apigateway-errors"></a>

O API Gateway trata todos os erros de invocação e função como erros internos. Se a API do Lambda rejeitar a solicitação de invocação, o API Gateway retornará um código de erro 500. Se a função é executada, mas retorna um erro ou retorna uma resposta no formato errado, o API Gateway retorna um código de erro 502. Em ambos os casos, o corpo da resposta do API Gateway é `{"message": "Internal server error"}`.

**nota**  
O API Gateway não tenta novamente nenhuma invocação do Lambda. Se o Lambda retornar um erro, o API Gateway retornará uma resposta de erro ao cliente.

O exemplo a seguir mostra um mapa de rastreamento do X-Ray para uma solicitação que resultou em um erro de função e um erro 502 do API Gateway. O cliente recebe a mensagem de erro genérica.

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/tracemap-apig-502.png)


Para personalizar a resposta de erro, é necessário detectar erros no código e formatar uma resposta no formato necessário.

**Example [index.mjs](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/nodejs-apig/function/index.mjs): erro de formatação**  

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

O API Gateway converte essa resposta em um erro HTTP com um código de status e um corpo personalizado. No mapa de rastreamento, o nó da função é verde porque ele tratou o erro.

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/tracemap-apig-404.png)


# Seleção de um método para invocar a função do Lambda usando uma solicitação HTTP
<a name="apig-http-invoke-decision"></a>

Muitos casos de uso comuns do Lambda envolvem invocar a função usando uma solicitação HTTP. Por exemplo, você pode querer que uma aplicação Web invoque sua função por meio de uma solicitação do navegador. As funções do Lambda também podem ser usadas para criar APIs REST completas, lidar com interações do usuário em aplicativos móveis, processar dados de serviços externos por meio de chamadas HTTP ou criar webhooks personalizados.

As seções a seguir explicam quais são as opções para invocar o Lambda por meio de HTTP e fornecem informações para que você tome a decisão certa para seu caso de uso específico.

## Quais são suas opções ao selecionar um método de invocação HTTP?
<a name="w2aad101c29c46b9"></a>

O Lambda oferece dois métodos principais para invocar uma função usando uma solicitação HTTP: [URLs de função](urls-configuration.md) e o [API Gateway](services-apigateway.md). As principais diferenças entre ambos são as duas opções seguintes:
+ Os **URLs de função do Lambda** fornecem um endpoint HTTP simples e direto para uma função do Lambda. Eles são otimizados para proporcionar simplicidade e economia e fornecem o caminho mais rápido para expor uma função do Lambda via HTTP.
+ O **API Gateway** é um serviço mais avançado para criar APIs completas. O API Gateway é otimizado para criar e gerenciar APIs de produção em grande escala e fornece ferramentas abrangentes para segurança, monitoramento e gerenciamento de tráfego.

## Recomendações se você já conhece seus requisitos
<a name="w2aad101c29c46c11"></a>

Se você já sabe quais são seus requisitos, estas são as nossas recomendações básicas:

Recomendamos usar os **[URLs de funções](urls-configuration.md)** para aplicações simples ou prototipagem em que você só precisa de métodos básicos de autenticação e tratamento de solicitações/respostas e onde deseja ter o mínimo de custo e a complexidade.

O **[API Gateway](services-apigateway.md)** é a melhor opção para aplicações de produção em grande escala ou para casos em que você precisa de recursos mais avançados, como suporte à [descrição de OpenAPI](https://www.openapis.org/), opções de autenticação, nomes de domínio personalizados ou tratamento avançado de solicitações/respostas, incluindo controle de utilização, armazenamento em cache e transformação de solicitação/resposta.

## O que considerar ao selecionar um método para invocar a função do Lambda
<a name="w2aad101c29c46c13"></a>

Ao selecionar entre URLs de função e o API Gateway, você precisa considerar os seguintes fatores:
+ Suas necessidades de autenticação, como se você precisa do OAuth ou do Amazon Cognito para autenticar usuários
+ Seus requisitos de escalabilidade e a complexidade da API que deseja implementar
+ Se você precisa de recursos avançados, como validação de solicitação e formatação de solicitação/resposta
+ Seus requisitos de monitoramento
+ Suas metas de custo

Ao compreender esses fatores, você pode selecionar a opção que melhor equilibra seus requisitos de segurança, complexidade e custo.

As informações a seguir resumem as principais diferenças entre as duas opções.

### Autenticação
<a name="w2aad101c29c46c13c11b1"></a>
+ Os **URLs de função** fornecem opções básicas de autenticação por meio do AWS Identity and Access Management (IAM). É possível configurar seus endpoints para serem públicos (sem autenticação) ou para exigirem a autenticação do IAM. Com a autenticação do IAM, você pode usar credenciais padrão da AWS ou perfis do IAM para controlar o acesso. Embora seja simples de configurar, essa abordagem oferece opções limitadas em comparação a outros métodos de autenticação.
+ O **API Gateway** fornece acesso a uma variedade maior de opções de autenticação. Além da autenticação do IAM, você pode usar [autorizadores do Lambda](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) (lógica de autenticação personalizada), grupos de usuários do [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html) e fluxos do OAuth2.0. Essa flexibilidade permite que você implemente esquemas complexos de autenticação, incluindo provedores de autenticação terceirizados, autenticação baseada em tokens e autenticação multifator.

### Tratamento de solicitação/resposta
<a name="w2aad101c29c46c13c11b3"></a>
+ Os **URLs de função** fornecem tratamento básico para solicitações e respostas HTTP. Eles são compatíveis com métodos HTTP padrão e incluem suporte integrado para compartilhamento de recursos de origem cruzada (CORS). Embora consigam lidar com cargas úteis JSON e parâmetros de consulta naturalmente, eles não oferecem recursos de transformação ou validação de solicitações. O tratamento de respostas é igualmente simples: o cliente recebe a resposta da sua função do Lambda exatamente como o Lambda a retorna.
+ O **API Gateway** fornece recursos sofisticados de tratamento de solicitações e respostas. É possível definir validadores de solicitações, transformar solicitações e respostas usando modelos de mapeamento, configurar cabeçalhos de solicitação/resposta e implementar o armazenamento em cache de respostas. O API Gateway também oferece suporte a cargas úteis binárias e nomes de domínio personalizados e pode modificar as respostas antes que elas cheguem ao cliente. É possível configurar modelos para validação e transformação de solicitação/resposta usando o esquema JSON.

### Escalabilidade
<a name="w2aad101c29c46c13c11b5"></a>
+ Os **URLs de funções** escalam diretamente com os limites de simultaneidade da sua função do Lambda e lidam com picos de tráfego escalando sua função até o limite máximo de simultaneidade configurado. Quando esse limite é atingido, o Lambda responde a solicitações adicionais com respostas HTTP 429. Não há um mecanismo de enfileiramento integrado, portanto, lidar com a escalabilidade depende inteiramente da configuração da sua função do Lambda. Por padrão, as funções do Lambda têm um limite de mil execuções simultâneas por Região da AWS.
+ O **API Gateway** fornece recursos adicionais de escalabilidade além da própria escalabilidade do Lambda. Ele inclui recursos integrados de enfileiramento e controle de utilização, permitindo que você gerencie os picos de tráfego com mais tranquilidade. Por padrão, o API Gateway pode lidar com até 10 mil solicitações por segundo por região, com uma capacidade de expansão de 5 mil solicitações por segundo. Ele também fornece ferramentas para solicitações de controle de utilização em diferentes níveis (API, estágio ou método) para proteger seu backend.

### Monitoramento
<a name="w2aad101c29c46c13c11b7"></a>
+ Os **URLs de funções** oferecem monitoramento básico por meio de métricas do Amazon CloudWatch, incluindo contagem de solicitações, latência e taxas de erro. Você tem acesso às métricas e logs padrão do Lambda, que mostram as solicitações brutas que chegam à sua função. Embora isso forneça visibilidade operacional essencial, as métricas se concentram principalmente na execução da função.
+ O **API Gateway** fornece recursos abrangentes de monitoramento, incluindo métricas detalhadas, geração de logs e opções de rastreamento. É possível monitorar chamadas de API, latência, taxas de erro e taxas de acerto/erro de cache por meio do CloudWatch. O API Gateway também se integra ao AWS X-Ray para rastreamento distribuído e fornece formatos de logs personalizáveis.

### Custo
<a name="w2aad101c29c46c13c11b9"></a>
+ Os **URLs de funções** seguem o modelo de preços padrão do Lambda: você paga somente pelas invocações de funções e pelo tempo de computação. Não há cobranças adicionais pelo endpoint do URL em si. Isso o torna uma opção econômica para APIs simples ou aplicações com pouco tráfego, caso você não precise dos recursos adicionais do API Gateway.
+ O **API Gateway** oferece um [nível gratuito](https://aws.amazon.com/api-gateway/pricing/#Free_Tier) que inclui um milhão de chamadas de API recebidas para APIs REST e um milhão de chamadas de API recebidas para APIs HTTP. Depois disso, o API Gateway cobra por chamadas de API, transferência de dados e armazenamento em cache (se habilitado). Consulte a [página de preços](https://aws.amazon.com/api-gateway/pricing/) do API Gateway para entender os custos do seu próprio caso de uso.

### Outros recursos
<a name="w2aad101c29c46c13c11c11"></a>
+ Os **URLs de funções** são projetados para oferecer simplicidade e integração direta com o Lambda. Eles são compatíveis com endpoints HTTP e HTTPS, oferecem suporte CORS integrado e fornecem endpoints de pilha dupla (IPv4 e IPv6). Embora não tenham recursos avançados, eles se destacam em cenários em que você precisa de uma forma rápida e direta de expor as funções do Lambda via HTTP.
+ O **API Gateway** inclui vários recursos adicionais, como versionamento de API, gerenciamento de estágios, chaves de API para planos de uso, documentação de API por meio do Swagger/OpenAPI, APIs de WebSocket, APIs privadas em uma VPC e integração com WAF para segurança extra. Ele também oferece suporte a implantações canário, integrações simuladas para testes e integração com outros Serviços da AWS além do Lambda.

## Seleção de um método para invocar a função do Lambda
<a name="w2aad101c29c46c15"></a>

Agora que você conhece os critérios para escolher entre URLs de funções do Lambda e o API Gateway, bem como as principais diferenças entre eles, você poderá selecionar a opção que melhor atende às suas necessidades e usar os recursos a seguir para ajudar a começar a usá-la.

------
#### [ Function URLs ]

**Conceitos básicos para usar URLs de funções com os recursos abaixo**
+ Siga o tutorial [Criar uma função do Lambda com um URL de função](urls-webhook-tutorial.md)
+ Saiba mais sobre URLs de funções no capítulo [Criar e gerenciar URLs de função do Lambda](urls-configuration.md) deste guia
+ Experimente o tutorial guiado no console **Criar um aplicativo Web simples** fazendo o seguinte:

1. Abra a [página de funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Abra o painel de ajuda escolhendo o ícone no canto superior direito da tela.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/console_help_screenshot.png)

1. Selecione **Tutoriais**.

1. Em **Criar um aplicativo Web simples**, escolha **Iniciar tutorial**.

------
#### [ API Gateway ]

**Conceitos básicos para usar o Lambda e o API Gateway com os recursos abaixo**
+ Siga o tutorial [Uso do Lambda com API Gateway](services-apigateway-tutorial.md) para criar uma API REST integrada a uma função do Lambda de backend.
+ Saiba mais sobre os diferentes tipos de API oferecidos pelo API Gateway nas seguintes seções do *Guia do desenvolvedor do Amazon API Gateway*:
  + [APIs REST do API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-rest-api.html)
  + [APIs HTTP do API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html)
  + [APIs de WebSocket do API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api.html)
+ Experimente um ou mais dos exemplos na seção [Tutoriais e workshops](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-tutorials.html) do *Guia do desenvolvedor do Amazon API Gateway*.

------

# Usar o AWS Lambda com o AWS Infrastructure Composer
<a name="services-appcomposer"></a>

AWS Infrastructure Composer é uma ferramenta de criação visual para projetar aplicações modernas na AWS. Para projetar a arquitetura das aplicações, basta arrastar, agrupar e conectar Serviços da AWS em uma tela visual. O Infrastructure Composer cria modelos de infraestrutura como código (IaC) com base no seu design que podem ser implantados usando o [AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html) ou o [CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html).

## Exportação da função do lambda para o Infrastructure Composer
<a name="services-appcomposer-export"></a>

Você pode começar a usar o Infrastructure Composer criando um projeto com base na configuração de uma função do Lambda existente usando o console do Lambda. Para exportar a configuração e o código da função para o Infrastructure Composer com o objetivo de criar um projeto, faça o seguinte:

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Selecione a função que você deseja usar como base para o projeto no Infrastructure Composer.

1. No painel **Visão geral da função**, escolha **Exportar para o Infrastructure Composer**.

   Para exportar a configuração e o código da função para o Infrastructure Composer, o Lambda cria um bucket do Amazon S3 na sua conta para armazenar esses dados temporariamente.

1. Na caixa de diálogo, escolha **Confirmar e criar projeto** para aceitar o nome padrão desse bucket e exportar a configuração e o código da função para o Infrastructure Composer.

1. (Opcional) Para escolher outro nome para o bucket do Amazon S3 criado pelo Lambda, insira um novo nome e escolha **Confirmar e criar projeto**. Os nomes de buckets do Amazon S3 devem ser exclusivos no mundo todo e seguir as [regras de nomenclatura de buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html).

1. Para salvar os arquivos de projeto e função no Infrastructure Composer, ative o [modo de sincronização local](https://docs.aws.amazon.com/application-composer/latest/dg/reference-features-local-sync.html).

**nota**  
Se você já usou o recurso **Exportar para o Application Composer** antes e criou um bucket do Amazon S3 usando o nome padrão, o Lambda pode reutilizar esse bucket, caso ele ainda exista. Aceite o nome padrão do bucket na caixa de diálogo para reutilizar o bucket existente.

### Configuração de transferência do bucket do Amazon S3
<a name="services-appcomposer-bucket-info"></a>

O bucket do Amazon S3 que o Lambda cria para transferir a configuração da função criptografa automaticamente os objetos usando o padrão de criptografia AES 256. O Lambda também configura o bucket para usar a [condição de proprietário do bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucket-owner-condition.html) a fim de garantir que apenas sua Conta da AWS possa adicionar objetos ao bucket.

O Lambda configura o bucket para excluir automaticamente os objetos dez dias após o upload. No entanto, o Lambda não exclui automaticamente o bucket em si. Para excluir o bucket da sua Conta da AWS, siga as instruções em [Excluir um bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html). O nome padrão do bucket usa o prefixo `lambdasam`, uma sequência alfanumérica de dez dígitos, e a Região da AWS em que você criou sua função:

```
lambdasam-06f22da95b-us-east-1
```

Para evitar que cobranças adicionais sejam incluídas na sua Conta da AWS, recomendamos que você exclua o bucket do Amazon S3 assim que terminar de exportar a função para o Infrastructure Composer.

Os [preços padrão do Amazon S3](https://aws.amazon.com/s3/pricing/) se aplicam.

### Permissões obrigatórias
<a name="services-appcomposer-permissions"></a>

Para usar a integração do Lambda com o recurso do Infrastructure Composer, você precisa de certas permissões para fazer o download de um modelo do AWS SAM e gravar a configuração da função no Amazon S3.

Para baixar um modelo do AWS SAM, você deve ter permissão para usar as seguintes ações de 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)

Você pode conceder permissão para usar todas essas ações adicionando a 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) gerenciada pela AWS ao seu perfil de usuário do IAM.

Para que o Lambda grave a configuração da sua função no Amazon S3, você precisa ter permissão para usar as seguintes ações de 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)

Caso não possa exportar a configuração da função para o Infrastructure Composer, verifique se a conta tem as permissões necessárias para essas operações. Se você tiver as permissões necessárias, mas ainda assim não conseguir exportar a configuração da função, verifique se há [políticas baseadas em recursos](access-control-resource-based.md) que talvez limitem o acesso ao Amazon S3.

## Outros recursos
<a name="w2aad101c33b7"></a>

Para obter um tutorial mais detalhado sobre como criar uma aplicação sem servidor no Infrastructure Composer com base em uma função do Lambda existente, consulte [Usar o Lambda com a infraestrutura como código (IaC)](foundation-iac.md).

Para usar o Infrastructure Composer e o AWS SAM para criar e implantar uma aplicação completa sem servidor usando o Lambda, você também pode seguir o [tutorial do AWS Infrastructure Composer](https://catalog.workshops.aws/serverless-patterns/en-US/dive-deeper/module1a) no [AWS Serverless Patterns Workshop](https://catalog.workshops.aws/serverless-patterns/en-US).

# Usar o AWS Lambda com o CloudFormation
<a name="services-cloudformation"></a>

Em um modelo do AWS CloudFormation, você pode especificar uma função do Lambda como o destino de um recurso personalizado. Use recursos personalizados para processar parâmetros, recuperar valores de configurações ou chamar outros Serviços da AWS durante eventos de ciclo de vida da pilha.

O exemplo a seguir invoca uma função que foi definida em outro lugar do modelo.

**Example – Definição 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
```

O token do serviço é o nome de recurso da Amazon (ARN) da função que o CloudFormation invoca quando você cria, atualiza ou exclui a pilha. Você também pode incluir propriedades, como `FunctionName`, que o CloudFormation transmite à sua função como está.

O CloudFormation invoca a função do Lambda [de forma assíncrona](invocation-async.md) com um evento que inclui um URL de retorno de chamada.

**Example –CloudFormation Evento de mensagem do**  

```
{
    "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"
    }
}
```

A função é responsável por retornar uma resposta ao URL de retorno que indica êxito ou falha. Para sintaxe de resposta completa, consulte [Objetos de resposta de recursos personalizados](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/crpg-ref-responses.html).

**Example –CloudFormation Resposta de recursos personalizados do**  

```
{
    "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"
}
```

O CloudFormation fornece uma biblioteca chamada `cfn-response` que lida com o envio da resposta. Se definir a função dentro de um modelo, você poderá exigir a biblioteca pelo nome. O CloudFormation adiciona a biblioteca ao pacote de implantação que cria para a função.

Se sua função usada por um recurso personalizado tiver uma [interface de rede elástica](configuration-vpc.md#configuration-vpc-enis) vinculada a ela, adicione os recursos a seguir à política da VPC, onde **region** é a região em que a função está, sem os traços. Por exemplo, `us-east-1` é `useast1`. Isso permitirá que o recurso personalizado responda ao URL de retorno de chamada que envia um sinal de volta para a pilha do CloudFormation.

```
arn:aws:s3:::cloudformation-custom-resource-response-region",
"arn:aws:s3:::cloudformation-custom-resource-response-region/*",
```

O exemplo a seguir invoca uma segunda função. Se a chamada tiver êxito, a função enviará uma resposta de êxito ao CloudFormation e a atualização da pilha continuará. O modelo usa o tipo de recurso [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html) fornecido pelo AWS Serverless Application Model.

**Example – Função de recurso personalizado**  

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

Se a função que o recurso personalizado invocar não estiver definida em um modelo, você poderá obter o código fonte para o `cfn-response` no [módulo cfn-response](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-lambda-function-code-cfnresponsemodule.html) no Manual do usuário do AWS CloudFormation.

Para obter mais informações sobre recursos personalizados, consulte [Recursos personalizados](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html)no *Guia do usuário do AWS CloudFormation*.

# Processar eventos do Amazon DocumentDB com o Lambda
<a name="with-documentdb"></a>

É possível usar uma função do Lambda para processar eventos em um [fluxo de alterações do Amazon DocumentDB (compatível com MongoDB)](https://docs.aws.amazon.com/documentdb/latest/developerguide/change_streams.html) ao configurar um cluster do Amazon DocumentDB como uma origem do evento. Em seguida, você pode automatizar workloads orientadas por eventos invocando a função do Lambda sempre que os dados são alterados com o cluster do Amazon DocumentDB.

**nota**  
O Lambda é compatível somente com as versões 4.0 e 5.0 do Amazon DocumentDB. O Lambda não é compatível com a versão 3.6.  
Além disso, para os mapeamentos da origem do evento, o Lambda oferece suporte somente a clusters baseados em instâncias e a clusters regionais. O Lambda não é compatível com [clusters elásticos](https://docs.aws.amazon.com/documentdb/latest/developerguide/docdb-using-elastic-clusters.html) ou [clusters globais](https://docs.aws.amazon.com/documentdb/latest/developerguide/global-clusters.html). Essa limitação não se aplica ao usar o Lambda como cliente para se conectar ao Amazon DocumentDB. O Lambda pode se conectar a todos os tipos de cluster para realizar operações CRUD.

O Lambda processa eventos dos fluxos de alterações do Amazon DocumentDB sequencialmente na ordem em que chegam. Consequentemente, a função só pode processar uma invocação simultânea do Amazon DocumentDB de cada vez. Para monitorar a função, você pode rastrear as [métricas de simultaneidade](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-concurrency.html) dela.

**Atenção**  
Os mapeamentos da origem do evento do Lambda processam cada evento ao menos uma vez, podendo haver o processamento duplicado de registros. Para evitar possíveis problemas relacionados a eventos duplicados, é altamente recomendável tornar o código da função idempotente. Para saber mais, consulte [Como tornar minha função do Lambda idempotente](https://repost.aws/knowledge-center/lambda-function-idempotent) no Centro de Conhecimentos da AWS.

**Topics**
+ [Exemplo de evento do Amazon DocumentDB](#docdb-sample-event)
+ [Pré-requisitos e permissões](#docdb-prereqs)
+ [Configuração da segurança de rede](#docdb-network)
+ [Criar um mapeamento da origem do evento do Amazon DocumentDB (console)](#docdb-configuration)
+ [Criar um mapeamento da origem do evento do Amazon DocumentDB (SDK ou CLI)](#docdb-api)
+ [Posições iniciais de sondagem e fluxo](#docdb-stream-polling)
+ [Monitorar a origem do evento do Amazon DocumentDB](#docdb-monitoring)
+ [Tutorial: uso do AWS Lambda com o Amazon DocumentDB Streams](with-documentdb-tutorial.md)

## Exemplo de evento do 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 obter mais informações sobre os eventos neste exemplo e suas formas, consulte [Alterar eventos](https://www.mongodb.com/docs/manual/reference/change-events/) no site de documentação do MongoDB.

## Pré-requisitos e permissões
<a name="docdb-prereqs"></a>

Antes que você possa usar o Amazon DocumentDB como origem do evento a sua função do Lambda, observe os pré-requisitos a seguir. Você deve:
+ **Ter um cluster do Amazon DocumentDB existente na mesma Conta da AWS e Região da AWS como sua função.** Se você não tiver um cluster existente, poderá criar um seguindo as etapas em [Get Started with Amazon DocumentDB](https://docs.aws.amazon.com/documentdb/latest/developerguide/get-started-guide.html) no *Guia do desenvolvedor do Amazon DocumentDB*. Como alternativa, o primeiro conjunto de etapas do [Tutorial: uso do AWS Lambda com o Amazon DocumentDB Streams](with-documentdb-tutorial.md) orientará você ao longo do processo de criação de um cluster do Amazon DocumentDB com todos os pré-requisitos necessários.
+ **Permitir que o Lambda tenha acesso aos recursos da Amazon Virtual Private Cloud (Amazon VPC) associados ao cluster do Amazon DocumentDB.** Para obter mais informações, consulte [Configuração da segurança de rede](#docdb-network).
+ **Habilitar o TLS no cluster do Amazon DocumentDB.** Essa é a configuração padrão. Se você desabilitar o TLS, o Lambda não poderá se comunicar com o cluster.
+ **Ativar os fluxos de alterações no cluster do Amazon DocumentDB.** Para obter mais informações, consulte [Usar fluxos de alterações com o Amazon DocumentDB](https://docs.aws.amazon.com/documentdb/latest/developerguide/change_streams.html) no *Guia do desenvolvedor do Amazon DocumentDB*.
+ **Fornecer ao Lambda credenciais para acessar o cluster  do Amazon DocumentDB.** Ao configurar a origem do evento, forneça a chave [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) que contém os detalhes de autenticação (nome de usuário e senha) necessários para acessar o cluster. Para fornecer essa chave durante a configuração, execute uma das seguintes ações:
  + Se você estiver usando o console do Lambda para configurar, forneça essa chave no campo **chave do Secrets Manager**.
  + Se você estiver usando o AWS Command Line Interface (AWS CLI) para configuração, forneça essa chave na opção `source-access-configurations`. É possível incluir essa opção com o 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) ou o 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). Por exemplo:

    ```
    aws lambda create-event-source-mapping \
        ...
        --source-access-configurations  '[{"Type":"BASIC_AUTH","URI":"arn:aws:secretsmanager:us-west-2:123456789012:secret:DocDBSecret-AbC4E6"}]' \
        ...
    ```
+ **Conceder permissões ao Lambda para gerenciar recursos relacionados ao fluxo do Amazon DocumentDB.** Adicione manualmente as seguintes permissões à [função de execução](lambda-intro-execution-role.md) da função:
  + [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)
+ **Manter o tamanho dos eventos de fluxos de alterações do Amazon DocumentDB que você envia para o Lambda abaixo de 6 MB.** O Lambda suporta apenas cargas úteis de até 6 MB. Se seu fluxo de alterações tentar enviar ao Lambda um evento maior que 6 MB, o Lambda descartará a mensagem e emitirá a métrica `OversizedRecordCount`. O Lambda emite todas as métricas com base no melhor esforço.

**nota**  
Embora as funções do Lambda normalmente tenham um limite máximo de tempo de 15 minutos, os mapeamentos da origem dos eventos para o Amazon MSK, o Apache Kafka autogerenciado, o Amazon DocumentDB e o Amazon MQ para ActiveMQ e RabbitMQ são compatíveis somente com funções com limites máximos de tempo limite de 14 minutos. Essa restrição garante que o mapeamento da origem do evento possa solucionar adequadamente os erros de função e repetições.

## Configuração da segurança de rede
<a name="docdb-network"></a>

Para conceder ao Lambda acesso total ao Amazon DocumentDB por meio do mapeamento da origem do evento, seu cluster deve usar um endpoint público (endereço IP público) ou você deve fornecer acesso à Amazon VPC na qual o cluster foi criado.

Ao usar o Amazon DocumentDB com o Lambda, recomendamos a criação de [endpoints de VPC do AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html) para conceder acesso da sua função aos recursos na sua Amazon VPC.

**nota**  
Os endpoints de VPC do AWS PrivateLink são necessários para funções com mapeamentos da origem de eventos que usam o modo padrão (sob demanda) para agentes de sondagem de eventos. Se o mapeamento da origem do evento usa o [modo provisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode), você não precisa configurar endpoints de VPC do AWS PrivateLink.

Crie um endpoint para fornecer acesso aos seguintes recursos:
+  Lambda: crie um endpoint para a entidade principal de serviço do Lambda. 
+  AWS STS: crie um endpoint para o AWS STS com a finalidade de possibilitar que uma entidade principal de serviço assuma um perfil em seu nome. 
+  Secrets Manager: caso o seu cluster use o Secrets Manager para armazenar credenciais, crie um endpoint específico para o Secrets Manager. 

Como alternativa, configure um gateway de NAT em cada sub-rede pública da Amazon VPC. Para obter mais informações, consulte [Habilitar o acesso à Internet para funções do Lambda conectadas à VPC](configuration-vpc-internet.md).

Ao criar um mapeamento da origem do evento para o Amazon DocumentDB, o Lambda verifica se as interfaces de rede elástica (ENIs) já estão presentes nas sub-redes e nos grupos de segurança configurados para a Amazon VPC. Se o Lambda encontrar ENIs existentes, ele tentará reutilizá-las. Caso contrário, o Lambda criará novas ENIs para se conectar à origem do evento e invocar sua função.

**nota**  
As funções do Lambda sempre são executadas em VPCs de propriedade do serviço Lambda. A configuração de VPC da sua função não afetará o mapeamento da origem do evento. Somente a configuração de rede da origem dos eventos determina como o Lambda estabelece conexão com a origem dos eventos.

Configure os grupos de segurança para a Amazon VPC que contém o cluster. Por padrão, o Amazon DocumentDB faz uso das seguintes portas: `27017`.
+ Regras de entrada: permitem todo o tráfego na porta padrão do agente para o grupo de segurança associado à origem dos eventos. Como alternativa, é possível usar uma regra de grupo de segurança autorreferenciada para permitir o acesso de instâncias dentro do mesmo grupo de segurança.
+ Regras de saída: permitir todo o tráfego na porta `443` para destinos externos se sua função precisar se comunicar com serviços da AWS. Como alternativa, você também poderá usar uma regra de grupo de segurança autorreferenciada para limitar o acesso ao operador se não precisar se comunicar com outros serviços AWS.
+ Regras de entrada para o endpoint da Amazon VPC: caso você esteja usando um endpoint da Amazon VPC, o grupo de segurança associado ao endpoint da Amazon VPC deve permitir o tráfego de entrada na porta `443` usando o grupo de segurança do cluster.

Caso o cluster use autenticação, é possível restringir a política de endpoint para o endpoint do Secrets Manager. Para chamar a API do Secrets Manager, o Lambda usa seu perfil de função, e não a entidade principal de serviço do Lambda.

**Example Política de endpoint da VPC: endpoint do 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"
          }
      ]
  }
```

Quando você usa os endpoints da Amazon VPC, a AWS roteia suas chamadas de API para invocar sua função usando a interface de rede elástica (ENI) do endpoint. A entidade principal do serviço Lambda precisa chamar `lambda:InvokeFunction` para quaisquer perfis e funções que usem essas ENIs.

Por padrão, os endpoints da Amazon VPC têm políticas do IAM abertas que permitem amplo acesso aos recursos. A prática recomendada é restringir essas políticas para executar as ações necessárias usando esse endpoint. Para garantir que seu mapeamento da origem do evento seja capaz de invocar sua função do Lambda, a política de endpoint da VPC deve permitir que a entidade principal do serviço Lambda chame `sts:AssumeRole` e `lambda:InvokeFunction`. A restrição de suas políticas de endpoint da VPC para permitir apenas chamadas de API originadas em sua organização impedirá o funcionamento adequado do mapeamento da origem do evento; portanto, `"Resource": "*"` é necessário nessas políticas.

O seguinte exemplo de políticas de endpoint da VPC mostra como conceder o acesso necessário à entidade principal do serviço Lambda para os endpoints do AWS STS e Lambda.

**Example Política de endpoint da VPC: endpoint do AWS STS**  

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

**Example Política de endpoint da VPC: endpoint do Lambda**  

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

## Criar um mapeamento da origem do evento do Amazon DocumentDB (console)
<a name="docdb-configuration"></a>

Para que uma função do Lambda faça leituras de um fluxo de alterações de um cluster do Amazon DocumentDB, crie um [mapeamento da origem do evento](invocation-eventsourcemapping.md). Esta seção descreve como fazer isso pelo console do Lambda. Para obter o AWS SDK e instruções da AWS CLI, consulte [Criar um mapeamento da origem do evento do Amazon DocumentDB (SDK ou CLI)](#docdb-api).

**Para criar um mapeamento da origem do evento do Amazon DocumentDB (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha o nome de uma função.

1. Em **Visão geral da função**, escolha **Adicionar gatilho**.

1. Em **Configuração do acionador**, na lista suspensa, escolha **DocumentDB**.

1. Configure as opções necessárias e escolha **Add** (Adicionar).

O Lambda oferece suporte às seguintes opções de origem do evento do Amazon DocumentDB:
+ **Cluster do DocumentDB**: selecione um cluster do Amazon DocumentDB.
+ **Ativar acionador**: escolha se você deseja ativar o acionador imediatamente. Se você marcar esta caixa de seleção, a função começará imediatamente a receber tráfego do fluxo de alterações do Amazon DocumentDB especificado após a criação do mapeamento da origem do evento. Recomendamos desmarcar a caixa de seleção para criar o mapeamento da origem do evento em um estado desativado para testes. Após a criação, é possível ativar o mapeamento da origem do evento a qualquer momento.
+ **Nome do banco de dados:** insira o nome de um banco de dados do cluster a ser consumido.
+ (Opcional) **Nome da coleção**: insira o nome de uma coleção no banco de dados a ser consumida. Se você não especificar uma coleção, o Lambda receberá todos os eventos de cada coleção no banco de dados.
+ **Tamanho do lote**: defina o número máximo de mensagens a serem recuperadas em um único lote, até 10 mil. O tamanho padrão do lote é 100.
+ **Posição inicial:** escolha a posição no fluxo para começar a ler registros.
  + **Mais recente**: processe somente novos registros adicionados ao fluxo. Sua função começa a processar registros somente depois que o Lambda termina de criar a origem do evento. Isso significa que alguns registros podem ser descartados até que a origem do evento seja criada com êxito.
  + **Trim horizon** (Redução horizontal): processe todos os registros na transmissão. O Lambda usa a duração da retenção de logs do cluster para determinar por onde começar a ler os eventos. Especificamente, o Lambda começa a ler a partir de `current_time - log_retention_duration`. O fluxo de alterações já deve estar ativo antes desse carimbo de data e hora para que o Lambda leia corretamente todos os eventos.
  + **At timestamp** (Na data e hora): processe registros a partir de uma hora específica. O fluxo de alterações já deve estar ativo antes do carimbo de data e hora especificado para que o Lambda leia corretamente todos os eventos.
+ **Autenticação**: escolha o método de autenticação para acessar os agentes do Kafka no cluster.
  + **BASIC\$1AUTH:** com a autenticação básica, é necessário fornecer a chave do Secrets Manager que contém as credenciais para acessar o cluster.
+ **Chave do Secrets Manager**: escolha a chave do Secrets Manager que contém os detalhes de autenticação (nome de usuário e senha) necessários para acessar o cluster do Amazon DocumentDB.
+ (Opcional) **Janela de lote**: defina o tempo máximo em segundos para reunir registros antes de invocar a função, até 300.
+ (Opcional) **Configuração completa do documento**: para operações de atualização de documentos, escolha o que você deseja enviar ao fluxo. O valor padrão é `Default`, o que significa que, para cada evento de fluxo de alterações, o Amazon DocumentDB enviará somente um delta descrevendo as alterações feitas. Para obter mais informações sobre esse campo, consulte [FullDocument](https://mongodb.github.io/mongo-java-driver/3.9/javadoc/com/mongodb/client/model/changestream/FullDocument.html#DEFAULT) na documentação da API do Javadoc do MongoDB.
  + **Padrão:** o Lambda envia somente um documento parcial descrevendo as alterações feitas.
  + **UpdateLookup:** o Lambda envia um delta descrevendo as alterações, junto com uma cópia de todo o documento.

## Criar um mapeamento da origem do evento do Amazon DocumentDB (SDK ou CLI)
<a name="docdb-api"></a>

Para criar ou gerenciar um mapeamento da origem do evento do Amazon DocumentDB com um [AWS SDK](https://aws.amazon.com/developer/tools/), você pode usar as seguintes operações de 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 criar o mapeamento da origem do evento com a AWS CLI, use o 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). O exemplo a seguir usa esse comando para mapear uma função denominada `my-function` para um fluxo de alterações do Amazon DocumentDB. A origem do evento é especificada por um nome do recurso da Amazon (ARN), com um tamanho de lote de 500, a partir do timestamp no horário do Unix. O comando também especifica a chave do Secrets Manager que o Lambda usa para se conectar ao Amazon DocumentDB. Além disso, ele inclui parâmetros `document-db-event-source-config` que especificam o banco de dados e a coleção de onde serão feitas as leituras.

```
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"}' \
```

Você deve ver uma saída semelhante a:

```
{
    "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"
}
```

Após a criação, você pode usar o 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 atualizar as configurações da origem do evento do Amazon DocumentDB. O exemplo a seguir atualiza o tamanho do lote para 1 mil e a janela do lote para dez segundos. Para esse comando, é necessário o UUID do mapeamento da origem do evento, que pode ser recuperado usando o comando `list-event-source-mapping` ou o console do Lambda.

```
aws lambda update-event-source-mapping --function-name my-function \
    --uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
    --batch-size 1000 \
    --batch-window 10
```

Você deve ver uma saída semelhante a:

```
{
    "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"
}
```

O Lambda atualiza as configurações de maneira assíncrona. Talvez você não veja essas alterações na saída até que o processo seja concluído. Para visualizar as configurações atuais do mapeamento da origem do evento, use o 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
```

Você deve ver uma saída semelhante a:

```
{
    "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 excluir o mapeamento da origem do evento do  Amazon DocumentDB, use o 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
```

## Posições iniciais de sondagem e fluxo
<a name="docdb-stream-polling"></a>

Esteja ciente de que a sondagem do fluxo durante a criação e as atualizações do mapeamento da origem do evento é, finalmente, consistente.
+ Durante a criação do mapeamento da origem do evento, pode levar alguns minutos para a sondagem de eventos do fluxo iniciar.
+ Durante as atualizações do mapeamento da origem do evento, pode levar alguns minutos para interromper e reiniciar a sondagem de eventos do fluxo.

Esse comportamento significa que, se você especificar `LATEST` como posição inicial do fluxo, o mapeamento da origem do evento poderá perder eventos durante a criação ou as atualizações. Para garantir que nenhum evento seja perdido, especifique a posição inicial do fluxo como `TRIM_HORIZON` ou `AT_TIMESTAMP`.

## Monitorar a origem do evento do Amazon DocumentDB
<a name="docdb-monitoring"></a>

Para ajudar você a monitorar a origem do evento do Amazon DocumentDB, o Lambda gera a métrica `IteratorAge` quando a função termina de processar um lote de registros. *Idade do iterador* é a diferença entre o carimbo de data e hora do evento mais recente e o carimbo de data e hora atual. Essencialmente a métrica `IteratorAge` indica a idade do último registro processado no lote. Se a função atualmente estiver processando novos eventos, você poderá usar a idade do iterador para estimar a latência entre quando um registro é adicionado e quando a função o processa. Uma tendência crescente em `IteratorAge` pode indicar problemas com a função. Para obter mais informações, consulte [Uso de métricas do CloudWatch com o Lambda](monitoring-metrics.md).

Os fluxos de alterações do Amazon DocumentDB não são otimizados para processar grandes intervalos de tempo entre os eventos. Se sua origem de eventos do Amazon DocumentDB não receber nenhum evento por um longo período de tempo, o Lambda poderá desabilitar o mapeamento da origem do evento. A duração desse período pode variar de algumas semanas a alguns meses, dependendo do tamanho do cluster e de outras workloads.

O Lambda é compatível com cargas úteis de até 6 MB. Entretanto, os eventos de fluxo de alterações do Amazon DocumentDB podem ter até 16 MB. Se seu fluxo de alterações tentar enviar ao Lambda um evento de fluxo de alterações maior que 6 MB, o Lambda descartará a mensagem e emitirá a métrica `OversizedRecordCount`. O Lambda emite todas as métricas com base no melhor esforço.

# Tutorial: uso do AWS Lambda com o Amazon DocumentDB Streams
<a name="with-documentdb-tutorial"></a>

 Neste tutorial, você criará uma função do Lambda que consome eventos de um stream de alterações do Amazon DocumentDB (compativel com MongoDB). Para concluir este tutorial, você passará pelos estágios a seguir: 
+ Configure seu cluster Amazon DocumentDB, conecte-se a ele e ative streams de alterações nele.
+ Crie a função do Lambda e configure seu cluster do Amazon DocumentDB como uma origem de eventos para a sua função.
+ Teste a configuração inserindo itens no banco de dados Amazon DocumentDB.

## Criar o cluster do Amazon DocumentDB
<a name="docdb-documentdb-cluster"></a>

1. Abra o [console do Amazon DocumentDB](https://console.aws.amazon.com/docdb/home#). Em **Clusters**, escolha **Criar**.

1. Crie um cluster com a seguinte configuração:
   + Em **Tipo de cluster**, escolha **Cluster baseado em instância**. Essa é a opção padrão.
   + Em **Configuração do cluster**, confira se a opção **Engine versão 5.0.0** está selecionada. Essa é a opção padrão.
   + Em **Configuração de instância**:
     + Em **Classe de instância de banco de dados**, selecione **Classes otimizadas para memória**. Essa é a opção padrão.
     + Em **Número de instâncias de réplicas regulares**, escolha 1.
     + Em **Classe de instância**, use a seleção padrão.
   + Em **Autenticação**, insira um nome de usuário para o usuário principal e escolha **Autogerenciado**. Insira uma senha e confirme-a.
   + Mantenha todas as outras configurações como o padrão.

1. Selecione **Criar cluster**.

## Criar o segredo no Secrets Manager
<a name="docdb-secret-in-secrets-manager"></a>

Enquanto o Amazon DocumentDB estiver criando o cluster, crie um segredo do AWS Secrets Manager para armazenar suas credenciais de banco de dados. Você fornecerá esse segredo ao criar o mapeamento da origem do evento do Lambda em uma etapa posterior.

**Para criar o segredo no Secrets Manager**

1. Abra o console do [Secrets Manager](https://console.aws.amazon.com/secretsmanager/home#) e escolha **Armazenar um novo segredo**.

1. Em **Escolha o tipo de segredo**, selecione as seguintes opções:
   + Em **Detalhes básicos**:
     + **Tipo de segredo**: credenciais para o banco de dados do Amazon DocumentDB
     + Em **Credenciais**, insira o nome de usuário e a senha que você usou para acessar o cluster do Amazon DocumentDB.
     + **Banco de dados**: escolha seu cluster do Amazon DocumentDB.
     + Escolha **Próximo**.

1. Em **Configurar segredo**, escolha as seguintes opções:
   + **Nome de segredo**: `DocumentDBSecret`
   + Escolha **Próximo**.

1. Escolha **Próximo**.

1. Escolha **Armazenar**.

1. Atualize o console para verificar se você armazenou o segredo `DocumentDBSecret` com êxito.

Anote o **ARN do segredo**. Você precisará dele em uma etapa posterior.

## Conectar-se ao cluster
<a name="docdb-connect-to-cluster"></a>

**Conectar-se ao cluster do Amazon DocumentDB usando o AWS CloudShell**

1. No console de gerenciamento do Amazon DocumentDB, em **Clusters**, localize o cluster que você criou. Escolha o cluster clicando na caixa de seleção ao lado dele.

1. Escolha **Conectar-se ao cluster**. A tela **Executar comando** do CloudShell é exibida.

1. No campo **Nome do novo ambiente**, insira um nome exclusivo, como "teste" e escolha **Criar e executar**.

1. Insira sua senha quando for solicitado. Quando o prompt se torna `rs0 [direct: primary] <env-name>>`, sua conexão com o cluster do Amazon DocumentDB foi estabelecida com êxito.

## Ativar os streams de alteração
<a name="docdb-activate-change-streams"></a>

Neste tutorial, você acompanhará as alterações na coleção de `products` do banco de dados `docdbdemo` em seu cluster do Amazon DocumentDB. Você faz isso com a ativação de [streams de alterações](https://docs.aws.amazon.com/documentdb/latest/developerguide/change_streams.html).

**Para criar um novo banco de dados em seu cluster**

1. Execute o seguinte comando para criar um novo banco de dados denominado `docdbdemo`:

   ```
   use docdbdemo
   ```

1. Na janela do terminal, use o seguinte comando para inserir um registro no `docdbdemo`:

   ```
   db.products.insertOne({"hello":"world"})
   ```

   Você deve ver uma saída como esta:

   ```
   {
     acknowledged: true,
     insertedId: ObjectId('67f85066ca526410fd531d59')
   }
   ```

1. Em seguida, ative os streams de alterações na coleção de `products` do banco de dados `docdbdemo` usando o seguinte comando:

   ```
   db.adminCommand({modifyChangeStreams: 1,
       database: "docdbdemo",
       collection: "products", 
       enable: true});
   ```

    Você deve ver uma saída semelhante a: 

   ```
   { "ok" : 1, "operationTime" : Timestamp(1680126165, 1) }
   ```

## Criar endpoints da VPC de interface
<a name="docdb-create-interface-vpc-endpoints"></a>

Em seguida, crie [endpoints da VPC de interface](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html#create-interface-endpoint-aws) para garantir que o Lambda e o Secrets Manager (usados posteriormente para armazenar nossas credenciais de acesso ao cluster) possam se conectar à sua VPC padrão.

**Para criar endpoints da VPC de interface**

1. Abra o [console da VPC](https://console.aws.amazon.com/vpc/home#). No menu à esquerda, em **Nuvem privada virtual**, escolha **Endpoints**.

1. Escolha **Criar endpoint**. Crie um endpoint com a seguinte configuração:
   + Em **Nomear tag**, insira `lambda-default-vpc`.
   + Em **Categoria do serviço**, escolha serviços da AWS.
   + Em **Serviços**, insira `lambda` na caixa de pesquisa. Escolha o serviço com formato `com.amazonaws.<region>.lambda`.
   + Em **VPC**, escolha a VPC em que está o cluster do Amazon DocumentDB. Normalmente, essa é a [VPC padrão](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html).
   + Em **sub-redes**, marque as caixas ao lado de cada zona de disponibilidade. Escolha O ID correto da sub-rede de cada zona de disponibilidade.
   + Em **Tipo de endereço IP**, selecione IPv4.
   + Em **Grupos de segurança**, escolha o grupo de segurança que o cluster do Amazon DocumentDB usa. Normalmente, esse é o grupo de segurança `default`.
   + Mantenha todas as outras configurações como o padrão.
   + Escolha **Criar endpoint**.

1. Novamente, escolha **Criar endpoint**. Crie um endpoint com a seguinte configuração:
   + Em **Nomear tag**, insira `secretsmanager-default-vpc`.
   + Em **Categoria do serviço**, escolha serviços da AWS.
   + Em **Serviços**, insira `secretsmanager` na caixa de pesquisa. Escolha o serviço com formato `com.amazonaws.<region>.secretsmanager`.
   + Em **VPC**, escolha a VPC em que está o cluster do Amazon DocumentDB. Normalmente, essa é a [VPC padrão](https://docs.aws.amazon.com/vpc/latest/userguide/default-vpc.html).
   + Em **sub-redes**, marque as caixas ao lado de cada zona de disponibilidade. Escolha O ID correto da sub-rede de cada zona de disponibilidade.
   + Em **Tipo de endereço IP**, selecione IPv4.
   + Em **Grupos de segurança**, escolha o grupo de segurança que o cluster do Amazon DocumentDB usa. Normalmente, esse é o grupo de segurança `default`.
   + Mantenha todas as outras configurações como o padrão.
   + Escolha **Criar endpoint**.

 Isso conclui a parte de configuração de cluster deste tutorial. 

## Criar a função de execução
<a name="docdb-create-the-execution-role"></a>

 No próximo conjunto de etapas, você criará sua função do Lambda. Primeiro, é necessário criar o perfil de execução que concede à sua função permissão para acessar o seu cluster. Você criará uma política do IAM primeiro e, em seguida, anexará essa política a um perfil do IAM. 

**Para criar uma política do IAM**

1. Abra a página [Políticas](https://console.aws.amazon.com/iam/home#/policies) no console do IAM e escolha **Criar política**.

1. Selecione a guia **JSON**. Na política a seguir, substitua o ARN do recurso Secrets Manager na linha final da declaração pelo ARN do seu segredo de antes, e copie a política no 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. Escolha **Próximo: Tags**, e, em seguida, escolha **Próximo: Revisar**.

1. Em **Nome**, insira `AWSDocumentDBLambdaPolicy`.

1. Escolha **Criar política**.

**Para criar perfil do IAM**

1. Abra a [página Perfis](https://console.aws.amazon.com/iam/home#/roles) no console do IAM e escolha **Criar perfil**.

1. Em **Selecionar entidade confiável**, escolha as seguintes opções:
   + **Tipo de entidade confiável**: serviço da AWS
   + **Serviço ou caso de uso**: Lambda
   + Escolha **Próximo**.

1. Em **Adicionar permissões**, escolha a política `AWSDocumentDBLambdaPolicy` que você acabou de criar, bem como `AWSLambdaBasicExecutionRole` para conceder à sua função permissões para gravar no Amazon CloudWatch Logs.

1. Escolha **Próximo**.

1. Em **Nome do perfil**, insira `AWSDocumentDBLambdaExecutionRole`.

1. Escolha **Create role** (Criar função).

## Criar a função do Lambda
<a name="docdb-create-the-lambda-function"></a>

Este tutorial usa o runtime do Python 3.14, mas também fornecemos exemplos de arquivos de código para outros runtimes. É possível selecionar a guia na caixa a seguir para ver o código do runtime do seu interesse.

O exemplo de código a seguir recebe uma entrada de evento do Amazon DocumentDB e processa a mensagem ali contida.

**Para criar a função do Lambda**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha a opção **Criar função**.

1. Escolher **Criar do zero**

1. Em **Basic information** (Informações básicas), faça o seguinte:

   1. Em **Nome da função**, inserir `ProcessDocumentDBRecords`

   1. Em **Runtime**, selecione **Python 3.14**.

   1. Em **Architecture** (Arquitetura), escolha **x86\$164**.

1. Na guia **Alterar função de execução padrão**, faça o seguinte:

   1. Expanda a guia e escolha **Usar uma função existente**.

   1. Selecione a `AWSDocumentDBLambdaExecutionRole` que você criou anteriormente.

1. Escolha **Criar função**.

**Para implantar o código da função**

1. Escolha a guia **Python** na caixa a seguir e copie o código.

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Processando um evento do Amazon DocumentDB com o Lambda ao usar .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumir um evento do Amazon DocumentDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumir um evento do Amazon DocumentDB com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumir um evento do Amazon DocumentDB com o Lambda usando 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));
   };
   ```
Consumir um evento do Amazon DocumentDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumir um evento do Amazon DocumentDB com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumir um evento do Amazon DocumentDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumir um evento do Amazon DocumentDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-docdb-to-lambda). 
Consumir um evento do Amazon DocumentDB com o Lambda usando 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. No painel de **Origem do código** no console do Lambda, cole o código no editor de código, substituindo o código criado pelo Lambda.

1. Na seção **DEPLOY**, escolha **Implantar** para atualizar o código da função:  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

## Crie o mapeamento da origem do evento do Lambda
<a name="docdb-create-the-lambda-event-source-mapping"></a>

 Crie o mapeamento da origem do evento que associa o seu fluxo de alterações do Amazon DocumentDB à sua função do Lambda. Depois que você criar esse mapeamento da origem do evento, o AWS Lambda começará imediatamente a sondar o stream. 

**Para criar o mapeamento da origem do evento**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) no console do Lambda.

1. Escolha a função `ProcessDocumentDBRecords` criada anteriormente.

1. Escolha a guia **Configuração** e depois escolha **Acionadores** no menu à esquerda.

1. Escolha **Add trigger**.

1. Em **Configuração do acionador**, para a origem, selecione **Amazon DocumentDB**.

1. Crie o mapeamento da origem do evento com a seguinte configuração:
   + **Cluster do Amazon DocumentDB**: escolha o cluster que você criou anteriormente.
   + **Nome do banco de dados**: docdbdemo
   + **Nome da coleção**: produtos
   + **Tamanho do lote**: 1
   + **Posição inicial**: a última
   + **Autenticação**: BASIC\$1AUTH
   + **Chave do Secrets Manager**: escolha o segredo do cluster do Amazon DocumentDB. O nome da chave será algo como `rds!cluster-12345678-a6f0-52c0-b290-db4aga89274f`.
   + **Janela de lote**: 1
   + **Configuração do documento total**: UpdateLookup

1. Escolha **Adicionar**. A criação do mapeamento da origem do evento pode levar alguns minutos.

## Testar a função
<a name="docdb-test-insert"></a>

Espere o mapeamento da origem do evento atingir o estado de **Habilitado**. Isso pode demorar vários minutos. Depois, teste a configuração de ponta a ponta inserindo, atualizando e excluindo registros do banco de dados. Antes de começar:

1. [Reconecte-se ao cluster do Amazon DocumentDB](#docdb-connect-to-cluster) no ambiente do CloudShell.

1. Execute o comando a seguir para garantir que esteja usando o banco de dados `docdbdemo`:

   ```
   use docdbdemo
   ```

### Inserir um registro
<a name="docdb-test-insert"></a>

Insira um registro na coleção `products` do banco de dados `docdbdemo`:

```
db.products.insertOne({"name":"Pencil", "price": 1.00})
```

Veja se a função processou o evento com êxito [verificando o CloudWatch Logs](monitoring-cloudwatchlogs-view.md#monitoring-cloudwatchlogs-console). Você deve ver uma entrada de log como esta:

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/documentdb-insert-log.png)


### Atualizar um registro
<a name="docdb-test-update"></a>

Atualize o registro que você acabou de inserir com o seguinte comando:

```
db.products.updateOne(
    { "name": "Pencil" },
    { $set: { "price": 0.50 }}
)
```

Veja se a função processou o evento com êxito [verificando o CloudWatch Logs](monitoring-cloudwatchlogs-view.md#monitoring-cloudwatchlogs-console). Você deve ver uma entrada de log como esta:

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/documentdb-update-log.png)


### Excluir um registro
<a name="docdb-test-delete"></a>

Exclua o registro que você acabou de atualizar com o seguinte comando:

```
db.products.deleteOne( { "name": "Pencil" } )
```

Veja se a função processou o evento com êxito [verificando o CloudWatch Logs](monitoring-cloudwatchlogs-view.md#monitoring-cloudwatchlogs-console). Você deve ver uma entrada de log como esta:

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/documentdb-delete-log.png)


## Solução de problemas
<a name="docdb-lambda-troubleshooting"></a>

Se você não vir nenhum evento de banco de dados nos logs do CloudWatch da sua função, verifique o seguinte:
+ Confira se o mapeamento da origem do evento do Lambda (também conhecido como acionador) está no estado **Habilitado**. A criação de mapeamentos de origens de eventos pode levar vários minutos.
+ Se o mapeamento da origem do evento estiver **Habilitado**, mas os eventos do banco de dados ainda não estiverem visíveis no CloudWatch:
  + Confira se o **Nome do banco de dados** no mapeamento da origem do evento está definido como `docdbdemo`.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/documentdb-trigger.png)
  + Verifique se o campo **Último resultado de processamento** do mapeamento da origem do evento mostra a seguinte mensagem "PROBLEMA: erro de conexão. A VPC deve conseguir se conectar ao Lambda e ao STS, e também ao Secrets Manager se for exigida autenticação". Se você vir esse erro, confira se [criou os endpoints de interface da VPC do Lambda e do Secrets Manager](#docdb-create-interface-vpc-endpoints), e se os endpoints usam a mesma VPC e as mesmas sub-redes que o cluster Amazon DocumentDB.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/documentdb-lastprocessingresult.png)

## Limpe os recursos
<a name="docdb-cleanup"></a>

 Agora você pode excluir os recursos criados para este tutorial, a menos que queira mantê-los. Excluindo os recursos da AWS que você não está mais usando, você evita cobranças desnecessárias em sua Conta da AWS. 

**Como excluir a função do Lambda**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Selecione a função que você criou.

1. Selecione **Ações**, **Excluir**.

1. Digite **confirm** no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir a função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione a função de execução que você criou.

1. Escolha **Excluir**.

1. Insira o nome do perfil no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir os endpoints da VPC**

1. Abra o [console da VPC](https://console.aws.amazon.com/vpc/home#). No menu à esquerda, em **Nuvem privada virtual**, escolha **Endpoints**.

1. Selecione os endpoints que você criou.

1. Escolha **Actions** (Ações), **Delete VPC endpoints** (Excluir endpoints da VPC).

1. Digite **delete** no campo de entrada de texto.

1. Escolha **Excluir**.

**Para excluir o cluster do Amazon DocumentDB**

1. Abra o [console do Amazon DocumentDB](https://console.aws.amazon.com/docdb/home#).

1. Escolha o cluster do Amazon DocumentDB que você criou para este tutorial e desative a proteção contra exclusão.

1. Na página principal de **Clusters**, escolha seu cluster do Amazon DocumentDB novamente.

1. Selecione **Ações**, **Excluir**.

1. Em **Criar snapshot final do cluster**, selecione **Não**.

1. Digite **delete** no campo de entrada de texto.

1. Escolha **Excluir**.

**Para excluir o segredo no Secrets Manager**

1. Abra o [console do Secrets Manager](https://console.aws.amazon.com/secretsmanager/home#).

1. Escolha o segredo que você criou para este tutorial.

1. Escolha **Ações**, **Excluir segredo**.

1. Escolha **Schedule deletion**.

# Usar o AWS Lambda com o Amazon DynamoDB
<a name="with-ddb"></a>

**nota**  
Se você deseja enviar dados para um destino que não seja uma função do Lambda ou enriquecer os dados antes de enviá-los, consulte [Amazon EventBridge Pipes](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html) (Pipes do Amazon EventBridge).

É possível usar uma função do AWS Lambda para processar registros em um [Amazon DynamoDB Stream](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html). Com o DynamoDB Streams, você pode acionar uma função do Lambda para executar o trabalho adicional cada vez que uma tabela do DynamoDB é atualizada.

Ao processar fluxos do DynamoDB, é necessário implementar uma lógica de resposta em lote parcial para evitar que registros processados com sucesso sejam repetidos quando alguns registros em um lote falham. O [utilitário Processador em Lote](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) do Powertools para AWS Lambda está disponível em Python, TypeScript, .NET e Java e simplifica essa implementação ao lidar automaticamente com a lógica de resposta em lote parcial, reduzindo o tempo de desenvolvimento e melhorando a confiabilidade.

**Topics**
+ [Fluxos de sondagem e agrupamento em lotes](#dynamodb-polling-and-batching)
+ [Posições iniciais de sondagem e fluxo](#dyanmo-db-stream-poll)
+ [Leitores simultâneos de um fragmento no DynamoDB Streams](#events-dynamodb-simultaneous-readers)
+ [Evento de exemplo](#events-sample-dynamodb)
+ [Processar registros do DynamoDB com o Lambda](services-dynamodb-eventsourcemapping.md)
+ [Configurar resposta em lote parcial com o DynamoDB e o Lambda](services-ddb-batchfailurereporting.md)
+ [Reter registros descartados para uma origem de eventos do DynamoDB no Lambda](services-dynamodb-errors.md)
+ [Implementar o processamento com estado do DynamoDB no Lambda](services-ddb-windows.md)
+ [Parâmetros do Lambda para os mapeamentos das origens de eventos do Amazon DynamoDB](services-ddb-params.md)
+ [Usar a filtragem de eventos com uma origem de eventos do DynamoDB](with-ddb-filtering.md)
+ [Tutorial: Usar o AWS Lambda com o Amazon DynamoDB Streams](with-ddb-example.md)

## Fluxos de sondagem e agrupamento em lotes
<a name="dynamodb-polling-and-batching"></a>

O Lambda sonda os fragmentos em sua transmissão do DynamoDB em busca de registros a uma taxa básica de 4 vezes por segundo. Quando os registros estão disponíveis, o Lambda invoca a função e aguarda o resultado. Se o processamento for bem-sucedido, o Lambda continua a sondagem até que ela receba mais registros.

Por padrão, o Lambda invoca a função assim que os registros estão disponíveis. Se o lote que o Lambda lê da fonte de eventos tiver apenas um registro, o Lambda enviará apenas um registro à função. Para evitar a invocação da função com poucos registros, instrua a fonte de eventos para armazenar os registros em buffer por até cinco minutos, configurando uma *janela de lotes*. Antes de invocar a função, o Lambda continua a ler registros da fonte de eventos até coletar um lote inteiro, até que a janela de lote expire ou até que o lote atinja o limite de carga útil de 6 MB. Para obter mais informações, consulte [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

**Atenção**  
Os mapeamentos da origem do evento do Lambda processam cada evento ao menos uma vez, podendo haver o processamento duplicado de registros. Para evitar possíveis problemas relacionados a eventos duplicados, é altamente recomendável tornar o código da função idempotente. Para saber mais, consulte [Como tornar minha função do Lambda idempotente](https://repost.aws/knowledge-center/lambda-function-idempotent) no Centro de Conhecimentos da AWS.

O Lambda não espera a conclusão de nenhuma [extensão](lambda-extensions.md)configurada para enviar o próximo lote para processamento. Em outras palavras, suas extensões podem continuar sendo executadas enquanto o Lambda processa o próximo lote de registros. Isso pode causar problemas de controle de utilização se você violar quaisquer configurações ou limites de [simultaneidade](lambda-concurrency.md) de sua conta. Para detectar se esse é um problema em potencial, monitore suas funções e verifique se você está vendo [métricas de simultaneidade](monitoring-concurrency.md#general-concurrency-metrics) mais altas do que o esperado para o seu mapeamento da origem do evento. Devido ao curto intervalo entre as invocações, o Lambda pode relatar brevemente um uso de simultaneidade maior do que o número de fragmentos. Isso pode ser verdadeiro até mesmo para funções do Lambda sem extensões.

Defina a configuração [ParallelizationFactor](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-ParallelizationFactor) para processar um fragmento de um fluxo de dados do DynamoDB com mais de uma invocação do Lambda simultaneamente. Você pode especificar o número de lotes simultâneos que o Lambda pesquisa de um fragmento por meio de um fator de paralelização de 1 (padrão) a 10. Por exemplo, quando você define `ParallelizationFactor` como 2, pode ter até 200 invocações simultâneas do Lambda para processar 100 fragmentos de fluxos do DynamoDB (embora, na prática, você possa ver valores diferentes para a métrica `ConcurrentExecutions`). Isso ajuda a aumentar a escala do throughput de processamento quando o volume de dados é volátil e o valor de [IteratorAge](monitoring-metrics-types.md#performance-metrics) é alto. Quando você aumentar o número de lotes simultâneos por fragmento, o Lambda ainda garantirá o processamento por ordem no nível de item (partição e chave de classificação).

## Posições iniciais de sondagem e fluxo
<a name="dyanmo-db-stream-poll"></a>

Esteja ciente de que a sondagem do fluxo durante a criação e as atualizações do mapeamento da origem do evento é, finalmente, consistente.
+ Durante a criação do mapeamento da origem do evento, pode levar alguns minutos para a sondagem de eventos do fluxo iniciar.
+ Durante as atualizações do mapeamento da origem do evento, pode levar alguns minutos para interromper e reiniciar a sondagem de eventos do fluxo.

Esse comportamento significa que, se você especificar `LATEST` como posição inicial do fluxo, o mapeamento da origem do evento pode perder eventos durante a criação ou as atualizações. Para garantir que nenhum evento seja perdido, especifique a posição inicial do fluxo como `TRIM_HORIZON`.

## Leitores simultâneos de um fragmento no DynamoDB Streams
<a name="events-dynamodb-simultaneous-readers"></a>

Para tabelas de região única que não são tabelas globais, você pode projetar até duas funções do Lambda para ler o mesmo fragmento do DynamoDB Streams ao mesmo tempo. Exceder esse limite pode resultar em controle de utilização de solicitação. Para tabelas globais, recomendamos que você limite o número de leitores simultâneos para 1 para evitar o controle de utilização de solicitações.

## Evento de exemplo
<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"
    }
  ]}
```

# Processar registros do DynamoDB com o Lambda
<a name="services-dynamodb-eventsourcemapping"></a>

Crie um mapeamento de fontes de eventos para orientar o Lambda a enviar registros de sua transmissão para uma função do Lambda. É possível criar vários mapeamentos de origem de evento para processar os mesmos dados com várias funções do Lambda ou processar itens de vários fluxos com uma única função.

Você pode configurar mapeamentos da origem do evento para processar registros de um fluxo em outra Conta da AWS. Para saber mais, consulte [Como criar mapeamentos da origem do evento entre contas](#services-dynamodb-eventsourcemapping-cross-account).

Para configurar sua função para ler do DynamoDB Streams, anexe a política [AWSLambdaDynamoDBExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaDynamoDBExecutionRole.html) gerenciada pela AWS ao seu perfil de execução e, em seguida, crie um gatilho **DynamoDB**.

**Para adicionar permissões e criar um acionador**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha o nome de uma função.

1. Escolha a guia **Configuration** (Configuração) e, depois, **Permissions** (Permissões).

1. Em **Nome do perfil**, escolha o link para seu perfil de execução. Esse link abre o perfil no console do IAM.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/execution-role.png)

1. Escolha **Adicionar permissões** e depois **Anexar políticas**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/attach-policies.png)

1. No campo de pesquisa, digite `AWSLambdaDynamoDBExecutionRole`. Adicione esta política ao seu perfil de execução Essa é uma política gerenciada pela AWS que contém as permissões de que a função precisa para ler um fluxo do DynamoDB. Para obter mais informações sobre essa política, consulte [AWSLambdaDynamoDBExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaDynamoDBExecutionRole.html) na *Referência de política gerenciada da AWS*.

1. Volte para a sua função no console do Lambda Em **Visão geral da função**, escolha **Adicionar gatilho**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/add-trigger.png)

1. Escolha um tipo de acionador.

1. Configure as opções necessárias e escolha **Add** (Adicionar).

O Lambda é compatível com as seguintes opções de origens de eventos do DynamoDB:

**Opções de fonte do evento**
+ **DynamoDB table** (Tabela do DynamoDB): a tabela do DynamoDB da qual os registros serão lidos.
+ **Batch size** (Tamanho do lote): o número de registros a serem enviados para a função em cada lote, até 10.000. O Lambda transmite todos os registros no batch para a função em uma única chamada, enquanto o tamanho total dos eventos não exceder o [limite de carga útil](gettingstarted-limits.md) para invocação síncrona (6 MB).
+ **Batch window** (Janela de lote): especifique o máximo de tempo para reunir registros antes de invocar a função, em segundos.
+ **Starting position** (Posição inicial): processe apenas registros novos ou todos os registros existentes.
  + **Latest** (Mais recente): processe novos registros adicionados ao fluxo.
  + **Trim horizon** (Redução horizontal): processe todos os registros na transmissão.

  Depois de processar todos os registros existentes, a função é capturada e continua a processar novos registros.
+ **Destino na falha**: uma fila padrão do SQS ou um tópico padrão do SNS para registros que não podem ser processados. Quando o Lambda descarta um lote de registros que é muito antigo ou esgotou todas as tentativas, ele envia detalhes sobre o lote à fila ou ao tópico.
+ **Retry attempts** (Tentativas de repetição): o número máximo de vezes que o Lambda tenta novamente quando a função retorna um erro. Isso não se aplica a erros de serviço ou controles em que o lote não atingiu a função.
+ **Idade máxima do registro**: a idade máxima de um registro que o Lambda envia para sua função.
+ **Dividir lote por erro**: quando a função retornar um erro, o lote é dividido em dois antes de uma nova tentativa. A configuração do tamanho do lote original permanece inalterada.
+ **Concurrent batches per shard** (Lotes simultâneos por fragmento): processa simultaneamente vários lotes do mesmo fragmento.
+ **Enabled** (Habilitado): defina como verdadeiro para habilitar o mapeamento de fontes de eventos. Defina como falso para interromper o processamento de registros. O Lambda monitora o último registro processado e retoma o processamento a partir desse ponto quando o mapeamento é habilitado novamente.

**nota**  
Você não é cobrado por chamadas da API GetRecords invocadas pelo Lambda como parte de acionadores do DynamoDB.

Para gerenciar a configuração da fonte do evento posteriormente, escolha o gatilho no designer.

## Como criar mapeamentos da origem do evento entre contas
<a name="services-dynamodb-eventsourcemapping-cross-account"></a>

O Amazon DynamoDB agora é compatível com [políticas baseadas em recursos](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/access-control-resource-based.html). Com esse recurso, você pode processar dados de um fluxo do DynamoDB em uma Conta da AWS com uma função do Lambda em outra conta.

Para criar um mapeamento da origem do evento para sua função do Lambda usando um fluxo do DynamoDB em outra Conta da AWS, você deve configurar o fluxo usando uma política baseada em recursos para dar permissão à função do Lambda para ler registros. Para saber como configurar o fluxo para permitir acesso entre contas, consulte [Compartilhar acesso com funções do Lambda entre contas](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/rbac-cross-account-access.html#rbac-analyze-cross-account-lambda-access) no *Guia do desenvolvedor do Amazon DynamoDB*.

Depois de configurar o fluxo com uma política baseada em recursos que conceda à função do Lambda as permissões necessárias, crie o mapeamento da origem do evento com seu ARN do fluxo entre contas. Você pode encontrar o ARN do fluxo na guia **Exportações e fluxos** da tabela no console do DynamoDB entre contas. 

Ao usar o console do Lambda, cole o ARN do fluxo diretamente no campo de entrada da tabela do DynamoDB na página de criação do mapeamento da origem do evento.

 **Observação:** não há suporte para gatilhos entre regiões. 

# Configurar resposta em lote parcial com o DynamoDB e o Lambda
<a name="services-ddb-batchfailurereporting"></a>

Ao consumir e processar dados de transmissão de uma fonte de eventos, o Lambda definirá checkpoints por padrão no número mais elevado na sequência de um lote somente quando o lote for um sucesso total. O Lambda trata todos os outros resultados como uma falha completa e tenta processar novamente o lote até o limite de novas tentativas. Para permitir sucessos parciais durante o processamento de lotes de um stream, ative `ReportBatchItemFailures`. Permitir sucessos parciais pode ajudar a reduzir o número de novas tentativas em um registro, embora não impeça totalmente a possibilidade de novas tentativas em um registro bem-sucedido.

Para ativar `ReportBatchItemFailures`, inclua o valor de enum **ReportBatchItemFailures** na lista [FunctionResponseTypes](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-FunctionResponseTypes). Essa lista indica quais tipos de resposta estão habilitados para sua função. Você pode configurar essa lista ao [criar](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) ou [atualizar](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) um mapeamento de origem de eventos.

**nota**  
Mesmo quando seu código de função retorna respostas parciais de falha em lote, essas respostas não serão processadas pelo Lambda, a menos que o atributo `ReportBatchItemFailures` esteja explicitamente ativado para o mapeamento da origem do evento.

## Sintaxe do relatório
<a name="streams-batchfailurereporting-syntax"></a>

Ao configurar relatórios sobre falhas de itens de lote, a classe `StreamsEventResponse` é retornada com uma lista de falhas de itens de lote. É possível usar um objeto `StreamsEventResponse` para retornar o número sequencial do primeiro registro com falha no lote. Você também pode criar sua própria classe personalizada usando a sintaxe de resposta correta. A seguinte estrutura JSON mostra a sintaxe de resposta necessária:

```
{ 
  "batchItemFailures": [ 
        {
            "itemIdentifier": "<SequenceNumber>"
        }
    ]
}
```

**nota**  
Se a matriz `batchItemFailures` contém vários itens, o Lambda usa o registro com o menor número de sequência como ponto de verificação. Em seguida, o Lambda repete todos os registros a partir desse ponto de verificação.

## Condições de sucesso e falha
<a name="streams-batchfailurereporting-conditions"></a>

O Lambda trata um lote como um sucesso completo se você retornar qualquer um destes:
+ Uma lista de `batchItemFailure` vazia
+ Uma lista de `batchItemFailure` nula
+ Uma vazia `EventResponse`
+ Uma nula `EventResponse`

O Lambda trata um lote como uma falha absoluta se você retornar qualquer um dos seguintes:
+ Uma string vazia `itemIdentifier`
+ Uma nula `itemIdentifier`
+ Um `itemIdentifier` com um nome de chave inválido

O Lambda faz novas tentativas após falhas com base na sua estratégia de repetição.

## Dividir um lote
<a name="streams-batchfailurereporting-bisect"></a>

Se a invocação falhar e `BisectBatchOnFunctionError` estiver ativado, o lote será dividido independentemente da configuração de `ReportBatchItemFailures`.

Quando uma resposta de sucesso parcial do lote é recebida e tanto `BisectBatchOnFunctionError` quanto `ReportBatchItemFailures` estão ativados, o lote é dividido no número de sequência retornado e o Lambda tenta novamente apenas os registros restantes.

Para simplificar a implementação da lógica de respostas parciais em lote, considere usar o [utilitário de processador em lote](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) da Powertools para AWS Lambda, que lida de maneira automática com essas complexidades para você.

Veja alguns exemplos de código de função que retornam a lista de IDs de mensagens com falha no lote:

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Como relatar falhas de itens em lote do DynamoDB com o Lambda usando .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Como relatar falhas de itens em lote do DynamoDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Como relatar falhas de itens em lote do DynamoDB com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Como relatar falhas de itens em lote do DynamoDB com o Lambda usando 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: [] };
};
```
Como relatar falhas de itens em lote do DynamoDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Relatar falhas de itens em lote do DynamoDB com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Como relatar falhas de itens em lote do DynamoDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Como relatar falhas de itens em lote do DynamoDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda-with-batch-item-handling). 
Como relatar falhas de itens em lote do DynamoDB com o Lambda usando 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
}
```

------

## Usar o Powertools para o processador em lote AWS Lambda
<a name="services-ddb-batchfailurereporting-powertools"></a>

O utilitário de processador em lote do Powertools para AWS Lambda lida de maneira automática com a lógica de respostas parciais em lote, reduzindo a complexidade da implementação de relatórios de falhas em lote. Veja a seguir alguns exemplos usando o processador em lote:

**Python**  
Para ver exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/).
Processamento de registros de fluxo do DynamoDB com processador em lote 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 exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.aws.amazon.com/powertools/typescript/latest/features/batch/).
Processamento de registros de fluxo do DynamoDB com processador em lote 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 exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.powertools.aws.dev/lambda/java/latest/utilities/batch/).
Processamento de registros de fluxo do DynamoDB com processador em lote 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 exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.aws.amazon.com/powertools/dotnet/utilities/batch-processing/).
Processamento de registros de fluxo do DynamoDB com processador em lote AWS Lambda.  

```
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; 
    }
}
```

# Reter registros descartados para uma origem de eventos do DynamoDB no Lambda
<a name="services-dynamodb-errors"></a>

O tratamento de erros para mapeamentos de origem de eventos do DynamoDB depende se o erro ocorre antes de a função ser invocada ou durante a invocação da função:
+ **Antes da invocação:** se um mapeamento de origem de eventos do Lambda não conseguir invocar a função devido a limitações ou a outros problemas, ele tentará novamente até que os registros expirem ou excedam a idade máxima configurada no mapeamento de origem de eventos ([MaximumRecordAgeInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)).
+ **Durante a invocação:** se a função for invocada, mas retornar um erro, o Lambda tentará novamente até que os registros expirem, excedam a idade máxima ([MaximumRecordAgeInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)) ou atinjam a cota de repetição configurada ([MaximumRetryAttempts](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRetryAttempts)). Para erros de função, também é possível pode configurar [BisectBatchOnFunctionError](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-response-BisectBatchOnFunctionError), que divide um lote com falha em dois lotes em lotes, isolando registros com problema e evitando exceder tempos limites. A divisão de lotes não consome a cota de repetição.

Se as medidas de tratamento de erros falharem, o Lambda descartará os registros e continuará processando lotes provenientes da transmissão. Com as configurações padrão, isso significa que um registro inválido pode bloquear o processamento no fragmento afetado por até um dia. Para evitar isso, configure o mapeamento de fontes de eventos da sua função com um número razoável de tentativas e uma idade máxima de registro que se adapte ao seu caso de uso.

## Configurar destinos para invocações com falha
<a name="dynamodb-on-failure-destination-console"></a>

Para reter registros de invocações de mapeamento da origem do evento com falha, adicione um destino ao mapeamento da origem de eventos da função. Cada registro enviado ao destino é um documento JSON que contém metadados sobre a invocação que falhou. Para destinos do Amazon S3, o Lambda também envia todo o registro da invocação junto com os metadados. É possível configurar qualquer tópico do Amazon SNS, fila do Amazon SQS, bucket do Amazon S3 ou Kafka como destino.

Com destinos do Amazon S3, você pode usar o recurso [Notificações de eventos do Amazon S3](https://docs.aws.amazon.com/) para receber notificações quando objetos forem carregados no bucket do S3 de destino. Também é possível configurar as notificações de eventos do S3 para invocar outra função do Lambda para realizar o processamento automatizado em lotes com falha.

Sua função de execução deve ter permissões para o destino:
+ **Para um destino do SQS:** [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)
+ **Para um destino do SNS:** [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)
+ **Para um destino do S3:** [s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) e [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/ListObjectsV2.html)
+ **Para um destino do Kafka**: [kafka-cluster:WriteData](https://docs.aws.amazon.com/msk/latest/developerguide/kafka-actions.html)

É possível configurar um tópico do Kafka como um destino do Kafka em caso de falha para os seus mapeamentos da origem do evento do Kafka. Quando o Lambda não consegue processar registros após exaurir as novas tentativas ou quando os registros excedem a idade máxima, o Lambda envia os registros com falha para o tópico especificado do Kafka para processamento posterior. Consulte [Uso de um tópico do Kafka como destino em caso de falha](kafka-on-failure-destination.md).

Se você habilitou a criptografia com sua própria chave do KMS para um destino do S3, o perfil de execução da função também deve ter permissão para chamar [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html). Se a chave do KMS e o destino do bucket do S3 estiverem em uma conta diferente da função do Lambda e do perfil de execução, configure a chave do KMS para confiar no perfil de execução para permitir kms:GenerateDataKey.

Para configurar um destino em caso de falha usando o console, siga estas etapas:

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha uma função.

1. Em **Function overview (Visão geral da função)**, escolha **Add destination (Adicionar destino)**.

1. Em **Origem**, escolha **Invocação do mapeamento da origem do evento**.

1. Em **Mapeamento da origem do evento**, escolha uma origem de eventos configurada para essa função.

1. Em **Condição**, selecione **Em caso de falha**. Para invocações de mapeamento da origem de eventos, essa é a única condição aceita.

1. Em **Tipo de destino**, escolha o tipo de destino para o qual o Lambda envia registros de invocação.

1. Em **Destination (Destino)**, escolha um recurso.

1. Escolha **Salvar**.

Também é possível configurar um destino em caso de falha usando a AWS Command Line Interface (AWS CLI). Por exemplo, o seguinte comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) adiciona um mapeamento de origem de eventos com um destino SQS em caso de falha 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"}}'
```

O comando [update-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) a seguir atualiza um mapeamento de origem de eventos para enviar registros de chamada com falha para um destino SNS após duas novas tentativas ou se os registros tiverem mais de uma hora.

```
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"}}'
```

As configurações atualizadas são aplicadas de forma assíncrona e não são refletidas na saída até que o processo seja concluído. Use o comando [get-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-event-source-mapping.html) para visualizar o status atual.

Para remover um destino, forneça uma string vazia como argumento para o parâmetro `destination-config`:

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--destination-config '{"OnFailure": {"Destination": ""}}'
```

### Práticas recomendadas de segurança para destinos do Amazon S3
<a name="ddb-s3-destination-security"></a>

Excluir um bucket do S3 configurado como destino sem remover o destino da configuração da sua função pode criar um risco de segurança. Se outro usuário souber o nome do seu bucket de destino, ele poderá recriar o bucket na Conta da AWS dele. Registros de invocações com falha serão enviados para o bucket do usuário, potencialmente expondo dados da sua função.

**Atenção**  
Para garantir que os registros de invocação da sua função não possam ser enviados para um bucket do S3 em outra Conta da AWS, adicione uma condição ao perfil de execução da função que limite as permissões `s3:PutObject` aos buckets na sua conta. 

O exemplo a seguir mostra uma política do IAM que limita as permissões `s3:PutObject` da função aos bucket da conta. Essa política também dá ao Lambda a permissão `s3:ListBucket` necessária para usar um bucket do 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 adicionar uma política de permissões ao perfil de execução da função usando o Console de gerenciamento da AWS ou a AWS CLI, consulte as instruções nos seguintes procedimentos:

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

**Para adicionar uma política de permissões ao perfil de execução de uma função (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Selecione a função do Lambda cujo perfil de execução você queira modificar.

1. Na guia **Configuração**, escolha **Permissões**.

1. Na guia **Perfil de execução**, selecione o **Nome do perfil** da função para abrir a página do console do IAM do perfil.

1. Adicione uma política de permissões ao perfil da seguinte maneira:

   1. No painel **Políticas de permissões**, escolha **Adicionar permissões** e **Criar política em linha**.

   1. No **Editor de políticas**, selecione **JSON**.

   1. Cole a política que você deseja adicionar no editor (substituindo o JSON existente) e escolha **Próximo**.

   1. No campo **Detalhes da política**, insira o **Nome da política**.

   1. Escolha **Criar política**.

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

**Para adicionar uma política de permissões ao perfil de execução de uma função (CLI)**

1. Crie um documento de política de JSON com as permissões necessárias e salve-o em um diretório local.

1. Use o comando da CLI `put-role-policy` do IAM para adicionar permissões ao perfil de execução da função. Execute o comando a seguir no diretório em que você salvou seu documento de política de JSON e substitua o nome do perfil, o nome da política e o documento da política pelos seus próprios valores.

   ```
   aws iam put-role-policy \
   --role-name my_lambda_role \
   --policy-name LambdaS3DestinationPolicy \
   --policy-document file://my_policy.json
   ```

------

### Exemplo de registro de invocação do Amazon SNS e do Amazon SQS
<a name="kinesis-on-failure-destination-example-sns-sqs"></a>

O exemplo a seguir mostra um registro de invocação enviado pelo Lambda para um destino do SQS ou do SNS para um fluxo do 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"
    }
}
```

É possível usar essas informações para recuperar os registros afetados da transmissão para solução de problemas. Os registros reais não estão incluídos, portanto, você deve processar esses registros e recuperá-los da transmissão antes que eles expirem e sejam perdidos.

### Exemplo de registro de invocação do Amazon S3
<a name="kinesis-on-failure-destination-example-sns-sqs-s3"></a>

O exemplo a seguir mostra um registro de invocação que o Lambda envia a um bucket do S3 para um fluxo do DynamoDB. Além de todos os campos do exemplo anterior para destinos do SQS e do SNS, o campo `payload` contém o registro de invocação original como uma string JSON com 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
}
```

O objeto do S3 que contém o registro de invocação usa a seguinte convenção de nomenclatura:

```
aws/lambda/<ESM-UUID>/<shardID>/YYYY/MM/DD/YYYY-MM-DDTHH.MM.SS-<Random UUID>
```

# Implementar o processamento com estado do DynamoDB no Lambda
<a name="services-ddb-windows"></a>

As funções do Lambda podem executar aplicações de processamento contínuo de transmissões. Um stream representa dados não vinculados que fluem continuamente por meio de sua aplicação. Para analisar as informações dessa entrada de atualização contínua, você pode vincular os registros incluídos usando uma janela definida em termos de tempo.

As janelas de tumbling são janelas de tempo distintas que abrem e fecham em intervalos regulares. Por padrão, as invocações do Lambda são sem estado. Não é possível usá-las para processar dados ao longo de várias invocações contínuas sem um banco de dados externo. No entanto, com as janelas de tumbling, você pode manter seu estado em todas as invocações. Esse estado contém o resultado agregado das mensagens previamente processadas para a janela atual. Seu estado pode ter no máximo 1 MB por fragmento. Se exceder esse tamanho, o Lambda encerra a janela antes.

Cada registro de um fluxo pertence a uma janela específica. O Lambda processará cada registro pelo menos uma vez, mas não garantirá que cada registro seja processado apenas uma vez. Em casos raros, como tratamento de erros, alguns registros poderão ser processados mais de uma vez. Os registros são sempre processados em ordem na primeira vez. Se os registros forem processados mais de uma vez, poderão ser processados fora de ordem.

## Agregação e processamento
<a name="streams-tumbling-processing"></a>

Sua função gerenciada pelo usuário é chamada tanto para agregação quanto para processamento dos resultados finais dessa agregação. O Lambda agrega todos os registros recebidos na janela. Você pode receber esses registros em vários lotes, cada um como uma invocação separada. Cada invocação recebe um estado. Assim, ao usar janelas de tumbling, sua resposta de função do Lambda deve conter uma propriedade de `state`. Se a resposta não contiver uma propriedade de `state`, o Lambda considerará esta uma invocação com falha. Para satisfazer essa condição, a função pode retornar um objeto do `TimeWindowEventResponse`, que tem a seguinte forma JSON:

**Example `TimeWindowEventResponse`Valores de**  

```
{
    "state": {
        "1": 282,
        "2": 715
    },
    "batchItemFailures": []
}
```

**nota**  
Para funções Java, recomendamos o uso de um `Map<String, String>` para representar o estado.

No final da janela, a sinalização `isFinalInvokeForWindow` é definida como `true` para indicar que esse é o estado final e que está pronto para processamento. Após o processamento, a janela é concluída e sua invocação final é concluída e, em seguida, o estado é descartado.

No final da janela, o Lambda usa o processamento final para ações sobre os resultados da agregação. Seu processamento final é invocado de forma síncrona. Após a invocação bem-sucedida, sua função define os pontos de verificação no número da sequência e o processamento de streams continua. Se a invocação não for bem-sucedida, sua função do Lambda suspenderá o processamento adicional até uma chamada bem-sucedida.

**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
}
```

## Configuração
<a name="streams-tumbling-config"></a>

Você pode configurar janelas em cascata ao criar ou atualizar um mapeamento de fonte de eventos. Para configurar uma janela em cascata, especifique a janela em segundos ([TumblingWindowInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-TumblingWindowInSeconds)). O comando de exemplo da AWS Command Line Interface (AWS CLI) a seguir cria um mapeamento de fonte de eventos em streaming com uma janela em cascata de 120 segundos. A função do Lambda definida para agregação e processamento é chamada de `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
```

O Lambda determina os limites da janela em cascata com base no horário em que os registros foram inseridos no stream. Todos os registros têm um carimbo de data/hora aproximado disponível que o Lambda usa para determinar os limites.

As agregações de janelas em cascata não são compatíveis com refragmentação. Quando o fragmento termina, o Lambda considera a janela como fechada e os fragmentos filhos iniciam suas próprias janelas em um novo estado.

As janelas em cascata são totalmente compatíveis com as políticas `maxRetryAttempts` e `maxRecordAge`.

**Example Handler.py: agregação e processamento**  
A função do Python a seguir demonstra como agregar e, em seguida, processar seu 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 do Lambda para os mapeamentos das origens de eventos do Amazon DynamoDB
<a name="services-ddb-params"></a>

Todos os tipos de origem de evento Lambda compartilham o mesmo[CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html)e[UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html)Operações de API do. No entanto, apenas alguns dos parâmetros se aplicam aos Fluxos do DynamoDB Streams.


| Parâmetro | Obrigatório | Padrão | Observações | 
| --- | --- | --- | --- | 
|  BatchSize  |  N  |  100  |  Máximo: 10.000.  | 
|  BisectBatchOnFunctionError  |  N  |  false  | nenhuma  | 
|  DestinationConfig  |  N  | N/D  |  Fila padrão do Amazon SQS ou um destino de tópico padrão do Amazon SNS para registros descartados  | 
|  Habilitado  |  N  |  true  | nenhuma  | 
|  EventSourceArn  |  S  | N/D |  O ARN do fluxo de dados ou um consumidor de fluxo  | 
|  FilterCriteria  |  N  | N/D  |  [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md)  | 
|  FunctionName  |  S  | N/D  | nenhuma  | 
|  FunctionResponseTypes  |  N  | N/D |  Para permitir que sua função reporte falhas específicas em um lote, inclua o valor `ReportBatchItemFailures` em `FunctionResponseTypes`. Para obter mais informações, consulte [Configurar resposta em lote parcial com o DynamoDB e o Lambda](services-ddb-batchfailurereporting.md).  | 
|  MaximumBatchingWindowInSeconds  |  N  |  0  | nenhuma  | 
|  MaximumRecordAgeInSeconds  |  N  |  -1  |  -1 significa infinito: registros com falha serão repetidos até que o registro expire. O [limite de retenção de dados para o DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html#Streams.DataRetention) é de 24 horas. Mínimo: -1 Máximo: 604.800  | 
|  MaximumRetryAttempts  |  N  |  -1  |  -1 significa infinito: registros com falha são repetidos até que o registro expire Mínimo: 0 Máximo: 10.000.  | 
|  ParallelizationFactor  |  N  |  1  |  Máximo: 10  | 
|  StartingPosition  |  S  | N/D  |  TRIM\$1HORIZON  | 
|  TumblingWindowInSeconds  |  N  | N/D  |  Mínimo: 0 Máximo: 900  | 

# Usar a filtragem de eventos com uma origem de eventos do DynamoDB
<a name="with-ddb-filtering"></a>

É possível usar filtragem de eventos para controlar quais registros de um stream ou fila que o Lambda enviará para a função. Para obter informações gerais sobre como a filtragem de eventos funciona, consulte [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md).

Esta seção tem como foco a filtragem de eventos para as origens de eventos do DynamoDB.

**nota**  
Mapeamentos de origens de eventos do DynamoDB somente são compatíveis com filtragem na chave `dynamodb`.

**Topics**
+ [evento do DynamoDB](#filtering-ddb)
+ [Como filtrar com atributos de tabela](#filtering-ddb-attributes)
+ [Como filtrar com expressões boolianas](#filtering-ddb-boolean)
+ [Usar o operador Exists](#filtering-ddb-exists)
+ [Formato JSON para filtragem do DynamoDB](#filtering-ddb-JSON-format)

## evento do DynamoDB
<a name="filtering-ddb"></a>

Suponha que você tenha uma tabela do DynamoDB com chave primária `CustomerName` e atributos `AccountManager` e `PaymentTerms`. Veja a seguir um exemplo de registro do stream da sua tabela do 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 com base nos valores de chave e atributo em sua tabela do DynamoDB, use a chave `dynamodb` no registro. As seções a seguir fornecem exemplos de diferentes tipos de filtro.

### Como filtrar com chaves de tabela
<a name="filtering-ddb-keys"></a>

Suponha que você queira que sua função processe somente os registros em que a chave primária `CustomerName` seja “AnyCompany Industries”. O objeto `FilterCriteria` seria como a seguir.

```
{
     "Filters": [
          {
              "Pattern": "{ \"dynamodb\" : { \"Keys\" : { \"CustomerName\" : { \"S\" : [ \"AnyCompany Industries\" ] } } } }"
          }
      ]
 }
```

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples. 

```
{
     "dynamodb": {
          "Keys": {
              "CustomerName": {
                  "S": [ "AnyCompany Industries" ]
                  }
              }
          }
 }
```

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

```
{ "dynamodb" : { "Keys" : { "CustomerName" : { "S" : [ "AnyCompany Industries" ] } } } }
```

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

```
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 adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

```
FilterCriteria:
   Filters:
     - Pattern: '{ "dynamodb" : { "Keys" : { "CustomerName" : { "S" : [ "AnyCompany Industries" ] } } } }'
```

------

## Como filtrar com atributos de tabela
<a name="filtering-ddb-attributes"></a>

Com o DynamoDB, você também pode usar as teclas `NewImage` e `OldImage` para filtrar os valores dos atributos. Suponha que você queira filtrar registros em que o atributo `AccountManager` na imagem mais recente da tabela seja “Pat Candella” ou “Shirley Rodriguez”. O objeto `FilterCriteria` seria como a seguir.

```
{
    "Filters": [
        {
            "Pattern": "{ \"dynamodb\" : { \"NewImage\" : { \"AccountManager\" : { \"S\" : [ \"Pat Candella\", \"Shirley Rodriguez\" ] } } } }"
        }
    ]
}
```

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples.

```
{
    "dynamodb": {
        "NewImage": {
            "AccountManager": {
                "S": [ "Pat Candella", "Shirley Rodriguez" ]
            }
        }
    }
}
```

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

```
{ "dynamodb" : { "NewImage" : { "AccountManager" : { "S" : [ "Pat Candella", "Shirley Rodriguez" ] } } } }
```

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

```
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 adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "dynamodb" : { "NewImage" : { "AccountManager" : { "S" : [ "Pat Candella", "Shirley Rodriguez" ] } } } }'
```

------

## Como filtrar com expressões boolianas
<a name="filtering-ddb-boolean"></a>

Você também pode criar filtros usando expressões boolianas AND. Essas expressões podem incluir os parâmetros de chave e de atributo da tabela. Suponha que você queira filtrar registros em que o valor de `NewImage` de `AccountManager` seja “Pat Candella” e o valor de `OldImage` seja “Terry Whitlock”. O objeto `FilterCriteria` seria como a seguir.

```
{
    "Filters": [
        {
            "Pattern": "{ \"dynamodb\" : { \"NewImage\" : { \"AccountManager\" : { \"S\" : [ \"Pat Candella\" ] } } } , \"dynamodb\" : { \"OldImage\" : { \"AccountManager\" : { \"S\" : [ \"Terry Whitlock\" ] } } } }"
        }
    ]
}
```

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples.

```
{ 
    "dynamodb" : { 
        "NewImage" : { 
            "AccountManager" : { 
                "S" : [ 
                    "Pat Candella" 
                ] 
            } 
        } 
    }, 
    "dynamodb": { 
        "OldImage": { 
            "AccountManager": { 
                "S": [ 
                    "Terry Whitlock" 
                ] 
            } 
        } 
    } 
}
```

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

```
{ "dynamodb" : { "NewImage" : { "AccountManager" : { "S" : [ "Pat Candella" ] } } } , "dynamodb" : { "OldImage" : { "AccountManager" : { "S" : [ "Terry Whitlock" ] } } } }
```

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

```
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 adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "dynamodb" : { "NewImage" : { "AccountManager" : { "S" : [ "Pat Candella" ] } } } , "dynamodb" : { "OldImage" : { "AccountManager" : { "S" : [ "Terry Whitlock" ] } } } }'
```

------

**nota**  
A filtragem de eventos do DynamoDB não oferece suporte ao uso de operadores numéricos (igualdade numérica e intervalo numérico). Mesmo que os itens em sua tabela sejam armazenados como números, esses parâmetros são convertidos em strings no objeto do registro JSON.

## Usar o operador Exists
<a name="filtering-ddb-exists"></a>

Devido à forma de estruturação dos objetos de evento JSON do DynamoDB, o uso do operador Exists requer cuidados especiais. O operador Exists só funciona em nós terminais no evento JSON. Portanto, se seu padrão de filtro usar Exists para testar um nó intermediário, ele não funcionará. Considere o seguinte item de tabela do DynamoDB:

```
{
  "UserID": {"S": "12345"},
  "Name": {"S": "John Doe"},
  "Organizations": {"L": [
      {"S":"Sales"},
      {"S":"Marketing"},
      {"S":"Support"}
    ]
  }
}
```

Talvez você queira criar um padrão de filtro como o seguinte, que teste os eventos que contenham `"Organizations"`:

```
{ "dynamodb" : { "NewImage" : { "Organizations" : [ { "exists": true } ] } } }
```

No entanto, esse padrão de filtro nunca retornaria uma correspondência porque `"Organizations"` não é um nó terminal. O exemplo a seguir mostra como usar corretamente o operador Exists para estruturar o padrão de filtro desejado:

```
{ "dynamodb" : { "NewImage" : {"Organizations": {"L": {"S": [ {"exists": true } ] } } } } }
```

## Formato JSON para filtragem do DynamoDB
<a name="filtering-ddb-JSON-format"></a>

Para filtrar corretamente eventos de origens do DynamoDB, tanto o campo de dados como os critérios de filtro para o campo de dados (`dynamodb`) devem estar em formato JSON válido. Se algum desses campos não estiver em um formato JSON válido, o Lambda descartará a mensagem ou emitirá uma exceção. A tabela a seguir resume o comportamento específico: 


| Formato dos dados recebidos | Formato de filtro padrão para propriedades de dados | Ação resultante | 
| --- | --- | --- | 
|  JSON válido  |  JSON válido  |  Filtros do Lambda com base em seus critérios de filtro.  | 
|  JSON válido  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  JSON válido  |  Não JSON  |  O Lambda emite uma exceção no momento da criação ou atualização do mapeamento da fonte de eventos. O padrão de filtro para propriedades de dados deve estar em um formato JSON válido.  | 
|  Não JSON  |  JSON válido  |  O Lambda descarta o registro.  | 
|  Não JSON  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  Não JSON  |  Não JSON  |  O Lambda emite uma exceção no momento da criação ou atualização do mapeamento da fonte de eventos. O padrão de filtro para propriedades de dados deve estar em um formato JSON válido.  | 

# Tutorial: Usar o AWS Lambda com o Amazon DynamoDB Streams
<a name="with-ddb-example"></a>

 Neste tutorial, você cria uma função do Lambda para consumir eventos do Amazon DynamoDB Streams.

## Pré-requisitos
<a name="with-ddb-prepare"></a>

### Instalar o AWS Command Line Interface
<a name="install_aws_cli"></a>

Se você ainda não instalou a AWS Command Line Interface, siga as etapas em [Instalar ou atualizar a versão mais recente da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalá-la.

O tutorial requer um terminal de linha de comando ou um shell para executar os comandos. No Linux e no macOS, use o gerenciador de pacotes e de shell de sua preferência.

**nota**  
No Windows, alguns comandos da CLI do Bash que você costuma usar com o Lambda (como `zip`) não são compatíveis com os terminais integrados do sistema operacional. Para obter uma versão do Ubuntu com o Bash integrada no Windows, [instale o Subsistema do Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Criar a função de execução
<a name="with-ddb-create-execution-role"></a>

Crie a [função de execução](lambda-intro-execution-role.md) que dá à sua função permissão para acessar recursos do AWS.

**Para criar uma função de execução**

1. Abra a [página Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione **Create role** (Criar função).

1. Crie uma função com as propriedades a seguir.
   + **Entidade confiável**: Lambda.
   + **Permissions** (Permissões): **AWSLambdaDynamoDBExecutionRole**.
   + **Role name (Nome da função** – **lambda-dynamodb-role**.

O **AWSLambdaDynamoDBExecutionRole** tem as permissões necessárias para a função ler itens do DynamoDB e gravar logs no CloudWatch Logs.

## Criar a função
<a name="with-ddb-example-create-function"></a>

Crie uma função do Lambda que processe seus eventos do DynamoDB. O código da função grava alguns dos dados de eventos de entrada no CloudWatch Logs.

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Como consumir um evento do DynamoDB com o Lambda usando .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Como consumir um evento do DynamoDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumir um evento do DynamoDB com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumir um evento do DynamoDB com o Lambda usando 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)}`);
};
```
Consumir um evento do DynamoDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Consumir um evento do DynamoDB com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Como consumir um evento do DynamoDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Como consumir um evento do DynamoDB com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-ddb-to-lambda). 
Como consumir um evento do DynamoDB com o Lambda usando 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(())
    
}
```

------

**Para criar a função**

1. Copie o código de amostra em um arquivo chamado `example.js`.

1. Crie um pacote de implantação.

   ```
   zip function.zip example.js
   ```

1. Crie uma função do Lambda com o 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
   ```

## Testar a função do Lambda
<a name="with-dbb-invoke-manually"></a>

Nesta etapa, você invoca sua função do Lambda manualmente usando o comando `invoke` da CLI do AWS Lambda e o seguinte exemplo de evento do DynamoDB. Copie o seguinte para um arquivo chamado `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"
      }
   ]
}
```

Execute o seguinte comando `invoke`. 

```
aws lambda invoke --function-name ProcessDynamoDBRecords \
    --cli-binary-format raw-in-base64-out \
    --payload file://input.txt outputfile.txt
```

A opção **cli-binary-format** será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [A AWS CLI comporta opções de linha de comando globais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) no *Guia do usuário da AWS Command Line Interface versão 2*.

A função retorna a string `message` no corpo da resposta. 

Verifique a saída no arquivo `outputfile.txt`.

## Criar uma tabela do DynamoDB com uma transmissão habilitada
<a name="with-ddb-create-buckets"></a>

Criar uma tabela do Amazon DynamoDB com uma transmissão habilitada.

**Como criar uma tabela do DynamoDB**

1. Abra o [console do DynamoDB](https://console.aws.amazon.com/dynamodb).

1. Escolha **Criar tabela**.

1. Crie uma tabela com as configurações a seguir.
   + **O nome da tabela** – **lambda-dynamodb-stream**
   + **Primary key** (Chave primária): **id** (string)

1. Escolha **Criar**.

**Como habilitar fluxos**

1. Abra o [console do DynamoDB](https://console.aws.amazon.com/dynamodb).

1. Escolha **Tables (Tabelas)**.

1. Escolha a tabela **lambda-dynamodb-stream**.

1. Em **Exports and streams** (Exportações e transmissões), escolha **DynamoDB stream details** (Detalhes da tranmissão do DynamoDB).

1. Selecione **Ativar**.

1. Em **Tipo de exibição**, escolha **Somente atributos principais**.

1. Escolha **Ativar fluxo**.

Anote o ARN do fluxo. Você precisará dele na próxima etapa quando for associar a transmissão à função do Lambda. Para obter mais informações sobre como habilitar fluxos, consulte [Capturing table activity with DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html) (Capturar atividades de tabelas com o DynamoDB Streams).

## Adicionar uma fonte de eventos no AWS Lambda
<a name="with-ddb-attach-notification-configuration"></a>

Crie um mapeamento da fonte do evento no AWS Lambda. Este mapeamento de fontes de eventos associa a transmissão do DynamoDB à função do Lambda. Depois de criar esse mapeamento da fonte do evento, o AWS Lambda começa a sondar o fluxo.

Execute o comando AWS CLI a seguir da `create-event-source-mapping`. Depois que o comando for executado, anote o UUID. Você precisará deste UUID para se referir ao mapeamento da fonte do evento em todos os comandos, por exemplo, ao excluir o mapeamento da fonte do evento.

```
aws lambda create-event-source-mapping --function-name ProcessDynamoDBRecords \
    --batch-size 100 --starting-position LATEST --event-source DynamoDB-stream-arn
```

 Isso cria um mapeamento entre a transmissão do DynamoDB especificado e a função do Lambda. Você pode associar uma transmissão do DynamoDB a várias funções do Lambda e associar a mesma função do Lambda a várias transmissões. No entanto, as funções do Lambda compartilharão o throughput de leitura para os fluxos dos quais compartilham. 

Você pode obter a lista de mapeamentos de fontes de eventos executando o comando a seguir.

```
aws lambda list-event-source-mappings
```

Esta lista retorna todos os mapeamentos de fontes de eventos que você criou, e para cada mapeamento mostra o `LastProcessingResult`, entre outras coisas. Este campo será usado para fornecer uma mensagem informativa, se houver problemas. Valores como `No records processed` (indica que o AWS Lambda não iniciou a sondagem ou de que não há registros no fluxo) e `OK` (indica que o AWS Lambda foi bem-sucedido na leitura dos registros do fluxo e invocou a função do Lambda) indicam que não há problemas. Se houver problemas, você receberá uma mensagem de erro.

Se você tiver muitos mapeamentos da fonte do evento, use o parâmetro de nome da função para refinar os resultados.

```
aws lambda list-event-source-mappings --function-name ProcessDynamoDBRecords
```

## Testar a configuração
<a name="with-ddb-final-integration-test-no-iam"></a>

Teste a experiência completa. À medida que você executa atualizações nas tabelas, o DynamoDB grava registros de eventos na transmissão. Quando o AWS Lambda sonda o stream, ele detecta novos registros no stream e executa a função do Lambda em seu nome, passando os eventos para a função. 

1. No console do DynamoDB, adicione, atualize ou exclua itens da tabela. O DynamoDB grava registros dessas ações na transmissão.

1. AWS LambdaO sonda a transmissão e, ao detectar atualizações nela, invoca a função do Lambda passando os dados do evento que ele encontrar na transmissão.

1. A função é executada e cria logs no Amazon CloudWatch. Você pode verificar os logs relatados no console do Amazon CloudWatch.

## Próximas etapas
<a name="with-ddb-next-steps"></a>

Este tutorial mostrou conceitos básicos do processamento de eventos de stream do DynamoDB com o Lambda. Para workloads de produção, considere implementar uma lógica de resposta parcial em lote para lidar com falhas de registros individuais de forma mais eficiente. O [utilitário de processador em lote](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) da Powertools para AWS Lambda está disponível em Python, TypeScript, .NET e Java e fornece uma solução robusta para isso, tratando automaticamente a complexidade das respostas parciais em lote e reduzindo o número de novas tentativas para registros processados com êxito.

## Limpe os recursos
<a name="cleanup"></a>

Agora você pode excluir os recursos criados para este tutorial, a menos que queira mantê-los. Excluindo os recursos da AWS que você não está mais usando, você evita cobranças desnecessárias em sua Conta da AWS.

**Como excluir a função do Lambda**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Selecione a função que você criou.

1. Selecione **Ações**, **Excluir**.

1. Digite **confirm** no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir a função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione a função de execução que você criou.

1. Escolha **Excluir**.

1. Insira o nome do perfil no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir uma tabela do DynamoDB**

1. Abra a [página Tables](https://console.aws.amazon.com//dynamodb/home#tables:) (Tabelas) no console do DynamoDB.

1. Selecione a tabela que você criou.

1. Escolha **Excluir**.

1. Digite **delete** na caixa de texto.

1. Selecione **Delete table** (Excluir tabela).

# Processar eventos do ciclo de vida do Amazon EC2 com uma função do Lambda
<a name="services-ec2"></a>

Você pode usar o AWS Lambda para processar eventos de ciclo de vida do Amazon Elastic Compute Cloud e gerenciar recursos do Amazon EC2. O Amazon EC2 envia eventos ao [Amazon EventBridge (CloudWatch Events)](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is.html) para [eventos de ciclo de vida](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-lifecycle.html), como quando uma instância muda de estado, quando o snapshot de um volume do Amazon Elastic Block Store é concluído ou quando uma instância spot está agendada para ser terminada. Configure o EventBridge (CloudWatch Events) para encaminhar esses eventos para uma função do Lambda para processamento.

O EventBridge (CloudWatch Events) invoca sua função do Lambda de forma assíncrona com o documento de evento no Amazon EC2.

**Example evento do ciclo de vida da instância**  

```
{
    "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 obter detalhes sobre como configurar eventos, consulte [Invocar uma função do Lambda segundo uma agenda](with-eventbridge-scheduler.md). Para obter uma função de exemplo que processa notificações de snapshot do Amazon EBS, consulte [EventBridge Scheduler para Amazon EBS](https://docs.aws.amazon.com/ebs/latest/userguide/ebs-cloud-watch-events.html).

Você também pode usar o AWS SDK para gerenciar instâncias e outros recursos com a API do Amazon EC2. 

## Conceder permissões ao EventBridge (CloudWatch Events)
<a name="services-ec2-permissions"></a>

Para processar eventos de ciclo de vida do Amazon EC2, o EventBridge (CloudWatch Events) precisa de permissão para invocar sua função. Essa permissão vem da [política baseada em recursos](access-control-resource-based.md) da função. Se você usar o console do EventBridge (CloudWatch Events) para configurar um acionador de evento, o console atualizará a política baseada em recursos em seu nome. Caso contrário, adicione uma instrução como a seguinte:

**Example instrução de política baseada em recursos para notificações de ciclo de vida do 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 adicionar uma instrução, use o comando `add-permission` da AWS CLI.

```
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/*'
```

Se sua função usar o AWS SDK para gerenciar recursos do Amazon EC2, adicione permissões do Amazon EC2 à [função de execução](lambda-intro-execution-role.md) da função.

# Processar solicitações do Application Load Balancer com o Lambda
<a name="services-alb"></a>

Você pode usar uma função do Lambda para processar solicitações de um Application Load Balancer. O Elastic Load Balancing é compatível com funções do Lambda como destino para um Application Load Balancer. Use regras de load balancer para rotear solicitações HTTP para uma função, com base no caminho ou em valores de cabeçalho. Processe a solicitação e retorne uma resposta HTTP de sua função do Lambda.

O Elastic Load Balancing invoca a função do Lambda de forma síncrona com um evento que contém o corpo da solicitação e os metadados.

**Example Evento de solicitação do Application Load Balancer**  

```
{
    "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
}
```

Sua função processa o evento e retorna um documento de resposta para o balanceador de carga no JSON. O Elastic Load Balancing converte o documento em uma resposta de sucesso ou de erro de HTTP e o devolve ao usuário.

**Example formato do documento de resposta**  

```
{
    "statusCode": 200,
    "statusDescription": "200 OK",
    "isBase64Encoded": False,
    "headers": {
        "Content-Type": "text/html"
    },
    "body": "<h1>Hello from Lambda!</h1>"
}
```

Para configurar um Application Load Balancer como um acionador de função, conceda ao Elastic Load Balancing permissão para executar a função, crie um grupo de destino que roteie as solicitações para a função e adicione uma regra ao balanceador de carga que envie solicitações para o grupo de destino.

Use o comando `add-permission` para adicionar uma instrução de permissão à política baseada em recursos de sua função.

```
aws lambda add-permission --function-name alb-function \
--statement-id load-balancer --action "lambda:InvokeFunction" \
--principal elasticloadbalancing.amazonaws.com
```

A seguinte saída deverá ser mostrada:

```
{
    "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 obter instruções sobre como configurar o listener e um grupo de destino do balanceador de carga da aplicação, consulte [Funções do Lambda como destino](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html) no *Guia do usuário para Application Load Balancers*.

## Manipulador de eventos do Powertools para Lambda AWS
<a name="services-alb-powertools"></a>

O manipulador de eventos do kit de ferramentas Powertools para AWS Lambda fornece roteamento, middleware, configuração CORS, geração de especificações OpenAPI, validação de solicitações, tratamento de erros e outros recursos úteis ao escrever funções do Lambda invocadas por um Application Load Balancer. O utilitário Manipulador de eventos está disponível para Python. Para obter mais informações, consulte a [API REST do Manipulador de eventos](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/) na documentação do *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)
```

# Invocar uma função do Lambda segundo uma agenda
<a name="with-eventbridge-scheduler"></a>

O [Agendador do Amazon EventBridge](https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html) utiliza a tecnologia sem servidor que permite criar, executar e gerenciar tarefas a partir de um serviço central gerenciado. Com o Agendador do EventBridge, você pode criar programações usando expressões cron e rate para padrões recorrentes ou configurar invocações únicas. Você pode configurar janelas de tempo flexíveis para entrega, definir limites de repetição e definir o tempo máximo de retenção para eventos não processados.

Quando você configura o EventBridge Scheduler com o Lambda, o EventBridge Scheduler invoca a função do Lambda de modo assíncrono. Esta página explica como usar o Agendador do EventBridge para invocar uma função do Lambda em uma programação.

## Configurar o perfil de execução
<a name="using-eventbridge-scheduler-execution-role"></a>

 Quando você cria uma programação, o Agendador do EventBridge deve ter permissão para invocar a operação da API de destino em seu nome. Você concede essas permissões ao Agendador do EventBridge usando um *perfil de execução*. A política de permissão que você anexa ao perfil de execução da programação define as permissões necessárias. As permissões dependem da API de destino que você deseja que o Agendador do EventBridge invoque.

 Quando você usa o console do Agendador do EventBridge para criar programações, como no procedimento a seguir, o Agendador do EventBridge configura automaticamente um perfil de execução com base no destino selecionado. Se você quiser criar uma programação usando um dos SDKs do Agendador do EventBridge, a AWS CLI ou o CloudFormation, você deve ter um perfil de execução que conceda as permissões que o Agendador do EventBridge precisa para invocar o destino. Para obter mais informações sobre como configurar manualmente um perfil de execução para programações, consulte [Como configurar um perfil de execução](https://docs.aws.amazon.com/scheduler/latest/UserGuide/setting-up.html#setting-up-execution-role) no *Guia do usuário do Agendador do EventBridge*. 

## Criar uma programação
<a name="using-eventbridge-scheduler-create"></a>

**Para criar uma programação usando o console**

1. Abra o console do Agendador do Amazon EventBridge em [https://console.aws.amazon.com/scheduler/home](https://console.aws.amazon.com/scheduler/home/).

1.  Na página **Programações**, clique em **Criar programação**. 

1.  Na página **Especificar detalhes da programação**, na seção **Nome e descrição da programação**, faça o seguinte: 

   1. Em **Nome da programação**, insira um nome para a programação. Por exemplo, **MyTestSchedule**. 

   1. (Opcional) Em **Descrição**, insira a descrição da programação. Por exemplo, **My first schedule**.

   1. Em **Grupo de programação**, escolha um grupo de programação na lista suspensa. Se você não tiver um grupo, escolha **padrão**. Para criar um grupo de programação, escolha **criar sua própria programação**. 

      Para adicionar tags a grupos de programação, você usa os grupos de programação. 

1. 

   1. Escolha as opções de programação.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/with-eventbridge-scheduler.html)

1. (Opcional) Se você escolher **Programação recorrente** na etapa anterior, na seção **Período**, faça o seguinte: 

   1. Em **Fuso horário**, escolha um fuso horário. 

   1. Em **Data e hora de início**, insira uma data válida no formato `YYYY/MM/DD` e, em seguida, especifique um carimbo de data/hora no formato de 24 horas `hh:mm`. 

   1. Para **Data e hora de término**, insira uma data válida no formato `YYYY/MM/DD` e, em seguida, especifique um carimbo de data/hora no formato 24 horas `hh:mm`. 

1. Escolha **Próximo**. 

1. Na página **Selecionar destino**, escolha a operação de API da AWS que o Agendador do EventBridge invoca: 

   1. Escolha **Invocar o AWS Lambda**.

   1. Na seção **Invocar**, selecione uma função ou escolha **Criar uma nova função do Lambda**.

   1. (Opcional) Insira uma carga útil JSON. Se você não inserir uma carga útil, o Agendador do EventBridge usará um evento vazio para invocar a função.

1. Escolha **Próximo**. 

1. Na página **Configurações**, faça o seguinte: 

   1. Para ativar a programação, em **Estado da programação**, mude para **Ativar programação**. 

   1. Para configurar uma política de novas tentativas para a programação, em **Política de novas tentativas e fila de mensagens não entregues (DLQ)**, faça o seguinte:
      + Mude para **Tentar novamente**.
      + Em **Duração máxima do evento**, insira o período máximo de **horas** e **minutos** que o Agendador do EventBridge deve manter um evento não processado.
      + O período máximo é de 24 horas.
      + Em **Máximo de tentativas**, insira o número máximo de vezes que o Agendador do EventBridge tentará executar a programação se o destino retornar um erro. 

         O valor máximo é 185 tentativas. 

      Com as políticas de novas tentativas, se a programação não conseguir invocar o destino, o Agendador do EventBridge tentará executar novamente a programação. Se configurado, você deve definir o tempo máximo de retenção e as novas tentativas da programação.

   1. Escolha onde o Agendador do EventBridge armazena os eventos não entregues.     
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/with-eventbridge-scheduler.html)

   1. Para usar uma chave gerenciada pelo cliente para criptografar a entrada de destino, em **Criptografia**, escolha **Personalizar as configurações de criptografia (avançado)**. 

      Se você escolher essa opção, insira o ARN da chave do KMS existente ou escolha **Criar AWS KMS key** para navegar até o console do AWS KMS. Para obter mais informações sobre como o Agendador do EventBridge criptografa os dados em repouso, consulte [Criptografia em repouso](https://docs.aws.amazon.com/scheduler/latest/UserGuide/encryption-rest.html) no *Guia do usuário do Agendador do Amazon EventBridge*. 

   1. Para que o Agendador do EventBridge crie um novo perfil de execução para você, escolha **Criar novo perfil para esta programação**. Depois, insira um nome em **Nome do perfil**. Se você escolher essa opção, o Agendador do EventBridge anexará as permissões necessárias para o destino de exemplo ao perfil.

1. Escolha **Próximo**. 

1.  Na página **Revisar e criar programação**, revise os detalhes da programação. Em cada seção, escolha **Editar** para voltar a essa etapa e editar seus detalhes. 

1. Clique em **Criar programação**. 

   Você pode ver a lista com as programações novas e existentes na página **Programações**. Na coluna **Status**, verifique se sua nova programação está **Ativada**. 

Para confirmar que o Agendador do EventBridge invocou a função, [verifique os logs do Amazon CloudWatch da função](monitoring-cloudwatchlogs-view.md#monitoring-cloudwatchlogs-console).

## Recursos relacionados
<a name="using-eventbridge-scheduler-related-resources"></a>

 Para obter mais informações sobre o Agendador do EventBridge, consulte: 
+ [Guia do usuário do Agendador do EventBridge](https://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html)
+ [Referência da API do Agendador do EventBridge](https://docs.aws.amazon.com/scheduler/latest/APIReference/Welcome.html)
+ [Preços do Agendador do EventBridge](https://aws.amazon.com/eventbridge/pricing/#Scheduler)

# Usar o AWS Lambda com o AWS IoT
<a name="services-iot"></a>

O AWS IoT fornece comunicação segura entre dispositivos conectados à Internet (como sensores) e a Nuvem AWS. Isso permite que você colete, armazene e analise dados de telemetria de vários dispositivos.

É possível criar regras de AWS IoT para que seus dispositivos interajam com Serviços da AWS. O [Mecanismo de regras](https://docs.aws.amazon.com/iot/latest/developerguide/iot-rules.html) do AWS IoT fornece uma linguagem baseada em SQL para selecionar dados de cargas de mensagem e enviar os dados para outros serviços, como o Amazon S3, o Amazon DynamoDB e o AWS Lambda. Defina uma regra para invocar uma função do Lambda quando quiser invocar outro serviço da AWS ou um serviço de terceiros. 

Quando uma mensagem de entrada da IoT aciona a regra, o AWS IoT invoca a função do Lambda de [forma assíncrona](invocation-async.md) e passa os dados da mensagem da IoT para a função. 

O exemplo a seguir mostra uma leitura de umidade do sensor de uma estufa. Os valores de **linha** e **pos** identificam a localização do sensor. Esse evento de exemplo é baseado no tipo de estufa nos [Tutoriais de regras da AWS IoT](https://docs.aws.amazon.com/iot/latest/developerguide/iot-rules-tutorial.html). 

**Example Evento de mensagem do AWS IoT**  

```
{
    "row" : "10",
    "pos" : "23",
    "moisture" : "75"
}
```

Para a invocação assíncrona, o Lambda coloca em fila a mensagem e [tenta novamente](invocation-retries.md) caso a sua função retorne um erro. Configure sua função com um [destino](invocation-async-retain-records.md#invocation-async-destinations) para manter os eventos que a função não puder processar.

É necessário conceder permissão para que o serviço da AWS IoT invoque sua função do Lambda. Use o comando `add-permission` para adicionar uma instrução de permissão à política baseada em recursos de sua função.

```
aws lambda add-permission --function-name my-function \
--statement-id iot-events --action "lambda:InvokeFunction" --principal iot.amazonaws.com
```

A seguinte saída deverá ser mostrada:

```
{
    "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 obter mais informações sobre como usar o Lambda com o AWS IoT, consulte [Criar uma regra do AWS Lambda](https://docs.aws.amazon.com/iot/latest/developerguide/iot-lambda-rule.html). 

# Como usar o Lambda para processar registros do Amazon Kinesis Data Streams
<a name="with-kinesis"></a>

Você pode usar uma função do Lambda para processar registros em um [fluxo de dados do Amazon Kinesis](https://docs.aws.amazon.com/streams/latest/dev/introduction.html). É possível mapear uma função do Lambda em um consumidor de throughput compartilhado (iterador padrão) do Kinesis Data Stream ou em um consumidor de throughput dedicado com [distribuição avançada](https://docs.aws.amazon.com/kinesis/latest/dev/enhanced-consumers.html). Para iteradores padrão, o Lambda sonda cada fragmento no stream do Kinesis em busca de registros usando o protocolo HTTP. O mapeamento da origem do evento compartilha a throughput de leitura com outros consumidores do fragmento.

 Para obter detalhes sobre transmissões de dados do Kinesis, consulte[Ler dados do Amazon Kinesis Data Streams](https://docs.aws.amazon.com/kinesis/latest/dev/building-consumers.html).

**nota**  
O Kinesis cobra por cada fragmento e, para distribuição avançada, dados lidos da transmissão. Para obter detalhes de preço, consulte [Preço do Amazon Kinesis](https://aws.amazon.com/kinesis/data-streams/pricing).

## Fluxos de sondagem e agrupamento em lotes
<a name="kinesis-polling-and-batching"></a>

O Lambda lê registros do fluxo de dados e invoca sua função [de maneira síncrona](invocation-sync.md) com um evento que contém registros de transmissão. O Lambda lê registros em lotes e invoca sua função para processar registros do lote. Cada lote contém registros de um único fragmento/fluxo de dados.

Sua função do Lambda é uma aplicação de consumidor para seu fluxo de dados. Ele processa um lote de registros por vez de cada estilhaço. É possível mapear uma função Lambda para um consumidor de throughput compartilhado (iterador padrão) ou para um consumidor de throughput dedicado com distribuição avançada.
+ **Iterador padrão**: o Lambda sonda cada fragmento em seu fluxo do Kinesis para identificar registros a uma taxa básica de uma vez por segundo. Quando houver mais registros disponíveis, o Lambda mantém lotes de processamento até que a função alcance o fluxo. O mapeamento da origem do evento compartilha a throughput de leitura com outros consumidores do fragmento.
+ **Distribuição avançada:** para minimizar a latência e maximizar o throughput da leitura, crie um consumidor de fluxo de dados com [distribuição avançada](https://docs.aws.amazon.com/streams/latest/dev/enhanced-consumers.html). Os consumidores da distribuição avançada obtêm uma conexão dedicada para cada fragmento que não afeta outros aplicativos que fazem leitura do stream. Os consumidores de fluxos usam HTTP/2 para reduzir a latência, enviando os registros para o Lambda por meio de uma conexão de longa duração e compactando cabeçalhos de solicitação. Você pode criar um consumidor de fluxo com a API [RegisterStreamConsumer](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_RegisterStreamConsumer.html) do Kinesis.

```
aws kinesis register-stream-consumer \
--consumer-name con1 \
--stream-arn arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream
```

A seguinte saída deverá ser mostrada:

```
{
    "Consumer": {
        "ConsumerName": "con1",
        "ConsumerARN": "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream/consumer/con1:1540591608",
        "ConsumerStatus": "CREATING",
        "ConsumerCreationTimestamp": 1540591608.0
    }
}
```

Para aumentar a velocidade com que sua função processa registros, [adicione fragmentos ao fluxo de dados](https://repost.aws/knowledge-center/kinesis-data-streams-open-shards). O Lambda processa registros em cada fragmento sequencialmente. Ele deixará de processar registros adicionais em um estilhaço se sua função retornar um erro. Com mais estilhaços, há mais lotes sendo processados de uma só vez, o que diminui o impacto de erros na simultaneidade.

Se a função não conseguir se expandir para lidar com o número total de lotes simultâneos, [solicite um aumento de cota](https://docs.aws.amazon.com/servicequotas/latest/userguide/request-quota-increase.html) ou [reserve simultaneidade](configuration-concurrency.md) para a função.

Por padrão, o Lambda invoca a função assim que os registros estão disponíveis. Se o lote que o Lambda lê da fonte de eventos tiver apenas um registro, o Lambda enviará apenas um registro à função. Para evitar a invocação da função com poucos registros, instrua a fonte de eventos para armazenar os registros em buffer por até cinco minutos, configurando uma *janela de lotes*. Antes de invocar a função, o Lambda continua a ler registros da fonte de eventos até coletar um lote inteiro, até que a janela de lote expire ou até que o lote atinja o limite de carga útil de 6 MB. Para obter mais informações, consulte [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

**Atenção**  
Os mapeamentos da origem do evento do Lambda processam cada evento ao menos uma vez, podendo haver o processamento duplicado de registros. Para evitar possíveis problemas relacionados a eventos duplicados, é altamente recomendável tornar o código da função idempotente. Para saber mais, consulte [Como tornar minha função do Lambda idempotente](https://repost.aws/knowledge-center/lambda-function-idempotent) no Centro de Conhecimentos da AWS.

O Lambda não espera a conclusão de nenhuma [extensão](lambda-extensions.md)configurada para enviar o próximo lote para processamento. Em outras palavras, suas extensões podem continuar sendo executadas enquanto o Lambda processa o próximo lote de registros. Isso pode causar problemas de controle de utilização se você violar quaisquer configurações ou limites de [simultaneidade](lambda-concurrency.md) de sua conta. Para detectar se esse é um problema em potencial, monitore suas funções e verifique se você está vendo [métricas de simultaneidade](monitoring-concurrency.md#general-concurrency-metrics) mais altas do que o esperado para o seu mapeamento da origem do evento. Devido ao curto intervalo entre as invocações, o Lambda pode relatar brevemente um uso de simultaneidade maior do que o número de fragmentos. Isso pode ser verdadeiro até mesmo para funções do Lambda sem extensões.

Configure a opção [ParallelizationFactor](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-ParallelizationFactor) para processar um fragmento de um fluxo de dados do Kinesis com mais de uma invocação do Lambda simultaneamente. Você pode especificar o número de lotes simultâneos que o Lambda pesquisa de um fragmento por meio de um fator de paralelização de 1 (padrão) a 10. Por exemplo, quando você define `ParallelizationFactor` como 2, pode ter até 200 invocações simultâneas do Lambda para processar 100 fragmentos de dados do Kinesis (embora, na prática, você possa ver valores diferentes para a métrica `ConcurrentExecutions`). Isso ajuda a aumentar o throughput de processamento quando o volume de dados é volátil e o valor de `IteratorAge` é alto. Quando você aumenta o número de lotes simultâneos por fragmento, o Lambda ainda garante o processamento em ordem no nível de chave de partição.

Você também pode usar `ParallelizationFactor` com a agregação do Kinesis. O comportamento do mapeamento da origem do evento depende de você estar ou não usando [fan-out avançado](https://docs.aws.amazon.com/streams/latest/dev/enhanced-consumers.html):
+ **Sem fan-out avançado**: todos os eventos dentro de um evento agregado devem ter a mesma chave de partição. A chave de partição também deve ser igual à do evento agregado. Se os eventos dentro do evento agregado tiverem chaves de partição diferentes, o Lambda não poderá garantir o processamento dos eventos na ordem, por chave de partição.
+ **Com fan-out avançado**: primeiro o Lambda decodifica o evento agregado em eventos individuais. O evento agregado pode ter uma chave de partição diferente da chave dos eventos que ele contém. Porém, os eventos que não correspondem à chave de partição são [descartados e perdidos](https://github.com/awslabs/kinesis-aggregation/blob/master/potential_data_loss.md). O Lambda não processa esses eventos e não os envia para um destino de falha configurado.

## Evento de exemplo
<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"
        }
    ]
}
```

# Processar registros do Amazon Kinesis Data Streams com o Lambda
<a name="services-kinesis-create"></a>

Para processar registros do Amazon Kinesis Data Streams com o Lambda, crie um mapeamento da origem do evento do Lambda. Você pode mapear uma função do Lambda para um iterador padrão ou para um consumidor de fan-out aprimorado. Para obter mais informações, consulte [Fluxos de sondagem e agrupamento em lotes](with-kinesis.md#kinesis-polling-and-batching).

## Criar um mapeamento da origem do evento do Kinesis
<a name="services-kinesis-eventsourcemapping"></a>

Para invocar sua função do Lambda com registros do fluxo de dados, crie um [mapeamento da origem do evento](invocation-eventsourcemapping.md). É possível criar vários mapeamentos de origem de eventos para processar os mesmos dados com várias funções do Lambda ou processar itens de vários fluxos de dados com uma única função. Ao processar itens de vários fluxos, cada lote conterá registros somente de um único fragmento ou transmissão.

Você pode configurar mapeamentos da origem do evento para processar registros de um fluxo em outra Conta da AWS. Para saber mais, consulte [Como criar mapeamentos da origem do evento entre contas](#services-kinesis-eventsourcemapping-cross-account).

Antes de criar um mapeamento da origem do evento, você precisará dar permissão à função do Lambda para ler a partir de um fluxo de dados do Kinesis. O Lambda precisa das permissões a seguir para gerenciar recursos relacionados ao seu fluxo de dados do 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)

A política gerenciada da AWS [AWSLambdaKinesisExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaKinesisExecutionRole.html) inclui essas permissões. Adicione essa política gerenciada à sua função, conforme descrito no procedimento a seguir.

**nota**  
Você não precisa da permissão `kinesis:ListStreams` para criar e gerenciar mapeamentos da origem do evento para o Kinesis. No entanto, se você criar um mapeamento da origem do evento no console e não tiver essa permissão, não poderá selecionar um stream do Kinesis em uma lista suspensa e o console exibirá um erro. Para criar o mapeamento da origem do evento, você precisará inserir manualmente o nome do recurso da Amazon (ARN) do seu stream.
O Lambda faz as chamadas de API `kinesis:GetRecords` e `kinesis:GetShardIterator` ao tentar novamente invocações com falha.

------
#### [ Console de gerenciamento da AWS ]

**Para adicionar permissões do Kinesis à sua função**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda e selecione a função.

1. Na guia **Configuração**, escolha **Permissões**.

1. No painel **Perfil de execução**, em **Nome do perfil**, escolha o link para o perfil de execução da sua função. Esse link abre a página para esse perfil no console do IAM.

1. No painel **Políticas de permissões**, escolha **Adicionar permissões** e, em seguida, selecione **Anexar políticas**.

1. No campo de pesquisa, digite **AWSLambdaKinesisExecutionRole**.

1. Marque a caixa de seleção próxima à política e escolha **Adicionar permissão**.

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

**Para adicionar permissões do Kinesis à sua função**
+ Execute o comando da CLI a seguir para adicionar a política `AWSLambdaKinesisExecutionRole` ao perfil de execução da sua função:

  ```
  aws iam attach-role-policy \
  --role-name MyFunctionRole \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaKinesisExecutionRole
  ```

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

**Para adicionar permissões do Kinesis à sua função**
+ Na definição da sua função, adicione a `Policies` propriedade, conforme mostrado no seguinte exemplo:

  ```
  Resources:
    MyFunction:
      Type: AWS::Serverless::Function
      Properties:
        CodeUri: ./my-function/
        Handler: index.handler
        Runtime: nodejs24.x
        Policies:
          - AWSLambdaKinesisExecutionRole
  ```

------

Depois de configurar as permissões necessárias, crie o mapeamento de origem de eventos.

------
#### [ Console de gerenciamento da AWS ]

**Para criar o mapeamento da origem do evento do Kinesis**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda e selecione a função.

1. No painel **Visão geral da função**, escolha **Adicionar gatilho**.

1. Em **Configuração do acionador**, para a origem, selecione **Kinesis**.

1. Selecione o fluxo do Kinesis para o qual você deseja criar o mapeamento da origem do evento e, opcionalmente, um consumidor do seu fluxo.

1. (Opcional) edite o **Tamanho do lote**, a **Posição inicial** e a **Janela do lote** para o mapeamento da origem do evento.

1. Escolha **Adicionar**.

Ao criar seu mapeamento da origem do evento no console, seu perfil do IAM deve ter as permissões [kinesis:ListStreams](https://docs.aws.amazon.com/lambda/latest/api/API_ListStreams.html) e [kinesis:ListStreamConsumers](https://docs.aws.amazon.com/lambda/latest/api/API_ListStreamConsumers.html).

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

**Para criar o mapeamento da origem do evento do Kinesis**
+ Execute o comando a seguir da CLI para criar um mapeamento da origem do evento do Kinesis. Escolha seu próprio tamanho de lote e posição inicial de acordo com seu 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 uma janela de agrupamento em lotes, adicione a opção `--maximum-batching-window-in-seconds`. Para obter mais informações sobre como este e outros parâmetros, consulte [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) na *Referência de comandos da AWS CLI*.

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

**Para criar o mapeamento da origem do evento do Kinesis**
+ Na definição da sua função, adicione a `KinesisEvent` propriedade, conforme mostrado no seguinte exemplo:

  ```
  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 saber mais sobre como criar um mapeamento de origem de eventos para o Kinesis Data Streams no AWS SAM, consulte [Kinesis](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-kinesis.html) no *Guia do desenvolvedor do AWS Serverless Application Model*.

------

## Posição inicial de sondagem e fluxo
<a name="services-kinesis-stream-start-pos"></a>

Esteja ciente de que a sondagem do fluxo durante a criação e as atualizações do mapeamento da origem do evento é, finalmente, consistente.
+ Durante a criação do mapeamento da origem do evento, pode levar alguns minutos para a sondagem de eventos do fluxo iniciar.
+ Durante as atualizações do mapeamento da origem do evento, pode levar alguns minutos para interromper e reiniciar a sondagem de eventos do fluxo.

Esse comportamento significa que, se você especificar `LATEST` como posição inicial do fluxo, o mapeamento da origem do evento poderá perder eventos durante a criação ou as atualizações. Para garantir que nenhum evento seja perdido, especifique a posição inicial do fluxo como `TRIM_HORIZON` ou `AT_TIMESTAMP`.

## Como criar mapeamentos da origem do evento entre contas
<a name="services-kinesis-eventsourcemapping-cross-account"></a>

O Amazon Kinesis Data Streams permite [políticas baseadas em recursos](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_identity-vs-resource.html). Por isso, você pode processar dados ingeridos em um fluxo em uma Conta da AWS com uma função do Lambda em outra conta.

Para criar um mapeamento da origem do evento para sua função do Lambda usando um fluxo do Kinesis em outra Conta da AWS, você deve configurar o fluxo usando uma política baseada em recursos para dar permissão à função do Lambda para ler itens. Para saber como configurar seu fluxo para permitir o acesso entre contas, consulte [Compartilhamento de acesso com funções do AWS Lambda entre contas](https://docs.aws.amazon.com/streams/latest/dev/resource-based-policy-examples.html#Resource-based-policy-examples-lambda) no *Guia do desenvolvedor do Amazon Kinesis Streams*.

Depois de configurar seu fluxo com uma política baseada em recursos que conceda à sua função do Lambda as permissões necessárias, crie o mapeamento da origem do evento usando qualquer um dos métodos descritos na seção anterior.

Se você optar por criar seu mapeamento da origem do evento usando o console Lambda, cole o ARN do seu fluxo diretamente no campo de entrada. Se você quiser especificar um consumidor para seu fluxo, colar o ARN do consumidor preencherá automaticamente o campo do fluxo.

# Configurar a resposta em lote parcial com o Kinesis Data Streams e o Lambda
<a name="services-kinesis-batchfailurereporting"></a>

Ao consumir e processar dados de transmissão de uma fonte de eventos, o Lambda definirá checkpoints por padrão no número mais elevado na sequência de um lote somente quando o lote for um sucesso total. O Lambda trata todos os outros resultados como uma falha completa e tenta processar novamente o lote até o limite de novas tentativas. Para permitir sucessos parciais durante o processamento de lotes de um stream, ative `ReportBatchItemFailures`. Permitir sucessos parciais pode ajudar a reduzir o número de novas tentativas em um registro, embora não impeça totalmente a possibilidade de novas tentativas em um registro bem-sucedido.

Para ativar `ReportBatchItemFailures`, inclua o valor de enum **ReportBatchItemFailures** na lista [FunctionResponseTypes](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-FunctionResponseTypes). Essa lista indica quais tipos de resposta estão habilitados para sua função. Você pode configurar essa lista ao [criar](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) ou [atualizar](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) um mapeamento de origem de eventos.

**nota**  
Mesmo quando seu código de função retorna respostas parciais de falha em lote, essas respostas não serão processadas pelo Lambda, a menos que o atributo `ReportBatchItemFailures` esteja explicitamente ativado para o mapeamento da origem do evento.

## Sintaxe do relatório
<a name="streams-batchfailurereporting-syntax"></a>

Ao configurar relatórios sobre falhas de itens de lote, a classe `StreamsEventResponse` é retornada com uma lista de falhas de itens de lote. É possível usar um objeto `StreamsEventResponse` para retornar o número sequencial do primeiro registro com falha no lote. Você também pode criar sua própria classe personalizada usando a sintaxe de resposta correta. A seguinte estrutura JSON mostra a sintaxe de resposta necessária:

```
{ 
  "batchItemFailures": [ 
        {
            "itemIdentifier": "<SequenceNumber>"
        }
    ]
}
```

**nota**  
Se a matriz `batchItemFailures` contém vários itens, o Lambda usa o registro com o menor número de sequência como ponto de verificação. Em seguida, o Lambda repete todos os registros a partir desse ponto de verificação.

## Condições de sucesso e falha
<a name="streams-batchfailurereporting-conditions"></a>

O Lambda trata um lote como um sucesso completo se você retornar qualquer um destes:
+ Uma lista de `batchItemFailure` vazia
+ Uma lista de `batchItemFailure` nula
+ Uma vazia `EventResponse`
+ Uma nula `EventResponse`

O Lambda trata um lote como uma falha absoluta se você retornar qualquer um dos seguintes:
+ Uma string vazia `itemIdentifier`
+ Uma nula `itemIdentifier`
+ Um `itemIdentifier` com um nome de chave inválido

O Lambda faz novas tentativas após falhas com base na sua estratégia de repetição.

## Dividir um lote
<a name="streams-batchfailurereporting-bisect"></a>

Se a invocação falhar e `BisectBatchOnFunctionError` estiver ativado, o lote será dividido independentemente da configuração de `ReportBatchItemFailures`.

Quando uma resposta de sucesso parcial do lote é recebida e tanto `BisectBatchOnFunctionError` quanto `ReportBatchItemFailures` estão ativados, o lote é dividido no número de sequência retornado e o Lambda tenta novamente apenas os registros restantes.

Para simplificar a implementação da lógica de respostas parciais em lote, considere usar o [utilitário de processador em lote](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) da Powertools para AWS Lambda, que lida de maneira automática com essas complexidades para você.

Veja alguns exemplos de código de função que retornam a lista de IDs de mensagens com falha no lote:

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Relatar falhas de itens em lote do Kinesis com o Lambda usando o .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Relatar falhas de itens em lote do Kinesis com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Relatar falhas de itens em lote do Kinesis com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/blob/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Relatar falhas de itens em lote do Kinesis com o Lambda usando 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;
}
```
Relatar falhas de itens em lote do Kinesis com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Relatar falhas de itens em lote do Kinesis com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Relatar falhas de itens em lote do Kinesis com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Relatar falhas de item em lote do Kinesis com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda-with-batch-item-handling). 
Relate falhas de itens em lote do Kinesis com o Lambda usando 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
}
```

------

## Usar o Powertools para o processador em lote AWS Lambda
<a name="services-kinesis-batchfailurereporting-powertools"></a>

O utilitário de processador em lote do Powertools para AWS Lambda lida de maneira automática com a lógica de respostas parciais em lote, reduzindo a complexidade da implementação de relatórios de falhas em lote. Veja a seguir alguns exemplos usando o processador em lote:

**Python**  
Para ver exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/).
Processamento de registros de stream do Kinesis Data Streams com o processador em lote 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 exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.aws.amazon.com/powertools/typescript/latest/features/batch/).
Processamento de registros de stream do Kinesis Data Streams com o processador em lote 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 exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.powertools.aws.dev/lambda/java/latest/utilities/batch/).
Processamento de registros de stream do Kinesis Data Streams com o processador em lote 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 exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.aws.amazon.com/powertools/dotnet/utilities/batch-processing/).
Processamento de registros de stream do Kinesis Data Streams com o processador em lote 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; 
    }
}
```

# Reter registros de lotes descartados para uma origem de eventos do Kinesis Data Streams no Lambda
<a name="kinesis-on-failure-destination"></a>

O tratamento de erros para mapeamentos de origem de eventos do Kinesis depende se o erro ocorre antes de a função ser invocada ou durante a invocação da função:
+ **Antes da invocação:** se um mapeamento de origem de eventos do Lambda não conseguir invocar a função devido a limitações ou a outros problemas, ele tentará novamente até que os registros expirem ou excedam a idade máxima configurada no mapeamento de origem de eventos ([MaximumRecordAgeInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)).
+ **Durante a invocação:** se a função for invocada, mas retornar um erro, o Lambda tentará novamente até que os registros expirem, excedam a idade máxima ([MaximumRecordAgeInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)) ou atinjam a cota de repetição configurada ([MaximumRetryAttempts](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRetryAttempts)). Para erros de função, também é possível pode configurar [BisectBatchOnFunctionError](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-response-BisectBatchOnFunctionError), que divide um lote com falha em dois lotes em lotes, isolando registros com problema e evitando exceder tempos limites. A divisão de lotes não consome a cota de repetição.

Se as medidas de tratamento de erros falharem, o Lambda descartará os registros e continuará processando lotes provenientes da transmissão. Com as configurações padrão, isso significa que um registro ruim pode bloquear o processamento no fragmento afetado por até uma semana. Para evitar isso, configure o mapeamento de fontes de eventos da sua função com um número razoável de tentativas e uma idade máxima de registro que se adapte ao seu caso de uso.

## Configurar destinos para invocações com falha
<a name="kinesis-on-failure-destination-console"></a>

Para reter registros de invocações de mapeamento da origem do evento com falha, adicione um destino ao mapeamento da origem de eventos da função. Cada registro enviado ao destino é um documento JSON que contém metadados sobre a invocação que falhou. Para destinos do Amazon S3, o Lambda também envia todo o registro da invocação junto com os metadados. É possível configurar qualquer tópico do Amazon SNS, fila do Amazon SQS, bucket do Amazon S3 ou Kafka como destino.

Com destinos do Amazon S3, você pode usar o recurso [Notificações de eventos do Amazon S3](https://docs.aws.amazon.com/) para receber notificações quando objetos forem carregados no bucket do S3 de destino. Também é possível configurar as notificações de eventos do S3 para invocar outra função do Lambda para realizar o processamento automatizado em lotes com falha.

Sua função de execução deve ter permissões para o destino:
+ **Para um destino do SQS:** [sqs:SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)
+ **Para um destino do SNS:** [sns:Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)
+ **Para um destino do S3:** [s3:PutObject](https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html) e [s3:ListBucket](https://docs.aws.amazon.com/AmazonS3/latest/API/ListObjectsV2.html)
+ **Para um destino do Kafka**: [kafka-cluster:WriteData](https://docs.aws.amazon.com/msk/latest/developerguide/kafka-actions.html)

É possível configurar um tópico do Kafka como um destino do Kafka em caso de falha para os seus mapeamentos da origem do evento do Kafka. Quando o Lambda não consegue processar registros após exaurir as novas tentativas ou quando os registros excedem a idade máxima, o Lambda envia os registros com falha para o tópico especificado do Kafka para processamento posterior. Consulte [Uso de um tópico do Kafka como destino em caso de falha](kafka-on-failure-destination.md).

Se você habilitou a criptografia com sua própria chave do KMS para um destino do S3, o perfil de execução da função também deve ter permissão para chamar [kms:GenerateDataKey](https://docs.aws.amazon.com/kms/latest/APIReference/API_GenerateDataKey.html). Se a chave do KMS e o destino do bucket do S3 estiverem em uma conta diferente da função do Lambda e do perfil de execução, configure a chave do KMS para confiar no perfil de execução para permitir kms:GenerateDataKey.

Para configurar um destino em caso de falha usando o console, siga estas etapas:

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha uma função.

1. Em **Function overview (Visão geral da função)**, escolha **Add destination (Adicionar destino)**.

1. Em **Origem**, escolha **Invocação do mapeamento da origem do evento**.

1. Em **Mapeamento da origem do evento**, escolha uma origem de eventos configurada para essa função.

1. Em **Condição**, selecione **Em caso de falha**. Para invocações de mapeamento da origem de eventos, essa é a única condição aceita.

1. Em **Tipo de destino**, escolha o tipo de destino para o qual o Lambda envia registros de invocação.

1. Em **Destination (Destino)**, escolha um recurso.

1. Escolha **Salvar**.

Também é possível configurar um destino em caso de falha usando a AWS Command Line Interface (AWS CLI). Por exemplo, o seguinte comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) adiciona um mapeamento de origem de eventos com um destino SQS em caso de falha 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"}}'
```

O comando [update-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) a seguir atualiza um mapeamento de origem de eventos para enviar registros de chamada com falha para um destino SNS após duas novas tentativas ou se os registros tiverem mais de uma hora.

```
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"}}'
```

As configurações atualizadas são aplicadas de forma assíncrona e não são refletidas na saída até que o processo seja concluído. Use o comando [get-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/get-event-source-mapping.html) para visualizar o status atual.

Para remover um destino, forneça uma string vazia como argumento para o parâmetro `destination-config`:

```
aws lambda update-event-source-mapping \
--uuid f89f8514-cdd9-4602-9e1f-01a5b77d449b \
--destination-config '{"OnFailure": {"Destination": ""}}'
```

### Práticas recomendadas de segurança para destinos do Amazon S3
<a name="kinesis-s3-destination-security"></a>

Excluir um bucket do S3 configurado como destino sem remover o destino da configuração da sua função pode criar um risco de segurança. Se outro usuário souber o nome do seu bucket de destino, ele poderá recriar o bucket na Conta da AWS dele. Registros de invocações com falha serão enviados para o bucket do usuário, potencialmente expondo dados da sua função.

**Atenção**  
Para garantir que os registros de invocação da sua função não possam ser enviados para um bucket do S3 em outra Conta da AWS, adicione uma condição ao perfil de execução da função que limite as permissões `s3:PutObject` aos buckets na sua conta. 

O exemplo a seguir mostra uma política do IAM que limita as permissões `s3:PutObject` da função aos bucket da conta. Essa política também dá ao Lambda a permissão `s3:ListBucket` necessária para usar um bucket do 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 adicionar uma política de permissões ao perfil de execução da função usando o Console de gerenciamento da AWS ou a AWS CLI, consulte as instruções nos seguintes procedimentos:

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

**Para adicionar uma política de permissões ao perfil de execução de uma função (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Selecione a função do Lambda cujo perfil de execução você queira modificar.

1. Na guia **Configuração**, escolha **Permissões**.

1. Na guia **Perfil de execução**, selecione o **Nome do perfil** da função para abrir a página do console do IAM do perfil.

1. Adicione uma política de permissões ao perfil da seguinte maneira:

   1. No painel **Políticas de permissões**, escolha **Adicionar permissões** e **Criar política em linha**.

   1. No **Editor de políticas**, selecione **JSON**.

   1. Cole a política que você deseja adicionar no editor (substituindo o JSON existente) e escolha **Próximo**.

   1. No campo **Detalhes da política**, insira o **Nome da política**.

   1. Escolha **Criar política**.

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

**Para adicionar uma política de permissões ao perfil de execução de uma função (CLI)**

1. Crie um documento de política de JSON com as permissões necessárias e salve-o em um diretório local.

1. Use o comando da CLI `put-role-policy` do IAM para adicionar permissões ao perfil de execução da função. Execute o comando a seguir no diretório em que você salvou seu documento de política de JSON e substitua o nome do perfil, o nome da política e o documento da política pelos seus próprios valores.

   ```
   aws iam put-role-policy \
   --role-name my_lambda_role \
   --policy-name LambdaS3DestinationPolicy \
   --policy-document file://my_policy.json
   ```

------

### Exemplo de registro de invocação do Amazon SNS e do Amazon SQS
<a name="kinesis-on-failure-destination-example-sns-sqs"></a>

O exemplo a seguir mostra o que é enviado pelo Lambda para uma fila do SQS ou tópico do SNS em caso de falha na invocação da origem de eventos do Kinesis. Como o Lambda envia somente os metadados para esses tipos de destino, use os campos `streamArn`, `shardId`, `startSequenceNumber` e `endSequenceNumber` para obter o registro original completo. Todos os campos mostrados na propriedade `KinesisBatchInfo` estarão sempre 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"
    }
}
```

É possível usar essas informações para recuperar os registros afetados da transmissão para solução de problemas. Os registros reais não estão incluídos, portanto, você deve processar esses registros e recuperá-los da transmissão antes que eles expirem e sejam perdidos.

### Exemplo de registro de invocação do Amazon S3
<a name="kinesis-on-failure-destination-example-sns-sqs-s3"></a>

O exemplo a seguir mostra o que é enviado pelo Lambda para um bucket do Amazon S3 em caso de falha na invocação da origem de eventos do Kinesis. Além de todos os campos do exemplo anterior para destinos do SQS e do SNS, o campo `payload` contém o registro de invocação original como uma string JSON com 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
}
```

O objeto do S3 que contém o registro de invocação usa a seguinte convenção de nomenclatura:

```
aws/lambda/<ESM-UUID>/<shardID>/YYYY/MM/DD/YYYY-MM-DDTHH.MM.SS-<Random UUID>
```

# Implementando o processamento com estado do Kinesis Data Streams no Lambda
<a name="services-kinesis-windows"></a>

As funções do Lambda podem executar aplicações de processamento contínuo de transmissões. Um stream representa dados não vinculados que fluem continuamente por meio de sua aplicação. Para analisar as informações dessa entrada de atualização contínua, você pode vincular os registros incluídos usando uma janela definida em termos de tempo.

As janelas de tumbling são janelas de tempo distintas que abrem e fecham em intervalos regulares. Por padrão, as invocações do Lambda são sem estado. Não é possível usá-las para processar dados ao longo de várias invocações contínuas sem um banco de dados externo. No entanto, com as janelas de tumbling, você pode manter seu estado em todas as invocações. Esse estado contém o resultado agregado das mensagens previamente processadas para a janela atual. Seu estado pode ter no máximo 1 MB por fragmento. Se exceder esse tamanho, o Lambda encerra a janela antes.

Cada registro de um fluxo pertence a uma janela específica. O Lambda processará cada registro pelo menos uma vez, mas não garantirá que cada registro seja processado apenas uma vez. Em casos raros, como tratamento de erros, alguns registros poderão ser processados mais de uma vez. Os registros são sempre processados em ordem na primeira vez. Se os registros forem processados mais de uma vez, poderão ser processados fora de ordem.

## Agregação e processamento
<a name="streams-tumbling-processing"></a>

Sua função gerenciada pelo usuário é chamada tanto para agregação quanto para processamento dos resultados finais dessa agregação. O Lambda agrega todos os registros recebidos na janela. Você pode receber esses registros em vários lotes, cada um como uma invocação separada. Cada invocação recebe um estado. Assim, ao usar janelas de tumbling, sua resposta de função do Lambda deve conter uma propriedade de `state`. Se a resposta não contiver uma propriedade de `state`, o Lambda considerará esta uma invocação com falha. Para satisfazer essa condição, a função pode retornar um objeto do `TimeWindowEventResponse`, que tem a seguinte forma JSON:

**Example `TimeWindowEventResponse`Valores de**  

```
{
    "state": {
        "1": 282,
        "2": 715
    },
    "batchItemFailures": []
}
```

**nota**  
Para funções Java, recomendamos o uso de um `Map<String, String>` para representar o estado.

No final da janela, a sinalização `isFinalInvokeForWindow` é definida como `true` para indicar que esse é o estado final e que está pronto para processamento. Após o processamento, a janela é concluída e sua invocação final é concluída e, em seguida, o estado é descartado.

No final da janela, o Lambda usa o processamento final para ações sobre os resultados da agregação. Seu processamento final é invocado de forma síncrona. Após a invocação bem-sucedida, sua função define os pontos de verificação no número da sequência e o processamento de streams continua. Se a invocação não for bem-sucedida, sua função do Lambda suspenderá o processamento adicional até uma chamada bem-sucedida.

**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
}
```

## Configuração
<a name="streams-tumbling-config"></a>

Você pode configurar janelas em cascata ao criar ou atualizar um mapeamento de fonte de eventos. Para configurar uma janela em cascata, especifique a janela em segundos ([TumblingWindowInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-TumblingWindowInSeconds)). O comando de exemplo da AWS Command Line Interface (AWS CLI) a seguir cria um mapeamento de fonte de eventos em streaming com uma janela em cascata de 120 segundos. A função do Lambda definida para agregação e processamento é chamada de `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
```

O Lambda determina os limites da janela em cascata com base no horário em que os registros foram inseridos no stream. Todos os registros têm um carimbo de data/hora aproximado disponível que o Lambda usa para determinar os limites.

As agregações de janelas em cascata não são compatíveis com refragmentação. Quando um fragmento termina, o Lambda considera a janela como fechada e os fragmentos filhos iniciam suas próprias janelas em um novo estado. Quando nenhum novo registro está sendo adicionado à janela atual, o Lambda aguarda até 2 minutos antes de assumir que a janela terminou. Isso ajuda a garantir que a função leia todos os registros na janela atual, mesmo que os registros sejam adicionados de forma intermitente.

As janelas em cascata são totalmente compatíveis com as políticas `maxRetryAttempts` e `maxRecordAge`.

**Example Handler.py: agregação e processamento**  
A função do Python a seguir demonstra como agregar e, em seguida, processar seu 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 do Lambda para mapeamento de origem de eventos do Amazon Kinesis Data Streams.
<a name="services-kinesis-parameters"></a>

Todos os mapeamentos de origem de evento Lambda compartilham as mesmas operações de API [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) e [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html). No entanto, apenas alguns dos parâmetros se aplicam ao Kinesis.


| Parâmetro | Obrigatório | Padrão | Observações | 
| --- | --- | --- | --- | 
|  [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  |  nenhuma | 
|  [DestinationConfig](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-DestinationConfig)  |  N  | N/D |  Uma fila do Amazon SQS ou um destino de tópico do Amazon SNS para registros descartados. Para ter mais informações, consulte [Configurar destinos para invocações com falha](kinesis-on-failure-destination.md#kinesis-on-failure-destination-console).  | 
|  [Ativado](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-Enabled)  |  N  |  verdadeiro  |  nenhuma | 
|  [EventSourceArn](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-EventSourceArn)  |  S  | N/D |  O ARN do fluxo de dados ou um consumidor de fluxo  | 
|  [FunctionName](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-FunctionName)  |  S  | N/D |  nenhuma | 
|  [FunctionResponseTypes](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-FunctionResponseTypes)  |  N  |  N/D |  Para permitir que sua função reporte falhas específicas em um lote, inclua o valor `ReportBatchItemFailures` em `FunctionResponseTypes`. Para ter mais informações, consulte [Configurar a resposta em lote parcial com o Kinesis Data Streams e o Lambda](services-kinesis-batchfailurereporting.md).  | 
|  [MaximumBatchingWindowInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumBatchingWindowInSeconds)  |  N  |  0  |  nenhuma | 
|  [MaximumRecordAgeInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-MaximumRecordAgeInSeconds)  |  N  |  -1  |  -1 significa infinito: o Lambda não descarta registros (as [configurações de retenção de dados do Kinesis Data Streams](https://docs.aws.amazon.com/streams/latest/dev/kinesis-extended-retention.html) ainda se aplicam) 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: registros com falha são repetidos até que o registro expire 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)  |  S  |  N/D |  AT\$1TIMESTAMP, TRIM\$1HORIZON, ou LATEST  | 
|  [StartingPositionTimestamp](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-StartingPositionTimestamp)  |  N  |  N/D |  Válido somente se StartingPosition estiver definido como AT\$1TIMESTAMP. O tempo a partir do qual iniciar a leitura, em segundos no horário do Unix  | 
|  [TumblingWindowInSeconds](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html#lambda-CreateEventSourceMapping-request-TumblingWindowInSeconds)  |  N  |  N/D |  Mínimo: 0 Máximo: 900  | 

# Usar a filtragem de eventos com uma origem de eventos do Kinesis
<a name="with-kinesis-filtering"></a>

É possível usar filtragem de eventos para controlar quais registros de um stream ou fila que o Lambda enviará para a função. Para obter informações gerais sobre como a filtragem de eventos funciona, consulte [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md).

Esta seção tem como foco a filtragem de eventos para as origens de eventos do Kinesis.

**nota**  
Os mapeamentos das origens dos eventos do Kineses são compatíveis apenas com filtragem na chave `data`.

**Topics**
+ [Conceitos básicos da filtragem de eventos do Kinesis](#filtering-kinesis)
+ [Filtragem de registros agregados do Kinesis](#filtering-kinesis-efo)

## Conceitos básicos da filtragem de eventos do Kinesis
<a name="filtering-kinesis"></a>

Suponha que um produtor esteja inserindo dados formatados em JSON em seu fluxo de dados do Kinesis. Um exemplo de registro seria semelhante ao a seguir, com os dados JSON convertidos em uma string codificada em Base64 no 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"
}
```

Desde que os dados que o produtor coloque no stream sejam JSON válido, é possível usar a filtragem de eventos para filtrar registros usando a chave `data`. Suponha que um produtor esteja inserindo dados em seu stream do Kinesis no formato JASON a seguir.

```
{
    "record": 12345,
    "order": {
        "type": "buy",
        "stock": "ANYCO",
        "quantity": 1000
        }
}
```

Para filtrar somente os registros em que o tipo de pedido é “comprar”, o objeto `FilterCriteria` seria como a seguir.

```
{
    "Filters": [
        {
            "Pattern": "{ \"data\" : { \"order\" : { \"type\" : [ \"buy\" ] } } }"
        }
    ]
}
```

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples. 

```
{
    "data": {
        "order": {
            "type": [ "buy" ]
            }
      }
}
```

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

```
{ "data" : { "order" : { "type" : [ "buy" ] } } }
```

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : { \"order\" : { \"type\" : [ \"buy\" ] } } }"}]}'
```

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

Para adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "data" : { "order" : { "type" : [ "buy" ] } } }'
```

------

Para filtrar corretamente eventos de origens do Kinesis, tanto o campo de dados como os critérios de filtro para o campo de dados devem estar em formato JSON válido. Se algum desses campos não estiver em um formato JSON válido, o Lambda descartará a mensagem ou emitirá uma exceção. A tabela a seguir resume o comportamento específico: 


| Formato dos dados recebidos | Formato de filtro padrão para propriedades de dados | Ação resultante | 
| --- | --- | --- | 
|  JSON válido  |  JSON válido  |  Filtros do Lambda com base em seus critérios de filtro.  | 
|  JSON válido  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  JSON válido  |  Não JSON  |  O Lambda emite uma exceção no momento da criação ou atualização do mapeamento da fonte de eventos. O padrão de filtro para propriedades de dados deve estar em um formato JSON válido.  | 
|  Não JSON  |  JSON válido  |  O Lambda descarta o registro.  | 
|  Não JSON  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  Não JSON  |  Não JSON  |  O Lambda emite uma exceção no momento da criação ou atualização do mapeamento da fonte de eventos. O padrão de filtro para propriedades de dados deve estar em um formato JSON válido.  | 

## Filtragem de registros agregados do Kinesis
<a name="filtering-kinesis-efo"></a>

Com o Kinesis, é possível agregar vários registros em um único registro do Kinesis Data Streams para aumentar seu throughput. O Lambda pode aplicar critérios de filtro a registros agregados somente quando você usar a [distribuição avançada](https://docs.aws.amazon.com/streams/latest/dev/enhanced-consumers.html) do Kinesis. Não há suporte para a filtragem de registros agregados com o Kinesis padrão. Ao usar a distribuição avançada, você configura um consumidor de throughput dedicado do Kinesis para atuar como acionador para sua função do Lambda. Em seguida, o Lambda filtra os registros agregados e passa somente os registros que atendam aos seus critérios de filtragem.

Para saber mais sobre a agregação de registros do Kinesis, consulte a seção [Agregação](https://docs.aws.amazon.com/streams/latest/dev/kinesis-kpl-concepts.html#kinesis-kpl-concepts-aggretation) na página Conceitos principais da Kinesis Producer Library (KPL). Para saber mais sobre como usar o Lambda com a distribuição avançada do Kinesis, consulte [Aumento do desempenho do processamento de streams em tempo real com a distribuição avançada do Amazon Kinesis Data Streams e o 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/) no blog de computação da AWS.

# Tutorial: Usar o Lambda com o Kinesis Data Streams
<a name="with-kinesis-example"></a>

Neste tutorial, você criará uma função do Lambda para consumir eventos de um fluxo de dados do Amazon Kinesis. 

1. O aplicativo personalizado grava registros no fluxo.

1. AWS LambdaO sonda a transmissão e, quando detecta novos registros, invoca sua função do Lambda.

1. AWS LambdaO executa a função do Lambda assumindo a função de execução especificada no momento da criação da função do Lambda.

## Pré-requisitos
<a name="with-kinesis-prepare"></a>

### Instalar o AWS Command Line Interface
<a name="install_aws_cli"></a>

Se você ainda não instalou a AWS Command Line Interface, siga as etapas em [Instalar ou atualizar a versão mais recente da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalá-la.

O tutorial requer um terminal de linha de comando ou um shell para executar os comandos. No Linux e no macOS, use o gerenciador de pacotes e de shell de sua preferência.

**nota**  
No Windows, alguns comandos da CLI do Bash que você costuma usar com o Lambda (como `zip`) não são compatíveis com os terminais integrados do sistema operacional. Para obter uma versão do Ubuntu com o Bash integrada no Windows, [instale o Subsistema do Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Criar a função de execução
<a name="with-kinesis-example-create-iam-role"></a>

Crie a [função de execução](lambda-intro-execution-role.md) que dá à sua função permissão para acessar recursos do AWS.

**Para criar uma função de execução**

1. Abra a [página Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione **Create role** (Criar função).

1. Crie uma função com as propriedades a seguir.
   + **Trusted entity (Entidade confiável** – **AWS Lambda**.
   + **Permissões**: **AWSLambdaKinesisExecutionRole**.
   + **Role name (Nome da função** – **lambda-kinesis-role**.

A política **AWSLambdaKinesisExecutionRole** tem as permissões necessárias para a função ler itens do Kinesis e gravar logs no CloudWatch Logs.

## Criar a função
<a name="with-kinesis-example-create-function"></a>

Crie uma função do Lambda que processe suas mensagens do Kinesis. O código da função registra o ID do evento e os dados do evento do registro do Kinesis no CloudWatch Logs.

Este tutorial usa o runtime do Node.js 24, mas também fornecemos exemplos de códigos em outras linguagens de runtime. Você pode selecionar a guia na caixa a seguir para ver o código do runtime do seu interesse. O código JavaScript que você usará nesta etapa é o primeiro exemplo mostrado na guia **JavaScript**.

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Consumir um evento do Kinesis com o Lambda usando .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Consumir um evento do Kinesis com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Consumir um evento do Kinesis com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/blob/main/integration-kinesis-to-lambda). 
Consumir um evento do Kinesis com o Lambda usando 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;
}
```
Consumir um evento do Kinesis com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Consumir um evento do Kinesis com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Consumir um evento do Kinesis com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Consumir um evento do Kinesis com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-kinesis-to-lambda). 
Consuma um evento do Kinesis com o Lambda usando 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
}
```

------

**Para criar a função**

1. Crie um diretório para o projeto e depois mude para esse diretório.

   ```
   mkdir kinesis-tutorial
   cd kinesis-tutorial
   ```

1. Copie o código JavaScript de amostra em um novo arquivo denominado `index.js`.

1. Crie um pacote de implantação.

   ```
   zip function.zip index.js
   ```

1. Crie uma função do Lambda com o 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
   ```

## Testar a função do Lambda
<a name="walkthrough-kinesis-events-adminuser-create-test-function-upload-zip-test-manual-invoke"></a>

Invoque sua função do Lambda manualmente usando o comando `invoke` da CLI do AWS Lambda e um evento do Kinesis de amostra.

**Para testar a função do Lambda**

1. Copie o JSON a seguir em um arquivo e salve-o 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. Use o comando `invoke` para enviar o evento para a função.

   ```
   aws lambda invoke --function-name ProcessKinesisRecords \
   --cli-binary-format raw-in-base64-out \
   --payload file://input.txt outputfile.txt
   ```

   A opção **cli-binary-format** será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [A AWS CLI comporta opções de linha de comando globais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) no *Guia do usuário da AWS Command Line Interface versão 2*.

   A resposta é salva no `out.txt`.

## Criar uma transmissão do Kinesis
<a name="with-kinesis-example-configure-event-source-create"></a>

Use o comando `create-stream ` para criar um fluxo.

```
aws kinesis create-stream --stream-name lambda-stream --shard-count 1
```

Execute o comando `describe-stream` a seguir para obter o ARN do stream.

```
aws kinesis describe-stream --stream-name lambda-stream
```

A seguinte saída deverá ser mostrada:

```
{
    "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
    }
}
```

Você usa o ARN do stream na próxima etapa para associar o stream à sua função do Lambda.

## Adicionar uma fonte de eventos no AWS Lambda
<a name="with-kinesis-example-configure-event-source-add-event-source"></a>

Execute o comando AWS CLI a seguir da `add-event-source`.

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

Observe o ID do mapeamento para uso posterior. Você pode obter uma lista de mapeamentos de origem de evento executando o comando `list-event-source-mappings` a seguir.

```
aws lambda list-event-source-mappings --function-name ProcessKinesisRecords \
--event-source arn:aws:kinesis:us-east-1:111122223333:stream/lambda-stream
```

Na resposta, pode verificar que o valor do status é `enabled`. Os mapeamentos de origem de eventos podem ser desabilitados para pausar a pesquisa temporariamente, sem perder nenhum registro.

## Testar a configuração
<a name="with-kinesis-example-configure-event-source-test-end-to-end"></a>

Para testar o mapeamento da origem do evento, adicione registros de eventos ao seu stream do Kinesis. O valor `--data` é uma string que a CLI codifica em base64 antes de enviá-la ao Kinesis. Você pode executar o mesmo comando mais de uma vez para adicionar vários registros ao fluxo.

```
aws kinesis put-record --stream-name lambda-stream --partition-key 1 \
--data "Hello, this is a test."
```

O Lambda usa a função de execução para ler registros da transmissão. Em seguida, ele invoca sua função do Lambda, transmitindo lotes de registros. A função decodifica os dados de cada registro e os registra, enviando a saída para CloudWatch Logs. Visualize os logs no [console do CloudWatch](https://console.aws.amazon.com/cloudwatch).

## Limpe os recursos
<a name="cleanup"></a>

Agora você pode excluir os recursos criados para este tutorial, a menos que queira mantê-los. Excluindo os recursos da AWS que você não está mais usando, você evita cobranças desnecessárias em sua Conta da AWS.

**Para excluir a função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione a função de execução que você criou.

1. Escolha **Excluir**.

1. Insira o nome do perfil no campo de entrada de texto e escolha **Delete** (Excluir).

**Como excluir a função do Lambda**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Selecione a função que você criou.

1. Selecione **Ações**, **Excluir**.

1. Digite **confirm** no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir a transmissão do Kinesis**

1. Faça login no Console de gerenciamento da AWS e abra o console do Kinesis em [ https://console.aws.amazon.com/kinesis](https://console.aws.amazon.com/kinesis).

1. Selecione a transmissão criada.

1. Selecione **Ações**, **Excluir**.

1. Digite **delete** no campo de entrada de texto.

1. Escolha **Excluir**.

# Usar o Lambda com o Kubernetes
<a name="with-kubernetes"></a>

Você pode implantar e gerenciar funções do Lambda com a API do Kubernetes usando o [AWS Controllers for Kubernetes (ACK)](https://aws-controllers-k8s.github.io/community/docs/community/overview/) ou o [Crossplane](https://docs.crossplane.io/latest/packages/providers/).

## AWS Controlllers for Kubernetes (ACK)
<a name="kubernetes-ack"></a>

Você pode usar o ACK para implantar e gerenciar recursos da AWS da API do Kubernetes. Por meio do ACK, a AWS fornece controladores personalizados de código aberto para serviços da AWS, como o Lambda, Amazon Elastic Container Registry (Amazon ECR), Amazon Simple Storage Service (Amazon S3) e Amazon SageMaker AI. Cada serviço da AWS compatível tem seu próprio controlador personalizado. Em seu cluster do Kubernetes, instale um controlador para cada serviço da AWS que você deseja usar. Em seguida, crie uma [Definição de recursos personalizados (CRD)](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/) para definir os recursos da AWS.

Recomendamos que você use [Helm 3.8 ou posterior](https://helm.sh/docs/intro/install/) para instalar controladores ACK. Todo controlador do ACK vem com seu próprio chart do Helm, que instala o controlador, os CRDs e as regras RBAC do Kubernetes. Para obter mais informações, consulte [Install an ACK Controller](https://aws-controllers-k8s.github.io/community/docs/user-docs/install/) na documentação do ACK.

Depois de criar o recurso do ACK personalizado, você pode usá-lo como qualquer outro objeto incorporado do Kubernetes. Por exemplo, você pode implantar e gerenciar funções do Lambda com suas cadeias de ferramentas do Kubernetes preferenciais, incluindo [kubectl](https://kubernetes.io/docs/reference/kubectl/).

Aqui estão alguns exemplos de casos de uso para provisionar funções do Lambda por meio do ACK:
+ Sua organização usa [controle de acesso baseado em funções (RBAC)](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) e [perfis do IAM para contas de serviço](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) para criar limites de permissões. Com o ACK, você pode reutilizar esse modelo de segurança para o Lambda sem precisar criar novos usuários e políticas.
+ Sua organização tem um processo de DevOps para implantar recursos em um cluster do Amazon Elastic Kubernetes Service (Amazon EKS) usando manifestos do Kubernetes. Com o ACK, você pode usar um manifesto para provisionar funções do Lambda sem criar uma infraestrutura separada como modelos de código.

Para obter mais informações sobre o uso do ACK, consulte [Lambda tutorial in the ACK documentation](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/) é um projeto de código aberto da Cloud Native Computing Foundation (CNCF) que usa o Kubernetes para gerenciar recursos de infraestrutura em nuvem. Com o Crossplane, os desenvolvedores podem solicitar infraestrutura sem precisar entender suas complexidades. As equipes da plataforma retêm o controle sobre como a infraestrutura é provisionada e gerenciada.

Usando o Crossplane, você pode implantar e gerenciar funções do Lambda com suas cadeias de ferramentas Kubernetes preferenciais, como [kubectl](https://kubernetes.io/docs/reference/kubectl/), e qualquer pipeline de CI/CD que possa implantar manifestos no Kubernetes. Aqui estão alguns exemplos de casos de uso para provisionar funções do Lambda por meio do Crossplane:
+ Sua organização deseja impor a conformidade garantindo que as funções do Lambda tenham as [tags](configuration-tags.md) corretas. As equipes da plataforma podem usar [Composições de Crossplane](https://docs.crossplane.io/latest/get-started/get-started-with-composition/) para definir essa política por meio de abstrações de API. Os desenvolvedores podem então usar essas abstrações para implantar funções do Lambda com tags.
+ Seu projeto usa o GitOps com o Kubernetes. Nesse modelo, o Kubernetes reconcilia continuamente o repositório git (estado desejado) com os recursos em execução dentro do cluster (estado atual). Se houver diferenças, o processo do GitOps fará alterações no cluster automaticamente. Você pode usar o GitOps com o Kubernetes para implantar e gerenciar funções do Lambda por meio do Crossplane, usando ferramentas e conceitos familiares do Kubernetes, como [CRDs](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/) e [Controladores](https://kubernetes.io/docs/concepts/architecture/controller/).

Para obter mais informações sobre como usar o Crossplane com o Lambda, veja o seguinte:
+ [Esquemas para Crossplane da AWS](https://github.com/awslabs/crossplane-on-eks/blob/main/examples/upbound-aws-provider/README.md#deploy-the-examples): este repositório inclui exemplos de como usar o Crossplane para implantar recursos da AWS, incluindo funções do Lambda.
**nota**  
Os esquemas para Crossplane da AWS estão em desenvolvimento ativo e não devem ser usados na produção.
+ [Deploying Lambda with Amazon EKS and Crossplane](https://www.youtube.com/watch?v=m-9KLq29K4k): este vídeo demonstra um exemplo avançado de implantação de um arquitetura sem servidor da AWS com Crossplane, explorando o design tanto da perspectiva do desenvolvedor quanto da plataforma.

# Usar o Lambda com o Amazon MQ
<a name="with-mq"></a>

**nota**  
Se você deseja enviar dados para um destino que não seja uma função do Lambda ou enriquecer os dados antes de enviá-los, consulte [Amazon EventBridge Pipes](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html) (Pipes do Amazon EventBridge).

O Amazon MQ é um serviço gerenciado de agente de mensagem para o [Apache ActiveMQ](https://activemq.apache.org/) e o [RabbitMQ](https://www.rabbitmq.com). Um *agente de mensagens* habilita aplicações de software e componentes para se comunicarem usando várias linguagens de programação, sistemas operacionais e protocolos de mensagens formais por meio de destinos de eventos de tópico ou fila.

O Amazon MQ também pode gerenciar instâncias do Amazon Elastic Compute Cloud (Amazon EC2) em seu nome instalando agentes do ActiveMQ ou RabbitMQ e fornecendo diferentes topologias de rede e outras necessidades de infraestrutura.

Você pode usar uma função do Lambda para processar registros do seu agente de mensagens do Amazon MQ. O Lambda invoca sua função por meio de um [mapeamento de fontes de eventos](invocation-eventsourcemapping.md), um recurso do Lambda que lê mensagens de seu agente e invoca a função [de modo síncrono](invocation-sync.md).

**Atenção**  
Os mapeamentos da origem do evento do Lambda processam cada evento ao menos uma vez, podendo haver o processamento duplicado de registros. Para evitar possíveis problemas relacionados a eventos duplicados, é altamente recomendável tornar o código da função idempotente. Para saber mais, consulte [Como tornar minha função do Lambda idempotente](https://repost.aws/knowledge-center/lambda-function-idempotent) no Centro de Conhecimentos da AWS.

O mapeamento de fontes de eventos do Amazon MQ tem as seguintes restrições de configuração:
+ Simultaneidade: as funções do Lambda que usam um mapeamento de origem do evento do Amazon MQ têm uma configuração padrão de [simultaneidade](lambda-concurrency.md) máxima. Para o ActiveMQ, o serviço Lambda limita o número de ambientes de execução simultâneos a cinco por mapeamento da origem do evento do Amazon MQ. Para o RabbitMQ, o número de ambientes de execução simultânea é limitado a um por mapeamento da origem do evento do Amazon MQ. Mesmo que você altere as configurações de simultaneidade reservada ou provisionada da função, o serviço Lambda não disponibilizará mais ambientes de execução. Para solicitar um aumento na simultaneidade máxima padrão para um único mapeamento da origem do evento do Amazon MQ, entre em contato com o Suporte tendo a UUID do mapeamento da origem do evento e também a região. Como os aumentos são aplicados no nível do mapeamento da origem do evento específico, não no nível da conta ou da região, você precisa solicitar manualmente um aumento de escalação para cada mapeamento da origem do evento.
+ Contas cruzadas: o Lambda não é compatível com o processamento de contas cruzadas. Não é possível usar o Lambda para processar registros de um agente de mensagens do Amazon MQ que esteja em uma Conta da AWS diferente.
+ Autenticação: para o ActiveMQ, somente o [SimpleAuthenticationPlugin](https://activemq.apache.org/security#simple-authentication-plugin) do ActiveMQ é compatível. Para RabbitMQ, somente o[PLAIN](https://www.rabbitmq.com/access-control.html#mechanisms)Mecanismo de autenticação é compatível. Os usuários devem usar o AWS Secrets Manager para gerenciar suas credenciais. Para obter mais informações sobre a autenticação do ActiveMQ, consulte[Integração de corretores ActiveMQ com LDAP](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/security-authentication-authorization.html)no*Guia do desenvolvedor do Amazon MQ*.
+ Cota de conexão: os agentes têm um número máximo de conexões permitidas por protocolo de nível de transmissão de dados. Essa cota é baseada no tipo de instância do agente. Para obter mais informações, consulte o .[Operadores](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-limits.html#broker-limits)seção do**Cotas no Amazon MQ**no*Guia do desenvolvedor do Amazon MQ*.
+ Conectividade: você pode criar agentes em uma Virtual Private Cloud (VPC) pública ou privada. Para VPCs privadas, sua função do Lambda precisa acessar a VPC para receber mensagens. Para obter mais informações, consulte [Configuração da segurança de rede](process-mq-messages-with-lambda.md#process-mq-messages-with-lambda-networkconfiguration) mais adiante nesta seção.
+ Destinos de eventos: somente destinos de fila são compatíveis. No entanto, você pode usar um tópico virtual, que se comporta como um tópico internamente enquanto interage com o Lambda como uma fila. Para obter mais informações, consulte [Virtual Destinations](https://activemq.apache.org/virtual-destinations) no site do Apache ActiveMQ e [Virtual Hosts](https://www.rabbitmq.com/vhosts.html) no site do RabbitMQ.
+ Topologia de rede: para o ActiveMQ, somente um agente de instância única ou em espera é aceito por mapeamento de fontes de eventos. Para o RabbitMQ, apenas um agente de instância única ou implantação de cluster é aceito por mapeamento de fonte de eventos. Os agentes de instância única requerem um endpoint de failover. Para obter mais informações sobre esses modos de implantação do agente, consulte[Arquitetura de operador do MQ](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-broker-architecture.html)e[Arquitetura de MQ do Rabbit](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/rabbitmq-broker-architecture.html)no*Guia do desenvolvedor do Amazon MQ*.
+ Protocolos — Os protocolos suportados dependem do tipo de integração do Amazon MQ.
  + Para integrações do ActiveMQ, o Lambda consome mensagens usando o protocolo OpenWire/Java Message Service (JMS). Nenhum outro protocolo é compatível para o consumo de mensagens. Dentro do protocolo JMS, somente [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) e [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) são compatíveis. O Lambda também é compatível com propriedades personalizadas do JMS. Para obter mais informações sobre o protocolo OpenWire, consulte [OpenWire](https://activemq.apache.org/openwire.html) no site do Apache ActiveMQ.
  + Para integrações RabbitMQ, o Lambda consome mensagens usando o protocolo AMQP 0-9-1. Nenhum outro protocolo é compatível para o consumo de mensagens. Para obter mais informações sobre a implementação do protocolo AMQP 0-9-1 pelo RabbitMQ, consulte[AMQP 0-9-1 Guia de referência completo](https://www.rabbitmq.com/amqp-0-9-1-reference.html)no site do RabbitMQ.

O Lambda oferece suporte automaticamente às versões mais recentes do ActiveMQ e RabbitMQ que não têm suporte no Amazon MQ. Para obter as versões compatíveis mais recentes, consulte[Notas de versão do Amazon MQ](https://docs.aws.amazon.com/amazon-mq/latest/developer-guide/amazon-mq-release-notes.html)no*Guia do desenvolvedor do Amazon MQ*.

**nota**  
Por padrão, o Amazon MQ tem uma janela de manutenção semanal para agentes. Durante essa janela de tempo, os agentes não estão disponíveis. Para agentes sem espera, o Lambda não é possível processar nenhuma mensagem durante essa janela.

**Topics**
+ [Entender o grupo de consumidores do Lambda para o Amazon MQ](#services-mq-configure)
+ [Configuração da origem do evento do Amazon MQ para o Lambda](process-mq-messages-with-lambda.md)
+ [Parâmetros de mapeamento da origem do evento](services-mq-params.md)
+ [Filtrar eventos de uma origem de eventos do Amazon MQ](with-mq-filtering.md)
+ [Solucionar problemas de erro de mapeamento da origem do evento do Amazon MQ](services-mq-errors.md)

## Entender o grupo de consumidores do Lambda para o Amazon MQ
<a name="services-mq-configure"></a>

Para interagir com o Amazon MQ, o Lambda cria um grupo de consumidores que pode ler a partir de seus agentes do Amazon MQ. O grupo de consumidores é criado com o mesmo ID que um UUID de mapeamento da fonte de eventos.

Para fontes de evento do Amazon MQ, o Lambda divide os registros em lotes e os envia para sua função em uma única carga útil. Para controlar o comportamento, é necessário configurar a janela de lotes e o tamanho do lote. O Lambda extrai mensagens até processar o tamanho máximo da carga útil de 6 MB, a janela de lotes expirar ou o número de registros atingir o tamanho total do lote. Para obter mais informações, consulte [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching).

O grupo de consumidores recupera as mensagens como um BLOB de bytes, as codifica em base64 para uma única carga útil JSON e depois invoca a função. Se sua função retorna um erro para qualquer uma das mensagens em um lote, o Lambda tenta novamente todo o lote de mensagens até que o processamento seja bem-sucedido ou as mensagens expiram.

**nota**  
Embora as funções do Lambda normalmente tenham um limite máximo de tempo de 15 minutos, os mapeamentos da origem dos eventos para o Amazon MSK, o Apache Kafka autogerenciado, o Amazon DocumentDB e o Amazon MQ para ActiveMQ e RabbitMQ são compatíveis somente com funções com limites máximos de tempo limite de 14 minutos. Essa restrição garante que o mapeamento da origem do evento possa solucionar adequadamente os erros de função e repetições.

Você pode monitorar o uso da simultaneidade de uma determinada função usando a métrica `ConcurrentExecutions` no Amazon CloudWatch. Para obter mais informações sobre a simultaneidade, consulte [Configurar a simultaneidade reservada para uma função](configuration-concurrency.md).

**Example Eventos de registro do 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=="
      }
    ]
  }
}
```
No exemplo RabbitMQ,`pizzaQueue`é o nome da fila do RabbitMQ e`/`é o nome do host virtual. Ao receber mensagens, a origem do evento lista as mensagens em `pizzaQueue::/`.

# Configuração da origem do evento do Amazon MQ para o Lambda
<a name="process-mq-messages-with-lambda"></a>

**Topics**
+ [Configuração da segurança de rede](#process-mq-messages-with-lambda-networkconfiguration)
+ [Criar o mapeamento da origem do evento](#services-mq-eventsourcemapping)

## Configuração da segurança de rede
<a name="process-mq-messages-with-lambda-networkconfiguration"></a>

Para conceder ao Lambda acesso total ao Amazon MQ por meio do mapeamento da origem do evento, seu agente deve usar um endpoint público (endereço IP público) ou você deve fornecer acesso à Amazon VPC na qual o agente foi criado.

Ao usar o Amazon MQ com o Lambda, recomendamos a criação de [endpoints de VPC do AWS PrivateLink](https://docs.aws.amazon.com/vpc/latest/privatelink/create-interface-endpoint.html) para conceder acesso da sua função aos recursos na sua Amazon VPC.

**nota**  
Os endpoints de VPC do AWS PrivateLink são necessários para funções com mapeamentos da origem de eventos que usam o modo padrão (sob demanda) para pesquisadores de eventos. Se o mapeamento da origem do evento usa o [modo provisionado](invocation-eventsourcemapping.md#invocation-eventsourcemapping-provisioned-mode), você não precisa configurar endpoints de VPC do AWS PrivateLink.

Crie um endpoint para fornecer acesso aos seguintes recursos:
+  Lambda: crie um endpoint para a entidade principal de serviço do Lambda. 
+  AWS STS: crie um endpoint para o AWS STS com a finalidade de possibilitar que uma entidade principal de serviço assuma um perfil em seu nome. 
+  Secrets Manager: caso o seu agente use o Secrets Manager para armazenar credenciais, crie um endpoint específico para o Secrets Manager. 

Como alternativa, configure um gateway NAT em cada sub-rede pública da Amazon VPC. Para obter mais informações, consulte [Habilitar o acesso à Internet para funções do Lambda conectadas à VPC](configuration-vpc-internet.md).

Ao criar um mapeamento da origem do evento para o Amazon MQ, o Lambda verifica se as interfaces de rede elástica (ENIs) já estão presentes nas sub-redes e nos grupos de segurança configurados para a Amazon VPC. Se o Lambda encontrar ENIs existentes, ele tentará reutilizá-las. Caso contrário, o Lambda criará novas ENIs para se conectar à origem do evento e invocar sua função.

**nota**  
As funções do Lambda sempre são executadas em VPCs de propriedade do serviço Lambda. A configuração de VPC da sua função não afetará o mapeamento da origem do evento. Somente a configuração de rede da origem dos eventos determina como o Lambda estabelece conexão com a origem dos eventos.

Configure os grupos de segurança para a Amazon VPC que contém o agente. Por padrão, o Amazon MQ usa as seguintes portas: `61617` (Amazon MQ para ActiveMQ) e `5671` (Amazon MQ para RabbitMQ).
+ Regras de entrada: permitem todo o tráfego na porta padrão do agente para o grupo de segurança associado à origem dos eventos. Como alternativa, é possível usar uma regra de grupo de segurança autorreferenciada para permitir o acesso de instâncias dentro do mesmo grupo de segurança.
+ Regras de saída: permitir todo o tráfego na porta `443` para destinos externos se sua função precisar se comunicar com serviços da AWS. Como alternativa, você também poderá usar uma regra de grupo de segurança autorreferenciada para limitar o acesso ao operador se não precisar se comunicar com outros serviços AWS.
+ Regras de entrada para o endpoint da Amazon VPC: caso você esteja usando um endpoint da Amazon VPC, o grupo de segurança associado ao endpoint da Amazon VPC deve permitir o tráfego de entrada na porta `443` usando o grupo de segurança do agente.

Caso o agente use autenticação, é possível restringir a política de endpoint para o endpoint do Secrets Manager. Para chamar a API do Secrets Manager, o Lambda usa seu perfil de função, e não a entidade principal de serviço do Lambda.

**Example Política de endpoint da VPC: endpoint do 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"
          }
      ]
  }
```

Quando você usa os endpoints da Amazon VPC, a AWS roteia suas chamadas de API para invocar sua função usando a interface de rede elástica (ENI) do endpoint. A entidade principal do serviço Lambda precisa chamar `lambda:InvokeFunction` para quaisquer perfis e funções que usem essas ENIs.

Por padrão, os endpoints da Amazon VPC têm políticas do IAM abertas que permitem amplo acesso aos recursos. A prática recomendada é restringir essas políticas para executar as ações necessárias usando esse endpoint. Para garantir que seu mapeamento da origem do evento seja capaz de invocar sua função do Lambda, a política de endpoint da VPC deve permitir que a entidade principal do serviço Lambda chame `sts:AssumeRole` e `lambda:InvokeFunction`. A restrição de suas políticas de endpoint da VPC para permitir apenas chamadas de API originadas em sua organização impedirá o funcionamento adequado do mapeamento da origem do evento; portanto, `"Resource": "*"` é necessário nessas políticas.

O seguinte exemplo de políticas de endpoint da VPC mostra como conceder o acesso necessário à entidade principal do serviço Lambda para os endpoints do AWS STS e Lambda.

**Example Política de endpoint da VPC: endpoint do AWS STS**  

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

**Example Política de endpoint da VPC: endpoint do Lambda**  

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

## Criar o mapeamento da origem do evento
<a name="services-mq-eventsourcemapping"></a>

Crie um [mapeamento de fontes de eventos](invocation-eventsourcemapping.md) para instruir o Lambda a enviar registros de um agente do Amazon MQ para uma função do Lambda. É possível criar vários mapeamentos de origem de evento para processar os mesmos dados com várias funções ou processar itens de várias fontes com uma única função.

Para configurar sua função para ler do Amazon MQ, adicione as permissões necessárias e crie um acionador do **MQ** no console do Lambda.

Para ler os registros de um agente do Amazon MQ, a função do Lambda precisa das permissões a seguir. Você concede ao Lambda permissão para interagir com o agente do Amazon MQ e seus recursos subjacentes adicionando instruções de permissão ao [perfil de execução](lambda-intro-execution-role.md) da função:
+ [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**  
Ao usar uma chave criptografada gerenciada pelo cliente, adicione a permissão `[kms:Decrypt](https://docs.aws.amazon.com/msk/1.0/apireference/clusters-clusterarn-bootstrap-brokers.html#clusters-clusterarn-bootstrap-brokersget)` também.

**Para adicionar permissões e criar um acionador**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha o nome de uma função.

1. Escolha a guia **Configuration** (Configuração) e, depois, **Permissions** (Permissões).

1. Em **Nome do perfil**, escolha o link para seu perfil de execução. Esse link abre o perfil no console do IAM.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/execution-role.png)

1. Escolha **Adicionar permissões** e, em seguida, **Criar política em linha**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/inline-policy.png)

1. Na seção **Editor de políticas**, escolha **JSON**. Insira a seguinte política. A função precisa dessas permissões para ler de um agente do 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**  
Ao usar uma chave gerenciada pelo cliente criptografada, também é necessário adicionar a permissão `kms:Decrypt`.

1. Escolha **Próximo**. Digite um nome para a política e escolha **Criar política**.

1. Volte para a sua função no console do Lambda Em **Visão geral da função**, escolha **Adicionar gatilho**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/add-trigger.png)

1. Selecione o tipo de acionador **MQ**.

1. Configure as opções necessárias e escolha **Add** (Adicionar).

O Lambda oferece suporte às seguintes opções de fontes de eventos do Amazon MQ:
+ **Agente do MQ**— Selecione um corretor do Amazon MQ.
+ **Batch size** (Tamanho do lote): defina o número máximo de mensagens a serem recuperadas em um único lote.
+ **Queue name** (Nome da fila): digite a fila do Amazon MQ a ser consumida.
+ **Configuração do acesso à fonte**— Insira as informações do host virtual e o segredo do Secrets Manager que armazena as credenciais do agente.
+ **Enable trigger** (Habilitar acionador): desabilite o acionador para interromper o processamento de registros.

Para habilitar ou desabilitar o trigger (ou excluí-lo), selecione o trigger do **MQ** no designer. Para reconfigurar o trigger, use as operações da API de mapeamento de fontes de eventos.

# Parâmetros de mapeamento da origem do evento
<a name="services-mq-params"></a>

Todos os tipos de origem de evento Lambda compartilham o mesmo[CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html)e[UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html)Operações de API do. No entanto, apenas alguns dos parâmetros se aplicam ao Amazon MQ e RabbitMQ.


| Parâmetro | Obrigatório | Padrão | Observações | 
| --- | --- | --- | --- | 
|  BatchSize  |  N  |  100  |  Máximo: 10.000.  | 
|  Habilitado  |  N  |  verdadeiro  | nenhuma | 
|  FunctionName  |  S  | N/D  | nenhuma | 
|  FilterCriteria  |  N  |  N/D   |  [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md)  | 
|  MaximumBatchingWindowInSeconds  |  N  |  500 ms  |  [Comportamento de lotes](invocation-eventsourcemapping.md#invocation-eventsourcemapping-batching)  | 
|  Filas  |  N  | N/D |  O nome da fila de destino do agente do Amazon MQ a ser consumido.  | 
|  SourceAccessConfigurations  |  N  | N/D  |  Para credenciais ActiveMQ, BASIC\$1AUTH. Para RabbitMQ, pode conter credenciais BASIC\$1AUTH e informações de VIRTUAL\$1HOST.  | 

# Filtrar eventos de uma origem de eventos do Amazon MQ
<a name="with-mq-filtering"></a>

É possível usar filtragem de eventos para controlar quais registros de um stream ou fila que o Lambda enviará para a função. Para obter informações gerais sobre como a filtragem de eventos funciona, consulte [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md).

Esta seção tem como foco a filtragem de eventos para as origens de eventos do Amazon MQ.

**nota**  
Os mapeamentos das origens dos eventos do Amazon MQ é compatível apenas com filtragem na chave `data`.

**Topics**
+ [Noções básicas da filtragem de eventos do Amazon MQ](#filtering-AMQ)

## Noções básicas da filtragem de eventos do Amazon MQ
<a name="filtering-AMQ"></a>

Suponha que sua fila de mensagens do Amazon MQ contenha mensagens em formato JSON válido ou como strings simples. Um exemplo de registro seria semelhante ao a seguir, com os dados convertidos em uma string codificada em Base64 no 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=="
}
```

------

Para os agentes Active MQ e Rabbit MQ, é possível usar a filtragem de eventos para filtrar registros usando a chave `data`. Suponha que a fila do Amazon MQ contenha mensagens no formato JSON a seguir.

```
{
    "timeout": 0,
    "IPAddress": "203.0.113.254"
}
```

Para filtrar somente os registros onde o campo `timeout` é maior que 0, o objeto `FilterCriteria` seria como a seguir.

```
{
    "Filters": [
        {
            "Pattern": "{ \"data\" : { \"timeout\" : [ { \"numeric\": [ \">\", 0] } } ] } }"
        }
    ]
}
```

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples.

```
{
    "data": {
        "timeout": [ { "numeric": [ ">", 0 ] } ]
        }
}
```

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

```
{ "data" : { "timeout" : [ { "numeric": [ ">", 0 ] } ] } }
```

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : { \"timeout\" : [ { \"numeric\": [ \">\", 0 ] } ] } }"}]}'
```

Para adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"data\" : { \"timeout\" : [ { \"numeric\": [ \">\", 0 ] } ] } }"}]}'
```

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

Para adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "data" : { "timeout" : [ { "numeric": [ ">", 0 ] } ] } }'
```

------

Com o Amazon MQ, você também pode filtrar registros onde a mensagem é uma string simples. Suponha que você queira processar somente registros onde a mensagem comece com “Resultado: ”. O objeto `FilterCriteria` seria como a seguir.

```
{
    "Filters": [
        {
            "Pattern": "{ \"data\" : [ { \"prefix\": \"Result: \" } ] }"
        }
    ]
}
```

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples.

```
{
    "data": [
        {
        "prefix": "Result: "
        }
    ]
}
```

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

```
{ "data" : [ { "prefix": "Result: " } ] }
```

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

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

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

Para adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "data" : [ { "prefix": "Result " } ] }'
```

------

As mensagens do Amazon MQ devem ser strings codificadas em UTF-8, sejam em strings simples ou no formato JSON. Isso porque o Lambda decodifica as matrizes de bytes do Amazon MQ em UTF-8 antes de aplicar os critérios de filtragem. Se as mensagens usarem outra codificação, como UTF-16 ou ASCII, ou se o formato da mensagem não corresponder ao formato dos `FilterCriteria`, o Lambda processará somente os filtros de metadados. A tabela a seguir resume o comportamento específico:


| Formato do da mensagem recebida | Formato padrão de filtro para propriedades de mensagem | Ação resultante | 
| --- | --- | --- | 
|  String simples  |  String simples  |  Filtros do Lambda com base em seus critérios de filtro.  | 
|  String simples  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  String simples  |  JSON válido  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  JSON válido  |  String simples  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  JSON válido  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  JSON válido  |  JSON válido  |  Filtros do Lambda com base em seus critérios de filtro.  | 
|  String não codificada em UTF-8  |  JSON, string de texto simples ou nenhum padrão  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 

# Solucionar problemas de erro de mapeamento da origem do evento do Amazon MQ
<a name="services-mq-errors"></a>

Quando uma função do Lambda encontra um erro irrecuperável, o consumidor do Amazon MQ interrompe o processamento de registros. Qualquer outro consumidor pode continuar o processamento, contanto que não encontre o mesmo erro. Para determinar a possível causa de um consumidor interrompido, verifique o campo `StateTransitionReason` nos detalhes de devolução do `EventSourceMapping` para obter um dos seguintes códigos:

**`ESM_CONFIG_NOT_VALID`**  
A configuração do mapeamento da fonte de eventos não é válida.

**`EVENT_SOURCE_AUTHN_ERROR`**  
O Lambda falhou ao autenticar a fonte de eventos.

**`EVENT_SOURCE_AUTHZ_ERROR`**  
O Lambda não tem as permissões necessárias para acessar a fonte de eventos.

**`FUNCTION_CONFIG_NOT_VALID`**  
A configuração da função não é válida.

Os registros também não serão processados se o Lambda os descartar devido ao seu tamanho. O limite de tamanho para registros do Lambda é de 6 MB. Para entregar mensagens novamente após um erro da função, use uma Dead Letter Queue (DLQ – Fila de mensagens mortas). Para obter mais informações, consulte [Message Redelivery and DLQ Handling](https://activemq.apache.org/message-redelivery-and-dlq-handling) no site do Apache ActiveMQ e [Reliability Guide](https://www.rabbitmq.com/reliability.html) no site do RabbitMQ.

**nota**  
O Lambda não oferece suporte às políticas de reentrega personalizadas. Em vez disso, o Lambda usa uma política com os valores padrão da página [Política de reentrega](https://activemq.apache.org/redelivery-policy) no site do Apache ActiveMQ, com `maximumRedeliveries` definido como 6.

# Usar o AWS Lambda com o Amazon RDS
<a name="services-rds"></a>

É possível conectar uma função do Lambda a um banco de dados do Amazon Relational Database Service (Amazon RDS) diretamente e por meio de um Amazon RDS Proxy. As conexões diretas são úteis em cenários simples e os proxies são recomendados para produção. Um proxy de banco de dados gerencia um pool de conexões de banco de dados compartilhadas, o que permite que sua função atinja altos níveis de simultaneidade sem esgotar as conexões de banco de dados.

Recomendamos o uso do Amazon RDS Proxy para funções do Lambda que fazem conexões curtas e frequentes com o banco de dados ou que abrem e fecham um grande número de conexões de banco de dados. Para obter mais informações, consulte [Conectar automaticamente uma função do Lambda e uma instância de banco de dados](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/lambda-rds-connect.html) no Guia do desenvolvedor do Amazon Relational Database Service.

**dica**  
Para conectar uma função do Lambda rapidamente a um banco de dados do Amazon RDS, é possível usar o assistente guiado no console. Para abrir o assistente, faça o seguinte:  
Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.
Selecione a função à qual você deseja conectar um banco de dados.
Na guia **Configuração**, selecione **bancos de dados do RDS**.
Escolha **Conectar ao banco de dados do RDS**.
Depois de conectar a função a um banco de dados, você pode criar um proxy escolhendo **Adicionar proxy**.

## Configurar a função para funcionar com recursos do RDS
<a name="rds-configuration"></a>

No console do Lambda, você pode provisionar e configurar instâncias de banco de dados e recursos de proxy do Amazon RDS. É possível fazer isso navegando até **Bancos de dados do RDS** na guia **Configuração**. Como alternativa, você também pode criar e configurar conexões com funções do Lambda no console do Amazon RDS. Ao configurar uma instância de banco de dados do RDS para usar com o Lambda, observe os seguintes critérios:
+ Para se conectar a um banco de dados, a função deve estar na mesma Amazon VPC em que o banco de dados é executado.
+ É possível usar bancos de dados do Amazon RDS com mecanismos MySQL, MariaDB, PostgreSQL ou Microsoft SQL Server.
+ Também é possível usar clusters de banco de dados do Aurora com mecanismos MySQL ou PostgreSQL.
+ Você precisa fornecer um segredo do Secrets Manager para a autenticação do banco de dados.
+ Um perfil do IAM deve fornecer permissão para usar o segredo e uma política de confiança deve permitir que o Amazon RDS assuma o perfil.
+  A entidade principal do IAM que usa o console para configurar o recurso do Amazon RDS e conectá-lo à função deve ter as seguintes permissões:

### Exemplo de política de permissões
<a name="rds-lambda-permissions"></a>

**nota**  
 Você só precisa das permissões do Amazon RDS Proxy se configurar um Amazon RDS Proxy para gerenciar um pool de conexões de banco de dados. 

------
#### [ 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": "*"
    }
  ]
}
```

------

O Amazon RDS cobra uma taxa horária por proxies com base no tamanho da instância do banco de dados. Consulte [Preço do RDS Proxy](https://aws.amazon.com/rds/proxy/pricing/) para obter detalhes. Para obter mais informações sobre conexões de proxy, consulte [Usar o Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) no Guia do usuário do Amazon RDS.

### Requisitos de SSL/TLS para conexões do Amazon RDS
<a name="rds-lambda-certificates"></a>

Para fazer conexões SSL/TLS seguras com uma instância de banco de dados do Amazon RDS, a função do Lambda deverá verificar a identidade do servidor de banco de dados usando um certificado confiável. O Lambda lida com esses certificados de forma diferente dependendo do tipo de pacote de implantação:
+ [Arquivamentos de arquivos .zip](configuration-function-zip.md): o tratamento de certificados varia de acordo com o runtime:
  + **Node.js 18 e versões anteriores**: o Lambda inclui certificados CA e certificados do RDS automaticamente.
  + **Node.js 20 e posteriores**: o Lambda não carrega mais certificados CA adicionais por padrão. Defina a variável de ambiente `NODE_EXTRA_CA_CERTS` como `/var/runtime/ca-cert.pem`.

  Até 4 semanas podem ser necessárias para que os certificados do Amazon RDS para novos Regiões da AWS sejam adicionados aos runtimes gerenciados do Lambda.
+ [Imagens de contêiner](images-create.md): as imagens base da AWS incluem apenas certificados de CA. Se sua função se conectar a uma instância de banco de dados do Amazon RDS, será necessário incluir os certificados apropriados na imagem do seu contêiner. Em seu Dockerfile, baixe o [pacote de certificados que corresponde à Região da AWS em que você hospeda seu banco de dados.](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.SSL.html#UsingWithRDS.SSL.CertificatesDownload) Exemplo:

  ```
  RUN curl https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem -o /us-east-1-bundle.pem
  ```

Esse comando baixa o pacote de certificados do Amazon RDS e o salva no caminho absoluto `/us-east-1-bundle.pem` no diretório raiz do seu contêiner. Ao configurar a conexão do banco de dados no código da função, você deve referenciar esse caminho exato. Exemplo:

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

A função `readFileSync` é necessária porque os clientes de banco de dados Node.js precisam do conteúdo real do certificado na memória, e não apenas do caminho para o arquivo do certificado. Sem `readFileSync`, o cliente interpreta a string do caminho como conteúdo do certificado, o que resulta em um erro de "certificado autoassinado na cadeia de certificados".

**Example Configuração de conexão Node.js para função 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 Configuração de conexão Python para função 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 funções Java que usam conexões JDBC, a string de conexão deve incluir:
+ `useSSL=true`
+ `requireSSL=true`
+ Um parâmetro `sslCA` que aponta para a localização do certificado do Amazon RDS na imagem do contêiner

**Example String de conexão Java para função 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 String de conexão .NET para conexão MySQL em função 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 funções em Go que usam conexões MySQL, carregue o certificado do Amazon RDS em um pool de certificados e registre-o com o driver do MySQL. A string de conexão deve então referenciar essa configuração usando o parâmetro `tls`.

**Example Código Go para conexão MySQL em função 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 Configuração de conexão Ruby para função 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
)
```

------

## Como se conectar a um banco de dados do Amazon RDS em uma função do Lambda
<a name="rds-connection"></a>

Os exemplos de código a seguir mostram como implementar uma função do Lambda que se conecta a um banco de dados do Amazon RDS. A função faz uma solicitação simples ao banco de dados e exibe o resultado.

**nota**  
Esses exemplos de código são válidos somente para [pacotes de implantação .zip](configuration-function-zip.md). Se você estiver implantando sua função usando uma [imagem de contêiner](images-create.md), será necessário especificar o arquivo de certificado do Amazon RDS no código da sua função, conforme explicado na [seção anterior](#oci-certificate).

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conectar-se a um banco de dados do Amazon RDS em uma função do Lambda usando .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conectar-se a um banco de dados do Amazon RDS em uma função do Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conectar-se a um banco de dados do Amazon RDS em uma função do Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conectar-se a um banco de dados do Amazon RDS em uma função do Lambda usando 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)
  }
};
```
Conectar-se a um banco de dados do Amazon RDS em uma função do Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conectar-se a um banco de dados do Amazon RDS em uma função do Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conectar-se a um banco de dados do Amazon RDS em uma função do Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conectar-se a um banco de dados do Amazon RDS em uma função do Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-connect-rds-iam). 
Conectar-se a um banco de dados do Amazon RDS em uma função do Lambda usando 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}")
    }))
}
```

------

## Processar notificações de eventos vindas do Amazon RDS
<a name="rds-events"></a>

É possível usar o Lambda para processar notificações de eventos em um banco de dados do Amazon RDS. O Amazon RDS envia notificações para um tópico do Amazon Simple Notification Service (Amazon SNS), que você pode configurar para invocar uma função do Lambda. O Amazon SNS envolve a mensagem do Amazon RDS em seu próprio documento de evento e a envia para sua função.

Para obter mais informações sobre como configurar um banco de dados do Amazon RDS para enviar notificações, consulte [Trabalhar com a notificação de eventos do Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_Events.html). 

**Example Mensagem do Amazon RDS em um evento do 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 do Lambda e do Amazon RDS
<a name="rds-database-samples"></a>
+ [Usar uma função do Lambda para acessar um banco de dados do Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html): no Guia do usuário do Amazon RDS, aprenda a usar uma função do Lambda para gravar dados em um banco de dados do Amazon RDS usando um Amazon RDS Proxy. A função do Lambda lerá registros de uma fila do Amazon SQS e gravará novos itens em uma tabela no banco de dados sempre que uma mensagem for adicionada.

# Selecione um serviço de banco de dados para suas aplicações baseadas em Lambda
<a name="ddb-rds-database-decision"></a>

Muitas aplicações com tecnologia sem servidor precisam armazenar e recuperar dados. A AWS oferece várias opções de banco de dados que funcionam com funções do Lambda. Duas das opções mais populares são o Amazon DynamoDB, um serviço de banco de dados NoSQL, e o Amazon RDS, uma solução tradicional de banco de dados relacional. As seções a seguir explicam as principais diferenças entre esses serviços ao usá-los com o Lambda e ajudam você a selecionar o serviço de banco de dados certo para sua aplicação com tecnologia sem servidor.

Para saber mais sobre os outros serviços de banco de dados oferecidos pela AWS e entender seus casos de uso e suas desvantagens de forma mais geral, consulte [Como escolher um serviço de banco de dados da AWS](https://docs.aws.amazon.com/decision-guides/latest/databases-on-aws-how-to-choose/databases-on-aws-how-to-choose.html). Todos os serviços de banco de dados da AWS são compatíveis com o Lambda, mas nem todos podem ser adequados ao seu caso de uso específico.

## Quais são suas opções ao selecionar um serviço de banco de dados com o Lambda?
<a name="w2aad101d101c19b9"></a>

A AWS oferece vários serviços de banco de dados. Para aplicações com tecnologia sem servidor, duas das opções mais populares são o DynamoDB e o Amazon RDS.
+ O **DynamoDB** é um serviço de banco de dados NoSQL totalmente gerenciado e otimizado para aplicações com tecnologia sem servidor. Ele fornece ajuste de escala perfeita e performance consistente de milissegundos de um dígito em qualquer escala.
+ O **Amazon RDS** é um serviço gerenciado de banco de dados relacional que oferece suporte a vários mecanismos de banco de dados, incluindo MySQL e PostgreSQL. Ele fornece recursos SQL familiares com infraestrutura gerenciada.

## Recomendações se você já conhece seus requisitos
<a name="w2aad101d101c19c11"></a>

Se você já sabe quais são seus requisitos, estas são as nossas recomendações básicas:

Recomendamos o [DynamoDB](with-ddb.md) para aplicações com tecnologia sem servidor que precisam de performance consistente de baixa latência, ajuste de escala automática e não exigem junções ou transações complexas. É especialmente adequado para aplicações baseadas em Lambda devido à sua natureza com tecnologia sem servidor.

O [Amazon RDS](services-rds.md) é a melhor opção quando você precisa de consultas SQL complexas, junções ou tem aplicações existentes usando bancos de dados relacionais. No entanto, esteja ciente de que conectar as funções do Lambda ao Amazon RDS requer configuração adicional e pode afetar os horários de inicialização a frio.

## O que considerar ao selecionar um serviço de banco de dados
<a name="w2aad101d101c19c13"></a>

Ao escolher entre o DynamoDB e o Amazon RDS para suas aplicações Lambda, considere estes fatores:
+ Gerenciamento de conexões e inicializações a frio
+ Padrões de acesso aos dados
+ Complexidade das consultas
+ Requisitos de consistência de dados.
+ Características de ajuste de escala
+ Modelo de custo

Ao compreender esses fatores, você pode selecionar a opção que melhor atenda às necessidades do seu caso de uso específico.

### Gerenciamento de conexões e inicializações a frio
<a name="w2aad101d101c19c13b9b1"></a>
+ O DynamoDB usa uma API HTTP para todas as operações. As funções do Lambda podem fazer solicitações imediatas sem manter conexões, resultando em melhor performance de inicialização a frio. Cada solicitação é autenticada usando credenciais da AWS sem sobrecarga de conexão.
+ O Amazon RDS exige o gerenciamento de pools de conexões, pois usa conexões de banco de dados tradicionais. Isso pode impactar as inicializações a frio, pois novas instâncias do Lambda precisam estabelecer conexões. Você precisará implementar estratégias de agrupamento de conexões e, potencialmente, usar o [Amazon RDS Proxy](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-proxy.html) para gerenciar conexões de forma eficaz. Observe que o uso do Amazon RDS Proxy incorre em custos adicionais.

### Padrões de acesso a dados
<a name="w2aad101d101c19c13b9b3"></a>
+ O DynamoDB funciona melhor com padrões de acesso conhecidos e designs de tabela única. É ideal para aplicações do Lambda que precisam de acesso consistente de baixa latência aos dados com base em chaves primárias ou índices secundários.
+ O Amazon RDS oferece flexibilidade para consultas complexas e padrões de acesso variáveis. É mais adequado quando suas funções do Lambda precisam realizar consultas exclusivas e personalizadas ou junções complexas em várias tabelas.

### Complexidade das consultas
<a name="w2aad101d101c19c13b9b5"></a>
+ O DynamoDB se destaca em operações simples baseadas em chaves e padrões de acesso predefinidos. As consultas complexas devem ser projetadas em torno de estruturas de índice, e as junções devem ser tratadas no código da aplicação.
+ O Amazon RDS oferece suporte a consultas SQL complexas com junções, subconsultas e agregações. Isso pode simplificar o código da sua função do Lambda quando operações de dados complexas são necessárias.

### Requisitos de consistência de dados.
<a name="w2aad101d101c19c13b9b7"></a>
+ O DynamoDB oferece opções de consistência eventual e forte, com consistência forte disponível para leituras de um único item. As transações são aceitas, mas com algumas limitações.
+ O Amazon RDS fornece conformidade total com atomicidade, consistência, isolamento e durabilidade (ACID) e suporte a transações complexas. Se suas funções do Lambda exigirem transações complexas ou consistência forte em vários registros, o Amazon RDS pode ser mais adequado.

### Características de ajuste de escala
<a name="w2aad101d101c19c13b9b9"></a>
+ O DynamoDB escala automaticamente com sua workload. Ele pode lidar com picos repentinos no tráfego das funções do Lambda sem pré-provisionamento. É possível usar o modo de capacidade sob demanda para pagar somente o que usar, combinando perfeitamente com o modelo de ajuste de escala do Lambda.
+ O Amazon RDS tem capacidade fixa com base no tamanho da instância que você escolher. Se várias funções do Lambda tentarem se conectar simultaneamente, você poderá exceder sua cota de conexão. Você precisa gerenciar cuidadosamente os pools de conexões e, potencialmente, implementar a lógica de novas tentativas.

### Modelo de custo
<a name="w2aad101d101c19c13b9c11"></a>
+ Os preços do DynamoDB se alinham bem com aplicações com tecnologia sem servidor. Com a capacidade sob demanda, você paga somente pelas leituras e gravações reais executadas pelas funções do Lambda. Não há cobranças por tempo ocioso.
+ O Amazon RDS cobra pela instância em execução, independentemente do uso. Isso pode ser menos econômico para workloads esporádicas que podem ser comuns em aplicações com tecnologia sem servidor. No entanto, pode ser mais econômico para workloads de alto throughput com uso consistente.

## Introdução ao serviço de banco de dados escolhido
<a name="w2aad101d101c19c15"></a>

Agora que você conhece os critérios para escolher entre o DynamoDB e o Amazon RDS, bem como as principais diferenças entre eles, poderá selecionar a opção que melhor atende às suas necessidades e usar os recursos a seguir para ajudar a começar a usá-lo.

------
#### [ DynamoDB ]

**Conceitos básicos para usar o DynamoDB com os recursos abaixo**
+ Para uma introdução ao serviço DynamoDB, leia [O que é o DynamoDB?](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) no *Guia do desenvolvedor do Amazon DynamoDB*.
+ Siga o tutorial [Uso do Lambda com API Gateway](services-apigateway-tutorial.md) para ver um exemplo do uso de uma função do Lambda para realizar operações CRUD em uma tabela do DynamoDB em resposta a uma solicitação de API.
+ Leia [Programação com o DynamoDB e os AWS SDKs](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.html) no *Guia do desenvolvedor do Amazon DynamoDB* para saber mais sobre como acessar o DynamoDB de dentro da sua função do Lambda usando um dos SDKs da AWS.

------
#### [ Amazon RDS ]

**Conceitos básicos para usar o Amazon RDS com os recursos abaixo**
+ Para uma introdução ao serviço Amazon RDS, leia [O que é o Amazon Relational Database Service (Amazon RDS)?](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/Welcome.html) no *Guia do usuário do Amazon Relational Database Service*.
+ Siga o tutorial [Usar uma função do Lambda para acessar um banco de dados Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/rds-lambda-tutorial.html) no *Guia do usuário do Amazon Relational Database Service*.
+ Saiba mais sobre o uso do Lambda com o Amazon RDS lendo o [Usar o AWS Lambda com o Amazon RDS](services-rds.md).

------

# Processar notificações de eventos do Amazon S3 com o Lambda
<a name="with-s3"></a>

Você pode usar o Lambda para processar [notificações de eventos](https://docs.aws.amazon.com/AmazonS3/latest/userguide/NotificationHowTo.html) do Amazon Simple Storage Service. O Amazon S3 pode enviar um evento para uma função do Lambda quando um objeto é criado ou excluído. Você define as configurações de notificação em um bucket e concede permissão ao Amazon S3 para invocar uma função na política de permissões baseada em recursos da função.

**Atenção**  
Se a função do Lambda usar o mesmo bucket que a aciona, isso poderá fazer a função ser executada em um loop. Por exemplo, se o bucket disparar uma função sempre que um objeto for carregado e a função fizer upload de um objeto no bucket, a função vai se disparar indiretamente. Para evitar isso, use dois buckets ou configure o trigger para só se aplicar a um prefixo usado em objetos recebidos.

O Amazon S3 invoca a função [de forma assíncrona](invocation-async.md) com um evento que contém detalhes sobre o objeto. O exemplo a seguir mostra um evento que o Amazon S3 enviou quando um pacote de implantação foi carregado no Amazon S3.

**Example Evento de notificação do 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 a função, o Amazon S3 precisa de permissão da [política baseada em recursos](access-control-resource-based.md) da função. Quando você configura um acionador do Amazon S3 no console do Lambda, o console modifica a política baseada em recursos para permitir que o Amazon S3 invoque a função se o nome do bucket e o ID da conta corresponderem. Se você configurar a notificação no Amazon S3, use a API do lambda para atualizar a política. Também é possível usar a API do Lambda para conceder permissão a outra conta ou restringir a permissão a um alias designado.

Se a sua função usa o AWS SDK para gerenciar recursos do Amazon S3, ela também precisa de permissões do Amazon S3 em sua [função de execução](lambda-intro-execution-role.md). 

**Topics**
+ [Tutorial: Usar um acionador do Amazon S3 para invocar uma função do Lambda](with-s3-example.md)
+ [Tutorial: Usar um acionador do Amazon S3 para criar imagens em miniatura](with-s3-tutorial.md)

# Tutorial: Usar um acionador do Amazon S3 para invocar uma função do Lambda
<a name="with-s3-example"></a>

Neste tutorial, você usará o console para criar uma função do Lambda e configurar um acionador para um bucket do Amazon Simple Storage Service (Amazon S3). Toda vez que você adiciona um objeto ao bucket do Amazon S3, sua função é executada e envia o tipo de objeto ao Amazon CloudWatch Logs.

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3_tut_config.png)


Este tutorial demonstra como:

1. Crie um bucket do Amazon S3.

1. Crie uma função do Lambda que retorne o tipo de objeto de um bucket do Amazon S3.

1. Configure um acionador do Lambda que invoque a função quando forem carregados objetos para o bucket.

1. Teste sua função, primeiro com um evento fictício e depois usando o acionador.

Ao concluir essas etapas, você aprenderá a configurar uma função do Lambda a ser executada sempre que forem adicionados ou excluídos objetos de um bucket do Amazon S3. Você pode concluir este tutorial usando somente o Console de gerenciamento da AWS.

## Criar um bucket do Amazon S3
<a name="with-s3-example-create-bucket"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps1.png)


**Como criar um bucket do Amazon S3**

1. Abra o [console do Amazon S3](https://console.aws.amazon.com/s3) e selecione a página **Buckets de uso geral**.

1. Selecione a Região da AWS mais próxima de sua localização geográfica. É possível alterar a região usando a lista suspensa na parte superior da tela. Mais adiante no tutorial, você deverá criar sua função do Lambda na mesma região.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/console_region_select.png)

1. Selecione **Criar bucket**.

1. Em **General configuration** (Configuração geral), faça o seguinte:

   1. Em **Tipo de bucket**, certifique-se de que **Uso geral** esteja selecionado.

   1. Em **Nome do bucket**, insira um nome global exclusivo que atenda às [regras de nomenclatura de buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html) do Amazon S3. Os nomes dos buckets podem conter apenas letras minúsculas, números, pontos (.) e hifens (-).

1. Deixe todas as outras opções com seus valores padrão e escolha **Criar bucket**.

## Carregar um objeto de teste em um bucket
<a name="with-s3-example-upload-test-object"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps2.png)


**Para carregar um objeto de teste**

1. Abra a página [Buckets](https://console.aws.amazon.com/s3/buckets) do console do Amazon S3 e escolha o bucket que você criou durante a etapa anterior.

1. Escolha **Carregar**.

1. Escolha **Adicionar arquivos** e selecione o objeto que deseja de carregar. Você pode selecionar qualquer arquivo (por exemplo, `HappyFace.jpg`).

1. Selecione **Abrir** e **Carregar**.

Posteriormente no tutorial, você testará a função do Lambda usando esse objeto.

## Criação de uma política de permissões
<a name="with-s3-example-create-policy"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps3.png)


Crie uma política de permissões que permita ao Lambda obter objetos de um bucket do Amazon S3 e gravar no Amazon CloudWatch Logs. 

**Para criar a política**

1. Abra a [página Policies](https://console.aws.amazon.com/iam/home#/policies) (Políticas) do console do IAM.

1. Escolha **Create Policy**.

1. Escolha a guia **JSON** e cole a política personalizada a seguir no 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. Escolha **Próximo: tags**.

1. Selecione **Próximo: revisar**.

1. No campo **Política de revisão**, em **Nome** da política, insira **s3-trigger-tutorial**.

1. Escolha **Criar política**.

## Criar uma função de execução
<a name="with-s3-example-create-role"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps4.png)


Um [perfil de execução](lambda-intro-execution-role.md) é um perfil do AWS Identity and Access Management (IAM) que concede a uma função do Lambda permissão para acessar recursos e Serviços da AWS. Nesta etapa, crie um perfil de execução usando a política de permissões que criou na etapa anterior.

**Para criar uma função de execução e vincular a política de permissões personalizada**

1. Abra a página [Funções](https://console.aws.amazon.com/iam/home#/roles) no console do IAM.

1. Selecione **Criar perfil**.

1. Para o tipo de entidade confiável, escolha **Serviço da AWS** e, em seguida, para o caso de uso, selecione **Lambda**.

1. Escolha **Próximo**.

1. Na caixa de pesquisa de política, insira **s3-trigger-tutorial**.

1. Nos resultados da pesquisa, selecione a política que você criou (`s3-trigger-tutorial`) e, depois, escolha **Next** (Avançar).

1. Em **Role details** (Detalhes do perfil), para **Role name** (Nome do perfil), insira **lambda-s3-trigger-role** e, em seguida, escolha **Create role** (Criar perfil).

## Criar a função do Lambda
<a name="with-s3-example-create-function"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps5.png)


Crie uma função do Lambda no console usando o runtime do Python 3.14.

**Para criar a função do Lambda**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Verifique se você está trabalhando na mesma Região da AWS em que criou o bucket do Amazon S3. Você pode alterar sua região usando a lista suspensa na parte superior da tela.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/console_region_select.png)

1. Escolha a opção **Criar função**.

1. Escolher **Criar do zero**

1. Em **Basic information** (Informações básicas), faça o seguinte:

   1. Em **Nome da função**, inserir `s3-trigger-tutorial`

   1. Em **Runtime**, selecione **Python 3.14**.

   1. Em **Architecture** (Arquitetura), escolha **x86\$164**.

1. Na guia **Alterar função de execução padrão**, faça o seguinte:

   1. Expanda a guia e escolha **Usar uma função existente**.

   1. Selecione a `lambda-s3-trigger-role` que você criou anteriormente.

1. Escolha **Criar função**.

## Implantar o código da função
<a name="with-s3-example-deploy-code"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps6.png)


Este tutorial usa o runtime do Python 3.14, mas também fornecemos exemplos de arquivos de código para outros runtimes. É possível selecionar a guia na caixa a seguir para ver o código do runtime do seu interesse.

A função do Lambda vai recuperar o nome da chave do objeto carregado e o nome do bucket do parâmetro `event` que receberá do Amazon S3. Em seguida, a função usará o método [get\$1object](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/get_object.html) do AWS SDK para Python (Boto3) para recuperar os metadados do objeto, incluindo o tipo de conteúdo (tipo MIME) do objeto carregado.

**Para implantar o código da função**

1. Escolha a guia **Python** na caixa a seguir e copie o código.

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Consumir um evento do S3 com o Lambda usando .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Consumir um evento do S3 com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Consumir um evento do S3 com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Consumir um evento do S3 com o Lambda usando 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);
       }
   };
   ```
Consumir um evento do S3 com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Como consumir um evento do S3 com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Consumir um evento do S3 com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Como consumir um evento do S3 com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-s3-to-lambda). 
Consumir um evento do S3 com o Lambda usando 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. No painel de **Origem do código** no console do Lambda, cole o código no editor de código, substituindo o código criado pelo Lambda.

1. Na seção **DEPLOY**, escolha **Implantar** para atualizar o código da função:  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/getting-started-tutorial/deploy-console.png)

## Criar o acionador do Amazon S3
<a name="with-s3-example-create-trigger"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps7.png)


**Para criar o acionador do Amazon S3**

1. No painel **Visão geral da função**, escolha **Adicionar gatilho**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/overview-trigger.png)

1. Selecione **S3**.

1. Em **Bucket**, selecione o bucket que você criou anteriormente no tutorial.

1. Em **Tipos de eventos**, garanta que a opção **Todos os eventos de criação de objetos** esteja selecionada.

1. Em **Invocação recursiva**, marque a caixa de seleção para confirmar que não é recomendável usar o mesmo bucket do Amazon S3 para entrada e saída.

1. Escolha **Adicionar**.

**nota**  
Quando você cria um acionador do Amazon S3 para uma função do Lambda usando o console do Lambda, o Amazon S3 configura uma [notificação de evento](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventNotifications.html) no bucket que você especificar. Antes de configurar essa notificação de evento, o Amazon S3 executa uma série de verificações para confirmar que o destino do evento existe e tem as políticas do IAM necessárias. O Amazon S3 também executa esses testes em qualquer outra notificação de evento configurada para esse bucket.  
Por causa dessa verificação, se o bucket tiver destinos de eventos previamente configurados para recursos que não existem mais ou para recursos que não têm as políticas de permissões necessárias, o Amazon S3 não poderá criar a nova notificação de evento. Você verá a seguinte mensagem de erro indicando que não foi possível criar seu acionador:  

```
An error occurred when creating the trigger: Unable to validate the following destination configurations.
```
Você poderá ver esse erro se tiver configurado anteriormente um acionador para outra função do Lambda usando o mesmo bucket e, desde então, tiver excluído a função ou modificado suas políticas de permissões.

## Testar sua função do Lambda com um evento fictício
<a name="with-s3-example-test-dummy-event"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps8.png)


**Para testar a função do Lambda com um evento fictício**

1. Na página de console do Lambda da sua função, escolha a guia **Testar**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/test-tab.png)

1. Em **Nome do evento**, insira `MyTestEvent`.

1. Em **Evento JSON**, cole o seguinte evento de teste. Não se esqueça de substituir estes valores:
   + Substitua `us-east-1` pela região em que você criou o bucket do Amazon S3.
   + Substitua ambas as instâncias de `amzn-s3-demo-bucket` pelo nome do seu próprio bucket do Amazon S3.
   + Substitua `test%2FKey` pelo nome do objeto de teste que você carregou anteriormente para o bucket (por exemplo, `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. Escolha **Salvar**.

1. Escolha **Test** (Testar).

1. Se a função for executada com êxito, você verá uma saída semelhante à seguinte na guia **Resultados da execução**.

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

### Testar a função do Lambda com o acionador do Amazon S3
<a name="with-s3-example-test-s3-trigger"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-example/s3trigger_tut_steps9.png)


Para testar a função com o gatilho configurado, carregue um objeto para o bucket do Amazon S3 usando o console. Para verificar se a função do Lambda foi executada conforme planejado, use o CloudWatch Logs para visualizar a saída da sua função.

**Para carregar um objeto para o bucket do Amazon S3**

1. Abra a página [Buckets](https://console.aws.amazon.com/s3/buckets) do console do Amazon S3 e escolha o bucket que você criou anteriormente.

1. Escolha **Carregar**.

1. Escolha **Adicionar arquivos** e use o seletor de arquivos para escolher um objeto que você deseje carregar. Esse objeto pode ser qualquer arquivo que você escolher.

1. Selecione **Abrir** e **Carregar**.

**Para verificar a invocação da função usando o CloudWatch Logs**

1. [Abra o console do CloudWatch](https://console.aws.amazon.com/cloudwatch/home).

1. Verifique se você está trabalhando na mesma Região da AWS em que criou a função do Lambda. Você pode alterar sua região usando a lista suspensa na parte superior da tela.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/console_region_select.png)

1. Escolha **Logs** e depois escolha **Grupos de logs**.

1. Escolha o nome do grupo de logs para sua função (`/aws/lambda/s3-trigger-tutorial`).

1. Em **Fluxos de logs**, escolha o fluxo de logs mais recente.

1. Se sua função tiver sido invocada corretamente em resposta ao gatilho do Amazon S3, você verá uma saída semelhante à seguinte. O `CONTENT TYPE` que você vê depende do tipo de arquivo que você carregou no bucket.

   ```
   2022-05-09T23:17:28.702Z	0cae7f5a-b0af-4c73-8563-a3430333cc10	INFO	CONTENT TYPE: image/jpeg
   ```

## Limpe os recursos
<a name="cleanup"></a>

Agora você pode excluir os recursos criados para este tutorial, a menos que queira mantê-los. Excluindo os recursos da AWS que você não está mais usando, você evita cobranças desnecessárias em sua Conta da AWS.

**Como excluir a função do Lambda**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Selecione a função que você criou.

1. Selecione **Ações**, **Excluir**.

1. Digite **confirm** no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir a função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione a função de execução que você criou.

1. Escolha **Excluir**.

1. Insira o nome do perfil no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir o bucket do S3**

1. Abra o [console Amazon S3](https://console.aws.amazon.com//s3/home#).

1. Selecione o bucket que você criou.

1. Escolha **Excluir**.

1. Insira o nome do bucket no campo de entrada de texto.

1. Escolha **Excluir bucket**.

## Próximas etapas
<a name="next-steps"></a>

No [Tutorial: Usar um acionador do Amazon S3 para criar imagens em miniatura](with-s3-tutorial.md), o gatilho do Amazon S3 invoca uma função para criar uma imagem em miniatura para cada arquivo de imagem que é carregado para um bucket. Este tutorial requer um nível moderado de conhecimento de domínios da AWS e do Lambda. Ele demonstra como criar recursos usando a AWS Command Line Interface (AWS CLI) e como criar um arquivo .zip de pacote de implantação de arquivamento para a sua função e suas dependências.

# Tutorial: Usar um acionador do Amazon S3 para criar imagens em miniatura
<a name="with-s3-tutorial"></a>

Neste tutorial, você criará e configurará uma função do Lambda que redimensiona as imagens adicionadas a um bucket do Amazon Simple Storage Service (Amazon S3). Quando você adiciona um arquivo de imagem ao bucket, o Amazon S3 invoca a função do Lambda. Em seguida, a função cria uma versão em miniatura da imagem e a envia para um bucket diferente do Amazon S3.

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_resources.png)


Para concluir este tutorial, execute as seguintes tarefas:

1. Crie buckets do Amazon S3 de origem e de destino e faça upload de uma imagem de amostra.

1. Crie uma função do Lambda que redimensiona uma imagem e envia uma miniatura para um bucket do Amazon S3.

1. Configure um acionador do Lambda que invoca a função quando os objetos são carregados no bucket de origem.

1. Teste a função com um evento fictício e, em seguida, ao fazer upload de uma imagem para o bucket de origem.

Ao concluir essas etapas, você aprenderá a usar o Lambda para executar uma tarefa de processamento de arquivos em objetos adicionados a um bucket do Amazon S3. Você pode concluir este tutorial usando o AWS Command Line Interface ou a AWS CLI (Console de gerenciamento da AWS).

Caso esteja procurando um exemplo mais simples para aprender como configurar um acionador do Amazon S3 para o Lambda, você pode experimentar o [Tutorial: usar um acionador do Amazon S3 para invocar uma função do Lambda](https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html).

**Topics**
+ [Pré-requisitos](#with-s3-example-prereqs)
+ [Crie dois buckets do Amazon S3](#with-s3-tutorial-prepare-create-buckets)
+ [Faça upload de uma imagem de teste para o bucket de origem](#with-s3-tutorial-test-image)
+ [Criação de uma política de permissões](#with-s3-tutorial-create-policy)
+ [Criar uma função de execução](#with-s3-tutorial-create-execution-role)
+ [Crie o pacote de implantação de função](#with-s3-tutorial-create-function-package)
+ [Criar a função do Lambda](#with-s3-tutorial-create-function-createfunction)
+ [Configure o Amazon S3 para invocar a função](#with-s3-tutorial-configure-s3-trigger)
+ [Testar sua função do Lambda com um evento fictício](#with-s3-tutorial-dummy-test)
+ [Teste a função usando o acionador do Amazon S3](#with-s3-tutorial-test-s3)
+ [Limpe os recursos](#s3-tutorial-cleanup)

## Pré-requisitos
<a name="with-s3-example-prereqs"></a>

Se desejar usar a AWS CLI para concluir o tutorial, instale a [versão mais recente da AWS Command Line Interface]().

Para o código de função do Lambda, você pode usar Python ou Node.js. Instale as ferramentas compatíveis de linguagens e um gerenciador de pacotes para a linguagem que deseja usar. 

### Instalar o AWS Command Line Interface
<a name="install_aws_cli"></a>

Se você ainda não instalou a AWS Command Line Interface, siga as etapas em [Instalar ou atualizar a versão mais recente da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalá-la.

O tutorial requer um terminal de linha de comando ou um shell para executar os comandos. No Linux e no macOS, use o gerenciador de pacotes e de shell de sua preferência.

**nota**  
No Windows, alguns comandos da CLI do Bash que você costuma usar com o Lambda (como `zip`) não são compatíveis com os terminais integrados do sistema operacional. Para obter uma versão do Ubuntu com o Bash integrada no Windows, [instale o Subsistema do Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Crie dois buckets do Amazon S3
<a name="with-s3-tutorial-prepare-create-buckets"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps1.png)


Primeiro, crie dois buckets do Amazon S3. O primeiro bucket corresponde ao bucket de origem para o qual você enviará as imagens. O segundo bucket é usado pelo Lambda para salvar a miniatura redimensionada quando você invoca a função.

------
#### [ Console de gerenciamento da AWS ]

**Criar os buckets do Amazon S3 (console)**

1. Abra o [console do Amazon S3](https://console.aws.amazon.com/s3) e selecione a página **Buckets de uso geral**.

1. Selecione a Região da AWS mais próxima de sua localização geográfica. É possível alterar a região usando a lista suspensa na parte superior da tela. Mais adiante no tutorial, você deverá criar sua função do Lambda na mesma região.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/console_region_select.png)

1. Selecione **Criar bucket**.

1. Em **General configuration** (Configuração geral), faça o seguinte:

   1. Em **Tipo de bucket**, certifique-se de que **Uso geral** esteja selecionado.

   1. Em **Nome do bucket**, insira um nome global exclusivo que atenda às [regras de nomenclatura de buckets](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html) do Amazon S3. Os nomes dos buckets podem conter apenas letras minúsculas, números, pontos (.) e hifens (-).

1. Deixe todas as outras opções com seus valores padrão e escolha **Criar bucket**.

1. Repita as etapas 1 a 5 para criar o bucket de destino. Em **Nome do bucket**, insira `amzn-s3-demo-source-bucket-resized`, em que `amzn-s3-demo-source-bucket` corresponde ao nome do bucket de origem que você acabou de criar.

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

**Criar os buckets do Amazon S3 (AWS CLI)**

1. Execute o comando da CLI apresentado a seguir para criar o bucket de origem. O nome escolhido para o bucket deve ser globalmente exclusivo e seguir as [Regras de nomeação de bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html) para o Amazon S3. Os nomes podem conter somente letras minúsculas, números, pontos (.) e hifens (-). Em `region` e `LocationConstraint`, escolha a [Região da AWS](https://docs.aws.amazon.com/general/latest/gr/lambda-service.html) mais próxima de sua localização geográfica.

   ```
   aws s3api create-bucket --bucket amzn-s3-demo-source-bucket --region us-east-1 \
   --create-bucket-configuration LocationConstraint=us-east-1
   ```

   Posteriormente no tutorial, você deverá criar a função do Lambda na mesma Região da AWS em que o bucket de origem foi criado, portanto, anote a região escolhida.

1. Execute o comando apresentado a seguir para criar o bucket de destino. Para o nome do bucket, você deve usar `amzn-s3-demo-source-bucket-resized`, em que `amzn-s3-demo-source-bucket` é o nome do bucket de origem criado na etapa 1. Em `region` e `LocationConstraint`, escolha a mesma Região da AWS que você usou ao criar o bucket de origem.

   ```
   aws s3api create-bucket --bucket amzn-s3-demo-source-bucket-resized --region us-east-1 \
   --create-bucket-configuration LocationConstraint=us-east-1
   ```

------

## Faça upload de uma imagem de teste para o bucket de origem
<a name="with-s3-tutorial-test-image"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps2.png)


Posteriormente no tutorial, você testará a função do Lambda ao invocá-la usando a AWS CLI ou o console do Lambda. Para confirmar que a função está funcionando corretamente, o bucket de origem precisa conter uma imagem de teste. Essa imagem pode ser qualquer arquivo JPG ou PNG que você escolher.

------
#### [ Console de gerenciamento da AWS ]

**Fazer upload de uma imagem de teste para o bucket de origem (console)**

1. Abra a página [Buckets](https://console.aws.amazon.com/s3/buckets) do console do Amazon S3.

1. Selecione o bucket de origem criado na etapa anterior.

1. Escolha **Carregar**.

1. Escolha **Adicionar arquivos** e use o seletor de arquivos para escolher o objeto que você deseja carregar.

1. Selecione **Abrir** e **Carregar**.

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

**Fazer upload de uma imagem de teste para o bucket de origem (AWS CLI)**
+ No diretório que contém a imagem que você deseja fazer upload, execute o comando da CLI apresentado a seguir. Substitua o parâmetro `--bucket` pelo nome do bucket de origem. Para os parâmetros `--key` e `--body`, use o nome de arquivo da imagem de teste.

  ```
  aws s3api put-object --bucket amzn-s3-demo-source-bucket --key HappyFace.jpg --body ./HappyFace.jpg
  ```

------

## Criação de uma política de permissões
<a name="with-s3-tutorial-create-policy"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps3.png)


A primeira etapa na criação da função do Lambda é criar uma política de permissões. Essa política concede à sua função as permissões necessárias para acessar outros recursos da AWS. Para este tutorial, a política concede ao Lambda permissões de leitura e gravação para buckets do Amazon S3 e permite que ele grave no Amazon CloudWatch Logs.

------
#### [ Console de gerenciamento da AWS ]

**Criar a política (console)**

1. Abra a [página Policies](https://console.aws.amazon.com/iamv2/home#policies) (Políticas) do console do AWS Identity and Access Management (IAM).

1. Escolha **Criar política**.

1. Escolha a guia **JSON** e cole a política personalizada a seguir no 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. Escolha **Próximo**.

1. No campo **Detalhes da política**, em **Nome da política**, insira `LambdaS3Policy`.

1. Escolha **Criar política**.

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

**Criar a política (AWS CLI)**

1. Salve o JSON a seguir em um arquivo denominado `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. No diretório em que você salvou o documento de política JSON, execute o comando da CLI apresentado a seguir.

   ```
   aws iam create-policy --policy-name LambdaS3Policy --policy-document file://policy.json
   ```

------

## Criar uma função de execução
<a name="with-s3-tutorial-create-execution-role"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps4.png)


Um perfil de execução é um perfil do IAM que concede a uma função do Lambda permissão para acessar os recursos e Serviços da AWS. Para conceder à sua função acesso de leitura e gravação a um bucket do Amazon S3, anexe a política de permissões criada na etapa anterior.

------
#### [ Console de gerenciamento da AWS ]

**Criar um perfil de execução e anexar a política de permissões (console)**

1. Abra a página [Perfis](https://console.aws.amazon.com/iamv2/home#roles) no console do IAM.

1. Escolha **Criar Perfil**.

1. Em **Tipo de entidade confiável**, selecione **AWS service (Serviço da AWS)**, e em **Caso de uso**, selecione **Lambda**.

1. Escolha **Próximo**.

1. Adicione a política de permissões criada na etapa anterior fazendo o seguinte:

   1. Na caixa de pesquisa de política, insira `LambdaS3Policy`.

   1. Nos resultados da pesquisa, marque a caixa de seleção `LambdaS3Policy`.

   1. Escolha **Próximo**.

1. Em **Detalhes do perfil**, em **Nome do perfil**, insira `LambdaS3Role`.

1. Selecione **Criar perfil**.

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

**Criar um perfil de execução e anexar a política de permissões (AWS CLI)**

1. Salve o JSON a seguir em um arquivo denominado `trust-policy.json`. Essa política de confiança permite que o Lambda use as permissões do perfil ao conceder à entidade principal de serviço a permissão `lambda.amazonaws.com` para chamar a ação `AssumeRole` do AWS Security Token Service (AWS STS).  
****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Service": "lambda.amazonaws.com"
         },
         "Action": "sts:AssumeRole"
       }
     ]
   }
   ```

1. No diretório em que você salvou o documento de política de confiança JSON, execute o comando da CLI apresentado a seguir para criar o perfil de execução.

   ```
   aws iam create-role --role-name LambdaS3Role --assume-role-policy-document file://trust-policy.json
   ```

1. Para anexar a política de permissões criada na etapa anterior, execute o comando da CLI apresentado a seguir. Substitua o número da Conta da AWS no ARN da política pelo número da sua conta.

   ```
   aws iam attach-role-policy --role-name LambdaS3Role --policy-arn arn:aws:iam::123456789012:policy/LambdaS3Policy
   ```

------

## Crie o pacote de implantação de função
<a name="with-s3-tutorial-create-function-package"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps5.png)


Para criar sua função, crie um *pacote de implantação* contendo o código de função e as dependências. Para essa função `CreateThumbnail`, o código de função usa uma biblioteca separada para o redimensionamento da imagem. Siga as instruções para a linguagem escolhida para criar um pacote de implantação contendo a biblioteca necessária.

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

**Criar o pacote de implantação (Node.js)**

1. Crie um diretório denominado `lambda-s3` para o código de função e as dependências e navegue até ele.

   ```
   mkdir lambda-s3
   cd lambda-s3
   ```

1. Crie um novo projeto Node.js com o `npm`. Para aceitar as opções padrão fornecidas na experiência interativa, pressione `Enter`.

   ```
   npm init
   ```

1. Salve o código de função apresentado a seguir em um arquivo denominado `index.mjs`. Certifique-se de substituir `us-east-1` pela Região da AWS na qual você criou seus próprios buckets de origem e 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. No diretório `lambda-s3`, instale a biblioteca sharp usando npm. Observe que a versão mais recente do sharp (0.33) não é compatível com o Lambda. Instale a versão 0.32.6 para concluir este tutorial.

   ```
   npm install sharp@0.32.6
   ```

   O comando npm `install` cria um diretório `node_modules` para seus módulos. Após esta etapa, sua estrutura de diretórios deve ser semelhante à apresentada a seguir.

   ```
   lambda-s3
   |- index.mjs
   |- node_modules
   |  |- base64js
   |  |- bl
   |  |- buffer
   ...
   |- package-lock.json
   |- package.json
   ```

1. Crie um pacote de implantação .zip contendo o código de função e as dependências. No MacOS e Linux, execute o comando apresentado a seguir.

   ```
   zip -r function.zip .
   ```

   No Windows, use o utilitário zip preferencial para criar um arquivo .zip. Certifique-se de que os arquivos `index.mjs`, `package.json` e `package-lock.json` e o diretório `node_modules` estejam todos na raiz do arquivo .zip.

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

**Criar o pacote de implantação (Python)**

1. Salve o exemplo de código como um arquivo 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. No mesmo diretório em que você criou o arquivo `lambda_function.py`, crie um novo diretório denominado `package` e instale a biblioteca [Pillow (PIL)](https://pypi.org/project/Pillow/) e o AWS SDK para Python (Boto3). Embora o runtime do Python no Lambda inclua uma versão do SDK do Boto3, recomendamos que você adicione todas as dependências da função ao pacote de implantação, mesmo que estejam inclusas no runtime. Para obter mais informações, consulte [Dependências de runtime em 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
   ```

   A biblioteca Pillow contém código C/C\$1\$1. Usando as opções `--platform manylinux_2014_x86_64` e `--only-binary=:all:`, o pip baixará e instalará uma versão do Pillow que contém binários pré-compilados compatíveis com o sistema operacional Amazon Linux 2. Isso garante que o pacote de implantação funcione no ambiente de execução do Lambda, independentemente do sistema operacional e da arquitetura da máquina de compilação local.

1. Crie um arquivo .zip contendo o código da aplicação e as bibliotecas Pillow e Boto3. No Linux ou no MacOS, execute os comandos a seguir na interface da linha de comando.

   ```
   cd package
   zip -r ../lambda_function.zip .
   cd ..
   zip lambda_function.zip lambda_function.py
   ```

    No Windows, use sua ferramenta de zip preferida para criar o arquivo `lambda_function.zip`. Certifique-se de que o arquivo `lambda_function.py` e as pastas que contêm as dependências estejam todos na raiz do arquivo .zip.

Também é possível criar seu pacote de implantação usando um ambiente virtual Python. Consulte [Trabalhar com arquivos .zip para funções do Lambda em Python](python-package.md)

------

## Criar a função do Lambda
<a name="with-s3-tutorial-create-function-createfunction"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps6.png)


Você pode criar a função do Lambda usando a AWS CLI ou o console do Lambda. Siga as instruções da linguagem escolhida para criar a função.

------
#### [ Console de gerenciamento da AWS ]

**Para criar a função (console)**

Para criar a função do Lambda usando o console, primeiro é necessário criar uma função básica contendo algum código “Hello world”. Em seguida, substitua esse código pelo seu código de função ao fazer upload do arquivo.zip ou JAR criado na etapa anterior.

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Verifique se você está trabalhando na mesma Região da AWS em que criou o bucket do Amazon S3. É possível alterar a região usando a lista suspensa na parte superior da tela.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/console_region_select.png)

1. Escolha **Create function** (Criar função).

1. Escolha **Author from scratch** (Criar do zero).

1. Em **Basic information** (Informações básicas), faça o seguinte:

   1. Em **Function name** (Nome da função), insira `CreateThumbnail`.

   1. Em **Runtime**, escolha **Node.js 22.x** ou **Python 3.12** de acordo com a linguagem que você escolheu para a função.

   1. Em **Architecture** (Arquitetura), escolha **x86\$164**.

1. Na guia **Alterar função de execução padrão**, faça o seguinte:

   1. Expanda a guia e escolha **Usar uma função existente**.

   1. Selecione a `LambdaS3Role` que você criou anteriormente.

1. Escolha **Criar função**.

**Fazer upload do código da função (console)**

1. No painel do **Código-fonte**, escolha **Carregar de**.

1. Escolha o **arquivo .zip**. 

1. Escolha **Carregar**.

1. No seletor de arquivos, selecione o arquivo .zip e escolha **Abrir**.

1. Escolha **Salvar**.

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

**Criar a função (AWS CLI)**
+ Execute o comando da CLI para a linguagem escolhida. Para o parâmetro `role`, certifique-se de substituir `123456789012` por seu ID da Conta da AWS. Para o parâmetro `region`, substitua `us-east-1` pela região em que você criou os buckets do Amazon S3.
  + Para **Node.js**, execute o comando a seguir no diretório que contém o arquivo `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**, execute o comando a seguir no diretório que contém o arquivo `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
    ```

------

## Configure o Amazon S3 para invocar a função
<a name="with-s3-tutorial-configure-s3-trigger"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps7.png)


Para que a função do Lambda seja executada quando você faz upload de uma imagem no bucket de origem, é necessário configurar um acionador para a função. Você pode configurar o acionador do Amazon S3 usando o console ou a AWS CLI.

**Importante**  
Este procedimento configura o bucket do Amazon S3 para invocar a função toda vez que um objeto é criado no bucket. Certifique-se de configurar isso somente no bucket de origem. Se a função do Lambda criar objetos no mesmo bucket que a invoca, a função poderá ser [invocada continuamente em um loop](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/recursive-runaway). Isso pode resultar em cobranças inesperadas para sua Conta da AWS.

------
#### [ Console de gerenciamento da AWS ]

**Configurar o acionador do Amazon S3 (console)**

1. Abra a [página de Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda e escolha sua função (`CreateThumbnail`).

1. Escolha **Add trigger**.

1. Selecione **S3**.

1. Em **Bucket**, selecione o bucket de origem.

1. Em **Tipos de eventos**, selecione **Todos os eventos de criação de objetos**.

1. Em **Invocação recursiva**, marque a caixa de seleção para confirmar que não é recomendável usar o mesmo bucket do Amazon S3 para entrada e saída. Saiba mais sobre padrões de invocação recursiva no Lambda lendo [Recursive patterns that cause run-away Lambda functions](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/recursive-runaway) no Serverless Land.

1. Escolha **Adicionar**.

   Quando você cria um acionador usando o console do Lambda, o Lambda cria automaticamente uma [política baseada em recursos](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html) para conceder permissão ao serviço selecionado para invocar a função. 

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

**Configurar o acionador do Amazon S3 (AWS CLI)**

1. Para que o bucket de origem do Amazon S3 invoque a função ao adicionar um arquivo de imagem, primeiro é necessário configurar permissões para a função usando uma [política baseada em recursos](https://docs.aws.amazon.com/lambda/latest/dg/access-control-resource-based.html). Uma instrução de política baseada em recursos concede permissão a outros Serviços da AWS para invocar sua função. Para conceder permissão ao Amazon S3 para invocar a função, execute o comando da CLI apresentado a seguir. Certifique-se de substituir o parâmetro `source-account` por seu ID da Conta da AWS e usar o nome do bucket de origem.

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

   A política que você define com este comando permite que o Amazon S3 invoque a função somente quando uma ação ocorre em seu bucket de origem.
**nota**  
Embora os nomes de bucket do Amazon S3 sejam globalmente exclusivos, ao usar políticas baseadas em recursos, é uma prática recomendada especificar que o bucket deve pertencer à sua conta. Isso ocorre porque, se você excluir um bucket, é possível que outra Conta da AWS crie um bucket com o mesmo nome do recurso da Amazon (ARN).

1. Salve o JSON a seguir em um arquivo denominado `notification.json`. Quando aplicado ao bucket de origem, esse JSON configura o bucket para enviar uma notificação à sua função do Lambda sempre que um novo objeto é adicionado. Substitua o número da Conta da AWS e a Região da AWS no ARN da função do Lambda por seu número de conta e sua região.

   ```
   {
   "LambdaFunctionConfigurations": [
       {
         "Id": "CreateThumbnailEventConfiguration",
         "LambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:CreateThumbnail",
         "Events": [ "s3:ObjectCreated:Put" ]
       }
     ]
   }
   ```

1. Execute o comando da CLI apresentado a seguir para aplicar as configurações de notificação no arquivo JSON criado ao bucket de origem. Substitua `amzn-s3-demo-source-bucket` pelo nome do bucket de origem.

   ```
   aws s3api put-bucket-notification-configuration --bucket amzn-s3-demo-source-bucket \
   --notification-configuration file://notification.json
   ```

   Para saber mais sobre o comando `put-bucket-notification-configuration` e a opção `notification-configuration`, consulte [put-bucket-notification-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-bucket-notification-configuration.html) na *Referência de comandos da CLI da AWS*.

------

## Testar sua função do Lambda com um evento fictício
<a name="with-s3-tutorial-dummy-test"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps8.png)


Antes de testar toda a configuração ao adicionar um arquivo de imagem ao bucket de origem do Amazon S3, teste se a função do Lambda está funcionando corretamente ao invocá-la com um evento fictício. Um evento no Lambda corresponde a um documento formatado em JSON que contém dados para sua função processar. Quando a função é invocada pelo Amazon S3, o evento enviado para a função contém informações como o nome do bucket, o ARN do bucket e a chave do objeto.

------
#### [ Console de gerenciamento da AWS ]

**Testar a função do Lambda com um evento fictício (console)**

1. Abra a [página de Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda e escolha sua função (`CreateThumbnail`).

1. Selecione a guia **Testar**.

1. Para criar o evento de teste, no painel **Evento de teste**, faça o seguinte:

   1. Em **Ação de evento de teste**, selecione **Criar novo evento**.

   1. Em **Nome do evento**, insira **myTestEvent**.

   1. Em **Modelo**, selecione **S3 Put**.

   1. Substitua os valores dos parâmetros apresentados a seguir por seus valores.
      + Em `awsRegion`, substitua `us-east-1` pela Região da AWS em que você criou os buckets do Amazon S3.
      + Em `name`, substitua `amzn-s3-demo-bucket` pelo nome do bucket de origem do Amazon S3.
      + Em `key`, substitua `test%2Fkey` pelo nome do arquivo do objeto de teste que você fez upload no bucket de origem na etapa [Faça upload de uma imagem de teste para o bucket de origem](#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. Escolha **Salvar**.

1. No painel **Evento de teste**, escolha **Testar**.

1. Para verificar se a função criou uma versão redimensionada da imagem e a armazenou em seu bucket de destino do Amazon S3, faça o seguinte:

   1. Abra a [página Buckets](https://console.aws.amazon.com/s3/buckets) do console do Amazon S3.

   1. Escolha o bucket de destino e confirme se o arquivo redimensionado está listado no painel **Objetos**.

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

**Testar a função do Lambda com um evento fictício (AWS CLI)**

1. Salve o JSON a seguir em um arquivo denominado `dummyS3Event.json`. Substitua os valores dos seguintes parâmetros por seus valores:
   + Em `awsRegion`, substitua `us-east-1` pela Região da AWS em que você criou os buckets do Amazon S3.
   + Em `name`, substitua `amzn-s3-demo-bucket` pelo nome do bucket de origem do Amazon S3.
   + Em `key`, substitua `test%2Fkey` pelo nome do arquivo do objeto de teste que você fez upload no bucket de origem na etapa [Faça upload de uma imagem de teste para o bucket de origem](#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. No diretório em que você salvou o arquivo `dummyS3Event.json`, invoque a função ao executar o comando da CLI apresentado a seguir. Esse comando invoca a função do Lambda de forma síncrona ao especificar `RequestResponse` como o valor do parâmetro para o tipo de invocação. Para saber mais sobre invocação assíncrona e síncrona, consulte [Chamada de funções do 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
   ```

   A opção cli-binary-format será necessária se você estiver usando a versão 2 da AWS CLI. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [Opções de linhas de comando globais compatíveis com a AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list).

1. Verifique se a função criou uma versão em miniatura da imagem e a salvou no bucket de destino do Amazon S3. Execute o comando da CLI apresentado a seguir, substituindo `amzn-s3-demo-source-bucket-resized` pelo nome do bucket de destino.

   ```
   aws s3api list-objects-v2 --bucket amzn-s3-demo-source-bucket-resized
   ```

   Você deve ver saída semelhante ao seguinte: O parâmetro `Key` mostra o nome do arquivo de imagem redimensionado.

   ```
   {
       "Contents": [
           {
               "Key": "resized-HappyFace.jpg",
               "LastModified": "2023-06-06T21:40:07+00:00",
               "ETag": "\"d8ca652ffe83ba6b721ffc20d9d7174a\"",
               "Size": 2633,
               "StorageClass": "STANDARD"
           }
       ]
   }
   ```

------

## Teste a função usando o acionador do Amazon S3
<a name="with-s3-tutorial-test-s3"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-s3-tutorial/s3thumb_tut_steps9.png)


Agora que você confirmou que a função do Lambda está funcionando corretamente, você está com tudo pronto para testar a configuração completa ao adicionar um arquivo de imagem ao bucket de origem do Amazon S3. Quando você adiciona a imagem ao bucket de origem, a função do Lambda deve ser invocada automaticamente. A função cria uma versão redimensionada do arquivo e a armazena no bucket de destino.

------
#### [ Console de gerenciamento da AWS ]

**Testar a função do Lambda usando o acionador do Amazon S3 (console)**

1. Para fazer upload de uma imagem para o bucket do Amazon S3, faça o seguinte:

   1. Abra a página [Buckets](https://console.aws.amazon.com/s3/buckets) do console do Amazon S3 e escolha o bucket de origem.

   1. Escolha **Carregar**.

   1. Escolha **Adicionar arquivos** e use o seletor de arquivo para escolher o arquivo de imagem que deseja carregar. O objeto de imagem pode ser qualquer arquivo .jpg ou .png.

   1. Selecione **Abrir** e **Carregar**.

1. Verifique se o Lambda salvou uma versão redimensionada do arquivo de imagem no bucket de destino fazendo o seguinte:

   1. Retorne para a página [Buckets](https://console.aws.amazon.com/s3/buckets) do console do Amazon S3 e escolha o bucket de destino.

   1. No painel **Objetos**, deve ser possível visualizar dois arquivos de imagem redimensionados, sendo um de cada teste da função do Lambda. Para baixar a imagem redimensionada, selecione o arquivo e escolha **Fazer download**.

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

**Testar a função do Lambda usando o acionador do Amazon S3 (AWS CLI)**

1. No diretório que contém a imagem que você deseja fazer upload, execute o comando da CLI apresentado a seguir. Substitua o parâmetro `--bucket` pelo nome do bucket de origem. Para os parâmetros `--key` e `--body`, use o nome de arquivo da imagem de teste. A imagem de teste pode ser qualquer arquivo .jpg ou .png.

   ```
   aws s3api put-object --bucket amzn-s3-demo-source-bucket --key SmileyFace.jpg --body ./SmileyFace.jpg
   ```

1. Verifique se a função criou uma versão em miniatura da imagem e a salvou no bucket de destino do Amazon S3. Execute o comando da CLI apresentado a seguir, substituindo `amzn-s3-demo-source-bucket-resized` pelo nome do bucket de destino.

   ```
   aws s3api list-objects-v2 --bucket amzn-s3-demo-source-bucket-resized
   ```

   Se a função for executada com êxito, você visualizará uma saída semelhante à apresentada a seguir. Agora, o bucket de destino deve conter dois arquivos 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"
           }
       ]
   }
   ```

------

## Limpe os recursos
<a name="s3-tutorial-cleanup"></a>

Agora você pode excluir os recursos criados para este tutorial, a menos que queira mantê-los. Excluindo os recursos da AWS que você não está mais usando, você evita cobranças desnecessárias em sua Conta da AWS.

**Como excluir a função do Lambda**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Selecione a função que você criou.

1. Selecione **Ações**, **Excluir**.

1. Digite **confirm** no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir a política que você criou**

1. Abra a [página Policies](https://console.aws.amazon.com/iam/home#/policies) (Políticas) do console do IAM.

1. Selecione a política que você criou (**AWSLambdaS3Policy**).

1. Escolha **Policy actions** (Ações de política) e **Delete** (Excluir).

1. Escolha **Excluir**.

**Para excluir a função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione a função de execução que você criou.

1. Escolha **Excluir**.

1. Insira o nome do perfil no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir o bucket do S3**

1. Abra o [console Amazon S3](https://console.aws.amazon.com//s3/home#).

1. Selecione o bucket que você criou.

1. Escolha **Excluir**.

1. Insira o nome do bucket no campo de entrada de texto.

1. Escolha **Excluir bucket**.

# Usar segredos do Secrets Manager em funções do Lambda
<a name="with-secrets-manager"></a>

O AWS Secrets Manager ajuda você a gerenciar credenciais, chaves de API e outros segredos de que as funções do Lambda precisam. Existem duas abordagens principais para recuperar segredos em suas funções do Lambda, ambas oferecendo melhor performance e custos mais baixos em comparação com a recuperação direta de segredos usando o AWSSDK:
+ **Parâmetros da AWS e segredos da extensão do Lambda**: uma solução independente de tempo de execução que fornece uma interface HTTP simples para recuperar segredos
+ **Utilitário de parâmetros do Powertools para AWS Lambda**: uma solução integrada de código que oferece suporte a vários provedores (Secrets Manager, Parameter Store, AppConfig) com transformações integradas

Ambas as abordagens mantêm caches locais de segredos, eliminando a necessidade de sua função chamar o Secrets Manager para cada invocação. Quando sua função solicita um segredo, o cache é verificado primeiro. Se o segredo estiver disponível e não tiver expirado, ele será retornado imediatamente. Caso contrário, ele é recuperado do Gerenciador de Segredos, armazenado em cache e retornado. O resultado desse mecanismo de armazenamento em cache são tempos de resposta mais rápidos e custos reduzidos por minimizar as chamadas de API.

## Como escolher uma abordagem
<a name="lambda-secrets-manager-choosing-approach"></a>

Considere estes fatores ao escolher entre a extensão e o PowerTools:

Use a extensão Lambda de parâmetros do AWS e segredos quando:  
+ Você deseja uma solução independente de runtime que funcione com qualquer runtime do Lambda
+ Você prefere não adicionar dependências de código à sua função.
+ Você só precisa recuperar segredos do Secrets Manager ou Parameter Store

Use o Powertools para o utilitário de parâmetros do AWS Lambda quando:  
+ Você quer uma experiência de desenvolvimento integrada com o código do seu aplicativo
+ Você precisa de suporte para vários provedores (Secrets Manager, Parameter Store, AppConfig)
+ Você deseja transformações de dados integradas (análise JSON, decodificação em base64)
+ Você está usando tempos de execução Python, TypeScript, Java ou .NET

## Quando usar o Secrets Manager com o Lambda
<a name="lambda-secrets-manager-when-to-use"></a>

Os cenários comuns para usar o Secrets Manager com o Lambda incluem:
+ Armazenamento de credenciais de banco de dados que a função usa para se conectar ao Amazon RDS ou outros bancos de dados
+ Gerenciamento de chaves de API para os serviços externos que a função chama
+ Armazenamento de chaves de criptografia ou outros dados de configuração confidenciais
+ Rodízio automático de credenciais sem precisar atualizar o código da função

## Usando os parâmetros AWS e segredos da extensão do Lambda
<a name="lambda-secrets-manager-extension-approach"></a>

Os parâmetros e segredos do AWS: a extensão do Lambda usa uma interface HTTP simples compatível com qualquer tempo de execução Lambda. Por padrão, ela armazena os segredos em cache por 300 segundos (5 minutos) e pode armazenar até 1.000 segredos. É possível [personalizar essas configurações com variáveis de ambiente](#lambda-secrets-manager-env-vars).

### Usar o Secrets Manager em uma função do Lambda
<a name="lambda-secrets-manager-setup"></a>

Esta seção pressupõe que você já tenha criado um segredo do Secrets Manager. Para criar um segredo, consulte [Criar um segredo do AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/create_secret.html).

#### Criar o pacote de implantação
<a name="lambda-secrets-manager-function-code"></a>

Escolha seu runtime preferido e siga as etapas para criar uma função que recupere os segredos do Secrets Manager. A função do exemplo recupera um segredo do Secrets Manager e pode ser usada para acessar credenciais de banco de dados, chaves de API ou outros dados de configuração confidenciais em seus aplicativos.

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

**Para criar uma função em Python**

1. Crie e navegue até um novo diretório de projeto. Exemplo:

   ```
   mkdir my_function
   cd my_function
   ```

1. Crie um arquivo denominado `lambda_function.py` com o código a seguir. Para `secret_name`, use o nome ou o nome do recurso da Amazon (ARN) do segredo.

   ```
   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. Crie um arquivo denominado `requirements.txt` com este conteúdo:

   ```
   requests
   ```

1. Instale as dependências:

   ```
   pip install -r requirements.txt -t .
   ```

1. Crie um arquivo .zip contendo todos os arquivos:

   ```
   zip -r function.zip .
   ```

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

**Para criar uma função em Node.js.**

1. Crie e navegue até um novo diretório de projeto. Exemplo:

   ```
   mkdir my_function
   cd my_function
   ```

1. Crie um arquivo denominado `index.mjs` com o código a seguir. Para `secret_name`, use o nome ou o nome do recurso da Amazon (ARN) do segredo.

   ```
   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. Crie um arquivo .zip que contenha o arquivo `index.mjs`:

   ```
   zip -r function.zip index.mjs
   ```

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

**Para criar uma função em Java**

1. Criar um projeto Maven:

   ```
   mvn archetype:generate \
       -DgroupId=example \
       -DartifactId=lambda-secrets-demo \
       -DarchetypeArtifactId=maven-archetype-quickstart \
       -DarchetypeVersion=1.4 \
       -DinteractiveMode=false
   ```

1. Navegue até o diretório de projeto:

   ```
   cd lambda-secrets-demo
   ```

1. Abra o `pom.xml` e substitua o conteúdo pelo seguinte:

   ```
   <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. Renomeie o `/lambda-secrets-demo/src/main/java/example/App.java` como `Hello.java` para corresponder ao nome do manipulador Java padrão do Lambda (`example.Hello::handleRequest`):

   ```
   mv src/main/java/example/App.java src/main/java/example/Hello.java
   ```

1. Abra o arquivo `Hello.java` e substitua o conteúdo pelo que se segue. Para `secretName`, use o nome ou o nome do recurso da Amazon (ARN) do segredo. 

   ```
   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. Remova o diretório de teste. O Maven o cria por padrão, mas não precisamos dele neste exemplo.

   ```
   rm -rf src/test
   ```

1. Criar o projeto:

   ```
   mvn package
   ```

1. Baixe o arquivo JAR (`target/function.jar`) para uso posterior.

------

#### Criar a função
<a name="lambda-secrets-manager-create"></a>

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Selecione **Criar função**.

1. Selecione **Criar do zero**.

1. Em **Function name** (Nome da função), insira **secret-retrieval-demo**.

1. Escolha seu **runtime** preferido.

1. Selecione **Criar função**.

**Para carregar o pacote de implantação**

1. Na guia **Código** da função, escolha **Carregar de** e selecione **arquivo .zip** (para Python e Node.js) ou **arquivo .jar** (para Java).

1. Carregue o pacote de implantação que você criou anteriormente.

1. Escolha **Salvar**.

#### Adicionar a extensão
<a name="lambda-secrets-manager-extension"></a>

**Para adicionar a extensão do Lambda AWS Parameters and Secrets como uma camada**

1. Na guia **Código** da função, role para baixo até **Camadas**.

1. Escolha **Add a layer**.

1. Selecione **Camadas da AWS**.

1. Escolha **AWS-Parameters-and-Secrets-Lambda-Extension**.

1. Selecione a versão mais recente.

1. Escolha **Adicionar**.

#### Adicionar permissões
<a name="lambda-secrets-manager-permissions"></a>

**Para adicionar permissões do Secrets Manager à função de execução**

1. Escolha a guia **Configuration** (Configuração) e, depois, **Permissions** (Permissões).

1. Em **Nome do perfil**, escolha o link para seu perfil de execução. Esse link abre o perfil no console do IAM.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/execution-role-console.png)

1. Escolha **Adicionar permissões** e, em seguida, **Criar política em linha**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/create-inline-policy.png)

1. Escolha a guia **JSON** e adicione a política a seguir. Em `Resource`, insira o ARN do segredo.

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

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "secretsmanager:GetSecretValue",
               "Resource": "arn:aws:secretsmanager:us-east-1:111122223333:secret:SECRET_NAME"
           }
       ]
   }
   ```

------

1. Escolha **Próximo**.

1. Insira um nome para a política.

1. Escolha **Criar política**.

#### Testar a função
<a name="lambda-secrets-manager-test"></a>

**Para testar a função**

1. Volte para o console do Lambda.

1. Selecione a guia **Testar**.

1. Escolha **Testar**. Você deverá ver a resposta a seguir:  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/execution-results-secret.png)

### Variáveis de ambiente
<a name="lambda-secrets-manager-env-vars"></a>

A extensão do Lambda AWS Parameters and Secrets usa as configurações padrão a seguir. É possível substituir essas configurações criando as [variáveis de ambiente](configuration-envvars.md#create-environment-variables) correspondentes. Para visualizar as configurações atuais de uma função, defina `PARAMETERS_SECRETS_EXTENSION_LOG_LEVEL` como `DEBUG`. A extensão registrará as informações de configuração no CloudWatch Logs no início de cada invocação de função.


| Configuração | Valor padrão | Valores válidos | Variável de ambiente | Detalhes | 
| --- | --- | --- | --- | --- | 
| Porta HTTP | 2773 | 1 - 65535 | PARAMETERS\$1SECRETS\$1EXTENSION\$1HTTP\$1PORT | Porta do servidor HTTP local | 
| Cache habilitado | TRUE | TRUE \$1 FALSE | PARAMETERS\$1SECRETS\$1EXTENSION\$1CACHE\$1ENABLED | Habilitar ou desabilitar o cache | 
| Tamanho do cache | 1000 | 0 - 1.000 | PARAMETERS\$1SECRETS\$1EXTENSION\$1CACHE\$1SIZE | Definir como 0 para desabilitar o cache | 
| TTL do Secrets Manager | 300 segundos | 0 - 300 segundos | SECRETS\$1MANAGER\$1TTL | Vida útil dos segredos em cache. Defina como 0 para desabilitar o cache. Essa variável será ignorada se o valor de PARAMETERS\$1S\$1SECRETS\$1S\$1EXTENSION\$1CACHE\$1SIZE for 0. | 
| TTL do Parameter Store | 300 segundos | 0 - 300 segundos | SSM PARAMETER\$1STORE\$1TTL | Vida útil dos parâmetros em cache. Defina como 0 para desabilitar o cache. Essa variável será ignorada se o valor de PARAMETERS\$1S\$1SECRETS\$1S\$1EXTENSION\$1CACHE\$1SIZE for 0. | 
| Nível de log | INFORMAÇÕES | DEPURAR \$1 INFORMAÇÕES \$1 AVISAR \$1 ERRO \$1 NENHUM | PARAMETERS\$1SECRETS\$1EXTENSION\$1LOG\$1LEVEL | O nível de detalhes relatado nos logs para a extensão | 
| Máximo de conexões | 3 | 1 ou mais | PARAMETERS\$1SECRETS\$1EXTENSION\$1MAX\$1CONNECTIONS | Número máximo de conexões HTTP para solicitações ao Parameter Store ou ao Secrets Manager | 
| Tempo limite do Secrets Manager | 0 (sem tempo limite) | Todos os números inteiros | SECRETS\$1MANAGER\$1TIMEOUT\$1MILLIS | Tempo limite para solicitações ao Secrets Manager (em milissegundos) | 
| Tempo limite do Parameter Store | 0 (sem tempo limite) | Todos os números inteiros | SSM\$1PARAMETER\$1STORE\$1TIMEOUT\$1MILLIS | Tempo limite para solicitações ao Parameter Store (em milissegundos) | 

### Trabalhar com rodízio de segredos
<a name="lambda-secrets-manager-rotation"></a>

Se você fizer o rodízio dos segredos com frequência, a duração padrão do cache de 300 segundos poderá fazer com que a função use segredos desatualizados. Você tem duas opções para garantir que a função use o valor secreto mais recente:
+ Reduza o TTL do cache definindo a variável de ambiente `SECRETS_MANAGER_TTL` como um valor menor (em segundos). Por exemplo, configurá-la como `60` garante que a função nunca use um segredo que tenha mais de um minuto.
+ Use os rótulos de preparação `AWSCURRENT` ou `AWSPREVIOUS` na solicitação de segredo para garantir que obterá a versão específica que deseja:

  ```
  secretsmanager/get?secretId=YOUR_SECRET_NAME&versionStage=AWSCURRENT
  ```

Escolha a abordagem que melhor equilibre suas necessidades de performance e brevidade. Um TTL mais baixo significa chamadas mais frequentes para o Secrets Manager, mas garante que você esteja trabalhando com os valores de segredo mais recentes.

## Uso do utilitário de parâmetros do Powertools para AWS Lambda
<a name="lambda-secrets-manager-powertools-approach"></a>

O utilitário de parâmetros do Powertools para AWS Lambda fornece uma interface unificada para recuperar segredos de vários provedores, incluindo Secrets Manager, Parameter Store e AppConfig. Ele lida com o armazenamento em cache, transformações e fornece uma experiência de desenvolvimento mais integrada em comparação com a abordagem de extensão.

### Benefícios do utilitário de parâmetros
<a name="lambda-secrets-manager-powertools-benefits"></a>
+ **Vários provedores**: recupere parâmetros do Secrets Manager, Parameter Store e AppConfig usando a mesma interface
+ **Transformações integradas**: análise automática de JSON, decodificação base64 e outras transformações de dados
+ Cache **integrado - Cache** configurável com suporte a TTL para reduzir as chamadas de API
+ **Segurança de digitação**: forte suporte de digitação em TypeScript e outros tempos de execução suportados
+ **Tratamento de erros**: lógica de repetição e tratamento de erros incorporados

### Exemplos de código
<a name="lambda-secrets-manager-powertools-examples"></a>

Os exemplos a seguir mostram como recuperar segredos usando o utilitário de Parâmetros em diferentes tempos de execução:

**Python**  
Para obter exemplos completos e instruções de configuração, consulte a [documentação do utilitário de Parâmetros](https://docs.powertools.aws.dev/lambda/python/latest/utilities/parameters/).
Recuperar segredos do Secrets Manager com o utilitário de Parâmetros do Powertools para 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 obter exemplos completos e instruções de configuração, consulte a [documentação do utilitário de Parâmetros](https://docs.aws.amazon.com/powertools/typescript/2.1.1/utilities/parameters/).
Recuperar segredos do Secrets Manager com o utilitário de Parâmetros do Powertools para 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 obter exemplos completos e instruções de configuração, consulte a [documentação do utilitário de Parâmetros](https://docs.powertools.aws.dev/lambda/java/latest/utilities/parameters/).
Recuperar segredos do Secrets Manager com o utilitário de Parâmetros do Powertools para 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 obter exemplos completos e instruções de configuração, consulte a [documentação do utilitário de Parâmetros](https://docs.aws.amazon.com/powertools/typescript/latest/features/parameters/).
Recuperar segredos do Secrets Manager com o utilitário de Parâmetros do Powertools para 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
    }
}
```

### Configuração e permissões
<a name="lambda-secrets-manager-powertools-setup"></a>

Para usar o utilitário de Parâmetros, você precisa:

1. Instalar o Powertools para AWS Lambda para seu runtime. Para obter detalhes, consulte [Powertools para AWS Lambda](powertools-for-lambda.md).

1. Para obter exemplos completos e instruções de configuração, consulte a documentação do utilitário de Parâmetros. Para mais detalhes, consulte [Gerenciando permissões no AWS Lambda](lambda-permissions.md).

1. Defina configurações opcionais por meio de [variáveis de ambiente](configuration-envvars.md).

As permissões do IAM obrigatórias são as mesmas que para a abordagem de extensão. O utilitário manipulará automaticamente o armazenamento em cache e as chamadas de API para o Secrets Manager com base na sua configuração.

# Usar o Lambda com o Amazon SQS
<a name="with-sqs"></a>

**nota**  
Se você deseja enviar dados para um destino que não seja uma função do Lambda ou enriquecer os dados antes de enviá-los, consulte [Amazon EventBridge Pipes](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-pipes.html) (Pipes do Amazon EventBridge).

É possível usar uma função do Lambda para processar mensagens em uma fila do Amazon Simple Queue Service (Amazon SQS). O Lambda oferece suporte a [filas padrão](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html) e [filas FIFO (primeiro a entrar, primeiro a sair)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html) para [mapeamentos de origem de eventos](invocation-eventsourcemapping.md). Também é possível usar o modo provisionado para alocar recursos de sondagem dedicados para seus mapeamentos da origem do evento do Amazon SQS. A função do Lambda e a fila do Amazon SQS devem estar na mesma Região da AWS, embora possam estar em [diferentes Contas da AWS](with-sqs-cross-account-example.md).

Ao processar mensagens do Amazon SQS, é necessário implementar uma lógica de resposta parcial em lote para evitar que as mensagens processadas com êxito sejam repetidas quando algumas mensagens em um lote falham. O [utilitário Processador em lote](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) do Powertools para AWS Lambda simplifica essa implementação ao lidar automaticamente com a lógica de resposta parcial em lote, reduzindo o tempo de desenvolvimento e melhorando a confiabilidade.

**Topics**
+ [Entender o comportamento de sondagens e lotes para mapeamentos de origem de eventos do Amazon SQS](#sqs-polling-behavior)
+ [Uso do modo provisionado com mapeamentos da origem do evento do Amazon SQS](#sqs-provisioned-mode)
+ [Configuração do modo provisionado para mapeamentos da origem do evento do Amazon SQS](#sqs-configuring-provisioned-mode)
+ [Exemplo de evento de mensagem de fila padrão](#example-standard-queue-message-event)
+ [Exemplo de evento de mensagem de fila FIFO](#sample-fifo-queues-message-event)
+ [Criar e configurar um mapeamento de origem de evento do Amazon SQS](services-sqs-configure.md)
+ [Configurar o comportamento de escalabilidade para mapeamentos de origem de eventos do SQS](services-sqs-scaling.md)
+ [Tratamento de erros para uma origem de eventos do SQS no Lambda](services-sqs-errorhandling.md)
+ [Parâmetros do Lambda para mapeamentos de origem de eventos do Amazon SQS](services-sqs-parameters.md)
+ [Usar a filtragem de eventos com uma origem de eventos do Amazon SQS](with-sqs-filtering.md)
+ [Tutorial: usar o Lambda com o Amazon SQS](with-sqs-example.md)
+ [Tutorial: Uso de uma fila do Amazon SQS entre contas como a origem de um evento](with-sqs-cross-account-example.md)

## Entender o comportamento de sondagens e lotes para mapeamentos de origem de eventos do Amazon SQS
<a name="sqs-polling-behavior"></a>

[Com os mapeamentos de origem de eventos do Amazon SQS, o Lambda sonda a fila e invoca sua função de forma síncrona](invocation-sync.md) com um evento. Cada evento pode conter um lote de várias mensagens da fila. O Lambda recebe esses eventos um lote por vez e invoca sua função uma vez para cada lote. Quando sua função processa um lote com êxito, o Lambda exclui suas mensagens da fila.

Quando o Lambda recebe um lote, as mensagens permanecem na fila, mas permanecem ocultas durante o [tempo limite de visibilidade](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) da fila. Se a função processar com êxito todas as mensagens no lote, o Lambda excluirá as mensagens da fila. Por padrão, se a sua função encontrar um erro durante o processamento de um lote, todas as mensagens naquele lote se tornarão visíveis na fila novamente após o tempo limite de visibilidade expirar. Por conta disso, o código da função deve ter a capacidade de processar a mesma mensagem várias vezes sem causar efeitos colaterais não intencionais.

**Atenção**  
Os mapeamentos da origem do evento do Lambda processam cada evento ao menos uma vez, podendo haver o processamento duplicado de registros. Para evitar possíveis problemas relacionados a eventos duplicados, é altamente recomendável tornar o código da função idempotente. Para saber mais, consulte [Como tornar minha função do Lambda idempotente](https://repost.aws/knowledge-center/lambda-function-idempotent) no Centro de Conhecimentos da AWS.

Para evitar que o Lambda processe uma mensagem diversas vezes, é possível configurar o mapeamento de origem de eventos para incluir [falhas de itens de lote](services-sqs-errorhandling.md#services-sqs-batchfailurereporting) na resposta da função ou usar a API [DeleteMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessage.html) para remover mensagens da fila à medida que a função do Lambda as processa com êxito.

Para obter informações sobre os parâmetros de configuração aceitos pelo Lambda para mapeamentos de origem de eventos do SQS, consulte [Criar um mapeamento de origem de evento do SQS](services-sqs-configure.md#events-sqs-eventsource).

## Uso do modo provisionado com mapeamentos da origem do evento do Amazon SQS
<a name="sqs-provisioned-mode"></a>

Para workloads em que você precisa ajustar o throughput do mapeamento da origem de eventos, você pode usar o modo provisionado. No modo provisionado, você define limites mínimos e máximos para a quantidade de agentes de sondagem de eventos provisionados. Esses agentes de sondagem de eventos provisionados são dedicados ao mapeamento da origem do evento e podem lidar com picos inesperados de mensagens por meio do ajuste de escala automático responsivo. O mapeamento da origem do evento do Amazon SQS configurado com o modo provisionado é escalado 3 vezes mais rápido (até 1.000 invocações simultâneas por minuto) e suporta uma simultaneidade 16x maior (até 20.000 invocações simultâneas) do que o recurso padrão de mapeamento da origem do evento do Amazon SQS. Recomendamos que você use o modo provisionado para workloads orientadas a eventos do Amazon SQS que tenham requisitos rígidos de performance, como empresas de serviços financeiros que processem feeds de dados de mercado, plataformas de comércio eletrônico que forneçam recomendações personalizadas em tempo real e empresas de jogos que gerenciem interações com jogadores ao vivo. O uso do modo provisionado incorre em custos adicionais. Para obter detalhes sobre preços, consulte [Definição de preços do AWS Lambda](https://aws.amazon.com/lambda/pricing/).

Cada agente de sondagem de eventos no modo provisionado pode tratar até 1 MB/s de throughput, até 10 invocações simultâneas ou até 10 chamadas da API de sondagem do Amazon SQS por segundo. O intervalo de valores aceitos para o número mínimo de agentes de sondagem de eventos (MinimumPollers) é entre 2 e 200, com um padrão de 2. O intervalo de valores aceitos para o número máximo de agentes de sondagem de eventos (MaximumPollers) é entre 2 e 2.000, com um padrão de 200. MaximumPollers deve ser maior ou igual a MinimumPollers.

### Determinação dos agentes de sondagem de eventos necessários
<a name="sqs-determining-event-pollers"></a>

Para estimar o número de agentes de sondagem de eventos necessários para garantir a performance ideal do processamento de mensagens ao usar o modo provisionado para o ESM do SQS, reúna as métricas a seguir para sua aplicação: pico de eventos de SQS por segundo que exijam processamento de baixa latência, tamanho médio da carga útil do evento de SQS, duração média da função do Lambda e tamanho do lote configurado.

Primeiro, é possível estimar o número de eventos de SQS por segundo (EPS) com suporte em um agente de sondagem de eventos para sua workload usando a fórmula a seguir:

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

Em seguida, é possível calcular o número mínimo de sondagens necessárias usando a fórmula abaixo. Esse cálculo garante que você provisione capacidade suficiente para tratar seus requisitos de pico de tráfego.

```
Required event pollers = (Peak number of events per second in Queue) / EPS per event poller
```

Considere uma workload com um tamanho de lote padrão de 10, tamanho médio de evento de 3 KB, duração média da função de 100 ms e um requisito para tratar 1.000 eventos por segundo. Nesse cenário, cada agente de sondagem de eventos oferecerá suporte a aproximadamente 100 eventos por segundo (EPS). Portanto, é necessário definir o mínimo de sondagens como 10 para lidar adequadamente com seus requisitos de pico de tráfego. Se sua workload tiver as mesmas características, mas com duração média de função de 1 segundo, cada agente de sondagem oferecerá suporte apenas a 10 EPS, exigindo que você configure 100 agentes de sondagem no mínimo para tratar 1.000 eventos por segundo em baixa latência.

Recomendamos usar um tamanho de lote padrão de 10 ou mais para maximizar a eficiência dos agentes de sondagem de eventos no modo provisionado. Tamanhos de lote maiores permitem que cada agente de sondagem processe mais eventos por invocação, para melhorar a produtividade e a eficiência de custos. Ao planejar sua capacidade de agentes de sondagem de eventos, considere possíveis picos de tráfego e considere definir o valor de minimumPollers um pouco acima do mínimo calculado para fornecer um buffer. Além disso, monitore as características da workload ao longo do tempo, pois mudanças no tamanho da mensagem, na duração da função ou nos padrões de tráfego podem exigir ajustes na configuração de agentes de sondage de eventos para manter a performance e a eficiência de custos ideais. Para obter um planejamento preciso da capacidade, recomendamos testar sua workload específica para determinar o EPS real que cada agente de sondagem de eventos pode gerar.

## Configuração do modo provisionado para mapeamentos da origem do evento do Amazon SQS
<a name="sqs-configuring-provisioned-mode"></a>

É possível configurar o modo provisionado para o mapeamento da origem do evento do Amazon SQS usando o console ou a API do Lambda.

**Para configurar o modo provisionado para um mapeamento da origem do evento do Amazon MSK existente (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha a função com o mapeamento da origem do evento do Amazon SQS para o qual você deseja configurar o modo provisionado.

1. Escolha **Configuração** e, em seguida, escolha **Acionadores**.

1. Escolha o mapeamento da origem do evento do Amazon SQS para o qual você deseja configurar o modo provisionado e, em seguida, escolha **Editar**.

1. Em **Configuração de mapeamento da origem do evento**, escolha **Configurar modo provisionado**.
   + Para **Agentes de sondagem de eventos mínimos**, insira um valor entre 2 e 200. Se você não especificar um valor, o Lambda vai atribuir o valor padrão de 2.
   + Para **Agentes de sondagem de eventos máximos**, insira um valor entre 2 e 2.000. Esse valor deve ser maior ou igual ao seu valor para **Agentes de sondagem de eventos mínimos**. Se você não especificar um valor, o Lambda vai atribuir o valor padrão de 200.

1. Escolha **Salvar**.

É possível configurar o modo provisionado programaticamente usando o objeto `ProvisionedPollerConfig` na sua `EventSourceMappingConfiguration`. Por exemplo, o comando `UpdateEventSourceMapping` a seguir da CLI configura um valor de `MinimumPollers` como 5 e um valor de `MaximumPollers` como 100.

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

Depois de configurar o modo provisionado, você pode observar o uso de agentes de sondagem de eventos para sua workload monitorando a métrica `ProvisionedPollers`. Para obter mais informações, consulte as métricas do mapeamento da origem do evento.

Para desabilitar o modo provisionado e retornar ao modo padrão (sob demanda), é possível usar o comando `UpdateEventSourceMapping` a seguir da CLI:

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

**nota**  
O modo provisionado não pode ser usado com a configuração de simultaneidade máxima. Ao usar o modo provisionado, você controla a simultaneidade máxima por meio do número máximo de agentes de sondagem de eventos.

Para obter mais informações sobre como configurar o modo provisionado, consulte [Criar e configurar um mapeamento de origem de evento do Amazon SQS](services-sqs-configure.md).

## Exemplo de evento de mensagem de fila padrão
<a name="example-standard-queue-message-event"></a>

**Example Evento de mensagem do Amazon SQS (fila padrão)**  

```
{
    "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"
        }
    ]
}
```

Por padrão, o Lambda pesquisará até 10 mensagens em sua fila de uma só vez e envia esse lote para sua função. Para evitar a invocação da função com poucos registros, você pode configurar a origem de eventos para armazenar os registros em buffer por até cinco minutos, configurando uma janela de lote. Antes de invocar a função, o Lambda continuará a sondar as mensagens da fila padrão até a janela de lote expirar, a [cota de tamanho da carga útil de invocação](gettingstarted-limits.md) ser atingida ou o tamanho de lote máximo configurado ser atingido.

Se você estiver usando uma janela em lote e sua fila do SQS contiver um volume de tráfego muito baixo, o Lambda poderá esperar até 20 segundos antes de invocar sua função. Isso será válido mesmo se você definir uma janela de lote inferior a 20 segundos. 

**nota**  
Em Java, talvez você observe erros de ponteiro nulo ao desserializar o JSON. Isso pode ser causado por como a caixa de “Records” e “EventSourceArn” é convertida pelo mapeador de objetos JSON.

## Exemplo de evento de mensagem de fila FIFO
<a name="sample-fifo-queues-message-event"></a>

Para as filas FIFO, os registros contêm atributos adicionais relacionados a desduplicação e sequenciamento.

**Example Evento de mensagem do Amazon SQS (fila 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"
        }
    ]
}
```

# Criar e configurar um mapeamento de origem de evento do Amazon SQS
<a name="services-sqs-configure"></a>

Para processar mensagens do Amazon SQS com o Lambda, configure sua fila com as configurações apropriadas e, em seguida, crie um mapeamento de origem de evento do Lambda.

**Topics**
+ [Configurar uma fila para usar com o Lambda](#events-sqs-queueconfig)
+ [Configurar permissões do perfil de execução do Lambda](#events-sqs-permissions)
+ [Criar um mapeamento de origem de evento do SQS](#events-sqs-eventsource)

## Configurar uma fila para usar com o Lambda
<a name="events-sqs-queueconfig"></a>

Se você ainda não tiver uma fila do Amazon SQS, [crie uma](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-configure-create-queue.html) para servir como uma origem de eventos para a sua função do Lambda. A função do Lambda e a fila do Amazon SQS devem estar na mesma Região da AWS, embora possam estar em [diferentes Contas da AWS](with-sqs-cross-account-example.md).

Para permitir que a função tenha tempo para processar cada lote de registros, defina o [tempo limite de visibilidade](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) da fila de origem para, no mínimo, seis vezes o [tempo limite da configuração](configuration-timeout.md) na sua função. Esse tempo extra permite que o Lambda repita o processo se a execução da sua função for limitada durante o processamento de um lote anterior.

**nota**  
O tempo limite da sua função deve ser menor ou igual ao tempo limite de visibilidade da fila. O Lambda valida esse requisito quando você cria ou atualiza um mapeamento da origem do evento e retornará um erro se o tempo limite da função exceder o tempo limite de visibilidade da fila.

Por padrão, se o Lambda se deparar com um erro em algum momento durante o processamento de um lote, todas as mensagens naquele lote retornarão para a fila. Após o [tempo limite de visibilidade](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html), as mensagens se tornam visíveis para o Lambda novamente. É possível configurar o mapeamento de origem de evento para usar [respostas parciais em lote](services-sqs-errorhandling.md#services-sqs-batchfailurereporting) para recolocar na fila somente as mensagens com falha. Além disso, se a sua função não conseguir processar uma mensagem várias vezes, o Amazon SQS poderá enviá-la para uma [fila de mensagens não entregues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html). Recomendamos definir a `maxReceiveCount` na [política de redirecionamento](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html#policies-for-dead-letter-queues) da fila de origem para pelo menos 5. Isso dá ao Lambda algumas chances de tentar novamente antes de enviar mensagens com falha diretamente para a fila de mensagens não entregues.

## Configurar permissões do perfil de execução do Lambda
<a name="events-sqs-permissions"></a>

A política gerenciada pela AWS [AWSLambdaSQSQueueExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaSQSQueueExecutionRole.html) inclui as permissões necessárias para o Lambda ler da sua fila do Amazon SQS. É possível [adicionar essa política gerenciada](lambda-intro-execution-role.md) ao perfil de execução da função.

Opcionalmente, se você estiver usando uma fila criptografada, também precisará adicionar a seguinte permissão à sua função de execução:
+ [kms:Decrypt](https://docs.aws.amazon.com/kms/latest/APIReference/API_Decrypt.html)

## Criar um mapeamento de origem de evento do SQS
<a name="events-sqs-eventsource"></a>

Crie um mapeamento de fontes de eventos para orientar o Lambda a enviar itens da sua fila para uma função do Lambda. É possível criar vários mapeamentos da fonte do evento para processar itens de várias filas com uma única função. Quando o Lambda invoca a função de destino, o evento pode conter vários itens, até um *tamanho de lote* máximo configurável.

Para configurar sua função para ler do Amazon SQS, associe a política gerenciada pela AWS [AWSLambdaSQSQueueExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaSQSQueueExecutionRole.html) ao seu perfil de execução. Em seguida, crie um mapeamento de origem de evento do **SQS** via console usando as etapas a seguir.

**Para adicionar permissões e criar um acionador**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha o nome de uma função.

1. Escolha a guia **Configuration** (Configuração) e, depois, **Permissions** (Permissões).

1. Em **Nome do perfil**, escolha o link para seu perfil de execução. Esse link abre o perfil no console do IAM.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/execution-role.png)

1. Escolha **Adicionar permissões** e depois **Anexar políticas**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/attach-policies.png)

1. No campo de pesquisa, digite `AWSLambdaSQSQueueExecutionRole`. Adicione esta política ao seu perfil de execução Essa é uma política gerenciada pela AWS que contém as permissões que sua função precisa para ler de uma fila do Amazon SQS. Para obter mais informações sobre essa política, consulte [AWSLambdaSQSQueueExecutionRole](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSLambdaSQSQueueExecutionRole.html) na *Referência de políticas gerenciadas pela AWS*.

1. Volte para a sua função no console do Lambda Em **Visão geral da função**, escolha **Adicionar gatilho**.  
![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/add-trigger.png)

1. Escolha um tipo de acionador.

1. Configure as opções necessárias e escolha **Add** (Adicionar).

O Lambda oferece suporte às seguintes opções de configuração para origens de eventos do Amazon SQS:

**Fila do SQS**  
A fila do Amazon SQS de onde os registros serão lidos. A função do Lambda e a fila do Amazon SQS devem estar na mesma Região da AWS, embora possam estar em [diferentes Contas da AWS](with-sqs-cross-account-example.md).

**Habilitar acionador**  
O status do mapeamento da origem do evento. **Enable trigger** (Habilitar acionador) está selecionado por padrão.

**Tamanho do lote**  
O número máximo de registros a serem enviados para a função em cada lote. Em uma fila padrão, isso pode ser até 10.000 registros. Em uma fila FIFO, o máximo é 10. Para um tamanho de lote acima de dez, você também deve definir a janela do lote (`MaximumBatchingWindowInSeconds`) para, no mínimo, um segundo.  
Configure o [tempo limite da função](https://serverlessland.com/content/service/lambda/guides/aws-lambda-operator-guide/configurations#timeouts) para permitir tempo suficiente para o processamento de um lote inteiro de itens. Se os itens levarem muito tempo para serem processados, escolha um tamanho de lote menor. Um tamanho de lote grande pode melhorar a eficiência das workloads muito rápidas ou com muita sobrecarga. Se você configurar a [simultaneidade reservada](configuration-concurrency.md) na sua função, defina pelo menos cinco execuções simultâneas para reduzir as chances de erros de controle de utilização quando o Lambda invocar a sua função.  
O Lambda transmite todos os registros do lote para a função em uma única chamada, desde que o tamanho total dos eventos não exceda a [cota de tamanho da carga útil de invocação](gettingstarted-limits.md) para invocação síncrona (6 MB). O Lambda e o Amazon SQS geram metadados para cada registro. Esses metadados adicionais contam para o tamanho total da carga útil e podem fazer com que o total de registros enviados em um lote seja menor que o tamanho do lote configurado. Os campos de metadados enviados pelo Amazon SQS podem variar em termos de comprimento. Para saber mais sobre os campos de metadados do Amazon SQS, consulte a documentação da operação de API [ReceiveMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html) na *Referência de APIs do Amazon Simple Queue Service*.

**Janela do lote**  
O máximo de tempo para reunir registros antes de invocar a função, em segundos. Aplicável somente a filas padrão.  
Se você estiver usando uma janela de lote maior que zero segundos, deverá considerar o aumento do tempo de processamento no [tempo limite de visibilidade](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html) da fila. Recomendamos definir o tempo limite de visibilidade da fila para seis vezes o [tempo limite da função](configuration-timeout.md), acrescido do valor de `MaximumBatchingWindowInSeconds`. Isso permite que sua função do Lambda tenha tempo para processar cada lote de eventos e tentar novamente em caso de erro de controle de utilização.  
Quando as mensagens ficam disponíveis, o Lambda começa a processar as mensagens em lotes. O Lambda começa a processar cinco lotes por vez com cinco invocações simultâneas de sua função. Se ainda houver mensagens disponíveis, o Lambda adicionará até 300 invocações simultâneas da sua função por minuto, até alcançar um máximo de 1.250 invocações simultâneas. Ao usar o modo provisionado, cada agente de sondagem de eventos pode tratar até 1 MB/s de throughput, até 10 invocações simultâneas ou até 10 chamadas da API de sondagem do Amazon SQS por segundo. O Lambda escala o número de agentes de sondagem de eventos entre o mínimo e o máximo configurados, adicionando rapidamente até 1.000 invocações simultâneas por minuto para fornecer processamento de baixa latência de seus eventos do Amazon SQS. Você controla a escalabilidade e a simultaneidade por meio dessas configurações mínimas e máximas do agente de sondagem de eventos. Para saber mais sobre a escalabilidade e simultaneidade de funções, consulte [Como entender a escalabilidade da função do Lambda](lambda-concurrency.md).  
Para processar mais mensagens, você pode otimizar sua função do Lambda para aumentar o throughput. Para obter mais informações, consulte [Entender como o AWS Lambda escala com as filas padrão do 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.).

**Critérios de filtro**  
Adicione critérios de filtro para controlar quais eventos o Lambda enviará à função para processamento. Para obter mais informações, consulte [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md).

**Simultaneidade máxima**  
O número máximo de funções simultâneas que a origem do evento pode invocar. Não pode ser usado com o modo provisionado habilitado. Para obter mais informações, consulte [Configuração de simultaneidade máxima para origens de eventos do Amazon SQS](services-sqs-scaling.md#events-sqs-max-concurrency).

**Modo provisionado**  
Quando habilitado, aloca recursos de sondagem dedicados para o mapeamento da origem do evento. É possível configurar o número mínimo (2-200) e máximo (2-2000) de agentes de sondagem de eventos. Cada agente de sondagem de eventos pode tratar até 1 MB/s de throughput, até 10 invocações simultâneas ou até 10 chamadas da API de sondagem do Amazon SQS por segundo.  
Observação: não é possível usar o modo provisionado e a simultaneidade máxima juntos. Quando o modo provisionado estiver habilitado, use a configuração máxima de agentes de sondagem para controlar a simultaneidade.

# Configurar o comportamento de escalabilidade para mapeamentos de origem de eventos do SQS
<a name="services-sqs-scaling"></a>

É possível controlar o comportamento de escalabilidade de seus mapeamentos da origem do evento do Amazon SQS por meio de configurações máximas de simultaneidade ou habilitando o modo provisionado. Estas são as opções mutuamente exclusivas.

Por padrão, o Lambda escala automaticamente os agentes de sondagem de eventos com base no volume de mensagens. Ao habilitar o modo provisionado, você aloca um número mínimo e máximo de recursos de sondagem dedicados que permanecem prontos para lidar com os padrões de tráfego esperados. Isso permite que você otimize a performance do mapeamento da origem do evento de duas maneiras:
+ Modo padrão (padrão): o Lambda gerencia automaticamente a escalabilidade, começando com um pequeno número de agentes de sondagem e aumentando ou diminuindo a escala com base na workload.
+ Modo provisionado: você configura recursos de sondagem dedicados com limites mínimos e máximos, permitindo um escalonamento 3 vezes mais rápido e uma capacidade de processamento até 16 vezes maior.

Para filas padrão, o Lambda usa [sondagem longa](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html#sqs-long-polling) para sondar uma fila até que ela se torne ativa. Quando as mensagens estão disponíveis, o Lambda começa a processar cinco lotes por vez com cinco invocações simultâneas da sua função. Se ainda houver mensagens disponíveis, o Lambda aumentará o número de processos de leitura de lotes em até 300 invocações simultâneas a mais por minuto. O número máximo de invocações que podem ser processadas simultaneamente por um mapeamento da origem do evento é 1.250. Quando não há muito tráfego, o Lambda reduz o processamento para cinco invocações simultâneas e pode otimizar para apenas duas invocações simultâneas para reduzir as chamadas do Amazon SQS e os custos correspondentes. Porém, essa otimização não está disponível quando você ativa a configuração máxima de simultaneidade.

Para filas FIFO, o Lambda envia mensagens para a função na ordem em que as recebe. Ao enviar uma mensagem para uma fila do FIFO, você especifica um[ID do grupo de mensagens](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html). O Amazon SQS garante que as mensagens no mesmo grupo sejam entregues ao Lambda em ordem. Quando o Lambda lê suas mensagens em lotes, cada lote poderá conter mensagens de mais de um grupo de mensagens, mas a ordem das mensagens será mantida. Se a função retornar um erro, ela fará todas as tentativas possíveis nas mensagens afetadas antes que o Lambda receba mensagens adicionais do mesmo grupo.

Ao usar o modo provisionado, cada agente de sondagem de eventos pode tratar até 1 MB/s de throughput, até 10 invocações simultâneas ou até 10 chamadas de API de sondagem do Amazon SQS por segundo. O Lambda escala o número de agentes de sondagem de eventos entre o mínimo e o máximo configurados, adicionando rapidamente até 1.000 simultaneidades por minuto para fornecer processamento consistente de baixa latência de seus eventos do Amazon SQS. O uso do modo provisionado incorre em custos adicionais. Para obter detalhes sobre preços, consulte [Definição de preços do AWS Lambda](https://aws.amazon.com/lambda/pricing/). Cada agente de sondagem de eventos usa uma [sondagem longa](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html) em sua fila do SQS com até 10 sondagens por segundo, o que incorre no custo das solicitações da API do SQS. Para obter mais detalhes, consulte [Definição de preços do Amazon SQS](https://aws.amazon.com/sqs/pricing/ ). Você controla a escalabilidade e a simultaneidade por meio dessas configurações mínimas e máximas do agente de sondagem de eventos, em vez de usar a configuração máxima de simultaneidade, pois essas opções não podem ser usadas juntas.

**nota**  
Não é possível usar a configuração máxima de simultaneidade e o modo provisionado ao mesmo tempo. Quando o modo provisionado está habilitado, você controla a escalabilidade e a simultaneidade do mapeamento da origem do evento do Amazon SQS por meio do número mínimo e máximo de agentes de sondagem de eventos.

## Configuração de simultaneidade máxima para origens de eventos do Amazon SQS
<a name="events-sqs-max-concurrency"></a>

É possível usar a configuração de simultaneidade máxima para controlar o comportamento de escalabilidade de suas fontes de eventos do SQS. Observe que a simultaneidade máxima não pode ser usada com o modo provisionado habilitado. A configuração de simultaneidade máxima limita o número de instâncias simultâneas da função que uma origem de evento do Amazon SQS pode invocar. A simultaneidade máxima é uma configuração em nível de origem do evento. Se você tiver diversas origens de eventos do Amazon SQS mapeadas para uma função, cada origem de evento poderá ter uma configuração de simultaneidade máxima separada. É possível usar a simultaneidade máxima para evitar que uma fila use toda a [simultaneidade reservada](configuration-concurrency.md) da função ou todo o restante da [cota de simultaneidade da conta](gettingstarted-limits.md). Não há custos para configurar a simultaneidade máxima em uma origem de evento do Amazon SQS.

Importante, a simultaneidade máxima e a simultaneidade reservada são duas configurações independentes. Não defina a simultaneidade máxima maior que a simultaneidade reservada da função. Se você configurar a simultaneidade máxima, certifique-se de que a simultaneidade reservada da função seja maior ou igual à simultaneidade máxima total para todas as origens de eventos do Amazon SQS na função. Caso contrário, o Lambda pode aplicar um controle de utilização para as suas mensagens.

Quando a cota de simultaneidade da sua conta é definida com o valor padrão de 1.000, um mapeamento de origem de eventos do Amazon SQS pode ser escalado para invocar instâncias de função até esse valor, a menos que você especifique uma simultaneidade máxima.

Se você receber um aumento na cota de simultaneidade padrão da sua conta, o Lambda talvez não consiga invocar instâncias de funções simultâneas até sua nova cota. Por padrão, o Lambda pode escalar para invocar até 1.250 instâncias de funções simultâneas para um mapeamento de origem de eventos do Amazon SQS. Se isso não for suficiente para seu caso de uso, entre em contato com o suporte da AWS para discutir um aumento na simultaneidade de mapeamento de origem de eventos do Amazon SQS da sua conta.

**nota**  
Para filas FIFO, as invocações simultâneas são limitadas pelo número de [IDs de grupos de mensagens](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html) (`messageGroupId`) ou pela configuração máxima de simultaneidade, o que for menor. Por exemplo, se você tiver seis IDs de grupo de mensagens e a simultaneidade máxima estiver definida como dez, sua função poderá ter no máximo seis invocações simultâneas.

É possível configurar a simultaneidade máxima em mapeamentos da origem do evento novos e existentes do Amazon SQS.

**Configuração da simultaneidade máxima usando o console do Lambda**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha o nome de uma função.

1. Em **Function overview** (Visão geral da função), escolha **SQS**. Isso abre a guia **Configuration** (Configuração).

1. Selecione o acionador do Amazon SQS e escolha **Edit** (Editar).

1. Em **Maximum concurrency** (Simultaneidade máxima), insira um número entre dois e mil. Para desativar a simultaneidade máxima, deixe a caixa em branco.

1. Escolha **Salvar**.

**Configuração da simultaneidade máxima usando a AWS Command Line Interface (AWS CLI)**  
Use o comando [update-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-event-source-mapping.html) com a opção `--scaling-config`. Exemplo:

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --scaling-config '{"MaximumConcurrency":5}'
```

Para desativar a simultaneidade máxima, insira um valor vazio para `--scaling-config`:

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --scaling-config "{}"
```

**Configuração da simultaneidade máxima usando a API do Lambda**  
Use a ação [CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html) ou [UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html) com um objeto [ScalingConfig](https://docs.aws.amazon.com/lambda/latest/api/API_ScalingConfig.html).

# Tratamento de erros para uma origem de eventos do SQS no Lambda
<a name="services-sqs-errorhandling"></a>

Para lidar com erros relacionados a uma fonte de eventos do SQS, o Lambda usa automaticamente uma estratégia de repetição com uma estratégia de recuo. Você também pode personalizar o comportamento de tratamento de erros configurando o mapeamento de origem de eventos do SQS para retornar [respostas parciais em lote](#services-sqs-batchfailurereporting).

## Estratégia de recuo para invocações com falha
<a name="services-sqs-backoff-strategy"></a>

Quando uma invocação falha, o Lambda tenta repetir a invocação enquanto implementa uma estratégia de recuo. A estratégia de recuo difere ligeiramente caso o Lambda tenha encontrado a falha devido a um erro no código da função ou devido ao controle de utilização.
+  Se o **código da função** causou o erro, o Lambda interromperá o processamento e repetirá a invocação. Enquanto isso, o Lambda recua gradualmente, reduzindo a quantidade de simultaneidade alocada ao mapeamento da origem do evento do Amazon SQS. Depois que limite de tempo de visibilidade da sua fila se esgotar, a mensagem será mostrada novamente na fila. 
+ Se a invocação apresentar falhas devido ao **controle de utilização**, o Lambda recua gradualmente as novas tentativas, reduzindo a quantidade de simultaneidade alocada para o mapeamento da origem do evento do Amazon SQS. O Lambda continuará a repetir a mensagem até que o carimbo de data/hora da mensagem exceda o tempo limite de visibilidade da fila, que corresponde ao momento em que o Lambda descartará a mensagem.

## Implementar respostas parciais em lote
<a name="services-sqs-batchfailurereporting"></a>

Quando sua função do Lambda encontra um erro ao processar um lote, todas as mensagens nesse lote tornam-se novamente visíveis na fila por padrão, incluindo mensagens que o Lambda processou com sucesso. Como resultado, a função pode acabar processando a mesma mensagem diversas vezes.

Para não precisar reprocessar todas as mensagens processadas com êxito em um lote com falha, você pode configurar o mapeamento da origem do evento para tornar visíveis novamente apenas as mensagens com falha. Isso se chama resposta parcial em lote. Para ativar respostas parciais em lote, especifique `ReportBatchItemFailures` para a ação [FunctionResponseTypes](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html#lambda-UpdateEventSourceMapping-request-FunctionResponseTypes) ao configurar o mapeamento da origem do evento. Isso permite que a função retorne um sucesso parcial, podendo ajudar a reduzir o número de novas tentativas desnecessárias nos registros.

**nota**  
O [utilitário de processador em lote](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/) do Powertools para AWS Lambda lida com toda a lógica de respostas parciais em lote de maneira automática. Ele simplifica a implementação de padrões de processamento em lote, além de reduzir o código personalizado necessário para lidar corretamente com falhas de itens em lote. Esse utilitário está disponível para Python, Java, Typescript e .NET.

Quando `ReportBatchItemFailures` estiver ativado, o Lambda não [reduzirá a escala verticalmente da sondagem de mensagens](#services-sqs-backoff-strategy) quando as invocações de funções falharem. Se você espera que algumas mensagens falhem, e não quer que essas falhas afetem a taxa de processamento de mensagens, use `ReportBatchItemFailures`.

**nota**  
Ao usar respostas parciais em lote, tenha em mente:  
Se a sua função lançar uma exceção, o lote inteiro será considerado uma falha total.
Se você estiver usando esse recurso com uma fila FIFO, a função deverá interromper o processamento de mensagens após a primeira falha e retornar todas as mensagens com falha e não processadas no `batchItemFailures`. Isso ajuda a preservar a ordem das mensagens na sua fila.

**Para ativar o relatório parcial em lote**

1. Leia as [práticas recomendadas para implementar respostas parciais em lote](https://docs.aws.amazon.com/prescriptive-guidance/latest/lambda-event-filtering-partial-batch-responses-for-sqs/best-practices-partial-batch-responses.html).

1. Execute o comando a seguir para ativar `ReportBatchItemFailures` para a função. Para recuperar o UUID do mapeamento da origem do evento, execute o comando [list-event-source-mappings](https://docs.aws.amazon.com/cli/latest/reference/lambda/list-event-source-mappings.html) da AWS CLI.

   ```
   aws lambda update-event-source-mapping \
   --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
   --function-response-types "ReportBatchItemFailures"
   ```

1. Atualize o código da função para capturar todas as exceções e retornar mensagens com falha em uma resposta `batchItemFailures` do JSON. A resposta `batchItemFailures` deve incluir uma lista de IDs de mensagens, como valores `itemIdentifier` do JSON.

   Por exemplo, suponha que você tenha um lote de cinco mensagens, com os IDs de mensagem `id1`, `id2`, `id3`, `id4` e `id5`. Sua função processa `id1`,`id3` e `id5` com sucesso. Para tornar as mensagens `id2` e `id4` novamente visíveis na fila, a função deve retornar a seguinte resposta: 

   ```
   { 
     "batchItemFailures": [ 
           {
               "itemIdentifier": "id2"
           },
           {
               "itemIdentifier": "id4"
           }
       ]
   }
   ```

   Veja alguns exemplos de código de função que retornam a lista de IDs de mensagens com falha no lote:

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Relatar falhas de itens em lote do SQS com o Lambda usando o .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Relatar falhas de itens em lote do SQS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Relatar falhas de itens em lote do SQS com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Relatar falhas de itens em lote do SQS com o Lambda usando 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}`);
   }
   ```
Relatar falhas de item em lote do SQS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Relatar falhas de itens em lote do SQS com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Relatar falhas de itens em lote do SQS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda-with-batch-item-handling). 
Relatar falhas de itens em lote do SQS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/lambda-function-sqs-report-batch-item-failures). 
Relatar falhas de itens em lote do SQS com o Lambda usando 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
   }
   ```

------

Se os eventos com falha não retornarem à fila, consulte [Como soluciono problemas da função do Lambda do SQS ReportBatchItemFailures?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-sqs-report-batch-item-failures/) no Centro de Conhecimento da AWS.

### Condições de sucesso e falha
<a name="sqs-batchfailurereporting-conditions"></a>

O Lambda considera um lote um sucesso total quando a função retorna qualquer um dos seguintes:
+ Uma lista de `batchItemFailures` vazia
+ Uma lista de `batchItemFailures` nula
+ Uma vazia `EventResponse`
+ Uma nula `EventResponse`

O Lambda considera um lote uma falha total quando a função retorna qualquer um dos seguintes:
+ Uma resposta JSON inválida
+ Uma string vazia `itemIdentifier`
+ Uma nula `itemIdentifier`
+ Um `itemIdentifier` com um nome de chave inválido
+ Um valor `itemIdentifier` com um ID de mensagem inexistente

### Métricas do CloudWatch
<a name="sqs-batchfailurereporting-metrics"></a>

Para determinar se a função está reportando falhas de itens em lote corretamente, é possível monitorar as métricas do Amazon SQS `NumberOfMessagesDeleted` e `ApproximateAgeOfOldestMessage` no Amazon CloudWatch.
+ `NumberOfMessagesDeleted` rastreia o número de mensagens removidas da sua fila. Se o número cair para 0, é um sinal de que a resposta da função não está retornando corretamente mensagens com falha.
+ `ApproximateAgeOfOldestMessage` rastreia quanto tempo a mensagem mais antiga permaneceu na sua fila. Um aumento acentuado nessa métrica pode indicar que a função não está retornando mensagens com falha corretamente.

### Usar o Powertools para o processador em lote AWS Lambda
<a name="services-sqs-batchfailurereporting-powertools"></a>

O utilitário de processador em lote do Powertools para AWS Lambda lida de maneira automática com a lógica de respostas parciais em lote, reduzindo a complexidade da implementação de relatórios de falhas em lote. Veja a seguir alguns exemplos usando o processador em lote:

**Python**  
Para ver exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.powertools.aws.dev/lambda/python/latest/utilities/batch/).
Processamento de mensagens do Amazon SQS com o processador em lote 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 exemplos completos e instruções de configuração, consulte a [documentação do processador em lote](https://docs.aws.amazon.com/powertools/typescript/latest/features/batch/).
Processamento de mensagens do Amazon SQS com o processador em lote 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 do Lambda para mapeamentos de origem de eventos do Amazon SQS
<a name="services-sqs-parameters"></a>

Todos os tipos de origem de evento Lambda compartilham o mesmo[CreateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_CreateEventSourceMapping.html)e[UpdateEventSourceMapping](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateEventSourceMapping.html)Operações de API do. No entanto, apenas alguns dos parâmetros se aplicam ao Amazon SQS.


| Parâmetro | Obrigatório | Padrão | Observações | 
| --- | --- | --- | --- | 
|  BatchSize  |  N  |  10  |  Para filas padrão, o máximo é 10 mil. Para filas FIFO, o máximo é dez.  | 
|  Habilitado  |  N  |  true  | nenhuma  | 
|  EventSourceArn  |  S  | N/D |  O ARN do fluxo de dados ou um consumidor de fluxo  | 
|  FunctionName  |  S  | N/D  | nenhuma  | 
|  FilterCriteria  |  N  |  N/D   |  [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md)  | 
|  FunctionResponseTypes  |  N  | N/D  |  Para permitir que sua função reporte falhas específicas em um lote, inclua o valor `ReportBatchItemFailures` em `FunctionResponseTypes`. Para obter mais informações, consulte [Implementar respostas parciais em lote](services-sqs-errorhandling.md#services-sqs-batchfailurereporting).  | 
|  MaximumBatchingWindowInSeconds  |  N  |  0  | A janela de lote não é compatível com filas FIFO | 
|  ProvisionedPollerConfig  |  N  |  N/D  |  Configura o número mínimo (2-200) e máximo (2-2000) de agentes de sondagem de eventos dedicados para o mapeamento da origem do evento do SQS. Cada agente de sondagem pode tratar até 1 MB/s de throughput e 10 invocações simultâneas.  | 
|  ScalingConfig  |  N  |  N/D   |  [Configuração de simultaneidade máxima para origens de eventos do Amazon SQS](services-sqs-scaling.md#events-sqs-max-concurrency)  | 

# Usar a filtragem de eventos com uma origem de eventos do Amazon SQS
<a name="with-sqs-filtering"></a>

É possível usar filtragem de eventos para controlar quais registros de um stream ou fila que o Lambda enviará para a função. Para obter informações gerais sobre como a filtragem de eventos funciona, consulte [Controlar quais eventos o Lambda envia para a função](invocation-eventfiltering.md).

Esta seção tem como foco a filtragem de eventos para fontes de eventos do Amazon SMQ.

**nota**  
Os mapeamentos das origens dos eventos do Amazon SQS é compatível apenas com filtragem na chave `body`.

**Topics**
+ [Conceitos básicos de filtragem de eventos do Amazon SQS](#filtering-SQS)

## Conceitos básicos de filtragem de eventos do Amazon SQS
<a name="filtering-SQS"></a>

Suponha que sua fila do Amazon SQS contenha mensagens no formato JSON a seguir.

```
{
    "RecordNumber": 1234,
    "TimeStamp": "yyyy-mm-ddThh:mm:ss",
    "RequestCode": "AAAA"
}
```

Um exemplo de registro para essa fila seria como a seguir.

```
{
    "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 com base no conteúdo de suas mensagens do Amazon SQS, use a chave `body` no registro de mensagens do Amazon SQS. Suponha que você queira processar somente os registros onde o `RequestCode` na sua mensagem do Amazon SQS seja “BBBB”. O objeto `FilterCriteria` seria como a seguir.

```
{
    "Filters": [
        {
            "Pattern": "{ \"body\" : { \"RequestCode\" : [ \"BBBB\" ] } }"
        }
    ]
}
```

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples. 

```
{
    "body": {
        "RequestCode": [ "BBBB" ]
        }
}
```

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

```
{ "body" : { "RequestCode" : [ "BBBB" ] } }
```

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

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

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

Para adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "body" : { "RequestCode" : [ "BBBB" ] } }'
```

------

Suponha que você queira que sua função processe somente os registros onde `RecordNumber` seja maior que 9999. O objeto `FilterCriteria` seria como a seguir.

```
{
    "Filters": [
        {
            "Pattern": "{ \"body\" : { \"RecordNumber\" : [ { \"numeric\": [ \">\", 9999 ] } ] } }"
        }
    ]
}
```

Para maior clareza, aqui está o valor de `Pattern` do filtro expandido em JSON simples. 

```
{
    "body": {
        "RecordNumber": [
            {
                "numeric": [ ">", 9999 ]
            }
        ]
    }
}
```

É possível adicionar seu filtro usando o console, a AWS CLI ou um modelo do AWS SAM.

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

Para adicionar esse filtro usando o console, siga as instruções em [Anexar critérios de filtro a um mapeamento de fonte de eventos (console)](invocation-eventfiltering.md#filtering-console) e insira a string a seguir em **Critérios do filtro**.

```
{ "body" : { "RecordNumber" : [ { "numeric": [ ">", 9999 ] } ] } }
```

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

Para criar um novo mapeamento da origem do evento com esses critérios de filtro usando a AWS Command Line Interface (AWS CLI), execute o comando a seguir.

```
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 adicionar esses critérios de filtro a um mapeamento da origem do evento existente, execute o comando a seguir.

```
aws lambda update-event-source-mapping \
    --uuid "a1b2c3d4-5678-90ab-cdef-11111EXAMPLE" \
    --filter-criteria '{"Filters": [{"Pattern": "{ \"body\" : { \"RecordNumber\" : [ { \"numeric\": [ \">\", 9999 ] } ] } }"}]}'
```

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

Para adicionar esse filtro usando o AWS SAM, adicione o trecho a seguir ao modelo YAML da origem do evento.

```
FilterCriteria:
  Filters:
    - Pattern: '{ "body" : { "RecordNumber" : [ { "numeric": [ ">", 9999 ] } ] } }'
```

------

No Amazon SQS, o corpo da mensagem pode ser qualquer string. Porém, isso pode ser problemático se os `FilterCriteria` esperarem que o `body` esteja em um formato JSON válido. O cenário oposto também é verdadeiro: se o corpo da mensagem recebida estiver em formato JSON, mas seus critérios de filtragem esperarem que o `body` seja uma string simples, isso poderá levar um comportamento não pretendido.

Para evitar esse problema, certifique-se de que o formato do corpo nos seus `FilterCriteria` corresponda ao formato esperado do `body` nas mensagens que você receber da fila. Antes de filtrar suas mensagens, o Lambda avalia automaticamente o formato do corpo da mensagem recebida e do seu padrão de filtro para o `body`. Se houver incompatibilidade, o Lambda descartará a mensagem. A tabela a seguir resume essa avaliação:


| Formato do `body` da mensagem recebida | Formato do `body` do padrão de filtro | Ação resultante | 
| --- | --- | --- | 
|  String simples  |  String simples  |  Filtros do Lambda com base em seus critérios de filtro.  | 
|  String simples  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  String simples  |  JSON válido  |  O Lambda descarta a mensagem.  | 
|  JSON válido  |  String simples  |  O Lambda descarta a mensagem.  | 
|  JSON válido  |  Nenhum padrão de filtro para propriedades de dados  |  Filtros do Lambda (somente nas outras propriedades de metadados) com base nos seus critérios de filtro.  | 
|  JSON válido  |  JSON válido  |  Filtros do Lambda com base em seus critérios de filtro.  | 

# Tutorial: usar o Lambda com o Amazon SQS
<a name="with-sqs-example"></a>

Neste tutorial, você criará uma função do Lambda que consome mensagens de uma fila do [Amazon Simple Queue Service (Amazon SQS)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html). A função do Lambda é executada sempre que uma nova mensagem é adicionada à fila. A função grava as mensagens em um fluxo do Amazon CloudWatch Logs. O diagrama a seguir mostrará os recursos da AWS que você usará para concluir o tutorial.

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


Para concluir este tutorial, execute as seguintes tarefas:

1. Crie uma função do Lambda que grave mensagens no CloudWatch Logs.

1. Crie uma fila do Amazon SQS.

1. Crie um mapeamento da origem do evento do Lambda. O mapeamento da origem do evento realiza a leitura da fila do Amazon SQS e invoca a função do Lambda quando uma nova mensagem é adicionada.

1. Teste a configuração ao adicionar mensagens à sua fila e ao monitorar os resultados no CloudWatch Logs.

## Pré-requisitos
<a name="with-sqs-prepare"></a>

### Instalar o AWS Command Line Interface
<a name="install_aws_cli"></a>

Se você ainda não instalou a AWS Command Line Interface, siga as etapas em [Instalar ou atualizar a versão mais recente da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalá-la.

O tutorial requer um terminal de linha de comando ou um shell para executar os comandos. No Linux e no macOS, use o gerenciador de pacotes e de shell de sua preferência.

**nota**  
No Windows, alguns comandos da CLI do Bash que você costuma usar com o Lambda (como `zip`) não são compatíveis com os terminais integrados do sistema operacional. Para obter uma versão do Ubuntu com o Bash integrada no Windows, [instale o Subsistema do Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Criar a função de execução
<a name="with-sqs-create-execution-role"></a>

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


Um [perfil de execução](lambda-intro-execution-role.md) é um perfil do AWS Identity and Access Management (IAM) que concede a uma função do Lambda permissão para acessar recursos e Serviços da AWS. Para permitir que a função realize a leitura de itens do Amazon SQS, anexe a política de permissões **AWSLambdaSQSQueueExecutionRole**.

**Criar um perfil de execução e anexar uma política de permissões do Amazon SQS**

1. Abra a página [Funções](https://console.aws.amazon.com/iam/home#/roles) no console do IAM.

1. Selecione **Criar perfil**.

1. Em **Tipo de entidade confiável**, escolha **Serviços da AWS**.

1. Em **Caso de uso**, escolha **Lambda**.

1. Escolha **Próximo**.

1. Na caixa de pesquisa **Políticas de permissões**, insira **AWSLambdaSQSQueueExecutionRole**.

1. Selecione a política **AWSLambdaSQSQueueExecutionRole** e, em seguida, escolha **Próximo**.

1. Em **Detalhes do perfil**, para **Nome do perfil**, insira **lambda-sqs-role** e, em seguida, escolha **Criar perfil**.

Após a criação da função, anote o nome de recurso da Amazon (ARN) do seu perfil de execução. Você precisará dele em etapas posteriores.

## Criar a função
<a name="with-sqs-create-function"></a>

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


Crie uma função do Lambda queprocessesuas mensagens do Amazon SQS. O código da função registra o corpo da mensagem do Amazon SQS no CloudWatch Logs.

Este tutorial usa o runtime do Node.js 24, mas também fornecemos exemplos de códigos em outras linguagens de runtime. Você pode selecionar a guia na caixa a seguir para ver o código do runtime do seu interesse. O código JavaScript que você usará nesta etapa é o primeiro exemplo mostrado na guia **JavaScript**.

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Consumir um evento do SQS com o Lambda usando .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Consumir um evento do SQS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Consumir um evento do SQS com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/blob/main/integration-sqs-to-lambda). 
Consumir um evento do SQS com o Lambda usando 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;
  }
}
```
Consumir um evento do SQS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Consumir um evento do SQS com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Consumir um evento do SQS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Consumir um evento do SQS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sqs-to-lambda). 
Consuma um evento do SQS com o Lambda usando 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
}
```

------

**Criar uma função do Lambda em Node.js**

1. Crie um diretório para o projeto e depois mude para esse diretório.

   ```
   mkdir sqs-tutorial
   cd sqs-tutorial
   ```

1. Copie o código JavaScript de amostra em um novo arquivo denominado `index.js`.

1. Crie um pacote de implantação usando o comando `zip` a seguir.

   ```
   zip function.zip index.js
   ```

1. Crie uma função do Lambda usando o comando [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html) da AWS CLI. Para o parâmetro `role`, insira o ARN da função de execução criada anteriormente.
**nota**  
A função do Lambda e a fila do Amazon SQS devem estar na mesma Região da 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
   ```

## Testar a função
<a name="with-sqs-create-test-function"></a>

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


Invoque sua função do Lambda manualmente usando o comando da `invoke` AWS CLI e um evento do Amazon SQS de amostra.

**Invocar a função do Lambda com um evento de amostra**

1. Salve o JSON a seguir como um arquivo denominado `input.json`. Esse JSON simula um evento que o Amazon SQS pode enviar para a função do Lambda, no qual `"body"` contém a mensagem real da fila. Neste exemplo, a mensagem é `"test"`.  
**Example Evento do Amazon SQS**  

   Este é um evento de teste, portanto, você não precisa alterar a mensagem ou o número da conta.

   ```
   {
       "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. Execute o comando [invoke](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/invoke.html) da AWS CLI apresentado a seguir. Esse comando retorna os logs do CloudWatch na resposta. Para obter mais informações sobre recuperação de logs, consulte [Acesso aos logs com a 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
   ```

   A opção **cli-binary-format** será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [A AWS CLI comporta opções de linha de comando globais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) no *Guia do usuário da AWS Command Line Interface versão 2*.

1. Encontre o log `INFO` na resposta. É aqui que a função do Lambda registra em log o corpo da mensagem. Você deve ver logs semelhantes a este:

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

## Criar uma fila do Amazon SQS
<a name="with-sqs-configure-sqs"></a>

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


Crie uma fila do Amazon SQS que a função do Lambda possa usar como uma fonte de eventos. A função do Lambda e a fila do Amazon SQS devem estar na mesma Região da AWS.

**Para criar uma fila**

1. Abra o [console do Amazon SQS](https://console.aws.amazon.com/sqs).

1. Selecione **Criar fila**.

1. Insira um nome para a fila. Deixe todas as outras opções nas configurações padrão.

1. Selecione **Criar fila**.

Depois de criar a fila, anote seu ARN. Você precisará dele na próxima etapa, quando for associar a fila à função do Lambda.

## Configurar a origem de evento
<a name="with-sqs-attach-notification-configuration"></a>

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


Conecte a fila do Amazon SQS à função do Lambda ao criar um [mapeamento da origem do evento](invocation-eventsourcemapping.md). O mapeamento da origem do evento realiza a leitura da fila do Amazon SQS e invoca a função do Lambda quando uma nova mensagem é adicionada.

Para criar um mapeamento entre a fila do Amazon SQS e a função do Lambda, use o comando [create-event-source-mapping](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-event-source-mapping.html) da AWS CLI. Exemplo:

```
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 obter uma lista dos mapeamentos da origem dos eventos, use o comando [list-event-source-mappings](https://awscli.amazonaws.com/v2/documentation/api/2.1.29/reference/lambda/list-event-source-mappings.html). Exemplo:

```
aws lambda list-event-source-mappings --function-name ProcessSQSRecord
```

## Envie uma mensagem de teste
<a name="with-sqs-test-message"></a>

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


**Enviar uma mensagem do Amazon SQS para a função do Lambda**

1. Abra o [console do Amazon SQS](https://console.aws.amazon.com/sqs).

1. Escolha a fila que você criou anteriormente.

1. Escolha **Enviar e receber mensagens**.

1. Em **Corpo da mensagem**, insira uma mensagem de teste, como “esta é uma mensagem de teste”.

1. Escolha **Send Message (Enviar mensagem)**.

O Lambda pesquisa a fila para atualizações. Quando há uma nova mensagem, o Lambda invoca a sua função com esses novos dados de evento da fila. Caso o manipulador de função retorne sem exceções, o Lambda considera a mensagem processada com êxito e começa a realizar a leitura de novas mensagens na fila. Após o processamento com êxito, uma mensagem,o Lambda a exclui automaticamente da fila. Se o manipulador gera uma exceção, o Lambda considera que o batch de mensagens não foi processado com êxito e o Lambda invoca novamente a função com o mesmo batch de mensagens.

## Verificar os logs do CloudWatch
<a name="with-sqs-check-logs"></a>

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


**Confirmar que a função processou a mensagem**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha a função **ProcessSQSRecord**.

1. Escolha **Monitor**.

1. Escolha **Visualizar logs do CloudWatch**.

1. No console do CloudWatch, escolha o **Fluxo de logs** para a função.

1. Encontre o log `INFO`. É aqui que a função do Lambda registra em log o corpo da mensagem. Você deve visualizar a mensagem que enviou da fila do Amazon SQS. Exemplo:

   ```
   2023-09-11T22:49:12.730Z b0c41e9c-0556-5a8b-af83-43e59efeec71 INFO Processed message this is a test message.
   ```

## Limpe os recursos
<a name="cleanup"></a>

Agora você pode excluir os recursos criados para este tutorial, a menos que queira mantê-los. Excluindo os recursos da AWS que você não está mais usando, você evita cobranças desnecessárias em sua Conta da AWS.

**Para excluir a função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione a função de execução que você criou.

1. Escolha **Excluir**.

1. Insira o nome do perfil no campo de entrada de texto e escolha **Delete** (Excluir).

**Como excluir a função do Lambda**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Selecione a função que você criou.

1. Selecione **Ações**, **Excluir**.

1. Digite **confirm** no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir a fila do Amazon SQS**

1. Faça login no Console de gerenciamento da AWS e abra o console do Amazon SQS em [https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/).

1. Selecione a fila que você criou.

1. Escolha **Excluir**.

1. Digite **confirm** no campo de entrada de texto.

1. Escolha **Excluir**.

# Tutorial: Uso de uma fila do Amazon SQS entre contas como a origem de um evento
<a name="with-sqs-cross-account-example"></a>

Neste tutorial, você criará uma função do Lambda que consome mensagens de uma fila do Amazon Simple Queue Service (Amazon SQS) em uma conta da AWS diferente. Este tutorial envolve duas contas da AWS: **Conta A** refere-se à conta que contém sua função do Lambda e **Conta B** refere-se à conta que contém a fila do Amazon SQS.

## Pré-requisitos
<a name="with-sqs-cross-account-prepare"></a>

### Instalar o AWS Command Line Interface
<a name="install_aws_cli"></a>

Se você ainda não instalou a AWS Command Line Interface, siga as etapas em [Instalar ou atualizar a versão mais recente da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalá-la.

O tutorial requer um terminal de linha de comando ou um shell para executar os comandos. No Linux e no macOS, use o gerenciador de pacotes e de shell de sua preferência.

**nota**  
No Windows, alguns comandos da CLI do Bash que você costuma usar com o Lambda (como `zip`) não são compatíveis com os terminais integrados do sistema operacional. Para obter uma versão do Ubuntu com o Bash integrada no Windows, [instale o Subsistema do Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Criar a função de execução (Conta A)
<a name="with-sqs-cross-account-create-execution-role"></a>

Na **Conta A**, crie uma [função de execução](lambda-intro-execution-role.md) que dê à sua função permissão para acessar os recursos da AWS necessários.

**Para criar uma função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do AWS Identity and Access Management (IAM).

1. Selecione **Criar perfil**.

1. Crie uma função com as propriedades a seguir.
   + **Trusted entity (Entidade confiável** – **AWS Lambda**
   + **Permissões**: **AWSLambdaSQSQueueExecutionRole**.
   + **Role name (Nome da função** – **cross-account-lambda-sqs-role**

A política **AWSLambdaSQSQueueExecutionRole** tem as permissões necessárias para a função ler itens do Amazon SQS e para gravar logs no Amazon CloudWatch Logs.

## Criar a função (Conta A)
<a name="with-sqs-cross-account-create-function"></a>

Na **Conta A**, crie uma função do Lambda para processar suas mensagens do Amazon SQS. A função do Lambda e a fila do Amazon SQS devem estar na mesma Região da AWS.

A seguir, o exemplo de código Node.js grava cada mensagem em um log do CloudWatch Logs.

**Example index.mjs**  

```
export const handler = async function(event, context) {
  event.Records.forEach(record => {
    const { body } = record;
    console.log(body);
  });
  return {};
}
```

**Para criar a função**
**nota**  
Seguir estas etapas cria uma função no Node.js. Para outras linguagens, as etapas são semelhantes, mas alguns detalhes são diferentes.

1. Salve o exemplo de código como um arquivo denominado `index.mjs`.

1. Crie um pacote de implantação.

   ```
   zip function.zip index.mjs
   ```

1. Crie a função usando o comando `create-function` da AWS Command Line Interface (AWS CLI). Substitua `arn:aws:iam::111122223333:role/cross-account-lambda-sqs-role` pelo ARN do perfil de execução que você criou 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
   ```

## Teste a função (Conta A)
<a name="with-sqs-cross-account-create-test-function"></a>

Na **Conta A**, invoque sua função do Lambda manualmente usando o comando `invoke` AWS CLI e um evento do Amazon SQS de exemplo.

Se o manipulador obtém um retorno normal sem exceções, o Lambda considerará a mensagem como processada com êxito e começará a ler novas mensagens na fila. Após o processamento com êxito, uma mensagem,o Lambda a exclui automaticamente da fila. Se o manipulador gera uma exceção, o Lambda considera que o batch de mensagens que não foram processadas com êxito e o Lambda invoca novamente a função com o mesmo batch de mensagens.

1. Salve o JSON a seguir como um arquivo 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"
           }
       ]
   }
   ```

   O JSON anterior simula um evento que o Amazon SQS pode enviar para a função do Lambda, onde `"body"` contém a mensagem real da fila.

1. Execute o comando `invoke` a seguir da AWS CLI.

   ```
   aws lambda invoke --function-name CrossAccountSQSExample \
   --cli-binary-format raw-in-base64-out \
   --payload file://input.txt outputfile.txt
   ```

   A opção **cli-binary-format** será necessária se você estiver usando a AWS CLI versão 2. Para que essa seja a configuração padrão, execute `aws configure set cli-binary-format raw-in-base64-out`. Para obter mais informações, consulte [A AWS CLI comporta opções de linha de comando globais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) no *Guia do usuário da AWS Command Line Interface versão 2*.

1. Verifique a saída no arquivo `outputfile.txt`.

## Criar uma fila do Amazon SQS (Conta B)
<a name="with-sqs-cross-account-configure-sqs"></a>

Na **Conta B**, crie uma fila do Amazon SQS que a função do Lambda na **Conta A** possa usar como uma fonte de eventos. A função do Lambda e a fila do Amazon SQS devem estar na mesma Região da AWS.

**Para criar uma fila**

1. Abra o [console do Amazon SQS](https://console.aws.amazon.com/sqs).

1. Selecione **Criar fila**.

1. Crie uma fila com as propriedades a seguir.
   + **Type** (Tipo): **Standard** (Padrão)
   + **Name** (Nome): **LambdaCrossAccountQueue**
   + **Configuration** (Configuração): mantenha as configurações padrão.
   + **Access policy** (Política de acesso): selecione **Advanced** (Avançado). Cole na seguinte política do JSON. Substitua os valores a seguir:
     + `111122223333`: Conta da AWS ID da **Conta A**
     + `444455556666`: Conta da AWS ID da **Conta B**

------
#### [ 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 à função de execução do Lambda na **Conta A** permissões para consumir mensagens desta fila do Amazon SQS.

1. Depois de criar a fila, registre o nome do recurso da Amazon (ARN). Você precisará dele na próxima etapa, quando for associar a fila à função do Lambda.

## Configurar a origem do evento (Conta A)
<a name="with-sqs-cross-account-event-source"></a>

Na **Conta A**, crie um mapeamento da origem do evento entre a fila do Amazon SQS na **Conta B** e sua função do Lambda executando o comando `create-event-source-mapping` da AWS CLI a seguir. Substitua `arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue` pelo ARN da fila do Amazon SQS que você criou na etapa 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 obter uma lista de mapeamentos de fonte do evento, execute o comando a seguir.

```
aws lambda list-event-source-mappings --function-name CrossAccountSQSExample \
--event-source-arn arn:aws:sqs:us-east-1:444455556666:LambdaCrossAccountQueue
```

## Testar a configuração
<a name="with-sqs-final-integration-test-no-iam"></a>

Você agora pode testar a configuração da seguinte forma:

1. Na **Conta B**, abra o [console do Amazon SQS](https://console.aws.amazon.com/sqs).

1. Escolha **LambdaCrossAccountQueue** criada anteriormente.

1. Escolha **Send and receive messages (Enviar e receber mensagens)**.

1. Em **Message body** (Corpo da mensagem), insira uma mensagem de teste.

1. Escolha **Send Message (Enviar mensagem)**.

Sua função do Lambda na **Conta A** deve receber a mensagem. O Lambda continuará a sondar a fila em busca de atualizações. Quando há uma nova mensagem, o Lambda invoca a sua função com esses novos dados de evento da fila. A função é executada e cria logs no Amazon CloudWatch. É possível visualizar os logs no [console do CloudWatch](https://console.aws.amazon.com/cloudwatch).

## Limpe os recursos
<a name="cleanup"></a>

Agora você pode excluir os recursos criados para este tutorial, a menos que queira mantê-los. Excluindo os recursos da AWS que você não está mais usando, você evita cobranças desnecessárias em sua Conta da AWS.

Na **Conta A**, limpe sua função de execução e a função do Lambda.

**Para excluir a função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione a função de execução que você criou.

1. Escolha **Excluir**.

1. Insira o nome do perfil no campo de entrada de texto e escolha **Delete** (Excluir).

**Como excluir a função do Lambda**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Selecione a função que você criou.

1. Selecione **Actions**, **Delete**.

1. Digite **confirm** no campo de entrada de texto e escolha **Delete** (Excluir).

Na **Conta B**, limpe a fila do Amazon SQS.

**Para excluir a fila do Amazon SQS**

1. Faça login no Console de gerenciamento da AWS e abra o console do Amazon SQS em [https://console.aws.amazon.com/sqs/](https://console.aws.amazon.com/sqs/).

1. Selecione a fila que você criou.

1. Escolha **Excluir**.

1. Digite **confirm** no campo de entrada de texto.

1. Escolha **Excluir**.

# Orquestrar funções do Lambda com o Step Functions
<a name="with-step-functions"></a>

O AWS Step Functions fornece orquestração visual do fluxo de trabalho para coordenar as funções do Lambda com outros serviços da AWS. Com integrações nativas a mais de 220 serviços da AWS e infraestrutura totalmente gerenciada e sem manutenção, o Step Functions é ideal quando você precisa de um design visual de fluxo de trabalho e integrações de serviços totalmente gerenciadas.

Para orquestração usando linguagens de programação padrão no Lambda, onde a lógica do fluxo de trabalho convive com a lógica de negócios, considere as [funções duráveis do Lambda](durable-functions.md). Para obter ajuda na escolha entre essas opções, consulte [Funções duráveis ou Step Functions](durable-step-functions.md).

Por exemplo, o processamento de um pedido pode exigir que os detalhes sejam válidos, os níveis de inventário sejam verificados, o pagamento seja processado e uma fatura seja gerada. Escreva funções do Lambda separadas para cada tarefa e use o Step Functions para gerenciar o fluxo de trabalho. O Step Functions coordena o fluxo de dados entre as funções e lida com os erros em cada etapa. Essa separação torna seus fluxos de trabalho mais fáceis de visualizar, modificar e manter à medida que se tornam mais complexos.

## Quando usar o Step Functions com o Lambda
<a name="when-to-use-step-functions"></a>

Os cenários a seguir são bons exemplos de quando o Step Functions é particularmente adequado para orquestrar aplicativos baseados no Lambda.
+ [Processamento sequencial](#sequential-processing)
+ [Tratamento de erros complexos](#complex-error-handling)
+ [Fluxos de trabalho condicionais e aprovações humanas](#conditional-workflows-human-approvals)
+ [Processamento paralelo](#parallel-processing)

### Processamento sequencial
<a name="sequential-processing"></a>

O processamento sequencial ocorre quando uma tarefa deve ser concluída antes que a próxima tarefa possa ser iniciada. Por exemplo, em um sistema de processamento de pedidos, o processamento do pagamento não pode começar até que a validação do pedido seja concluída, e a geração da fatura deve aguardar a confirmação do pagamento. Escreva funções do Lambda separadas para cada tarefa e use o Step Functions para gerenciar o fluxo de trabalho e lidar com o fluxo de dados entre as funções.

#### Exemplo de antipadrão
<a name="anti-pattern-sequential"></a>

Uma única função do Lambda gerencia todo o fluxo de trabalho de processamento de pedidos:
+ Invocar outras funções Lambda em sequência
+ Analisar e validar respostas de cada função
+ Implementar a lógica de tratamento e recuperação de erros
+ Gerenciar o fluxo de dados entre as funções

#### (Abordagem recomendada)
<a name="recommended-sequential"></a>

Use duas funções Lambda: uma para validar o pedido e outra para processar o pagamento. O Step Functions coordena essas funções:
+ Executando tarefas na sequência correta
+ Passando dados entre funções
+ Implementando tratamento de erros em cada etapa
+ Usando estados de [Escolha](https://docs.aws.amazon.com/step-functions/latest/dg/state-choice.html) para garantir que somente pedidos válidos prossigam para o pagamento

**Example gráfico do fluxo de trabalho**  

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


**nota**  
**Alternativa que prioriza o código:** para processamento sequencial com pontos de verificação e repetição baseados em código, consulte [Etapas das funções duráveis do Lambda](durable-basic-concepts.md).

### Tratamento de erros complexos
<a name="complex-error-handling"></a>

Embora o Lambda forneça [recursos de novas tentativas para invocações assíncronas e mapeamentos de origens de eventos](invocation-retries.md), o Step Functions oferece tratamento de erros mais sofisticado para fluxos de trabalho complexos. Você pode [configurar novas tentativas automáticas](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html#error-handling-retrying-after-an-error) com recuo exponencial e definir diferentes políticas de novas tentativas para diferentes tipos de erros. Quando as novas tentativas se esgotarem, use `Catch` para rotear os erros para um [estado de fallback](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html#error-handling-fallback-states). Isso é particularmente útil quando você precisa de um tratamento de erros no nível de fluxo de trabalho que coordene várias funções e serviços.

Para saber mais sobre como tratar erros de função do Lambda em uma máquina de estado, consulte [Handling errors](https://catalog.workshops.aws/stepfunctions/handling-errors) no *The AWS Step Functions Workshop*.

#### Exemplo de antipadrão
<a name="anti-pattern-error-handling"></a>

Uma única função do Lambda lida com todos os itens a seguir:
+ Tentativas de chamar um serviço de processamento de pagamentos
+ Se o serviço de pagamentos não estiver disponível, a função aguardará e tentará novamente mais tarde.
+ Implementa um recuo exponencial personalizado para o tempo de espera
+ Depois que todas as tentativas falham, captura o erro e escolhe outro fluxo

#### (Abordagem recomendada)
<a name="recommended-error-handling"></a>

Use uma única função do Lambda com foco exclusivamente no processamento de pagamentos. O Step Functions gerencia o tratamento de erros ao:
+ [Repetir automaticamente as tarefas que falharam com períodos de recuo configuráveis](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-error-handling.html#error-handling-retrying-after-an-error)
+ Aplicar políticas de novas tentativas diferentes com base nos tipos de erros
+ Rotear diferentes tipos de erros para os estados de fallback adequados
+ Manter o estado e o histórico de tratamento de erros

**Example gráfico do fluxo de trabalho**  

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


**nota**  
**Alternativa que prioriza o código:** funções duráveis oferecem tratamento de erros de tentativa e captura com estratégias de repetição configuráveis. Consulte [Tratamento de erros em funções duráveis](durable-execution-sdk-retries.md).

### Fluxos de trabalho condicionais e aprovações humanas
<a name="conditional-workflows-human-approvals"></a>

Use o [estado de escolha](https://docs.aws.amazon.com/step-functions/latest/dg/state-choice.html) do Step Functions para rotear fluxos de trabalho com base na saída da função e o [sufixo waitForTaskToken](https://docs.aws.amazon.com/step-functions/latest/dg/connect-to-resource.html#connect-wait-token) para pausar os fluxos de trabalho para decisões humanas. Por exemplo, para processar uma solicitação de aumento do limite de crédito, use uma função do Lambda para avaliar os fatores de risco. Depois, use o Step Functions para encaminhar solicitações de alto risco para aprovação manual e solicitações de baixo risco para aprovação automática.

Para implantar um exemplo de fluxo de trabalho que use um padrão de integração de token de tarefa de retorno de chamada, consulte [Callback with Task Token](https://catalog.workshops.aws/stepfunctions/integrating-services/3-callback-token) no *The AWS Step Functions Workshop*. 

#### Exemplo de antipadrão
<a name="anti-pattern-conditional"></a>

Uma única função do Lambda gerencia um fluxo de trabalho de aprovação complexo ao:
+ Implementar uma lógica condicional aninhada para avaliar solicitações de crédito
+ Invocar diferentes funções de aprovação com base nos valores da solicitação
+ Gerenciar vários caminhos de aprovação e pontos de decisão
+ Rastrear o estado das aprovações pendentes
+ Implementar uma lógica de tempo limite e de notificação para aprovações

#### (Abordagem recomendada)
<a name="recommended-conditional"></a>

Use três funções do Lambda: uma para avaliar o risco de cada solicitação, uma para aprovar solicitações de baixo risco e outra para encaminhar solicitações de alto risco a um gerente para análise. O Step Functions gerencia o fluxo de trabalho:
+ Usando estados de [Escolha](https://docs.aws.amazon.com/step-functions/latest/dg/state-choice.html) para rotear solicitações com base no valor e no nível de risco
+ Pausar a execução enquanto aguarda a aprovação humana
+ Gerenciar tempos limite para aprovações pendentes
+ Fornecer visibilidade do estado atual de cada solicitação

**Example gráfico do fluxo de trabalho**  

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


**nota**  
**Alternativa que prioriza o código:** funções duráveis oferecem suporte a retornos de chamada para fluxos de trabalho com intervenção humana. Consulte [Retornos de chamada em funções duráveis](durable-execution-sdk.md).

### Processamento paralelo
<a name="parallel-processing"></a>

O Step Functions fornece três maneiras de lidar com processamento em paralelo:
+ O [estado Em paralelo](https://docs.aws.amazon.com/step-functions/latest/dg/state-parallel.html) executa várias ramificações do fluxo de trabalho simultaneamente. Use isso quando precisar executar funções diferentes em paralelo, como gerar miniaturas enquanto extrai metadados de imagem.
+ O [estado Mapa em linha](https://docs.aws.amazon.com/step-functions/latest/dg/state-map-inline.html) processa matrizes de dados com até 40 iterações simultâneas. Use isso para conjuntos de dados pequenos e médios nos quais que você precisa realizar a mesma operação em todos os itens.
+ O [estado de Mapa distribuído](https://docs.aws.amazon.com/step-functions/latest/dg/state-map-distributed.html) lida com o processamento em paralelo de grande escala, com até 10.000 execuções simultâneas, sendo compatível com matrizes JSON e fontes de dados do Amazon Simple Storage Service (Amazon S3). Use isso ao processar grandes conjuntos de dados ou quando precisar de mais simultaneidade.

#### Exemplo de antipadrão
<a name="anti-pattern-parallel"></a>

Uma única função do Lambda tenta gerenciar o processamento em paralelo ao:
+ Invocar simultaneamente várias funções de processamento de imagem
+ Implementar uma lógica personalizada de execução em paralelo
+ Gerenciar limites de tempo e tratamento de erros para cada tarefa paralela
+ Coletar e agregar resultados de todas as funções

#### (Abordagem recomendada)
<a name="recommended-parallel"></a>

Use três funções do Lambda: uma para criar uma imagem em miniatura, outra para adicionar uma marca d'água e outra para extrair os metadados. O Step Functions gerencia essas funções ao:
+ Executar todas as funções simultaneamente usando o estado [Em paralelo](https://docs.aws.amazon.com/step-functions/latest/dg/state-parallel.html)
+ Coletar os resultados de cada função para uma matriz ordenada
+ Gerenciar limites de tempo e tratamento de erros em todas as execuções paralelas
+ Prosseguir apenas quando todas as ramificações paralelas são concluídas

**Example gráfico do fluxo de trabalho**  

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


**nota**  
**Alternativa que prioriza o código:** as funções duráveis oferecem operações `parallel()` e `map()`. Consulte [Execução paralela](durable-execution-sdk.md).

## Quando não usar o Step Functions com o Lambda
<a name="when-not-to-use"></a>

Nem todas as aplicações baseadas no Lambda se beneficiam com o uso do Step Functions. Considere esses cenários ao escolher a arquitetura da sua aplicação.
+ [Uma aplicação simples](#simple-applications)
+ [Processamento de dados complexos](#complex-data-processing)
+ [Workloads com uso intenso de CPU](#cpu-intensive)

### Uma aplicação simples
<a name="simple-applications"></a>

**nota**  
Para fluxos de trabalho que não exigem design visual ou integrações abrangentes de serviços, as [funções duráveis do Lambda](durable-functions.md) podem ser uma alternativa mais simples que mantém a lógica do fluxo de trabalho no código dentro do Lambda.

Para aplicações que não exigem orquestração complexa, o uso do Step Functions pode adicionar complexidade desnecessária. Por exemplo, se estiver simplesmente processando as mensagens de uma fila do Amazon SQS ou respondendo aos eventos do Amazon EventBridge, você poderá configurar esses serviços para invocar as funções do Lambda diretamente. Da mesma forma, se a aplicação consistir em apenas uma ou duas funções do Lambda com tratamento simples de erros, a invocação direta do Lambda ou as arquiteturas orientadas por eventos podem ser mais simples de implantar e manter.

### Processamento de dados complexos
<a name="complex-data-processing"></a>

Você pode usar o estado de [Mapa distribuído](https://docs.aws.amazon.com/step-functions/latest/dg/state-map-distributed.html) do Step Functions para processar simultaneamente grandes conjuntos de dados do Amazon S3 com funções do Lambda. Isso é eficaz para muitas workloads paralelas de grande escala, incluindo processamento de dados semiestruturados, como arquivos JSON ou CSV. Porém, para transformações de dados mais complexas ou para analytics avançada, considere estas alternativas:
+ **Pipelines de transformação de dados**: use AWS Glue para trabalhos de ETL que processam dados estruturados ou semiestruturados de várias fontes. O AWS Glue é particularmente útil quando precisar de recursos integrados de gerenciamento de catálogo de dados e esquemas.
+ **Análise de dados:** use o Amazon EMR para data analytics em escala de petabytes, especialmente quando precisar de ferramentas do ecossistema Apache Hadoop ou para workloads de machine learning que excedam os limites de [memória](configuration-memory.md) do Lambda.

### Workloads com uso intenso de CPU
<a name="cpu-intensive"></a>

Embora o Step Functions possa orquestrar tarefas com uso intensivo de CPU, as funções do Lambda talvez não sejam adequadas para essas workloads devido aos seus recursos limitados de CPU. Para operações computacionalmente intensivas em seus fluxos de trabalho, considere estas alternativas:
+ **Orquestração de contêineres:** use o Step Functions para gerenciar as tarefas do Amazon Elastic Container Service (Amazon ECS) para obter recursos computacionais mais consistentes e escaláveis.
+ **Processamento em lotes:** integre o AWS Batch ao Step Functions para gerenciar trabalhos em lotes com uso intensivo de computação que exijam uso contínuo da CPU.

# Invocar uma função do Lambda com eventos em lote do Amazon S3
<a name="services-s3-batch"></a>

É possível usar operações em lote do Amazon S3 para invocar uma função do Lambda em um grande conjunto de objetos do Amazon S3. O Amazon S3 rastreia o andamento das operações em lote, envia notificações e armazena um relatório de conclusão que mostra o status de cada ação. 

Para executar uma operação em lote, crie um Amazon S3[trabalho de operações em lote](https://docs.aws.amazon.com/AmazonS3/latest/dev/batch-ops-operations.html). Ao criar o trabalho, forneça um manifesto (a lista de objetos) e configure a ação a ser executada nesses objetos. 

Quando o trabalho em lote é iniciado, o Amazon S3 invoca a função do Lambda [de forma síncrona](invocation-sync.md) para cada objeto no manifesto. O parâmetro do evento inclui os nomes do bucket e do objeto. 

O exemplo a seguir mostra o evento que o Amazon S3 envia à função do Lambda para um objeto denominado **customerImage1.jpg** no bucket **amzn-s3-demo-bucket**.

**Example Eventos de solicitação em lote do 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"
        }
    ]  
}
```

A função do Lambda deve retornar um objeto JSON com os campos, conforme mostrado no exemplo a seguir. É possível copiar o `invocationId` e `taskId` do parâmetro do evento. Você pode retornar uma string no `resultString`. O Amazon S3 salva o`resultString`no relatório de conclusão. 

**Example Resposta em lote do Amazon S3**  

```
{
  "invocationSchemaVersion": "1.0",
  "treatMissingKeysAs" : "PermanentFailure",
  "invocationId" : "YXNkbGZqYWRmaiBhc2RmdW9hZHNmZGpmaGFzbGtkaGZza2RmaAo",
  "results": [
    {
      "taskId": "dGFza2lkZ29lc2hlcmUK",
      "resultCode": "Succeeded",
      "resultString": "[\"Alice\", \"Bob\"]"
    }
  ]
}
```

## Invocar funções do Lambda de operações em lote do Amazon S3
<a name="invoking"></a>

É possível invocar a função do Lambda com um ARN de função qualificado ou não qualificado. Se você quiser usar a mesma versão de função para todo o trabalho em lote, configure uma versão de função específica no parâmetro `FunctionARN` ao criar o trabalho. Se você configurar um alias ou o qualificador \$1LATEST, o trabalho em lote começará imediatamente a chamar a nova versão da função se o alias ou \$1LATEST for atualizado durante a execução do trabalho. 

Observe que não é possível reutilizar uma função baseada em evento do Amazon S3 para operações em lote. Isso ocorre, pois a operação em lote do Amazon S3 transmite um parâmetro de evento diferente para a função do Lambda e espera uma mensagem de retorno com uma estrutura JSON específica.

Na [política baseada em recursos](access-control-resource-based.md) criada para o trabalho em lote do Amazon S3, verifique se você definiu a permissão para o trabalho invocar a função do Lambda.

Na [função de execução](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-iam-role-policies.html) da função, defina uma política de confiança para que o Amazon S3 assuma a função quando ele executar a função.

Se a função usar o AWS SDK para gerenciar recursos do Amazon S3, será necessário adicionar permissões do Amazon S3 na função de execução. 

Quando o trabalho é executado, o Amazon S3 inicia várias instâncias de função para processar os objetos do Amazon S3 em paralelo, até o[Limite de simultaneidade](lambda-concurrency.md)da função do. O Amazon S3 limita a aceleração de instâncias para evitar custo em excesso para trabalhos menores. 

Se a função do Lambda retornar um código de resposta `TemporaryFailure`, o Amazon S3 tentará novamente realizar a operação. 

Para obter mais informações sobre como gerenciar operações em lote do Amazon S3, consulte [Executar operações em lote](https://docs.aws.amazon.com/AmazonS3/latest/dev/batch-ops.html) no *Guia do desenvolvedor do Amazon S3*. 

Para obter um exemplo de como usar uma função do Lambda nas operações em lote do Amazon S3, consulte [Invocar uma função do Lambda de operações em lote do Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/dev/batch-ops-invoke-lambda.html) no *Guia do desenvolvedor do Amazon S3*. 

# Invocar funções do Lambda com notificações do Amazon SNS
<a name="with-sns"></a>

Você pode usar uma função do Lambda para processar notificações do Amazon Simple Notification Service (Amazon SNS). O Amazon SNS oferece suporte às funções do Lambda como destino para mensagens enviadas para um tópico. É possível inscrever a sua função em tópicos na mesma conta ou em outras contas da AWS. Para obter uma descrição detalhada, consulte [Tutorial: usar o AWS Lambda com o Amazon Simple Notification Service](with-sns-example.md).

O Lambda oferece suporte a acionadores do SNS somente para tópicos do SNS padrão. Não há suporte a tópicos FIFO.

O Lambda processa mensagens do SNS de forma assíncrona, enfileirando as mensagens e lidando com novas tentativas. Se o Amazon SNS não puder acessar o Lambda ou se a mensagem for rejeitada, o Amazon SNS tentará novamente em intervalos crescentes ao longo de várias horas. Para obter detalhes, consulte [Confiabilidade](https://aws.amazon.com/sns/faqs/#Reliability) nas Perguntas frequentes do Amazon SNS.

**Atenção**  
As invocações assíncronas do Lambda processam cada evento ao menos uma vez, e o processamento duplicado de registros pode ocorrer. Para evitar possíveis problemas relacionados a eventos duplicados, é altamente recomendável tornar o código da função idempotente. Para saber mais, consulte [Como tornar minha função do Lambda idempotente](https://repost.aws/knowledge-center/lambda-function-idempotent) no Centro de Conhecimentos da AWS.

## Utilitário de idempotência do Powertools para Lambda AWS
<a name="services-sns-powertools-idempotency"></a>

O utilitário de idempotência do Powertools para AWS Lambda torna suas funções do Lambda idempotentes. Está disponível para Python, TypeScript, Java e .NET. *Para obter mais informações, consulte [Utilitário de idempotência](https://docs.powertools.aws.dev/lambda/python/latest/utilities/idempotency/) na documentação do *Powertools para AWS Lambda (Python*), [Utilitário de idempotência](https://docs.aws.amazon.com/powertools/typescript/2.1.1/utilities/idempotency/) na *documentação do Powertools para AWS Lambda (TypeScript)*, [Utilitário de idempotência](https://docs.powertools.aws.dev/lambda/java/latest/utilities/idempotency/) na *documentação do Powertools para AWS Lambda (Java)* e [Utilitário de idempotência](https://docs.powertools.aws.dev/lambda/dotnet/utilities/idempotency/) na documentação do Powertools para AWS Lambda* (.NET).

**Topics**
+ [Utilitário de idempotência do Powertools para Lambda AWS](#services-sns-powertools-idempotency)
+ [Adicionar um acionador de tópico do Amazon SNS para uma função do Lambda usando o console](#sns-trigger-console)
+ [Adicionar manualmente um acionador de tópico do Amazon SNS para uma função do Lambda](#sns-trigger-manual)
+ [Exemplo de formato de evento do SNS](#sns-sample-event)
+ [Tutorial: usar o AWS Lambda com o Amazon Simple Notification Service](with-sns-example.md)

## Adicionar um acionador de tópico do Amazon SNS para uma função do Lambda usando o console
<a name="sns-trigger-console"></a>

Para adicionar um tópico do SNS como acionador de uma função do Lambda, a maneira mais fácil é usar o console do Lambda. Quando você adiciona o acionador por meio do console, o Lambda configura automaticamente as permissões e assinaturas necessárias para começar a receber eventos do tópico do SNS.

**Para adicionar um tópico do SNS como acionador para uma função do Lambda (console)**

1. Abra a [página Funções](https://console.aws.amazon.com/lambda/home#/functions) do console do Lambda.

1. Escolha o nome da função à qual você deseja adicionar o acionador.

1. Escolha **Configuração** e, em seguida, escolha **Acionadores**.

1. Escolha **Add trigger**.

1. Em **Configuração do acionador**, no menu suspenso, escolha **SNS**.

1. Em **Tópico do SNS**, escolha o tópico do SNS para assinar.

## Adicionar manualmente um acionador de tópico do Amazon SNS para uma função do Lambda
<a name="sns-trigger-manual"></a>

Para configurar manualmente um acionador do SNS para uma função do Lambda, é necessário concluir as seguintes etapas:
+ Definir uma política baseada em recurso para a sua função para permitir que o SNS a invoque.
+ Inscrever a função do Lambda no tópico do Amazon SNS.
**nota**  
Se seu tópico do SNS e sua função do Lambda estiverem em contas da AWS diferentes, também será necessário conceder permissões extras para permitir assinaturas entre contas do tópico do SNS. Para obter mais informações, consulte [Concede permissões entre contas para assinatura do Amazon SNS](with-sns-example.md#with-sns-subscription-grant-permission).

Você pode usar o AWS Command Line Interface (AWS CLI) para concluir essas duas etapas. Primeiro, para definir uma política baseada em recursos para uma função do Lambda que permita invocações do SNS, use o comando da AWS CLI a seguir. Certifique-se de substituir o valor de `--function-name` pelo nome da função do Lambda e o valor de `--source-arn` pelo ARN do tópico do 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
```

Para inscrever sua função no tópico do SNS, use o comando da AWS CLI a seguir. Substitua o valor de `--topic-arn` pelo ARN do tópico do SNS e o valor de `--notification-endpoint` pelo ARN da função do 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
```

## Exemplo de formato de evento do SNS
<a name="sns-sample-event"></a>

O Amazon SNS invoca a função [de forma assíncrona](invocation-async.md) com um evento que contém uma mensagem e metadados.

**Example Evento da mensagem do 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: usar o AWS Lambda com o Amazon Simple Notification Service
<a name="with-sns-example"></a>

Neste tutorial, você usa uma função do Lambda em uma Conta da AWS para assinar um tópico do Amazon Simple Notification Service (Amazon SNS) em uma Conta da AWS separada. Quando você publica mensagens em seu tópico do Amazon SNS, sua função do Lambda lê o conteúdo da mensagem e a envia para o Amazon CloudWatch Logs. Para concluir este tutorial, use o AWS Command Line Interface (AWS CLI).

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-sns-tutorial/sns_tut_resources.png)


Para concluir este tutorial, execute as seguintes etapas:
+ Na **conta A**, crie um tópico do Amazon SNS.
+ Na **conta B**, crie uma função do Lambda que leia as mensagens do tópico.
+ Na **conta B**, crie uma assinatura para o tópico.
+ Publique mensagens para o tópico do Amazon SNS na **conta A** e confirme se a função do Lambda na **conta B** os envia para o CloudWatch Logs.

Ao concluir essas etapas, você aprenderá a configurar um tópico do Amazon SNS para invocar uma função do Lambda. Você também aprenderá como criar uma política do AWS Identity and Access Management (IAM) que dá permissão para um recurso em outra Conta da AWS para invocar o Lambda.

No tutorial, você usa duas Contas da AWS separadas. Os comandos da AWS CLI ilustram isso usando dois perfis nomeados `accountA` e `accountB`, cada um configurado para uso com uma Conta da AWS.diferente. Para saber como configurar a AWS CLI para usar perfis diferentes, consulte [Configurações de arquivos de configuração e credenciais](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html) no *Guia do usuário da AWS Command Line Interface para a versão 2*. Certifique-se de configurar o mesmo padrão de Região da AWS para ambos os perfis.

Se os perfis da AWS CLI criados para as duas Contas da AWS usarem nomes diferentes, ou se você usa o perfil padrão e um perfil nomeado, modifique os comandos da AWS CLI nas seguintes etapas, conforme necessário.

## Pré-requisitos
<a name="with-sns-prereqs"></a>

### Instalar o AWS Command Line Interface
<a name="install_aws_cli"></a>

Se você ainda não instalou a AWS Command Line Interface, siga as etapas em [Instalar ou atualizar a versão mais recente da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) para instalá-la.

O tutorial requer um terminal de linha de comando ou um shell para executar os comandos. No Linux e no macOS, use o gerenciador de pacotes e de shell de sua preferência.

**nota**  
No Windows, alguns comandos da CLI do Bash que você costuma usar com o Lambda (como `zip`) não são compatíveis com os terminais integrados do sistema operacional. Para obter uma versão do Ubuntu com o Bash integrada no Windows, [instale o Subsistema do Windows para Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 

## Criar um tópico do Amazon SNS (conta A)
<a name="with-sns-create-topic"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_1.png)


**Para criar um tópico do**
+ Na **conta A**, crie um tópico padrão do Amazon SNS usando o comando da AWS CLI a seguir.

  ```
  aws sns create-topic --name sns-topic-for-lambda --profile accountA
  ```

  Você deve ver saída semelhante ao seguinte:

  ```
  {
      "TopicArn": "arn:aws:sns:us-west-2:123456789012:sns-topic-for-lambda"
  }
  ```

  Anote o nome do recurso da Amazon (ARN) do seu tópico. Você precisará dele posteriormente no tutorial ao adicionar permissões à sua função do Lambda para assinar o tópico.

## Criar uma função de execução da função (conta B)
<a name="with-sns-example-create-iam-role"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_2.png)


Um perfil de execução é um perfil do IAM que concede a uma função do Lambda permissão para acessar os recursos e Serviços da AWS. Antes de criar sua função na **conta B**, você cria um perfil que dá à função permissões básicas para gravar logs no CloudWatch Logs. Adicionaremos as permissões para ler seu tópico do Amazon SNS em uma etapa posterior.

**Para criar uma função de execução**

1. Na **conta B**, abra a [página de perfis](https://console.aws.amazon.com/iam/home#/roles) no console do IAM.

1. Selecione **Criar perfil**.

1. Em **Tipo de entidade confiável**, escolha **Serviços da AWS**.

1. Em **Caso de uso**, escolha **Lambda**.

1. Escolha **Próximo**.

1. Adicione uma política de permissões básica para o perfil ao fazer o seguinte:

   1. Na caixa de pesquisa **Políticas de permissões**, insira **AWSLambdaBasicExecutionRole**.

   1. Escolha **Próximo**.

1. Finalize a criação do perfil fazendo o seguinte:

   1. Em **Detalhes do perfil**, insira **lambda-sns-role** para **Nome do perfil**.

   1. Selecione **Criar perfil**.

## Criar uma função Lambda (conta B)
<a name="with-sns-example-create-test-function"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_3.png)


Criar uma função do Lambda que processe suas mensagens do Amazon SNS. O código da função registra o conteúdo da mensagem de cada registro no Amazon CloudWatch Logs.

Este tutorial usa o runtime do Node.js 24, mas também fornecemos exemplos de códigos em outras linguagens de runtime. Você pode selecionar a guia na caixa a seguir para ver o código do runtime do seu interesse. O código JavaScript que você usará nesta etapa é o primeiro exemplo mostrado na guia **JavaScript**.

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

**SDK para .NET**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Consumir um evento do SNS com o Lambda usando .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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Consumir um evento do SNS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Consumir um evento do SNS com o Lambda usando 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)**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório de [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/blob/main/integration-sns-to-lambda). 
Consumir um evento do SNS com o Lambda usando 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;
  }
}
```
Consumir um evento do SNS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Consumir um evento do SNS com o Lambda usando 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).**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Consumir um evento do SNS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Consumir um evento do SNS com o Lambda usando 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**  
 Há mais no GitHub. Encontre o exemplo completo e saiba como configurar e executar no repositório dos [Exemplos sem servidor](https://github.com/aws-samples/serverless-snippets/tree/main/integration-sns-to-lambda). 
Consuma um evento do SNS com o Lambda usando 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
}
```

------

**Para criar a função**

1. Crie um diretório para o projeto e depois mude para esse diretório.

   ```
   mkdir sns-tutorial
   cd sns-tutorial
   ```

1. Copie o código JavaScript de amostra em um novo arquivo denominado `index.js`.

1. Crie um pacote de implantação usando o comando `zip` a seguir.

   ```
   zip function.zip index.js
   ```

1. Execute o comando da AWS CLI a seguir para criar sua função do Lambda na **conta 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
   ```

   Você deve ver saída semelhante ao seguinte:

   ```
   {
       "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. O nome do recurso da Amazon (ARN) da sua função. Você precisará dele posteriormente no tutorial ao adicionar permissões para permitir que o Amazon SNS invoque sua função.

## Adicionar permissões à função (conta B)
<a name="with-sns-create-function-permissions"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_4.png)


Para que o Amazon SNS invoque a sua função, você precisa conceder permissão em uma declaração de uma [política baseada em recursos](access-control-resource-based.md). Você adiciona essa declaração usando o comando `add-permission` da AWS CLI.

**Para conceder permissão ao Amazon SNS para invocar sua função**
+ Na **conta B**, execute o seguinte comando da AWS CLI usando o ARN para o tópico do Amazon SNS que você gravou 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
  ```

  Você deve ver saída semelhante ao seguinte:

  ```
  {
      "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**  
Se a conta com o tópico do Amazon SNS estiver hospedada em uma [Região da AWS de aceitação](https://docs.aws.amazon.com/accounts/latest/reference/manage-acct-regions.html), será necessário especificar a região na entidade principal. Por exemplo, se você estiver trabalhando com um tópico do Amazon SNS na região Ásia-Pacífico (Hong Kong), será necessário especificar `sns.ap-east-1.amazonaws.com` em vez de `sns.amazonaws.com` para a entidade principal. 

## Conceder permissão entre contas para assinatura do Amazon SNS (conta A)
<a name="with-sns-subscription-grant-permission"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_5.png)


Para que a sua função do Lambda na **conta B** assine o tópico do Amazon SNS criado na **conta A**, você precisa conceder permissão para que a **conta B** assine seu tópico. Você concede essa permissão usando o comando `add-permission` da AWS CLI. 

**Para conceder permissão para a conta B assinar o tópico**
+ Na **conta A**, execute o comando da AWS CLI a seguir. Use o ARN para o tópico do Amazon SNS que você gravou 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
  ```

## Criar uma assinatura (conta B)
<a name="with-sns-create-subscription"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_6.png)


Na **conta B**, agora você assina a sua função do Lambda no tópico do Amazon SNS criado no início do tutorial na **conta A**. Quando uma mensagem é enviada para esse tópico (`sns-topic-for-lambda`), o Amazon SNS invoca sua função do Lambda `Function-With-SNS` na **conta B**. 

**Criar uma assinatura**
+ Na **conta B**, execute o comando da AWS CLI a seguir. Use sua região padrão na qual você criou seu tópico e os ARNs para seu tópico e função do 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
  ```

  Você deve ver saída semelhante ao seguinte:

  ```
  {
      "SubscriptionArn": "arn:aws:sns:us-east-1:<AccountA_ID>:sns-topic-for-lambda:5d906xxxx-7c8x-45dx-a9dx-0484e31c98xx"
  }
  ```

## Publicar mensagens no tópico (conta A e conta B)
<a name="with-sns-publish-message"></a>

![\[\]](http://docs.aws.amazon.com/pt_br/lambda/latest/dg/images/services-sns-tutorial/sns_tut_steps_7.png)


Agora que a sua função do Lambda na **conta B** está assinada em seu tópico do Amazon SNS na **conta A**, é hora de testar sua configuração publicando mensagens em seu tópico. Para confirmar se o Amazon SNS invocou sua função do Lambda, use o CloudWatch Logs para visualizar a saída da função.

**Para publicar uma mensagem em seu tópico e ver a saída da sua função**

1. Insira `Hello World` em um arquivo de texto e salve-o como `message.txt`.

1. No mesmo diretório em que você salvou seu arquivo de texto, execute o comando da AWS CLI a seguir na **conta A**. Use o ARN para seu próprio tópico.

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

   Isso retornará um ID de mensagem com um identificador exclusivo, indicando que a mensagem foi aceita pelo Amazon SNS. Depois, o Amazon SNS tenta enviar a mensagem aos assinantes do tópico. Para confirmar se o Amazon SNS invocou sua função do Lambda, use o CloudWatch Logs para visualizar a saída da função:

1. Na **conta B**, abra a página [Grupos de logs](https://console.aws.amazon.com/cloudwatch/home#logsV2:log-groups) do console do Amazon CloudWatch.

1. Escolha o nome do grupo de logs para sua função (`/aws/lambda/Function-With-SNS`).

1. Escolha o stream de logs mais recente.

1. Se sua função foi invocada corretamente, você verá uma saída semelhante à seguinte, mostrando o conteúdo da mensagem que você publicou no seu tópico.

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

## Limpe os recursos
<a name="cleanup"></a>

Agora você pode excluir os recursos criados para este tutorial, a menos que queira mantê-los. Excluindo os recursos da AWS que você não está mais usando, você evita cobranças desnecessárias em sua Conta da AWS.

Em **Account A** (Conta A), limpe o tópico do Amazon SNS.

**Para excluir o tópico do Amazon SNS**

1. Abra a [página Topics](https://console.aws.amazon.com//sns/home#topics:) (Tópicos) no console do Amazon SNS.

1. Selecione o tópico que você criou.

1. Escolha **Excluir**.

1. Digite **delete me** no campo de entrada de texto.

1. Escolha **Excluir**.

Em **Account B** (Conta B), limpe sua função de execução, a função Lambda e a assinatura do Amazon SNS.

**Para excluir a função de execução**

1. Abra a página [Roles](https://console.aws.amazon.com/iam/home#/roles) (Funções) no console do IAM.

1. Selecione a função de execução que você criou.

1. Escolha **Excluir**.

1. Insira o nome do perfil no campo de entrada de texto e escolha **Delete** (Excluir).

**Como excluir a função do Lambda**

1. Abra a página [Functions](https://console.aws.amazon.com/lambda/home#/functions) (Funções) no console do Lambda.

1. Selecione a função que você criou.

1. Selecione **Ações**, **Excluir**.

1. Digite **confirm** no campo de entrada de texto e escolha **Delete** (Excluir).

**Para excluir a inscrição do Amazon SNS**

1. Abrir o[Página Assinaturas](https://console.aws.amazon.com//sns/home#subscriptions:)No console do Amazon SNS.

1. Selecione a assinatura que você criou.

1. Escolha **Delete** (Excluir), **Yes, Delete** (Sim, excluir).