Invocar una función de AWS Lambda desde una instancia de base de datos de RDS for PostgreSQL - Amazon Relational Database Service

Invocar una función de AWS Lambda desde una instancia de base de datos de RDS for PostgreSQL

AWS Lambda es un servicio de computación controlado por eventos que permite ejecutar código sin aprovisionar ni administrar servidores. Está disponible para su uso con muchos servicios de AWS, incluidos RDS for PostgreSQL. Por ejemplo, puede utilizar funciones de Lambda para procesar notificaciones de eventos desde una base de datos o para cargar datos desde archivos cada vez que se carga un nuevo archivo en Simple Storage Service (Amazon S3). Para obtener más información sobre Lambda, consulte ¿Qué es AWS Lambda? en la Guía para desarrolladores de AWS Lambda.

nota

La invocación de una función de AWS Lambda se admite en estas versiones de RDS for PostgreSQL:

  • Todas las versiones 16 de PostgreSQL

  • Todas las versiones 15 de PostgreSQL

  • PostgreSQL 14.1 y versiones secundarias posteriores

  • PostgreSQL 13.2 y versiones secundarias posteriores

  • PostgreSQL 12.6 y versiones secundarias posteriores

La configuración de RDS for PostgreSQL para trabajar con las funciones de Lambda es un proceso de varios pasos que incluye AWS Lambda, IAM, su VPC y su instancia de base de datos de RDS for PostgreSQL. A continuación, se muestran resúmenes de los pasos necesarios.

Para obtener más información acerca de las funciones de Lambda, consulte Introducción a Lambda y Conceptos básicos de AWS Lambda en la Guía para desarrolladores de AWS Lambda.

Paso 1: configure la instancia de base de datos de RDS for PostgreSQL para conexiones salientes a AWS Lambda.

Las funciones de Lambda siempre se ejecutan dentro de una Amazon VPC propiedad del servicio de AWS Lambda. Lambda aplica acceso a la red y reglas de seguridad a esta VPC y mantiene y supervisa la VPC automáticamente. Su instancia de base de datos de RDS for PostgreSQL envía tráfico de red a la VPC del servicio de Lambda. La manera en que se configura esto depende de si la instancia de base de datos es pública o privada.

  • Instancia de base de datos de RDS for PostgreSQL pública: una instancia de base de datos es pública si se encuentra en una subred pública de la VPC y si la propiedad “PubliclyAccessible” de la instancia es true. Para encontrar el valor de esta propiedad, puede utilizar el comando describe-db-instances de AWS CLI. O, si lo desea, puede utilizar AWS Management Console para abrir la pestaña Connectivity & security (Conectividad y seguridad) y verificar que Publicly accessible (Acceso público) sea Yes (Sí). Para comprobar que la instancia está en la subred pública de la VPC, puede utilizar la AWS Management Console o la AWS CLI.

    Para configurar el acceso a Lambda, utilice la AWS Management Console o la AWS CLI para crear una regla de salida en el grupo de seguridad de la VPC. La regla de salida especifica que TCP puede utilizar el puerto 443 para enviar paquetes a cualquier dirección IPv4 (0.0.0.0/0).

  • Clúster Instancia de base de datos de RDS PostgreSQL: en este caso, la propiedad “PubliclyAccessible” de la instancia es false o está en una subred privada. Para permitir el funcionamiento de la instancia con Lambda, puede utilizar una puerta de enlace de traducción de direcciones de red (NAT). Para obtener más información, consulte Puerta de enlace NAT. O bien, puede configurar su VPC con un punto de conexión de VPC para Lambda. Para obtener más información, consulte Puntos de enlace de la VPC en la Guía del usuario de Amazon VPC. El punto de conexión responde a las llamadas hechas por su instancia de base de datos de RDS para PostgreSQL a las funciones de Lambda. El punto de conexión de VPC utiliza su propia resolución DNS privada. RDS for PostgreSQL no puede utilizar el punto de conexión de VPC de Lambda hasta que cambie el valor de rds.custom_dns_resolution de su valor predeterminado 0 (no habilitado) a 1. Para ello:

    • Cree un grupo de parámetros de base de datos personalizado.

    • Cambie el valor del parámetro rds.custom_dns_resolution del valor predeterminado de 0 a 1.

    • Modifique la instancia de base de datos para usar el grupo de parámetros de base de datos personalizado.

    • Reinicie la instancia para que el parámetro modificado tenga efecto.

La VPC ahora puede interactuar con la VPC de AWS Lambda en el ámbito de red. A continuación, debe configurar los permisos mediante IAM.

Paso 2: configure IAM para su instancia de base de datos de RDS for PostgreSQL y AWS Lambda.

La invocación de funciones de Lambda desde su instancia de base de datos de RDS for PostgreSQL requiere ciertos privilegios. Para configurar los privilegios necesarios, recomendamos crear una política de IAM que permita invocar funciones de Lambda, asignar esa política a un rol y c a su instancia de base de datos. Este enfoque da a la instancia de base de datos privilegios para invocar la función de Lambda especificada en su nombre. En los pasos siguientes se muestra cómo hacer esto con AWS CLI.

Para configurar los permisos de IAM para utilizar su instancia de Amazon RDS con Lambda, lleve a cabo el siguiente procedimiento.
  1. Utilice el comando create-policy de AWS CLI para crear una política de IAM que permita a su instancia de base de datos de RDS for PostgreSQL invocar la función de Lambda especificada. (El ID de instrucción [Sid] es una descripción opcional de la instrucción de política y no afecta al uso). Esta política proporciona a su instancia de base de datos los permisos mínimos necesarios para invocar la función de Lambda especificada.

    aws iam create-policy --policy-name rds-lambda-policy --policy-document '{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAccessToExampleFunction", "Effect": "Allow", "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:aws-region:444455556666:function:my-function" } ] }'

    También puede utilizar la política predefinida de AWSLambdaRole que le permite invocar cualquiera de las funciones de Lambda. Para obtener más información, consulte Políticas de IAM basadas en identidades para Lambda.

  2. Utilice el comando de la AWS CLI create-role para crear un rol de IAM que la política pueda asumir en tiempo de ejecución.

    aws iam create-role --role-name rds-lambda-role --assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "rds.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }'
  3. Aplique la política al rol mediante el comando attach-role-policy de AWS CLI.

    aws iam attach-role-policy \ --policy-arn arn:aws:iam::444455556666:policy/rds-lambda-policy \ --role-name rds-lambda-role --region aws-region
  4. Aplique el rol a su instancia de base de datos de RDS for PostgreSQL mediante el comando add-role-to-db-instance de la AWS CLI. En este último paso se permite a los usuarios de bases de datos de su instancia de base de datos invocar funciones de Lambda.

    aws rds add-role-to-db-instance \ --db-instance-identifier my-instance-name \ --feature-name Lambda \ --role-arn arn:aws:iam::444455556666:role/rds-lambda-role \ --region aws-region

Con la VPC y las configuraciones de IAM completadas, ahora puede instalar la extensión de aws_lambda. (Tenga en cuenta que puede instalar la extensión en cualquier momento, pero hasta que no configure la compatibilidad con VPC y los privilegios de IAM correctos, la extensión de aws_lambda no agrega nada a las capacidades de su instancia de base de datos de RDS for PostgreSQL.

Paso 3: instale la extensión de aws_lambda para una instancia de base de datos de RDS for PostgreSQL

Para utilizar AWS Lambda con su instancia de base de datos de RDS para PostgreSQL, agregue la extensión de PostgreSQL de aws_lambda a su instancia de base de datos de RDS para PostgreSQL. Esta extensión proporciona a su instancia de base de datos de RDS for PostgreSQL la capacidad de llamar a funciones de Lambda desde PostgreSQL.

Para instalar la extensión de aws_lambda en su instancia de base de datos de RDS for PostgreSQL

Utilice la línea de comandos psql de PostgreSQL o la herramienta pgAdmin para conectarse a su instancia de base de datos de RDS for PostgreSQL.

  1. Conéctese a su instancia de base de datos de RDS for PostgreSQL como usuario con privilegios de rds_superuser. El valor predeterminado de usuario de postgres se muestra en el ejemplo.

    psql -h instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
  2. Instale la extensión de aws_lambda. La extensión de aws_commons también es necesaria. Proporciona funciones auxiliares para aws_lambda y muchas otras extensiones de Aurora para PostgreSQL. Si aún no está en su instancia de base de datos de RDS for PostgreSQL, se instala con aws_lambda como se muestra a continuación.

    CREATE EXTENSION IF NOT EXISTS aws_lambda CASCADE; NOTICE: installing required extension "aws_commons" CREATE EXTENSION

La extensión de aws_lambda se instala en su instancia de base de datos Ahora puede crear estructuras de conveniencia para invocar las funciones de Lambda.

Paso 4: utilice las funciones auxiliares de Lambda con su instancia de base de datos de RDS for PostgreSQL (Opcional)

Puede utilizar las funciones auxiliares en la extensión de aws_commons para preparar entidades que puede invocar con más facilidad desde PostgreSQL. Para ello, debe tener la siguiente información sobre las funciones de Lambda:

  • Nombre de la función: el nombre, el nombre de recurso de Amazon (ARN), la versión o el alias de la función de Lambda. La política de IAM creada en Paso 2: configure IAM para su instancia y Lambda requiere el ARN, por lo que recomendamos utilizar el ARN de su función.

  • Región de AWS: (Opcional) la región de AWS en la que se encuentra la función de Lambda si no se encuentra en la misma región que su instancia de base de datos de RDS for PostgreSQL.

Para mantener la información del nombre de la función Lambda, utilice la función aws_commons.create_lambda_function_arn. Esta función auxiliar crea una estructura compuesta de aws_commons._lambda_function_arn_1 con los detalles necesarios para la función de invocación. A continuación, encontrará tres enfoques alternativos para configurar esta estructura compuesta.

SELECT aws_commons.create_lambda_function_arn( 'my-function', 'aws-region' ) AS aws_lambda_arn_1 \gset
SELECT aws_commons.create_lambda_function_arn( '111122223333:function:my-function', 'aws-region' ) AS lambda_partial_arn_1 \gset
SELECT aws_commons.create_lambda_function_arn( 'arn:aws:lambda:aws-region:111122223333:function:my-function' ) AS lambda_arn_1 \gset

Cualquiera de estos valores se puede utilizar en las llamadas a la función aws_lambda.invoke. Para ver ejemplos, consulte Paso 5: invoque una función de Lambda desde su instancia de base de datos de RDS for PostgreSQL.

Paso 5: invoque una función de Lambda desde su instancia de base de datos de RDS for PostgreSQL

La función aws_lambda.invoke se comporta de forma sincrónica o asíncrona, según invocation_type. Las dos alternativas para este parámetro son RequestResponse (el valor predeterminado) y Event, como se muestra a continuación.

  • RequestResponse: este tipo de invocación es sincrónico. Es el comportamiento predeterminado cuando la llamada se hace sin especificar un tipo de invocación. La carga de respuesta incluye los resultados de la función aws_lambda.invoke. Utilice este tipo de invocación cuando el flujo de trabajo requiera recibir los resultados de la función de Lambda antes de continuar.

  • Event: este tipo de invocación es asíncrono. La respuesta no incluye una carga que contenga resultados. Utilice este tipo de invocación cuando el flujo de trabajo no necesite un resultado de la función de Lambda para continuar con el procesamiento.

Como simple prueba de la configuración, puede conectarse a la instancia de base de datos mediante psql e invocar una función de ejemplo desde la línea de comandos. Supongamos que tiene una de las funciones básicas configuradas en su servicio Lambda, como la sencilla función de Python que se muestra en la siguiente captura de pantalla.


            Ejemplo de función de Lambda de ejemplo que se muestra en AWS CLI para AWS Lambda.
Para invocar una función de ejemplo
  1. Conéctese a la instancia de base de datos con psql o pgAdmin.

    psql -h instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
  2. Invoque la función mediante su ARN.

    SELECT * from aws_lambda.invoke(aws_commons.create_lambda_function_arn('arn:aws:lambda:aws-region:444455556666:function:simple', 'us-west-1'), '{"body": "Hello from Postgres!"}'::json );

    La respuesta tiene el siguiente aspecto.

    status_code | payload | executed_version | log_result -------------+-------------------------------------------------------+------------------+------------ 200 | {"statusCode": 200, "body": "\"Hello from Lambda!\""} | $LATEST | (1 row)

Si el intento de invocación no se lleva a cabo correctamente, consulte Mensajes de error de la función de Lambda .

Paso 6: Conceder permiso a otros usuarios para invocar las funciones de Lambda

En este punto de los procedimientos, solo usted como rds_superuser puede invocar las funciones de Lambda. Para permitir que otros usuarios puedan invocar cualquier función que haya creado usted, deberá otorgarles permiso.

Para otorgar permiso para invocar una función de Lambda
  1. Conéctese a la instancia de base de datos con psql o pgAdmin.

    psql -h instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
  2. Ejecute los siguientes comandos SQL:

    postgres=> GRANT USAGE ON SCHEMA aws_lambda TO db_username; GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA aws_lambda TO db_username;

Ejemplos: invoque las funciones de Lambda desde su instancia de base de datos de RDS for PostgreSQL

A continuación, puede encontrar varios ejemplos de llamada a la función de aws_lambda.invoke. La mayoría de los ejemplos utilizan la estructura compuesta aws_lambda_arn_1 que se crea en Paso 4: utilice las funciones auxiliares de Lambda con su instancia de base de datos de RDS for PostgreSQL (Opcional) para simplificar la transferencia de los detalles de la función. Para obtener un ejemplo de invocación asincrónica, consulte Ejemplo: invocación asincrónica (Event) de funciones de Lambda. El resto de ejemplos enumerados utilizan la invocación sincrónica.

Para obtener más información acerca de los tipos de invocación de Lambda, consulte Invocación de funciones de Lambda en la Guía para desarrolladores de AWS Lambda. Para obtener más información acerca de aws_lambda_arn_1, consulte aws_commons.create_lambda_function_arn.

Ejemplo: invocación sincrónica (RequestResponse) de funciones de Lambda

Lo que sigue son dos ejemplos de una invocación de función de Lambda sincrónica. Los resultados de estas llamadas de funciones de aws_lambda.invoke son iguales.

SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json);
SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse');

Los parámetros se describen de la siguiente manera:

  • :'aws_lambda_arn_1': este parámetro identifica la estructura compuesta creada en Paso 4: utilice las funciones auxiliares de Lambda con su instancia de base de datos de RDS for PostgreSQL (Opcional), con la función auxiliar de aws_commons.create_lambda_function_arn. También puede crear esta estructura en línea dentro de su llamada de aws_lambda.invoke de la siguiente manera.

    SELECT * FROM aws_lambda.invoke(aws_commons.create_lambda_function_arn('my-function', 'aws-region'), '{"body": "Hello from Postgres!"}'::json );
  • '{"body": "Hello from PostgreSQL!"}'::json – La carga útil JSON que se va a pasar a la función Lambda.

  • 'RequestResponse' – El tipo de invocación Lambda.

Ejemplo: invocación asincrónica (Event) de funciones de Lambda

Lo que sigue es un ejemplo de una invocación de función asincrónica Lambda. El tipo de invocación Event programa la invocación de la función Lambda con la carga útil de entrada especificada y regresa inmediatamente. Utilice el tipo de invocación Event en ciertos flujos de trabajo que no dependen de los resultados de la función Lambda.

SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'Event');

Ejemplo: captura del registro de ejecución de Lambda en una respuesta de función

Puede incluir los últimos 4 KB del registro de ejecución en la respuesta de función mediante el parámetro log_type en su llamada a funciones de aws_lambda.invoke. De forma predeterminada, este parámetro se establece en None, pero puede especificar Tail para capturar los resultados del registro de ejecución de Lambda en la respuesta, como se muestra a continuación.

SELECT *, select convert_from(decode(log_result, 'base64'), 'utf-8') as log FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse', 'Tail');

Establezca el parámetro aws_lambda.invoke de la función log_type en Tail para incluir el registro de ejecución en la respuesta. El valor predeterminado para el parámetro log_type es None.

El log_result que se devuelve es una cadena codificada base64. Puede decodificar el contenido utilizando una combinación de las funciones decode y convert_from PostgreSQL.

Para obtener más información acerca de log_type, consulte aws_lambda.invoke.

Ejemplo: inclusión del contexto del cliente en una función Lambda

La función aws_lambda.invoke tiene un parámetro context que puede utilizar para pasar la información por separado de la carga, como se muestra a continuación.

SELECT *, convert_from(decode(log_result, 'base64'), 'utf-8') as log FROM aws_lambda.invoke(:'aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse', 'Tail');

Para incluir el contexto del cliente, utilice un objeto JSON para el parámetro aws_lambda.invoke de la función context.

Para obtener más información sobre los parámetros de context, consulte la referencia de aws_lambda.invoke.

Ejemplo: invocación de una versión específica de una función de Lambda

Se puede especificar una versión concreta de una función de Lambda mediante el parámetro qualifier con la llamada de aws_lambda.invoke. A continuación, encontrará información sobre el ejemplo que hace esto mediante 'custom_version' como alias de la versión.

SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json, 'RequestResponse', 'None', NULL, 'custom_version');

Además, puede proporcionar un calificador de función de Lambda con los detalles del nombre de función en su lugar de la siguiente manera.

SELECT * FROM aws_lambda.invoke(aws_commons.create_lambda_function_arn('my-function:custom_version', 'us-west-2'), '{"body": "Hello from Postgres!"}'::json);

Para obtener más información acerca de qualifier y otros parámetros, consulte la referencia de aws_lambda.invoke.

Mensajes de error de la función de Lambda

En la siguiente lista encontrará información sobre los mensajes de error, con posibles causas y soluciones.

  • Problemas de configuración de la VPC

    Los problemas de configuración de la VPC pueden generar los siguientes mensajes de error al intentar conectarse:

    ERROR: invoke API failed DETAIL: AWS Lambda client returned 'Unable to connect to endpoint'. CONTEXT: SQL function "invoke" statement 1

    Una causa común de este error es configurar erróneamente el grupo de seguridad de la VPC. Asegúrese de tener abierta una regla de salida para TCP en el puerto 443 de su grupo de seguridad de la VPC para que la VPC pueda conectarse a la VPC de Lambda.

    Si la instancia de base de datos es privada, verifique la configuración de DNS privada de la VPC. Asegúrese de establecer el parámetro de rds.custom_dns_resolution en 1 y configure AWS PrivateLink tal como se describe en Paso 1: configure la instancia de base de datos de RDS for PostgreSQL para conexiones salientes a AWS Lambda.. Para obtener más información, consulte Puntos de conexión de VPC de la interfaz (AWS PrivateLink).

  • Falta de permisos necesarios para invocar funciones de Lambda

    Si ve alguno de los siguientes mensajes de error, significa que el usuario (rol) que invoca la función no tiene los permisos adecuados.

    ERROR: permission denied for schema aws_lambda
    ERROR: permission denied for function invoke

    Se deben otorgar permisos específicos a un usuario (rol) para que pueda invocar funciones de Lambda. Para obtener más información, consulte Paso 6: Conceder permiso a otros usuarios para invocar las funciones de Lambda.

  • Gestión incorrecta de errores en las funciones de Lambda

    Si una función Lambda lanza una excepción durante el procesamiento de la solicitud, aws_lambda.invoke se produce un error de PostgreSQL como el siguiente.

    SELECT * FROM aws_lambda.invoke('aws_lambda_arn_1', '{"body": "Hello from Postgres!"}'::json); ERROR: lambda invocation failed DETAIL: "arn:aws:lambda:us-west-2:555555555555:function:my-function" returned error "Unhandled", details: "<Error details string>".

    Asegúrese de controlar los errores en las funciones de Lambda o en la aplicación de PostgreSQL.