Invocar uma função do AWS Lambda de uma instância de banco de dados do RDS for PostgreSQL - Amazon Relational Database Service

Invocar uma função do AWS Lambda de uma instância de banco de dados do RDS for PostgreSQL

O AWS Lambda é um serviço computacional orientado a eventos que permite executar código sem o provisionamento ou gerenciamento de servidores. Está disponível para uso com muitos serviços da AWS, incluindo o RDS for PostgreSQL. Por exemplo, você pode usar funções Lambda para processar notificações de eventos de um banco de dados ou para carregar dados de arquivos sempre que um novo arquivo é carregado para o Simple Storage Service (Amazon S3). Para saber mais sobre o Lambda, consulte O que é o AWS Lambda? no Guia do desenvolvedor do AWS Lambda.

nota

A chamada de uma função AWS Lambda é aceita nas seguintes versões do RDS for PostgreSQL:

  • Todas as versões 16 do PostgreSQL

  • Todas as versões do PostgreSQL 15

  • PostgreSQL 14.1 e versões secundárias posteriores

  • PostgreSQL 13.2 e versões secundárias posteriores

  • PostgreSQL 12.6 e versões secundárias posteriores

Configurar o RDS for PostgreSQL para trabalhar com funções Lambda é um processo de várias etapas envolvendo o AWS Lambda, o IAM, sua VPC e sua instância de banco de dados do RDS for PostgreSQL. A seguir, você pode encontrar resumos das etapas necessárias.

Para obter mais informações sobre como criar uma função Lambda, consulte Conceitos básicos do Lambda e Tópicos essenciais do AWS Lambda no Guia do desenvolvedor do AWS Lambda.

Etapa 1: configurar a instância de banco de dados do RDS for PostgreSQL para conexões de saída para o AWS Lambda

As funções do Lambda sempre são executadas dentro de uma Amazon VPC de propriedade do serviço AWS Lambda. O Lambda aplica regras de segurança e acesso à rede a essa VPC e mantém e monitora a VPC automaticamente. Sua instância de banco de dados do RDS para PostgreSQL envia tráfego de rede para a VPC do serviço Lambda. Como você configura isso depende se sua instância de banco de dados primária do é pública ou privada.

  • Instância de banco de dados pública do RDS para PostgreSQL: uma instância de banco de dados é pública se está localizada em uma sub-rede pública na VPC e se a propriedade “PubliclyAccessible” da instância é true. Para encontrar o valor dessa propriedade, você pode usar o comando da AWS CLI describe-db-instances. Ou, você pode usar o AWS Management Console para abrir a guia Connectivity & security (Conectividade e segurança) e verificar se Publicly accessible (Publicamente acessível) está definido como Yes (Sim). Para verificar se a instância está na sub-rede pública da VPC, use o AWS Management Console ou a AWS CLI.

    Para configurar o acesso ao Lambda, use o AWS Management Console ou a AWS CLI para criar uma regra de saída no grupo de segurança da VPC. A regra de saída especifica que o TCP pode usar a porta 443 para enviar pacotes para qualquer endereço IPv4 (0.0.0.0/0).

  • Instância de banco de dados privada do RDS para PostgreSQL: nesse caso, a propriedade “PubliclyAccessible” da instância é false ou está em uma sub-rede privada. Para permitir que a instância funcione com o Lambda, use um gateway de conversão de endereços de rede (NAT). Para obter mais informações, consulte Gateways de NAT. Ou configure sua VPC com um endpoint da VPC para o Lambda. Para obter mais informações, consulte Endpoints da VPC no Guia do usuário da Amazon VPC. O endpoint responde às chamadas feitas pela instância de banco de dados do RDS para PostgreSQL para suas funções do Lambda. O endpoint da VPC usa sua própria resolução DNS privada. O RDS for PostgreSQL não pode usar o endpoint da VPC do Lambda até que você altere o valor do rds.custom_dns_resolution de seu valor padrão 0 (não habilitado) para 1. Para fazer isso:

    • Crie um grupo de parâmetros de banco de dados personalizado.

    • Altere o valor do parâmetro rds.custom_dns_resolution de seu padrão 0 para 1.

    • Modifique sua instância de banco de dados para aplicar seu grupo de parâmetros de banco de dados personalizado.

    • Reinicialize a instância de banco de dados para que a alteração do parâmetro tenha efeito.

Agora, sua VPC pode interagir com o VPC do AWS Lambda no nível da rede. Depois, configure as permissões usando o IAM.

Etapa 2: configurar o IAM para a instância de banco de dados do RDS for PostgreSQL e AWS Lambda

Invocar funções Lambda da sua instância de banco de dados do RDS for PostgreSQL requer certos privilégios. Para configurar os privilégios necessários, recomendamos que você crie uma política do IAM que permita chamar funções Lambda, atribuir essa política a uma função e, em seguida, aplicar a função ao à instância de banco de dados. Essa abordagem dá à instância de banco de dados privilégios para invocar a função Lambda especificada em seu nome. As etapas a seguir mostram como fazer isso usando a AWS CLI.

Para configurar permissões do IAM para usar sua instância do Amazon RDS com o Lambda
  1. Use o comando da AWS CLI create-policy para criar uma política do IAM que permita que a sua instância de banco de dados do RDS for PostgreSQL invoque a função Lambda especificada. (O ID da instrução (Sid) é uma descrição opcional para sua instrução de política e não tem efeito sobre o uso.) Esta política fornece à sua instância de banco de dados as permissões mínimas necessárias para invocar a função 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" } ] }'

    Você também pode usar a política AWSLambdaRole predefinida que permite invocar qualquer uma das suas funções Lambda. Para obter mais informações, consulte Políticas do IAM baseadas em identidade para o Lambda.

  2. Use o comando da AWS CLI create-role para criar uma função do IAM que a política possa assumir em tempo de execução.

    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. Anexe a política à função usando o comando da AWS CLI attach-role-policy.

    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 a função à sua instância de banco de dados do RDS for PostgreSQL usando o comando da AWS CLI add-role-to-db-instance Esta última etapa permite que seus usuários de banco de dados de instâncias de banco de dados invoquem funções 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

Com a VPC e as configurações do IAM concluídas, agora você pode instalar a extensão aws_lambda. (Observe que você pode instalar a extensão a qualquer momento, mas até configurar o suporte à VPC e os privilégios do IAM corretos, a extensão aws_lambda não adiciona nada às capacidades da instância de banco de dados do RDS for PostgreSQL.)

Etapa 3: instalar a extensão aws_lambda para uma instância de banco de dados do RDS for PostgreSQL

Para usar o AWS Lambda com a instância de banco de dados do RDS para PostgreSQL, adicione a extensão aws_lambda do PostgreSQL à instância de banco de dados do RDS para PostgreSQL. Esta extensão fornece a instância de banco de dados do RDS for PostgreSQL com a capacidade de chamar funções Lambda do PostgreSQL.

Para instalar a extensão aws_lambda em sua instância de banco de dados do RDS for PostgreSQL

Use a linha de comando psql do PostgreSQL ou a ferramenta pgAdmin para se conectar à sua instância de banco de dados do RDS for PostgreSQL.

  1. Conecte-se à sua instância de banco de dados do RDS for PostgreSQL como usuário com privilégios rds_superuser. O usuário padrão postgres é mostrado no exemplo.

    psql -h instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
  2. Instale a extensão aws_lambda. A extensão aws_commons também é necessária. Ela fornece funções auxiliares para aws_lambda e muitas outras extensões do Aurora para PostgreSQL. Se ainda não estiver na sua instância de banco de dados do RDS for PostgreSQL, ela é instalada com aws_lambda como mostrado a seguir.

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

A extensão aws_lambda está instalada em sua instância de banco de dados primária do . Agora você pode criar estruturas de conveniência para chamar suas funções Lambda.

Etapa 4: usar as funções Lambda auxiliares com a instância de banco de dados do RDS for PostgreSQL (opcional)

Você pode usar as funções auxiliares na extensão aws_commons para preparar entidades que você pode invocar mais facilmente a partir do PostgreSQL. Para isso, você precisa ter as seguintes informações sobre suas funções Lambda:

  • Nome da função – O nome, nome do recurso da Amazon (ARN), versão ou apelido da função Lambda. A política do IAM criada em Etapa 2: configurar o IAM para o cluster e o Lambda requer o ARN, portanto, recomendamos que você use o ARN da sua função.

  • Região da AWS – (Opcional) A região da AWS onde a função Lambda está localizada se não estiver na mesma região que sua instância de banco de dados do RDS for PostgreSQL.

Para manter as informações do nome da função Lambda, você pode usar a função aws_commons.create_lambda_function_arn. Esta função auxiliar cria uma estrutura composta aws_commons._lambda_function_arn_1 com os detalhes necessários para a função de invocação. A seguir, você pode encontrar três abordagens alternativas para configurar essa estrutura composta.

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

Qualquer um desses valores pode ser usado em chamadas para a função aws_lambda.invoke. Para ver exemplos, consulte Etapa 5: invocar uma função Lambda da sua instância de banco de dados do RDS for PostgreSQL.

Etapa 5: invocar uma função Lambda da sua instância de banco de dados do RDS for PostgreSQL

A função aws_lambda.invoke se comporta de forma síncrona ou assíncrona, dependendo do invocation_type. As duas alternativas para esse parâmetro são RequestResponse (o padrão) e Event, da seguinte forma:

  • RequestResponse – Este tipo de invocação é síncrono. É o comportamento padrão quando a chamada é feita sem especificar um tipo de invocação. A carga útil da resposta inclui os resultados da função aws_lambda.invoke. Use esse tipo de invocação de quando seu fluxo de trabalho exigir o recebimento de resultados da função Lambda antes de continuar.

  • Event – Este tipo de invocação é assíncrono. A resposta não inclui uma carga útil contendo resultados. Use esse tipo de invocação quando o fluxo de trabalho não precisar de um resultado da função Lambda para continuar o processamento.

Como um teste simples de sua configuração, você pode se conectar à sua instância de banco de dados usando psql e chamar uma função de exemplo a partir da linha de comando. Suponha que você tenha uma das funções básicas configuradas em seu serviço Lambda, como a função Python simples mostrada na captura de tela a seguir.


            Exemplo de função Lambda mostrada na AWS CLI pelo AWS Lambda
Para invocar uma função de exemplo
  1. Conecte-se à sua instância de banco de dados usando psql ou pgAdmin.

    psql -h instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
  2. Invoque a função usando seu 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 );

    A resposta se parece com esta a seguir.

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

Se sua tentativa de invocação não for bem-sucedida, consulte Mensagens de erro da função Lambda .

Etapa 6: Conceder a outros usuários permissão para invocar funções do Lambda

Neste ponto dos procedimentos, apenas você como rds_superuser pode invocar suas funções do Lambda. Para permitir que outros usuários invoquem quaisquer funções criadas por você, é necessário conceder permissão a eles.

Como conceder a outros permissão para invocar funções do Lambda
  1. Conecte-se à sua instância de banco de dados usando psql ou pgAdmin.

    psql -h instance.444455556666.aws-region.rds.amazonaws.com -U postgres -p 5432
  2. Execute os seguintes comandos SQL:

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

Exemplos: Invocar uma função do Lambda da instância de banco de dados do RDS for PostgreSQL

A seguir, você pode encontrar alguns exemplos de como chamar a função aws_lambda.invoke. A maioria dos exemplos usa a estrutura composta aws_lambda_arn_1 que você cria em Etapa 4: usar as funções Lambda auxiliares com a instância de banco de dados do RDS for PostgreSQL (opcional) para simplificar a passagem dos detalhes da função. Para obter um exemplo de invocação assíncrona, consulte Exemplo: invocação assíncrona (evento) de funções Lambda. Todos os outros exemplos listados usam invocação síncrona.

Para saber mais sobre os tipos de invocação do Lambda, consulte Invocação de funções Lambda no Guia do desenvolvedor do AWS Lambda. Para obter mais informações sobre o aws_lambda_arn_1, consulte aws_commons.create_lambda_function_arn.

Exemplo: invocação síncrona (RequestResponse) de funções Lambda

A seguir estão dois exemplos de uma invocação síncrona de função Lambda. Os resultados dessas chamadas de funções aws_lambda.invoke são os mesmos.

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');

Os parâmetros são descritos da seguinte forma:

  • :'aws_lambda_arn_1' – Este parâmetro identifica a estrutura composta criada em Etapa 4: usar as funções Lambda auxiliares com a instância de banco de dados do RDS for PostgreSQL (opcional), com a função auxiliar aws_commons.create_lambda_function_arn. Você também pode criar essa estrutura em linha dentro da sua chamada aws_lambda.invoke da seguinte forma:

    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 – A carga útil JSON para passar para a função Lambda.

  • 'RequestResponse' – O Lambda tipo de invocação.

Exemplo: invocação assíncrona (evento) de funções Lambda

Segue-se um exemplo de uma invocação de função Lambda assíncrona. O tipo de invocação Event agenda a invocação de função Lambda com a carga de entrada específica e retorna imediatamente. Use o tipo de invocação de Event em determinados fluxos de trabalho que não dependem dos resultados da função Lambda.

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

Exemplo: capturar o log de execução do Lambda em uma resposta de função

Você pode incluir os últimos 4 KB do log de execução na resposta da função usando o parâmetro log_type em sua chamada de função aws_lambda.invoke. Por padrão, esse parâmetro é definido como None, mas você pode especificar Tail para capturar os resultados do log de execução do Lambda na resposta, conforme mostrado a seguir.

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');

Defina o parâmetro aws_lambda.invoke da função log_type para Tail incluir o log de execução na resposta. O valor padrão para o parâmetro log_type é None.

O log_result que é retornado é uma string codificada de base64. Você pode decodificar os conteúdos usando uma combinação das funções PostgreSQL decode e convert_from.

Para obter mais informações sobre o log_type, consulte aws_lambda.invoke.

Exemplo: incluir o contexto do cliente em uma função Lambda

A função aws_lambda.invoke tem um parâmetro context que você pode usar para passar informações separadas da carga útil, como mostrado a seguir.

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 o contexto do cliente, use um objeto JSON para o parâmetro aws_lambda.invoke da funçãocontext.

Para obter mais informações sobre os parâmetros do context, consulte a referência aws_lambda.invoke.

Exemplo: invocar uma versão específica de uma função Lambda

Você pode especificar uma determinada versão de uma função Lambda incluindo o parâmetro qualifier com a chamada aws_lambda.invoke. A seguir, você pode encontrar um exemplo que faz isso usando 'custom_version' como um alias para a versão.

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

Você também pode fornecer um qualificador de função Lambda com as informações de nome da função da forma a seguir.

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

Para obter mais informações sobre qualifier e outros parâmetros, consulte a referência aws_lambda.invoke.

Mensagens de erro da função Lambda

Na lista a seguir, você pode encontrar informações sobre mensagens de erro, com possíveis causas e soluções.

  • Problemas de configuração da VPC

    Problemas de configuração da VPC podem gerar as seguintes mensagens de erro ao tentar se conectar:

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

    Uma causa comum para esse erro é o grupo de segurança da VPC configurado incorretamente. É necessário ter uma regra de saída para TCP aberta na porta 443 para que o grupo de segurança de sua VPC possa se conectar à VPC do Lambda.

    Se sua instância de banco de dados for privada, verifique a configuração DNS privada para sua VPC. Verifique se você definiu o parâmetro rds.custom_dns_resolution como 1 e configurou o AWSPrivateLink conforme descrito em Etapa 1: configurar a instância de banco de dados do RDS for PostgreSQL para conexões de saída para o AWS Lambda. Para obter mais informações, consulte Endpoints da VPC (AWS PrivateLink).

  • Falta de permissões necessárias para invocar funções do Lambda

    Se você vir uma das seguintes mensagens de erro, isso significa que o usuário (função) que está invocando a função não tem as permissões adequadas.

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

    Um usuário (função) deve receber concessões específicas para invocar funções do Lambda. Para obter mais informações, consulte Etapa 6: Conceder a outros usuários permissão para invocar funções do Lambda.

  • Tratamento inadequado de erros em suas funções do Lambda

    Se uma função Lambda lança uma exceção durante o processamento da solicitação, aws_lambda.invoke terá um erro do PostgreSQL, como o seguinte.

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

    Certifique-se de lidar com erros nas funções Lambda ou na aplicação PostgreSQL.