

# 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)

------