

# Tutorial: criar um runtime personalizado
<a name="runtimes-walkthrough"></a>

Neste tutorial, você criará uma função do Lambda com um runtime personalizado. Você começa incluindo o runtime no pacote de implantação da função. Em seguida, você o migra para uma camada gerenciada de forma independente da função. Por fim, você compartilha a camada de runtime com o mundo atualizando sua política de permissões com base em recursos.

## Pré-requisitos
<a name="runtimes-walkthrough-prereqs"></a>

Este tutorial presume que você tenha algum conhecimento de operações básicas do Lambda e do console do Lambda. Caso ainda não tenha feito isso, siga as instruções em [Criar uma função do Lambda com o console](getting-started.md#getting-started-create-function) para criar sua primeira função do Lambda.

Para concluir as etapas apresentadas a seguir, é necessário ter a [versão 2 da AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). Os comandos e a saída esperada são mostrados em blocos separados:

```
aws --version
```

A seguinte saída deverá ser mostrada:

```
aws-cli/2.13.27 Python/3.11.6 Linux/4.14.328-248.540.amzn2.x86_64 exe/x86_64.amzn.2
```

Para comandos longos, um caractere de escape (`\`) é usado para dividir um comando em várias linhas.

No Linux e no macOS, use seu gerenciador preferido de pacotes e de shell.

**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). Os exemplos de comandos da CLI neste guia usam a formatação Linux. Os comandos que incluem documentos JSON em linha deverão ser reformatados se você estiver usando a CLI do Windows. 

Você precisa de uma função do IAM para criar uma função do Lambda. O perfil precisa de permissão para enviar logs ao CloudWatch Logs e acessar os Serviços da AWS que a função usa. Se você ainda não tiver uma função para o desenvolvimento de funções, crie uma agora.

**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 **Criar perfil**.

1. Crie uma função com as propriedades a seguir.
   + **Entidade confiável**–**Lambda**.
   + **Permissions** (Permissões): **AWSLambdaBasicExecutionRole**.
   + **Role name** (Nome da função): **lambda-role**.

   A política **AWSLambdaBasicExecutionRole** tem as permissões necessárias para a função gravar logs no CloudWatch Logs.

## Criar uma função
<a name="runtimes-walkthrough-function"></a>

Criar uma função do Lambda com um runtime personalizado. Este exemplo inclui dois arquivos: um arquivo `bootstrap` de runtime e um manipulador de funções. Ambos são implementados em Bash.

1. Crie um diretório para o projeto e depois mude para esse diretório.

   ```
   mkdir runtime-tutorial
   cd runtime-tutorial
   ```

1. Crie um novo arquivo chamado `bootstrap`. Esse é o runtime personalizado.  
**Example bootstrap**  

   ```
   #!/bin/sh
   
   set -euo pipefail
   
   # Initialization - load function handler
   source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
   
   # Processing
   while true
   do
     HEADERS="$(mktemp)"
     # Get an event. The HTTP request will block until one is received
     EVENT_DATA=$(curl -sS -LD "$HEADERS" "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
   
     # Extract request ID by scraping response headers received above
     REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
   
     # Run the handler function from the script
     RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
   
     # Send the response
     curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response"  -d "$RESPONSE"
   done
   ```

   O runtime carrega um script de função do pacote de implantação. Ele usa duas variáveis para localizar o script. `LAMBDA_TASK_ROOT` informa onde o pacote foi extraído e `_HANDLER` inclui o nome do script.

   Depois que o runtime carrega o script da função, ele usa a API de runtime para recuperar um evento de invocação do Lambda, transmite o evento para o manipulador e publica a resposta de volta no Lambda. Para obter o ID de solicitação, o runtime salva os cabeçalhos na resposta da API em um arquivo temporário e lê o cabeçalho `Lambda-Runtime-Aws-Request-Id` do arquivo.
**nota**  
Os runtimes têm responsabilidades adicionais, incluindo o processamento de erros e o fornecimento de informações de contexto para o manipulador. Para obter detalhes, consulte [Requisitos](runtimes-custom.md#runtimes-custom-build).

1. Crie um script para a função. O exemplo de script a seguir define uma função do manipulador que usa dados de eventos, os registra no log `stderr` e os retorna.  
**Example function.sh**  

   ```
   function handler () {
     EVENT_DATA=$1
     echo "$EVENT_DATA" 1>&2;
     RESPONSE="Echoing request: '$EVENT_DATA'"
   
     echo $RESPONSE
   }
   ```

   Agora, diretório `runtime-tutorial` será desta forma:

   ```
   runtime-tutorial
   ├ bootstrap
   └ function.sh
   ```

1. Torne os arquivos executáveis e os adicione a um arquivo .zip. Esse é o pacote de implantação.

   ```
   chmod 755 function.sh bootstrap
   zip function.zip function.sh bootstrap
   ```

1. Crie uma função chamada `bash-runtime`. Para `--role`, insira o ARN do seu [perfil de execução](lambda-intro-execution-role.md) do Lambda.

   ```
   aws lambda create-function --function-name bash-runtime \
   --zip-file fileb://function.zip --handler function.handler --runtime provided.al2023 \
   --role arn:aws:iam::123456789012:role/lambda-role
   ```

1. Invoque a função.

   ```
   aws lambda invoke --function-name bash-runtime --payload '{"text":"Hello"}' response.txt --cli-binary-format raw-in-base64-out
   ```

   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*.

   Você obterá uma resposta parecida com esta:

   ```
   {
       "StatusCode": 200,
       "ExecutedVersion": "$LATEST"
   }
   ```

1. Verifique a resposta.

   ```
   cat response.txt
   ```

   Você obterá uma resposta parecida com esta:

   ```
   Echoing request: '{"text":"Hello"}'
   ```

## Criar uma camada
<a name="runtimes-walkthrough-layer"></a>

Para separar o código do runtime do código da função, crie uma camada que contenha apenas o runtime. As camadas permitem que você desenvolva dependências da sua função de forma independente e podem reduzir o uso de armazenamento quando você usa a mesma camada com várias funções. Para ter mais informações, consulte [Gerenciar dependências do Lambda com camadas](chapter-layers.md).

1. Crie um arquivo .zip que contenha o arquivo `bootstrap`.

   ```
   zip runtime.zip bootstrap
   ```

1. Crie uma camada com o comando [publish-layer-version](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/publish-layer-version.html?highlight=nodejs16%20x).

   ```
   aws lambda publish-layer-version --layer-name bash-runtime --zip-file fileb://runtime.zip
   ```

   Isso cria a primeira versão da camada.

## Atualizar a função
<a name="runtimes-walkthrough-update"></a>

Para usar a camada de runtime com a função, configure a função para usar a camada e remova o código de runtime da função.

1. Atualize a configuração de função para extrair na camada.

   ```
   aws lambda update-function-configuration --function-name bash-runtime \
   --layers arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:1
   ```

   Isso adiciona o runtime à função no diretório `/opt`. Para garantir que o Lambda use o runtime na camada, você precisa remover o `boostrap` do pacote de implantação da função, conforme mostrado nas próximas duas etapas.

1. Crie um arquivo .zip que contenha o código da função.

   ```
   zip function-only.zip function.sh
   ```

1. Atualize o código da função para incluir apenas o script do manipulador.

   ```
   aws lambda update-function-code --function-name bash-runtime --zip-file fileb://function-only.zip
   ```

1. Invoque a função para confirmar se ela funciona com a camada de runtime.

   ```
   aws lambda invoke --function-name bash-runtime --payload '{"text":"Hello"}' response.txt --cli-binary-format raw-in-base64-out
   ```

   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*.

   Você obterá uma resposta parecida com esta:

   ```
   {
       "StatusCode": 200,
       "ExecutedVersion": "$LATEST"
   }
   ```

1. Verifique a resposta.

   ```
   cat response.txt
   ```

   Você obterá uma resposta parecida com esta:

   ```
   Echoing request: '{"text":"Hello"}'
   ```

## Atualizar o runtime
<a name="runtimes-walkthrough-runtime"></a>

1. Para registrar informações sobre o ambiente de execução, atualize o script de runtime para gerar variáveis de ambiente.  
**Example bootstrap**  

   ```
   #!/bin/sh
   
   set -euo pipefail
   
   # Configure runtime to output environment variables
   echo "##  Environment variables:"
   env
   
   # Load function handler
   source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
   
   # Processing
   while true
   do
     HEADERS="$(mktemp)"
     # Get an event. The HTTP request will block until one is received
     EVENT_DATA=$(curl -sS -LD "$HEADERS" "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
   
     # Extract request ID by scraping response headers received above
     REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
   
     # Run the handler function from the script
     RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
   
     # Send the response
     curl "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response"  -d "$RESPONSE"
   done
   ```

1. Crie um arquivo .zip que contenha a nova versão do arquivo `bootstrap`.

   ```
   zip runtime.zip bootstrap
   ```

1. Crie uma nova versão da camada `bash-runtime`.

   ```
   aws lambda publish-layer-version --layer-name bash-runtime --zip-file fileb://runtime.zip
   ```

1. Configure a função para usar a nova versão da camada.

   ```
   aws lambda update-function-configuration --function-name bash-runtime \
   --layers arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:2
   ```

## Compartilhar a camada
<a name="runtimes-walkthrough-share"></a>

Para compartilhar uma camada com outra Conta da AWS, adicione uma instrução de permissões entre contas à [política baseada no recurso](access-control-resource-based.md) da camada. Execute o comando [add-layer-version-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-layer-version-permission.html) e especifique o ID da conta como a `principal`. Em cada instrução, você pode conceder permissão apenas a uma conta, a todas as contas ou a uma organização do [AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html).

O exemplo a seguir concede à conta 111122223333 acesso à versão 2 da camada `bash-runtime`.

```
aws lambda add-layer-version-permission \
  --layer-name bash-runtime \
  --version-number 2 \  
  --statement-id xaccount \
  --action lambda:GetLayerVersion \
  --principal 111122223333 \
  --output text
```

A saída deve ser semelhante a:

```
{"Sid":"xaccount","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::111122223333:root"},"Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:2"}
```

As permissões se aplicam apenas a uma única versão de camada. Repita o processo sempre que criar uma nova versão da camada.

## Limpeza
<a name="runtimes-walkthrough-cleanup"></a>

Exclua cada versão da camada.

```
aws lambda delete-layer-version --layer-name bash-runtime --version-number 1
aws lambda delete-layer-version --layer-name bash-runtime --version-number 2
```

Como a função contém uma referência à versão 2 da camada, ela ainda existe no Lambda. A função continua a funcionar, mas as funções não podem mais ser configuradas para usar a versão excluída. Se você modificar a lista de camadas na função, precisará especificar uma nova versão ou omitir a camada excluída.

Exclua a função com o comando [delete-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/delete-function.html).

```
aws lambda delete-function --function-name bash-runtime
```