

# Tutorial: cómo crear un tiempo de ejecución personalizado
<a name="runtimes-walkthrough"></a>

En este tutorial creará una función de Lambda con un tiempo de ejecución personalizado. Para empezar incluirá el tiempo de ejecución en el paquete de implementación de la función. A continuación, lo migrará a una capa que gestiona independientemente de la función. Por último, compartirá la capa de tiempo de ejecución globalmente actualizando su política de permisos basados en recursos.

## Requisitos previos
<a name="runtimes-walkthrough-prereqs"></a>

En este tutorial, se presupone que tiene algunos conocimientos sobre las operaciones básicas de Lambda y la consola de Lambda. Si aún no lo ha hecho, siga las instrucciones de [Cree una función de Lambda con la consola.](getting-started.md#getting-started-create-function) para crear su primera función de Lambda.

Para completar los siguientes pasos, necesita la [versión 2 de la AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html). Los comandos y la salida esperada se enumeran en bloques separados:

```
aws --version
```

Debería ver los siguientes datos de salida:

```
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 largos, se utiliza un carácter de escape (`\`) para dividir un comando en varias líneas.

En Linux y macOS, use su administrador de intérprete de comandos y paquetes preferido.

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

Necesita un rol de IAM para crear una función de Lambda. El rol necesita permiso para enviar registros a los Registros de CloudWatch y acceder a los Servicios de AWS que utiliza su función. Si no tiene un rol de para el desarrollo de funciones, cree uno.

**Para crear un rol de ejecución**

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

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

1. Cree un rol con las propiedades siguientes.
   + **Trusted entity (Entidad de confianza).**–**Lambda:**.
   + **Permisos**: **AWSLambdaBasicExecutionRole**.
   + **Nombre de rol**: **lambda-role**.

   La política **AWSLambdaBasicExecutionRole** tiene permisos que la función necesita para escribir registros a Registros de CloudWatch.

## Crear una función
<a name="runtimes-walkthrough-function"></a>

Cree una función de Lambda con un tiempo de ejecución personalizado. En este ejemplo se incluyen dos archivos: un archivo `bootstrap` de tiempo de ejecución y un controlador de la función. Ambos se implementan en Bash.

1. Cree un directorio para el proyecto y, a continuación, cambie a ese directorio.

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

1. Cree un nuevo archivo denominado `bootstrap`. Este es el tiempo de ejecución 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
   ```

   El tiempo de ejecución carga un script de función desde el paquete de implementación. Utiliza dos variables para localizar el script. `LAMBDA_TASK_ROOT` le indica dónde se extrajo el paquete y `_HANDLER` incluye el nombre del script.

   Luego de que el tiempo de ejecución carga el script de la función, utiliza la API de tiempo de ejecución para recuperar un evento de invocación de Lambda, pasa el evento al controlador y publica la respuesta de vuelta en Lambda. Para obtener el ID de la solicitud, el tiempo de ejecución guarda los encabezados de la respuesta de la API en un archivo temporal y lee el encabezado `Lambda-Runtime-Aws-Request-Id` del archivo.
**nota**  
Los tiempos de ejecución se encargan de algunas cosas más, como gestionar errores y proporcionar información de contexto al controlador. Para obtener más información, consulte [Requisitos](runtimes-custom.md#runtimes-custom-build).

1. Cree un script para la función. El script del ejemplo a continuación, define una función de controlador que toma datos de eventos, los registra en `stderr` y los devuelve.  
**Example function.sh**  

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

   El directorio `runtime-tutorial` debe tener ahora el siguiente aspecto:

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

1. Haga los archivos ejecutables y añádalos a un archivo .zip. Este es el paquete de implementación.

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

1. Cree una función llamada `bash-runtime`. Para `--role`, introduzca el ARN de su [rol de ejecución](lambda-intro-execution-role.md) de 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 la función.

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

   La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 2*.

   Debería ver una respuesta como la siguiente:

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

1. Verifique la respuesta.

   ```
   cat response.txt
   ```

   Debería ver una respuesta como la siguiente:

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

## Crear una capa
<a name="runtimes-walkthrough-layer"></a>

Para separar el código de tiempo de ejecución del código de la función, cree una capa que solo contenga el tiempo de ejecución. Las capas le permiten desarrollar las dependencias de la función de forma independiente y, si utiliza la misma capa con varias funciones, podrá hacer un menor uso del almacenamiento. Para obtener más información, consulte [Administración de las dependencias de Lambda con capas](chapter-layers.md).

1. Cree un archivo .zip que contenga el archivo `bootstrap`.

   ```
   zip runtime.zip bootstrap
   ```

1. Cree una capa con el 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
   ```

   Esto crea la primera versión de la capa.

## Actualización de la función
<a name="runtimes-walkthrough-update"></a>

Para utilizar la capa de tiempo de ejecución con la función, configure la función para que use la capa, y elimine de ella el código de tiempo de ejecución.

1. Actualice la configuración de la función para incluir la capa.

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

   Esto agrega el tiempo de ejecución a la función en el directorio `/opt`. Para garantizar que Lambda utilice el tiempo de ejecución de la capa, debe eliminar el `boostrap` del paquete de implementación de la función, como se muestra en los dos pasos a continuación.

1. Cree un archivo .zip que contenga el código de la función.

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

1. Actualice el código de la función para que incluya solo el script del controlador.

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

1. Invoque la función para confirmar que funciona con la capa de tiempo de ejecución.

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

   La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 2*.

   Debería ver una respuesta como la siguiente:

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

1. Verifique la respuesta.

   ```
   cat response.txt
   ```

   Debería ver una respuesta como la siguiente:

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

## Actualización del tiempo de ejecución
<a name="runtimes-walkthrough-runtime"></a>

1. Para registrar información sobre el entorno de ejecución, actualice el script de tiempo de ejecución para emitir variables de entorno.  
**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. Cree un archivo .zip que contenga la nueva versión del archivo `bootstrap`.

   ```
   zip runtime.zip bootstrap
   ```

1. Cree una nueva versión de la capa `bash-runtime`.

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

1. Configure la función para utilizar la nueva versión de la capa.

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

## Uso compartido de la capa
<a name="runtimes-walkthrough-share"></a>

Para compartir una función con otra Cuenta de AWS, agregue una declaración de permisos entre cuentas a la [política basada en los recursos](access-control-resource-based.md) de la capa. Ejecute el comando [add-layer-version-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-layer-version-permission.html) y especifique el ID de la cuenta como `principal`. En cada instrucción, puede conceder permiso a una única cuenta, a todas las cuentas o a una organización en [AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html).

El siguiente ejemplo concede a la cuenta 111122223333 acceso a la versión 2 de la capa `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
```

Debería ver una salida similar a esta:

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

Los permisos solo se aplican a una única versión de una capa. Repita el proceso cada vez que cree una nueva versión de la capa.

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

Elimine cada versión de la capa.

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

Puesto que la función contiene una referencia a la versión 2 de la capa, esta sigue existiendo en Lambda. Si bien la función sigue funcionando, ya no se pueden configurar funciones para que utilicen la versión eliminada. Si modifica la lista de capas de la función, deberá especificar una nueva versión u omitir la capa eliminada.

Elimine la función con el comando [delete-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/delete-function.html).

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