Tutorial: usar o AWS Lambda com o Amazon S3 - AWS Lambda

Tutorial: usar o AWS Lambda com o Amazon S3

Suponha que você deseja criar uma miniatura para cada arquivo de imagem que é obtida por upload em um bucket. Você pode criar uma função do Lambda (CreateThumbnail) que o Amazon S3 pode invocar quando os objetos são criados. Em seguida, a função do Lambda pode ler o objeto de imagem do bucket de origem e criar um bucket de destino da imagem em miniatura.

Ao concluir este tutorial, você terá os seguintes recursos do Amazon S3, do Lambda e do IAM na sua conta:

Recursos do Lambda

  • Uma função do Lambda.

  • Uma política de acesso associada à sua função do Lambda que concede a permissão do Amazon S3 para invocar a função do Lambda.

Recursos do IAM

  • Uma função de execução que concede permissões de que sua função do Lambda precisa por meio da política de permissões associada a essa função.

Recursos do Amazon S3

  • Um bucket de origem com uma configuração de notificação que invoca a função do Lambda.

  • Um bucket de destino em que a função salva imagens redimensionadas.

Pré-requisitos

Este tutorial pressupõe que você tenha algum conhecimento das operações básicas do Lambda e do console do Lambda. Caso ainda não tenha feito isso, siga as instruções em Conceitos básicos do AWS Lambda para criar sua primeira função do Lambda.

Para seguir os procedimentos neste manual, você precisa de um terminal de linha de comando ou de um shell para executar os comandos. Nas listagens, os comandos são mostrados precedidos por um símbolo de prompt ($) e pelo nome do diretório atual, quando apropriado:

~/lambda-project$ this is a command this is output

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. No Windows 10, você pode instalar o Subsistema Windows para Linux para obter uma versão do Ubuntu integrada com o Windows e o Bash.

Instalar o npm para gerenciar as dependências da função.

O tutorial usa comandos da CLI da AWS para criar e chamar a função do Lambda. Instale a CLI da AWS e configure-a usando com suas credenciais da AWS

Criar a função de execução

Crie a função de execução que dá à sua função permissão para acessar recursos do AWS.

Para criar uma função de execução

  1. Abra a página Roles no console do IAM.

  2. Selecione Create role.

  3. Crie uma função com as seguintes propriedades.

    • Trusted entity (Entidade confiável)AWS Lambda.

    • Permissions (Permissões)AWSLambdaExecute.

    • Nome da funçãolambda-s3-role.

A política AWSLambdaExecute tem as permissões de que a função precisa para gerenciar objetos no Amazon S3 e gravar logs no CloudWatch Logs.

Criar buckets e fazer upload de um objeto de exemplo

Siga as etapas para criar buckets e fazer upload de um objeto.

  1. Abra o console do Amazon S3.

  2. Crie dois buckets. O nome do bucket de destino deve ser source seguido por -resized, em que source é o nome do bucket que você deseja usar como a origem. Por exemplo, mybucket e mybucket-resized.

  3. No bucket de origem, faça upload de um objeto.jpg, HappyFace.jpg.

    Quando você invoca a função do Lambda manualmente antes de se conectar ao Amazon S3, você passa os dados do evento de exemplo para a função que especifica o bucket de origem e HappyFace.jpg como o objeto recém-criado, portanto, você precisa criar esse objeto de exemplo primeiro.

Criar a função

O código de amostra a seguir recebe uma entrada de evento Amazon S3 e processa a mensagem que ela contém. Ele redimensiona uma imagem no bucket de origem e salva a saída no bucket de destino.

nota

Para ver o código de exemplo em outras linguagens, consulte Código de exemplo da função do Amazon S3.

exemplo index.js

// dependencies const AWS = require('aws-sdk'); const util = require('util'); const sharp = require('sharp'); // get reference to S3 client const s3 = new AWS.S3(); exports.handler = async (event, context, callback) => { // Read options from the event parameter. console.log("Reading options from event:\n", util.inspect(event, {depth: 5})); const srcBucket = event.Records[0].s3.bucket.name; // Object key may have spaces or unicode non-ASCII characters. const srcKey = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, " ")); const dstBucket = srcBucket + "-resized"; const dstKey = "resized-" + srcKey; // Infer the image type from the file suffix. const typeMatch = srcKey.match(/\.([^.]*)$/); if (!typeMatch) { console.log("Could not determine the image type."); return; } // Check that the image type is supported const imageType = typeMatch[1].toLowerCase(); if (imageType != "jpg" && imageType != "png") { console.log(`Unsupported image type: ${imageType}`); return; } // Download the image from the S3 source bucket. try { const params = { Bucket: srcBucket, Key: srcKey }; var origimage = await s3.getObject(params).promise(); } catch (error) { console.log(error); return; } // set thumbnail width. Resize will set the height automatically to maintain aspect ratio. const width = 200; // Use the Sharp module to resize the image and save in a buffer. try { var buffer = await sharp(origimage.Body).resize(width).toBuffer(); } catch (error) { console.log(error); return; } // Upload the thumbnail image to the destination bucket try { const destparams = { Bucket: dstBucket, Key: dstKey, Body: buffer, ContentType: "image" }; const putResult = await s3.putObject(destparams).promise(); } catch (error) { console.log(error); return; } console.log('Successfully resized ' + srcBucket + '/' + srcKey + ' and uploaded to ' + dstBucket + '/' + dstKey); };

Analise o código anterior e observe o seguinte:

  • A função conhece o nome do bucket de origem e o nome da chave do objeto dos dados do evento que recebe como parâmetros. Se o objeto for um .jpg ou um .png, o código criará e salvará uma miniatura no bucket de destino.

  • O código pressupõe que o bucket de destino existe e seu nome é uma concatenação do nome do bucket de origem seguido pela string -resized. Por exemplo, se o bucket de origem identificado nos dados do evento for examplebucket, o código pressuporá que você tem um bucket de destino examplebucket-resized.

  • Para a miniatura que cria, o código deriva seu nome de chave como a concatenação da string resized- seguida pelo nome da chave do objeto de origem. Por exemplo, se a chave do objeto de origem for sample.jpg, o código criará um objeto em miniatura que terá a chave resized-sample.jpg.

O pacote de implantação é um arquivo .zip que contém o código de sua função de Lambda e as dependências.

Como criar um pacote de implantação

  1. Salve o código da função como index.js em uma pasta chamada lambda-s3.

  2. Instale a biblioteca Sharp com npm. No Linux, use o comando a seguir:

    lambda-s3$ npm install sharp

    No macOS, use o comando a seguir:

    lambda-s3$ npm install --arch=x64 --platform=linux --target=12.13.0 sharp

    Depois de concluir esta etapa, você terá a seguinte estrutura de pastas:

    lambda-s3 |- index.js |- /node_modules/sharp └ /node_modules/...
  3. Crie um pacote de implantação com o código da função e as dependências.

    lambda-s3$ zip -r function.zip .

Para criar a função

  • Crie uma função do Lambda com o comando create-function.

    $ aws lambda create-function --function-name CreateThumbnail \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs12.x \ --timeout 10 --memory-size 1024 \ --role arn:aws:iam::123456789012:role/lambda-s3-role

No parâmetro de função, substitua a sequência numérica pelo ID de conta da AWS. O exemplo de comando anterior especifica um valor de tempo limite de 10 segundos como a configuração da função. Dependendo do tamanho dos objetos obtidos por upload, pode ser necessário aumentar o valor do tempo limite usando o seguinte comando da AWS CLI.

$ aws lambda update-function-configuration --function-name CreateThumbnail --timeout 30

Testar a função do Lambda

Nessa etapa, você invoca a função do Lambda manualmente usando dados do evento de exemplo do Amazon S3.

Para testar a função do Lambda

  1. Salve os seguintes dados dos eventos de exemplo do Amazon S3 em um arquivo e salve-o como inputFile.txt. Você precisa atualizar o JSON fornecendo o nome do sourcebucket e uma chave do objeto .jpg.

    { "Records":[ { "eventVersion":"2.0", "eventSource":"aws:s3", "awsRegion":"us-west-2", "eventTime":"1970-01-01T00:00:00.000Z", "eventName":"ObjectCreated:Put", "userIdentity":{ "principalId":"AIDAJDPLRKLG7UEXAMPLE" }, "requestParameters":{ "sourceIPAddress":"127.0.0.1" }, "responseElements":{ "x-amz-request-id":"C3D13FE58DE4C810", "x-amz-id-2":"FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD" }, "s3":{ "s3SchemaVersion":"1.0", "configurationId":"testConfigRule", "bucket":{ "name":"sourcebucket", "ownerIdentity":{ "principalId":"A3NL1KOZZKExample" }, "arn":"arn:aws:s3:::sourcebucket" }, "object":{ "key":"HappyFace.jpg", "size":1024, "eTag":"d41d8cd98f00b204e9800998ecf8427e", "versionId":"096fKKXTRTtl3on89fVO.nfljtsv6qko" } } } ] }
  2. Execute o comando invoke da CLI do Lambda para invocar a função. Observe que o comando solicita execução assíncrona. Opcionalmente, você pode invocá-la de forma síncrona especificando RequestResponse como o valor do parâmetro invocation-type.

    $ aws lambda invoke --function-name CreateThumbnail --invocation-type Event \ --payload file://inputFile.txt outputfile.txt
  3. Verifique se a miniatura foi criada no bucket de destino.

Configurar o Amazon S3 para publicar eventos

Nessa etapa, você adiciona o restante da configuração para que o Amazon S3 possa publicar eventos criados por objetos no AWS Lambda e invocar sua função do Lambda. Nesta etapa, faça o seguinte:

  • Adicione permissões à política de acesso da função do Lambda para permitir que o Amazon S3 invoque a função.

  • Adicione a configuração de notificação ao bucket de origem. Na configuração de notificação, você fornece o seguinte:

    • Tipo de evento para o qual você deseja que o Amazon S3 publique eventos. Para este tutorial, você especifica o tipo de evento s3:ObjectCreated:* para que o Amazon S3 publique eventos quando forem criados objetos.

    • Função Lambda para invocar.

Como adicionar permissões à política de função

  1. Execute o comando add-permission da CLI do Amazon S3 para conceder à entidade de serviço do Lambda (s3.amazonaws.com) as principais permissões para executar a ação lambda:InvokeFunction. Observe que a permissão será concedida ao Amazon S3 para invocar a função somente se as seguintes condições forem atendidas:

    • Um evento criado por objeto é detectado em um bucket específico.

    • O bucket é de propriedade da sua conta. Se você excluir um bucket, será possível que outra conta crie um bucket com o mesmo ARN.

    $ aws lambda add-permission --function-name CreateThumbnail --principal s3.amazonaws.com \ --statement-id s3invoke --action "lambda:InvokeFunction" \ --source-arn arn:aws:s3:::sourcebucket \ --source-account account-id
  2. Verifique a política de acesso da função executando o comando AWS CLI get-policy.

    $ aws lambda get-policy --function-name CreateThumbnail

Adicione a configuração de notificação no bucket de origem para solicitar que o Amazon S3 publique os eventos criados pelo objeto no Lambda.

Importante

Este procedimento configura o bucket para chamar a função sempre que um objeto é criado nele. Certifique-se de configurar essa opção somente no bucket de origem e não criar objetos no bucket de origem a partir da função disparada. Caso contrário, a função pode fazer com que ela seja invocada continuamente em um loop.

Como configurar notificações

  1. Abra o console do Amazon S3.

  2. Escolha o bucket de origem.

  3. Escolha Propriedades.

  4. Em Events (Eventos), configure uma notificação com as configurações a seguir.

    • Name (Nome)lambda-trigger.

    • Events (Eventos)ObjectCreate (All).

    • Send to (Enviar para)Lambda function.

    • LambdaCreateThumbnail.

Para obter mais informações sobre a configuração de eventos, consulte Habilitar notificações de eventos no Guia do usuário do console do Amazon Simple Storage Service.

Testar a configuração

Agora você pode testar a configuração da seguinte forma:

  1. Fazer upload dos objetos .jpg ou .png no bucket de origem usando o console do Amazon S3.

  2. Verificar se a miniatura foi criada no bucket de destino usando a função CreateThumbnail.

  3. Visualize logs no console do CloudWatch.