Exponer una función Lambda mediante una API HTTP

AWSBeginner
Practicar Ahora

Introducción

Una página de estado necesita un endpoint HTTP que indique si una aplicación está sana. Conectarás un controlador Lambda suministrado a una API HTTP, enviarás solicitudes, diagnosticarás su permiso de invocación y eliminarás tus recursos.

Completa Ejecutar una función Lambda con un evento JSON y Configurar y diagnosticar una función Lambda, incluidos sus requisitos previos de roles y registros. Este entorno nuevo proporciona el controlador y el rol de ejecución.

Relación con las certificaciones

Este laboratorio ofrece práctica para los siguientes temas de examen.

Desplegar la función de salud

En este paso, empaquetarás el controlador de salud suministrado y desplegarás una función capaz de responder a un evento HTTP.

Entra en el espacio de trabajo preparado:

cd /home/labex/project

Abre AWS View, junto a Terminal, para seguir el mismo estado de función, API y registros que tus comandos. Inicialmente solo existen registros de referencia ajenos al laboratorio; consérvalos.

Lee la aplicación suministrada antes de empaquetarla:

cat app.py

El controlador recibe un evento, registra esa entrada y devuelve una respuesta proxy con statusCode, headers y una cadena JSON en body. El formato de carga útil HTTP 2.0 coloca los parámetros de consulta de la URL en queryStringParameters. El parámetro opcional name cambia el saludo. RELEASE_LABEL es una configuración de entorno que se devuelve junto a él.

Usa zip para colocar app.py en la raíz del archivo de despliegue:

zip health.zip app.py

Lee el ARN del rol preparado en una variable del shell. --query selecciona un campo de respuesta y --output text permite usarlo en el siguiente comando:

ROLE_ARN=$(aws iam get-role --role-name labex-a01-execution --query 'Role.Arn' --output text)

Despliega app.handler con Python 3.12 y el rol de ejecución preparado. fileb:// carga los bytes del Zip. El mapa JSON Variables usa el mismo formato que el laboratorio de configuración de Lambda. Su valor de cadena identifica la primera publicación:

aws lambda create-function \
  --function-name labex-a01-health \
  --runtime python3.12 \
  --role "$ROLE_ARN" \
  --handler app.handler \
  --timeout 5 \
  --environment '{"Variables":{"RELEASE_LABEL":"initial"}}' \
  --zip-file fileb://health.zip \
  --query '{Name:FunctionName,Handler:Handler,Runtime:Runtime}'

La respuesta debe identificar labex-a01-health, app.handler y python3.12. Abre AWS View e inspecciona la tarjeta Function. Una función desplegada por sí sola todavía no proporciona una ruta HTTP; la tarjeta HTTP APIs permanece vacía.

Conectar la ruta HTTP y enviar una solicitud

En este paso, conectarás una solicitud HTTP a tu función desplegada. Amazon API Gateway proporciona la entrada HTTP. Una ruta selecciona una integración de backend para un método y una ruta, como GET /health.

Crea una API HTTP y guarda su ID generado en una variable del shell. La sustitución de comandos, $(...), captura el ID de API seleccionado en lugar de mostrarlo:

API_ID=$(aws apigatewayv2 create-api --name labex-a01 --protocol-type HTTP --query ApiId --output text)

Registra ese ID para tu inventario de recursos. La redirección, >, escribe el valor en un archivo:

printf '%s\n' "$API_ID" > api-id.txt

Una etapa, o stage, es la entrada de despliegue de la API. La etapa $default no tiene un segmento de nombre de etapa en la URL. --auto-deploy aplica los cambios automáticamente. Las comillas simples conservan el signo de dólar literal:

aws apigatewayv2 create-stage --api-id "$API_ID" --stage-name '$default' --auto-deploy --query '{Stage:StageName,AutoDeploy:AutoDeploy}'

Lee el ARN de la función desplegada y después crea una integración AWS_PROXY. Las integraciones Lambda usan POST para invocar el backend, aunque la ruta entrante del cliente que aparece a continuación usa GET. El formato de carga útil 2.0 coincide con el controlador suministrado:

FUNCTION_ARN=$(aws lambda get-function-configuration --function-name labex-a01-health --query FunctionArn --output text)
INTEGRATION_ID=$(aws apigatewayv2 create-integration --api-id "$API_ID" --integration-type AWS_PROXY --integration-method POST --integration-uri "$FUNCTION_ARN" --payload-format-version 2.0 --query IntegrationId --output text)

Una clave de ruta combina el método HTTP del cliente con la ruta. Su destino apunta a la integración que acabas de crear:

aws apigatewayv2 create-route \
  --api-id "$API_ID" \
  --route-key 'GET /health' \
  --target "integrations/$INTEGRATION_ID" \
  --authorization-type NONE \
  --query '{Route:RouteKey,Authorization:AuthorizationType}'

Esta ruta pública de salud usa NONE; el inicio de sesión de la aplicación se presenta más adelante. El rol de ejecución controla qué puede hacer el código de la función, mientras que la política de recursos de la función controla quién puede invocarla. API Gateway todavía necesita una concesión precisa de invocación.

Lee el ID de la cuenta seleccionada y construye el ARN de origen de la ruta GET /health de la etapa predeterminada de esta API. El signo de dólar escapado conserva $default literalmente dentro de la cadena expandida:

ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
SOURCE_ARN="arn:aws:execute-api:us-east-1:$ACCOUNT_ID:$API_ID/\$default/GET/health"

Concede únicamente a esta ruta de API permiso para invocar la función:

aws lambda add-permission \
  --function-name labex-a01-health \
  --statement-id ApiHealth \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-account "$ACCOUNT_ID" \
  --source-arn "$SOURCE_ARN" \
  --query Statement \
  --output text

Para solicitudes HTTP en este espacio de trabajo, usa la dirección de API preparada con tu ID de API generado. Esta es la entrada de API del espacio de trabajo, no un nombre de host público de AWS:

API_URL="http://127.0.0.1:8081/api/$API_ID"

La Console oficial muestra el mismo ID de API, la etapa $default y la configuración Auto deploy. Su Invoke URL es un endpoint de AWS; continúa con el API_URL del espacio de trabajo indicado arriba para este laboratorio.

API Gateway Console oficial muestra los detalles de la API y la URL de invocación de la etapa predeterminada

Fuente: AWS API Gateway.

curl -i muestra tanto las cabeceras HTTP como el cuerpo de respuesta. El parámetro de consulta de la URL se convierte en parte del evento real de Lambda:

curl -i "$API_URL/health?name=Maya"

Espera HTTP 200 y este cuerpo JSON:

{"healthy": true, "message": "Hello, Maya", "release": "initial"}

Vuelve a AWS View. La tarjeta HTTP APIs debe mostrar GET /health, NONE y $default · AutoDeploy true. La tarjeta CloudWatch Logs debe mostrar la ruta, el estado y la respuesta reales. Haz clic en Show logs y encuentra queryStringParameters con name: Maya. Esta observación manual relaciona la solicitud HTTP con la entrada de la función desplegada; la verificación comprueba la configuración remota y la ejecución real.

Ruta HTTP de salud y su respuesta Lambda en AWS View

Este ejemplo muestra la ruta configurada y su respuesta correcta Maya / initial. Tu ID de API generado y la huella del código serán distintos.

La ruta de salud selecciona la integración Lambda para la solicitud.

Diagnosticar el permiso de invocación y publicar una nueva versión de la aplicación

En este paso, observarás un límite de invocación roto, restablecerás la concesión precisa y probarás una configuración modificada de la función.

Elimina la instrucción por su ID. Esto deja intactos la API, la integración y el rol de ejecución:

aws lambda remove-permission --function-name labex-a01-health --statement-id ApiHealth

Envía otra solicitud mientras falta la concesión:

curl -i "$API_URL/health?name=Noah"

Espera HTTP 502 con Invocation permission denied. El despliegue de la API y la configuración de rutas no conceden por sí mismos permiso de invocación de Lambda. En AWS View, la invocación correcta existente permanece; esta solicitud rechazada no ha ejecutado el controlador. Compara manualmente los registros antes y después de la solicitud. La comprobación automática no deduce un rechazo histórico a partir de la política final restablecida.

Restablece la misma concesión acotada por cuenta y ruta:

aws lambda add-permission \
  --function-name labex-a01-health \
  --statement-id ApiHealth \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-account "$ACCOUNT_ID" \
  --source-arn "$SOURCE_ARN" \
  --query Statement \
  --output text

Cambia el entorno de la función para marcar la publicación ready. El controlador lee esta configuración cuando se ejecuta:

aws lambda update-function-configuration --function-name labex-a01-health --environment '{"Variables":{"RELEASE_LABEL":"ready"}}' --query 'Environment.Variables'

La ruta sigue apuntando a la misma función. Envía una solicitud con un valor de consulta distinto:

curl -i "$API_URL/health?name=Noah"

Espera HTTP 200 y una respuesta calculada a partir de la nueva consulta y del entorno:

{"healthy": true, "message": "Hello, Noah", "release": "ready"}

En AWS View, inspecciona la última respuesta y expande sus registros. Confirma que la entrada dice Noah y el cuerpo dice ready. La respuesta anterior de Maya debe seguir disponible. Estos resultados diferentes demuestran que la integración ejecuta la función desplegada en lugar de devolver un único mensaje fijo de salud.

Eliminar tu API y tu función

En este paso, eliminarás los recursos que creaste y demostrarás que permanecen los registros de referencia ajenos al laboratorio.

Tu inventario consta del ID de API de api-id.txt, labex-a01-health y /aws/lambda/labex-a01-health. La API posee su ruta, integración y etapa predeterminada. Elimina primero la API para que no pueda recibir más solicitudes:

aws apigatewayv2 delete-api --api-id "$API_ID"

Elimina la función y su política de invocación:

aws lambda delete-function --function-name labex-a01-health

Los grupos de registros de Lambda tienen su propio ciclo de vida. Elimina únicamente el grupo de esta función:

aws logs delete-log-group --log-group-name /aws/lambda/labex-a01-health

Lee correctamente los inventarios nativos; los errores de solicitud no demuestran la eliminación:

aws apigatewayv2 get-apis --query 'Items[].Name'
aws lambda list-functions --query 'Functions[].FunctionName'

Ambas listas deben estar vacías. Lee los grupos de registros restantes:

aws logs describe-log-groups --query 'logGroups[].logGroupName'

Solo debe permanecer /labex/labex-a01-reference. Consérvalo junto con el rol de ejecución preparado. En AWS View, confirma que las tarjetas API, Function e invocaciones están vacías mientras Reference logs sigue mostrando INFO platform reference keep unchanged.

Resumen

Desplegaste un controlador de salud Python, conectaste una ruta de API HTTP mediante una integración de carga útil 2.0 y habilitaste su etapa predeterminada. Acotaste la concesión de invocación Lambda de la API, diagnosticaste su eliminación y observaste distintas respuestas a partir de valores reales de consulta y configuraciones de función. Por último, eliminaste tu API, función y grupo de registros conservando los recursos ajenos al laboratorio.