

# Usar o Lambda com a infraestrutura como código (IaC)
<a name="foundation-iac"></a>

As funções do Lambda raramente são executadas de forma isolada. Em vez disso, elas fazem parte de uma aplicação sem servidor com outros recursos, como bancos de dados, filas e armazenamento. Com a [infraestrutura como código (IaC)](https://aws.amazon.com/what-is/iac/), você pode automatizar os processos de implantação para implantar e atualizar de forma rápida e repetitiva aplicações inteiras sem servidor envolvendo vários recursos da AWS separados. Essa abordagem agiliza o ciclo de desenvolvimento, torna o gerenciamento de configurações mais fácil e garante que seus recursos sejam implantados sempre da mesma forma.

## Ferramentas de IaC para o Lambda
<a name="foundation-iac-tools"></a>

**CloudFormation**  
O CloudFormation é o serviço básico de IaC da AWS. Você pode usar [modelos YAML ou JSON](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-guide.html) para modelar e provisionar toda a sua infraestrutura da AWS, incluindo funções do Lambda. O CloudFormation lida com as complexidades de criar, atualizar e excluir os recursos da AWS.

**AWS Serverless Application Model (AWS SAM)**  
O AWS SAM é um framework de código aberto baseado no CloudFormation. Ele fornece uma sintaxe simplificada para definir aplicações sem servidor. Use [modelos do AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy.html) para provisionar rapidamente APIs, bancos de dados, origens de eventos e funções do Lambda com apenas algumas linhas de YAML.

**AWS Cloud Development Kit (AWS CDK)**  
O CDK é uma abordagem de Code First para o IaC. Você pode definir a arquitetura baseada no Lambda usando TypeScript, JavaScript, Python, Java, C\$1/.Net ou Go. Escolha sua linguagem preferencial e use elementos de programação como parâmetros, condicionais, loops, composição e herança para definir o resultado desejado da infraestrutura. O CDK então gera os modelos subjacentes do CloudFormation para implantação. Para obter um exemplo de como usar o Lambda com o CDK, consulte [Implantar funções do Lambda com o AWS CDK](lambda-cdk-tutorial.md).

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


A AWS também fornece um serviço denominado AWS Infrastructure Composer para desenvolver modelos de IaC usando uma interface gráfica simples. Com o Infrastructure Composer, você projeta uma arquitetura de aplicação arrastando, agrupando e conectando os Serviços da AWS em uma tela visual. O Infrastructure Composer então cria um modelo do AWS SAM ou do CloudFormation com base no seu design que você pode usar para implantar aplicações.

Na seção [Use as funções do Lambda no AWS SAM e no Compositor de Infraestrutura](foundation-iac-getting-started.md) abaixo, o Infrastructure Composer é usado para desenvolver um modelo para uma aplicação sem servidor baseada em uma função do Lambda existente.

# Use as funções do Lambda no AWS SAM e no Compositor de Infraestrutura
<a name="foundation-iac-getting-started"></a>

Neste tutorial, você pode começar a usar a IaC com o Lambda criando um modelo do AWS SAM com base em uma função do Lambda existente e, em seguida, desenvolvendo uma aplicação sem servidor no Infrastructure Composer adicionando outros recursos da AWS.

Ao realizar este tutorial, você aprenderá alguns conceitos fundamentais, como a forma que os recursos da AWS são especificados no AWS SAM. Você também aprenderá a usar o Infrastructure Composer para desenvolver uma aplicação sem servidor que você pode implantar usando o AWS SAM ou o CloudFormation.

Para concluir o tutorial, você executará as seguintes tarefas:
+ Criar exemplo de função do Lambda
+ Usar o console do Lambda para visualizar o modelo do AWS SAM para a função
+ Exportar a configuração da função para o AWS Infrastructure Composer e criar uma aplicação simples sem servidor com base na configuração da função
+ Salvar um modelo do AWS SAM atualizado que você possa usar como base para implantar sua aplicação sem servidor

## Pré-requisitos
<a name="foundation-iac-prerequisites"></a>

Neste tutorial, o recurso de [sincronização local](https://docs.aws.amazon.com/application-composer/latest/dg/reference-features-local-sync.html) do Infrastructure Composer é usado para salvar os arquivos de modelo e código na sua máquina de compilação local. Para usar esse recurso, você precisa de um navegador compatível com a API File System Access, que permite a uma aplicação da Web ler, gravar e salvar arquivos no sistema de arquivos local. Recomendamos usar o Google Chrome ou o Microsoft Edge. Para obter mais informações sobre a API File System Access, consulte [What is the File System Access API?](https://docs.aws.amazon.com/application-composer/latest/dg/reference-fsa.html#reference-fsa-api)

## Criar uma função do Lambda
<a name="foundation-iac-create-function"></a>

Nessa primeira etapa, você criará uma função do Lambda que poderá ser usada para concluir o restante do tutorial. Para simplificar, use o console do Lambda para criar uma função básica “Hello world” com o runtime do Python 3.11.

**Para criar uma função do Lambda “Hello world” com o console:**

1. Abra o [console do lambda](https://console.aws.amazon.com/lambda).

1. Escolha a opção **Criar função**.

1. Deixe a opção **Criar do zero** selecionada e, em **Informações básicas**, insira **LambdaIaCDemo** em **Nome da função**.

1. Em **Runtime**, escolha **Python 3.11**.

1. Escolha a opção **Criar função**.

## Ver o modelo do AWS SAM da sua função
<a name="foundation-iac-view-template"></a>

Antes de exportar a configuração da função para o Infrastructure Composer, use o console do Lambda para ver a configuração atual da função como um modelo do AWS SAM. Seguindo as etapas desta seção, você aprenderá sobre a anatomia de um modelo do AWS SAM e como definir recursos, como funções do Lambda, para começar a especificar uma aplicação sem servidor.

**Ver o modelo do AWS SAM da função**

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

1. Escolha a função que você acabou de criar (`LambdaIaCDemo`).

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

   No lugar do diagrama que representa a configuração da sua função, você verá um modelo do AWS SAM para sua função. O modelo será algo assim:

   ```
   # This AWS SAM template has been generated from your function's 
   # configuration. If your function has one or more triggers, note 
   # that the AWS resources associated with these triggers aren't fully 
   # specified in this template and include placeholder values.Open this template 
   # in AWS Application Composer or your favorite IDE and modify 
   # it to specify a serverless application with other AWS resources. 
   AWSTemplateFormatVersion: '2010-09-09'
   Transform: AWS::Serverless-2016-10-31
   Description: An AWS Serverless Specification template describing your function.
   Resources:
     LambdaIaCDemo:
       Type: AWS::Serverless::Function
       Properties:
         CodeUri: .
         Description: ''
         MemorySize: 128
         Timeout: 3
         Handler: lambda_function.lambda_handler
         Runtime: python3.11
         Architectures:
           - x86_64
         EventInvokeConfig:
           MaximumEventAgeInSeconds: 21600
           MaximumRetryAttempts: 2
         EphemeralStorage:
           Size: 512
         RuntimeManagementConfig:
           UpdateRuntimeOn: Auto
         SnapStart:
           ApplyOn: None
         PackageType: Zip
         Policies:
           Statement:
             - Effect: Allow
               Action:
                 - logs:CreateLogGroup
               Resource: arn:aws:logs:us-east-1:123456789012:*
             - Effect: Allow
               Action:
                 - logs:CreateLogStream
                 - logs:PutLogEvents
               Resource:
                 - >-
                   arn:aws:logs:us-east-1:123456789012:log-group:/aws/lambda/LambdaIaCDemo:*
   ```

Vamos analisar o modelo YAML da sua função e entender alguns conceitos-chave.

O modelo começa com a declaração `Transform: AWS::Serverless-2016-10-31`. Ela é necessária porque os modelos do AWS SAM são implantados em segundo plano por meio do CloudFormation. A declaração `Transform` identifica o modelo como um arquivo de modelo do AWS SAM.

Após a declaração `Transform`, temos a seção `Resources`. Nela, são definidos os recursos da AWS que você deseja implantar com o modelo do AWS SAM. Os modelos do AWS SAM podem conter uma combinação de recursos do AWS SAM e do CloudFormation. Isso ocorre porque, durante a implantação, os modelos do AWS SAM se expandem para modelos do CloudFormation; portanto, qualquer sintaxe válida do CloudFormation pode ser adicionada a um modelo do AWS SAM.

No momento, só há um recurso definido na seção `Resources` do modelo, sua função do Lambda `LambdaIaCDemo`. Para adicionar uma função do Lambda a um modelo do AWS SAM, use o tipo de recurso `AWS::Serverless::Function`. O recurso `Properties` de uma função do Lambda define o runtime da função, o manipulador da função e outras opções de configuração. O caminho para o código-fonte da função que o AWS SAM deve usar para implantar a função também é definido aqui. Para saber mais sobre os recursos da função do Lambda no AWS SAM, consulte [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html) no *Guia do desenvolvedor do AWS SAM*.

Além das propriedades e configurações da função, o modelo também especifica uma política do AWS Identity and Access Management (IAM) para a função. Essa política concede permissão à função para gravar logs no Amazon CloudWatch Logs. Quando você cria uma função no console do Lambda, ele anexa automaticamente essa política à sua função. Para saber mais sobre como especificar uma política do IAM para uma função em um modelo do AWS SAM, consulte a propriedade `policies` na página [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html) do *Guia do desenvolvedor do AWS SAM*.

Para saber mais sobre a estrutura de modelos do AWS SAM, consulte [AWS SAM template anatomy](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy.html).

## Usar o AWS Infrastructure Composer para criar uma aplicação sem servidor
<a name="foundation-iac-design-app"></a>

Para começar a desenvolver uma aplicação simples sem servidor usando o modelo do AWS SAM da função como ponto de partida, exporte a configuração da função para o Infrastructure Composer e ative o modo de sincronização local dele. A sincronização local salva automaticamente o código da função e o modelo do AWS SAM na máquina de compilação local e mantém o modelo salvo sincronizado à medida que você adiciona outros recursos da AWS ao Infrastructure Composer.

**Para exportar a função para o Infrastructure Composer**

1. No painel **Visão geral da função**, escolha **Exportar para o Application 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).

   Ao selecionar **Confirmar e criar projeto**, o console do Infrastructure Composer é aberto. Na *tela*, você verá sua função do Lambda.

1. No **Menu** suspenso, escolha **Ativar sincronização local**.

1. Na caixa de diálogo exibida, escolha **Selecionar pasta** e selecione uma pasta na sua máquina de compilação local.

1. Escolha **Ativar** para ativar a sincronização local.

Para exportar a função para o Infrastructure Composer, você precisa de permissão para usar determinadas ações de API. Se não conseguir exportar sua função, consulte [Permissões obrigatórias](services-appcomposer.md#services-appcomposer-permissions) e verifique se você tem as permissões necessárias.

**nota**  
O [preço padrão do Amazon S3](https://aws.amazon.com/s3/pricing) se aplica ao bucket criado pelo Lambda quando você exporta uma função para o Infrastructure Composer. Os objetos que o Lambda coloca no bucket são excluídos automaticamente após dez dias, mas o Lambda não exclui o bucket em si.  
Para evitar que cobranças adicionais sejam adicionadas à sua Conta da AWS, siga as instruções em [Excluir um bucket](https://docs.aws.amazon.com/AmazonS3/latest/userguide/delete-bucket.html) depois de exportar a função para o Infrastructure Composer. Para obter mais informações sobre o bucket do Amazon S3 criado pelo Lambda, consulte [Usar o AWS Lambda com o AWS Infrastructure Composer](services-appcomposer.md).

**Para projetar a aplicação sem servidor no Infrastructure Composer**

Depois de ativar a sincronização local, as alterações feitas no Infrastructure Composer serão refletidas no modelo do AWS SAM salvo na sua máquina de compilação local. Agora você pode arrastar e soltar recursos adicionais da AWS na tela do Infrastructure Composer para criar a aplicação. Neste exemplo, você adiciona uma fila simples do Amazon SQS como gatilho para sua função do Lambda e uma tabela do DynamoDB na qual a função gravará os dados.

1. Para adicionar um gatilho do Amazon SQS à função do Lambda, faça o seguinte:

   1. No campo de pesquisa na paleta **Recursos**, insira **SQS**.

   1. Arraste o recurso **Fila do SQS** para sua tela e posicione-o à esquerda da função do Lambda.

   1. Escolha **Detalhes** e, em **ID lógico**, insira **LambdaIaCQueue**.

   1. Escolha **Salvar**.

   1. Conecte seus recursos do Amazon SQS e do Lambda clicando na porta **Assinatura** no cartão de fila do SQS e arrastando-a para a porta à esquerda no cartão da função do Lambda. Se aparecer uma linha entre os dois recursos, é sinal de que a conexão teve êxito. O Infrastructure Composer também exibe uma mensagem na parte inferior da tela indicando que os dois recursos foram conectados com êxito.

1. Para adicionar uma tabela do Amazon DynamoDB na qual a função do Lambda gravará os dados, faça o seguinte:

   1. No campo de pesquisa na paleta **Recursos**, insira **DynamoDB**.

   1. Arraste o recurso **Tabela do DynamoDB** para sua tela e posicione-o à direita da função do Lambda.

   1. Escolha **Detalhes** e, em **ID lógico**, insira **LambdaIaCTable**.

   1. Escolha **Salvar**.

   1. Conecte a tabela do DynamoDB à sua função do Lambda clicando na porta à direita do cartão da função do Lambda e arrastando-a até a porta à esquerda do cartão do DynamoDB. 

Agora que esses recursos extras foram adicionados, vamos dar uma olhada no modelo do AWS SAM atualizado que foi criado pelo Infrastructure Composer.

**Ver o modelo do AWS SAM atualizado**
+ Na tela do Infrastructure Composer, escolha **Modelo** para alternar da visualização da tela para a visualização do modelo.

Agora, seu modelo do AWS SAM deve conter os seguintes recursos e propriedades adicionais:
+ Uma fila do Amazon SQS com o identificador `LambdaIaCQueue`

  ```
  LambdaIaCQueue:
      Type: AWS::SQS::Queue
      Properties:
        MessageRetentionPeriod: 345600
  ```

  Quando você adiciona uma fila do Amazon SQS usando o Infrastructure Composer, ele define a propriedade `MessageRetentionPeriod`. Você também pode definir a propriedade `FifoQueue` selecionando **Detalhes** no cartão da fila do SQS e marcando ou desmarcando **Fila FIFO**.

  Para definir outras propriedades para sua fila, você pode adicioná-las manualmente ao modelo. Para saber mais sobre o recurso `AWS::SQS::Queue` e suas propriedades disponíveis, consulte [AWS::SQS::Queue](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html) no *Guia do usuário do CloudFormation*.
+ Uma propriedade `Events` na definição da função do Lambda que especifica a fila do Amazon SQS usada como gatilho para a função.

  ```
  Events:
    LambdaIaCQueue:
      Type: SQS
      Properties:
        Queue: !GetAtt LambdaIaCQueue.Arn
        BatchSize: 1
  ```

  A propriedade `Events` consiste em um tipo de evento e um conjunto de propriedades que dependem desse tipo. Para saber mais sobre os diferentes Serviços da AWS que você pode configurar para acionar uma função do Lambda e as propriedades que podem ser definidas, consulte [EventSource](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-function-eventsource.html) no *Guia do Desenvolvedor do AWS SAM*.
+ Uma tabela do DynamoDB com o identificador `LambdaIaCTable`

  ```
  LambdaIaCTable:
      Type: AWS::DynamoDB::Table
      Properties:
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
        BillingMode: PAY_PER_REQUEST
        KeySchema:
          - AttributeName: id
            KeyType: HASH
        StreamSpecification:
          StreamViewType: NEW_AND_OLD_IMAGES
  ```

  Ao adicionar uma tabela do DynamoDB usando o Infrastructure Composer, você pode definir as chaves da tabela escolhendo **Detalhes** no cartão da tabela do DynamoDB e editando os valores das chaves. O Infrastructure Composer também define valores padrão para várias outras propriedades, incluindo `BillingMode` e `StreamViewType`.

  Para saber mais sobre essas propriedades e outras que você pode adicionar ao modelo do AWS SAM, consulte [AWS::DynamoDB::Table](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html) no *Guia do usuário do CloudFormation*.
+ Uma nova política do IAM que dá permissão à sua função para realizar operações CRUD na tabela do DynamoDB que você adicionou.

  ```
  Policies:
  ...
    - DynamoDBCrudPolicy:
      TableName: !Ref LambdaIaCTable
  ```

O modelo completo do AWS SAM resultante será algo assim:

```
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: An AWS Serverless Specification template describing your function.
Resources:
  LambdaIaCDemo:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: .
      Description: ''
      MemorySize: 128
      Timeout: 3
      Handler: lambda_function.lambda_handler
      Runtime: python3.11
      Architectures:
        - x86_64
      EventInvokeConfig:
        MaximumEventAgeInSeconds: 21600
        MaximumRetryAttempts: 2
      EphemeralStorage:
        Size: 512
      RuntimeManagementConfig:
        UpdateRuntimeOn: Auto
      SnapStart:
        ApplyOn: None
      PackageType: Zip
      Policies:
        - Statement:
            - Effect: Allow
              Action:
                - logs:CreateLogGroup
              Resource: arn:aws:logs:us-east-1:594035263019:*
            - Effect: Allow
              Action:
                - logs:CreateLogStream
                - logs:PutLogEvents
              Resource:
                - arn:aws:logs:us-east-1:594035263019:log-group:/aws/lambda/LambdaIaCDemo:*
        - DynamoDBCrudPolicy:
            TableName: !Ref LambdaIaCTable
      Events:
        LambdaIaCQueue:
          Type: SQS
          Properties:
            Queue: !GetAtt LambdaIaCQueue.Arn
            BatchSize: 1
      Environment:
        Variables:
          LAMBDAIACTABLE_TABLE_NAME: !Ref LambdaIaCTable
          LAMBDAIACTABLE_TABLE_ARN: !GetAtt LambdaIaCTable.Arn
  LambdaIaCQueue:
    Type: AWS::SQS::Queue
    Properties:
      MessageRetentionPeriod: 345600
  LambdaIaCTable:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      BillingMode: PAY_PER_REQUEST
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      StreamSpecification:
        StreamViewType: NEW_AND_OLD_IMAGES
```

## Implantar a aplicação sem servidor usando o AWS SAM (opcional)
<a name="foundation-iac-deploy"></a>

Se você quiser usar o AWS SAM para implantar uma aplicação sem servidor usando o modelo que acabou de criar no Infrastructure Composer, é necessário primeiro instalar a CLI do AWS SAM. Para isso, siga as instruções em [Installing the AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html).

Antes de implantar a aplicação, você também precisa atualizar o código da função que o Infrastructure Composer salvou junto com o modelo. No momento, o arquivo `lambda_function.py` que o Infrastructure Composer salvou contém somente o código básico “Hello world” que o Lambda forneceu quando você criou a função. 

Para atualizar o código da função, copie o código a seguir e cole-o no arquivo `lambda_function.py` que o Infrastructure Composer salvou na máquina de compilação local. Você especificou o diretório no qual o Infrastructure Composer deve salvar esse arquivo quando ativou o modo de sincronização local.

Esse código aceita um par de chave-valor em uma mensagem da fila do Amazon SQS que você criou no Infrastructure Composer. Se a chave e o valor forem strings, o código as usará para gravar um item na tabela do DynamoDB definida no modelo.

### Código da função do Python atualizado
<a name="foundation-iac-updated-code"></a>

```
import boto3
import os
import json

# define the DynamoDB table that Lambda will connect to
tablename = os.environ['LAMBDAIACTABLE_TABLE_NAME']

# create the DynamoDB resource
dynamo = boto3.client('dynamodb')

def lambda_handler(event, context):
    # get the message out of the SQS event
    message = event['Records'][0]['body']
    data = json.loads(message)
    # write event data to DDB table
    if check_message_format(data):
        key = next(iter(data))
        value = data[key]
        dynamo.put_item(
            TableName=tablename,
            Item={
                'id': {'S': key},
                'Value': {'S': value}
            }
        )
    else:
        raise ValueError("Input data not in the correct format")

# check that the event object contains a single key value  
# pair that can be written to the database
def check_message_format(message):
    if len(message) != 1:
        return False
        
    key, value = next(iter(message.items()))
    
    if not (isinstance(key, str) and isinstance(value, str)):
        return False

    else:
        return True
```

**Implantar a aplicação sem servidor**

Para implantar sua aplicação usando a CLI do AWS SAM, execute as etapas a seguir. Para que sua função seja compilada e implantada corretamente, a versão 3.11 do Python deve estar instalada na máquina de compilação e no `PATH`.

1. Execute o comando a seguir do diretório no qual o Infrastructure Composer salvou os arquivos `template.yaml` e `lambda_function.py`.

   ```
   sam build
   ```

   Esse comando reúne os artefatos de compilação da aplicação e os coloca no formato e no local adequados para implantá-los.

1. Para implantar a aplicação e criar os recursos do Lambda, do Amazon SQS e do DynamoDB especificados no modelo do AWS SAM, execute o comando a seguir.

   ```
   sam deploy --guided
   ```

   Usar o sinalizador `--guided` significa que o AWS SAM mostrará instruções para guiar você no processo de implantação. Para a implantação, aceite as opções padrão pressionando Enter.

Durante o processo de implantação, o AWS SAM cria os seguintes recursos na sua Conta da AWS:
+ Uma [pilha](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-whatis-concepts.html#cfn-concepts-stacks) do CloudFormation chamada `sam-app`
+ Uma função do Lambda com o formato de nome `sam-app-LambdaIaCDemo-99VXPpYQVv1M`
+ Uma fila do Amazon SQS com o formato do nome `sam-app-LambdaIaCQueue-xL87VeKsGiIo`
+ Uma tabela do DynamoDB com o formato do nome `sam-app-LambdaIaCTable-CN0S66C0VLNV`

O AWS SAM também cria as funções e as políticas do IAM necessárias para que a função do Lambda possa ler mensagens da fila do Amazon SQS e realizar operações CRUD na tabela do DynamoDB.

## Testar a aplicação implantada (opcional)
<a name="foundation-iac-test"></a>

Para confirmar que a aplicação sem servidor foi implantada corretamente, envie uma mensagem para a fila do Amazon SQS que contenha um par de valores-chave e verifique se o Lambda grava um item na tabela do DynamoDB usando esses valores.

**Testar a aplicação sem servidor**

1. Abra a página [Filas](https://console.aws.amazon.com/sqs/v2/home#/queues) do console do Amazon SQS e selecione a fila que o AWS SAM criou com base no modelo. O nome tem o formato `sam-app-LambdaIaCQueue-xL87VeKsGiIo`.

1. Selecione **Enviar e receber mensagens** e cole o JSON a seguir no **Corpo da mensagem** na seção **Enviar mensagem**.

   ```
   {
       "myKey": "myValue"
   }
   ```

1. Escolha **Send Message (Enviar mensagem)**.

   Enviar a mensagem para a fila fará com que o Lambda invoque sua função por meio do mapeamento da origem do evento definido no modelo do AWS SAM. Para confirmar que o Lambda invocou sua função conforme o esperado, verifique se um item foi adicionado à tabela do DynamoDB.

1. Abra a página [Tabelas](https://console.aws.amazon.com/dynamodbv2#tables) do console do DynamoDB e selecione sua tabela. O nome tem o formato `sam-app-LambdaIaCTable-CN0S66C0VLNV`.

1. Escolha **Explore table items** (Explorar itens da tabela). No painel **Itens retornados**, você verá um item com o **id** `myKey` e o **Valor** `myValue`.

# Implantar funções do Lambda com o AWS CDK
<a name="lambda-cdk-tutorial"></a>

O AWS Cloud Development Kit (AWS CDK) é um framework de infraestrutura como código (IAC) que pode ser usado para definir a infraestrutura da Nuvem AWS usando uma linguagem de programação da sua escolha. Para definir sua própria infraestrutura de nuvem, primeiro é necessário criar uma aplicação (em uma das linguagens aceitas pelo CDK) que contenha uma ou mais pilhas. Em seguida, sintetize-a em um modelo do CloudFormation e implante seus recursos na Conta da AWS. Siga as etapas neste tópico para implantar uma função do Lambda que retorna um evento de um endpoint do Amazon API Gateway.

A AWS Construct Library, incluída no CDK, fornece módulos que podem ser usados para modelar os recursos fornecidos por cada serviço da Serviços da AWS. Para serviços populares, a biblioteca fornece construções selecionadas com padrões inteligentes e práticas recomendadas. Você pode usar o módulo [aws\$1lambda](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html) para definir a função e os recursos compatíveis com apenas algumas linhas de código. 

## Pré-requisitos
<a name="lambda-cdk-prerequisites"></a>

Antes de começar este tutorial, instale o AWS CDK executando o comando a seguir.

```
npm install -g aws-cdk
```

## Etapa 1: configurar o projeto do AWS CDK
<a name="lambda-cdk-step-1"></a>

Crie um diretório para a nova aplicação do AWS CDK e inicialize o projeto.

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

```
mkdir hello-lambda
cd hello-lambda
cdk init --language javascript
```

------
#### [ TypeScript ]

```
mkdir hello-lambda
cd hello-lambda
cdk init --language typescript
```

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

```
mkdir hello-lambda
cd hello-lambda
cdk init --language python
```

Depois que o projeto for iniciado, ative o ambiente virtual dele e instale as dependências de linha de base do AWS CDK.

```
source .venv/bin/activate
python -m pip install -r requirements.txt
```

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

```
mkdir hello-lambda
cd hello-lambda
cdk init --language java
```

Importe esse projeto do Maven para o ambiente de desenvolvimento integrado (IDE) do Java. Por exemplo, no Eclipse, escolha **Arquivo**, **Importar**, **Maven**, **Projetos existentes do Maven**.

------
#### [ C\$1 ]

```
mkdir hello-lambda
cd hello-lambda
cdk init --language csharp
```

------

**nota**  
O modelo de aplicação do AWS CDK usa o nome do diretório do projeto para gerar nomes para arquivos e classes de origem. Neste exemplo, o diretório se chama `hello-lambda`. Se você escolher outro nome de diretório de projeto, sua aplicação não corresponderá a estas instruções.

O AWS CDK v2 inclui construções estáveis para todos os Serviços da AWS em um único pacote chamado `aws-cdk-lib`. Esse pacote é instalado como uma dependência quando o projeto é inicializado. Quando determinadas linguagens de programação são usadas, o pacote é instalado quando o projeto é compilado pela primeira vez.

## Etapa 2: definir a pilha do AWS CDK
<a name="lambda-cdk-step-2"></a>

Uma *pilha* do CDK é uma coleção de um ou mais constructos que definem os recursos AWS. Cada pilha do CDK representa uma pilha do CloudFormation na aplicação do CDK.

Para definir a pilha CDK, siga as instruções da linguagem de programação de sua preferência. Esta pilha define o seguinte:
+ O nome lógico da função: `MyFunction`
+ O local do código da função, especificado na propriedade `code`. Para obter mais informações, consulte [Handler code](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda-readme.html#handler-code) na *referência de APIs do AWS Cloud Development Kit (AWS CDK)*.
+ O nome lógico da API REST: `HelloApi`
+ O nome lógico do endpoint do API Gateway: `ApiGwEndpoint`

Observe que todas as pilhas do CDK neste tutorial usam o [runtime](lambda-runtimes.md) Node.js para a função do Lambda. Você pode usar diferentes linguagens de programação para a pilha do CDK e a função do Lambda para aproveitar os pontos fortes de cada linguagem. Por exemplo, você pode usar o TypeScript para a pilha do CDK para aproveitar os benefícios da tipagem estática para seu código de infraestrutura. Você pode usar o JavaScript para a função do Lambda para aproveitar a flexibilidade e o rápido desenvolvimento de uma linguagem de tipagem dinâmica.

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

Abra o arquivo `lib/hello-lambda-stack.js` e substitua o conteúdo pelo seguinte.

```
const { Stack } = require('aws-cdk-lib');
const lambda = require('aws-cdk-lib/aws-lambda');
const apigw = require('aws-cdk-lib/aws-apigateway');

class HelloLambdaStack extends Stack {
  /**
   *
   * @param {Construct} scope
   * @param {string} id
   * @param {StackProps=} props
   */
  constructor(scope, id, props) {
    super(scope, id, props);
    const fn = new lambda.Function(this, 'MyFunction', {
      code: lambda.Code.fromAsset('lib/lambda-handler'),
      runtime: lambda.Runtime.NODEJS_LATEST,
      handler: 'index.handler'
    });

    const endpoint = new apigw.LambdaRestApi(this, 'MyEndpoint', {
      handler: fn,
      restApiName: "HelloApi"
    });

  }
}

module.exports = { HelloLambdaStack }
```

------
#### [ TypeScript ]

Abra o arquivo `lib/hello-lambda-stack.ts` e substitua o conteúdo pelo seguinte.

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as apigw from "aws-cdk-lib/aws-apigateway";
import * as lambda from "aws-cdk-lib/aws-lambda";
import * as path from 'node:path';

export class HelloLambdaStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps){
    super(scope, id, props)
    const fn = new lambda.Function(this, 'MyFunction', {
      runtime: lambda.Runtime.NODEJS_LATEST,
      handler: 'index.handler',
      code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')),
    });

    const endpoint = new apigw.LambdaRestApi(this, `ApiGwEndpoint`, {
      handler: fn,
      restApiName: `HelloApi`,
    });

  }
}
```

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

Abra o arquivo `/hello-lambda/hello_lambda/hello_lambda_stack.py` e substitua o conteúdo pelo seguinte.

```
from aws_cdk import (
    Stack,
    aws_apigateway as apigw,
    aws_lambda as _lambda
)
from constructs import Construct

class HelloLambdaStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        fn = _lambda.Function(
            self,
            "MyFunction",
            runtime=_lambda.Runtime.NODEJS_LATEST,
            handler="index.handler",
            code=_lambda.Code.from_asset("lib/lambda-handler")
        )

        endpoint = apigw.LambdaRestApi(
            self,
            "ApiGwEndpoint",
            handler=fn,
            rest_api_name="HelloApi"
        )
```

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

Abra o arquivo `/hello-lambda/src/main/java/com/myorg/HelloLambdaStack.java` e substitua o conteúdo pelo seguinte.

```
package com.myorg;

import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.services.apigateway.LambdaRestApi;
import software.amazon.awscdk.services.lambda.Function;

public class HelloLambdaStack extends Stack {
    public HelloLambdaStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public HelloLambdaStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Function hello = Function.Builder.create(this, "MyFunction")
                            .runtime(software.amazon.awscdk.services.lambda.Runtime.NODEJS_LATEST)
                            .code(software.amazon.awscdk.services.lambda.Code.fromAsset("lib/lambda-handler"))
                            .handler("index.handler")
                            .build();

        LambdaRestApi api = LambdaRestApi.Builder.create(this, "ApiGwEndpoint")
                                .restApiName("HelloApi")
                                .handler(hello)
                                .build();

    }
}
```

------
#### [ C\$1 ]

Abra o arquivo `src/HelloLambda/HelloLambdaStack.cs` e substitua o conteúdo pelo seguinte.

```
using Amazon.CDK;
using Amazon.CDK.AWS.APIGateway;
using Amazon.CDK.AWS.Lambda;
using Constructs;

namespace HelloLambda
{
    public class HelloLambdaStack : Stack
    {
        internal HelloLambdaStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            var fn = new Function(this, "MyFunction", new FunctionProps
            {
                Runtime = Runtime.NODEJS_LATEST,
                Code = Code.FromAsset("lib/lambda-handler"),
                Handler = "index.handler"
            });

            var api = new LambdaRestApi(this, "ApiGwEndpoint", new LambdaRestApiProps
            {
                Handler = fn
            });
        }
    }
}
```

------

## Etapa 3: criar o código da função do Lambda
<a name="lambda-cdk-step-3"></a>

1. Na raiz do seu projeto (`hello-lambda`), crie o diretório `/lib/lambda-handler` para o código da função do Lambda. Esse diretório é especificado na propriedade `code` da sua pilha do AWS CDK.

1. Crie um novo arquivo chamado `index.js` no diretório `/lib/lambda-handler`. Cole o seguinte código no arquivo. A função extrai propriedades específicas da solicitação da API e as retorna como uma resposta JSON.

   ```
   exports.handler = async (event) => {
     // Extract specific properties from the event object
     const { resource, path, httpMethod, headers, queryStringParameters, body } = event;
     const response = {
       resource,
       path,
       httpMethod,
       headers,
       queryStringParameters,
       body,
     };
     return {
       body: JSON.stringify(response, null, 2),
       statusCode: 200,
     };
   };
   ```

## Etapa 4: implantar a pilha do AWS CDK
<a name="lambda-cdk-step-4"></a>

1. Na raiz do seu projeto, execute o comando [cdk synth](https://docs.aws.amazon.com/cdk/v2/guide/ref-cli-cmd-synth.html):

   ```
   cdk synth
   ```

   Esse comando sintetiza um modelo do AWS CloudFormation da sua pilha do CDK. O modelo é um arquivo YAML com aproximadamente 400 linhas, semelhante ao exibido abaixo. 
**nota**  
Se você receber o erro a seguir, verifique se está na raiz do diretório do projeto.  

   ```
   --app is required either in command-line, in cdk.json or in ~/.cdk.json
   ```  
**Example Modelo do CloudFormation**  

   ```
   Resources:
     MyFunctionServiceRole3C357FF2:
       Type: AWS::IAM::Role
       Properties:
         AssumeRolePolicyDocument:
           Statement:
             - Action: sts:AssumeRole
               Effect: Allow
               Principal:
                 Service: lambda.amazonaws.com
           Version: "2012-10-17"		 	 	 
         ManagedPolicyArns:
           - Fn::Join:
               - ""
               - - "arn:"
                 - Ref: AWS::Partition
                 - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
       Metadata:
         aws:cdk:path: HelloLambdaStack/MyFunction/ServiceRole/Resource
     MyFunction1BAA52E7:
       Type: AWS::Lambda::Function
       Properties:
         Code:
           S3Bucket:
             Fn::Sub: cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}
           S3Key: ab1111111cd32708dc4b83e81a21c296d607ff2cdef00f1d7f48338782f92l3901.zip
         Handler: index.handler
         Role:
           Fn::GetAtt:
             - MyFunctionServiceRole3C357FF2
             - Arn
         Runtime: nodejs24.x
         ...
   ```

1. Execute o comando [cdk deploy](https://docs.aws.amazon.com/cdk/v2/guide/ref-cli-cmd-deploy.html):

   ```
   cdk deploy
   ```

   Aguarde enquanto os recursos são criados. A saída final inclui o URL do endpoint do API Gateway. Exemplo:

   ```
   Outputs:
   HelloLambdaStack.ApiGwEndpoint77F417B1 = https://abcd1234.execute-api.us-east-1.amazonaws.com/prod/
   ```

## Etapa 5: testar a função
<a name="lambda-cdk-step-5"></a>

Para invocar a função do Lambda, copie o endpoint do API Gateway e cole-o em um navegador da web ou execute um comando `curl`:

```
curl -s https://abcd1234.execute-api.us-east-1.amazonaws.com/prod/
```

A resposta é uma representação JSON das propriedades selecionadas do objeto de evento original, que contém informações sobre a solicitação feita ao endpoint do API Gateway. Exemplo:

```
{
  "resource": "/",
  "path": "/",
  "httpMethod": "GET",
  "headers": {
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
    "Accept-Encoding": "gzip, deflate, br, zstd",
    "Accept-Language": "en-US,en;q=0.9",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Desktop-Viewer": "true",
    "CloudFront-Is-Mobile-Viewer": "false",
    "CloudFront-Is-SmartTV-Viewer": "false",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Viewer-ASN": "16509",
    "CloudFront-Viewer-Country": "US",
    "Host": "abcd1234.execute-api.us-east-1.amazonaws.com",
     ...
```

## Etapa 6: limpar os recursos
<a name="lambda-cdk-step-6"></a>

O endpoint do API Gateway pode ser acessado publicamente. Para evitar cobranças inesperadas, execute o comando [cdk destroy](https://docs.aws.amazon.com/cdk/v2/guide/ref-cli-cmd-destroy.html) para excluir a pilha e todos os recursos associados.

```
cdk destroy
```

## Próximas etapas
<a name="lambda-cdk-next-steps"></a>

Para obter informações sobre como criar aplicações do AWS CDK em sua linguagem preferida, consulte:

------
#### [ TypeScript ]

[Trabalhar com o AWS CDK no TypeScript](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-typescript.html)

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

[Trabalhar com o AWS CDK no JavaScript](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-javascript.html)

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

[Trabalhar com o AWS CDK no Python](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-python.html)

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

[Trabalhar com o AWS CDK no Java](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-java.html)

------
#### [ C\$1 ]

[Trabalhar com o AWS CDK em C\$1](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-csharp.html)

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

[Working with the AWS CDK in Go](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-go.html)

------