AWS Lambda
Guia do desenvolvedor

Tutorial: acionar uma função Lambda com eventos do AWS CloudTrail

É possível configurar o Amazon S3 para publicar eventos no AWS Lambda quando o AWS CloudTrail armazenar logs de chamadas de API. A função Lambda pode ler o objeto de log e processar os registros de acesso realizados pelo CloudTrail.

Use as instruções a seguir para criar uma função Lambda que notifica você quando uma chamada de API específica é feita em sua conta. A função processa eventos de notificação do Amazon S3, lê logs de um bucket e publica alertas por meio de um tópico do Amazon SNS. Para este tutorial, você cria:

  • Uma trilha do CloudTrail e um bucket do S3 no qual salvar logs.

  • Um tópico do Amazon SNS para publicar notificações de alerta.

  • Uma função de usuário do IAM com permissões para ler itens de um bucket do S3 e gravar logs no Amazon CloudWatch.

  • Uma função Lambda que processa logs do CloudTrail e envia uma notificação sempre que um tópico do Amazon SNS é criado.

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.

Antes de começar, verifique se você tem as seguintes ferramentas:

Etapa 1: Criar uma trilha no CloudTrail

Quando você cria uma trilha, o CloudTrail registra as chamadas de API em arquivos de log e as armazena no Amazon S3. Um log do CloudTrail é uma matriz de eventos não ordenados no formato JSON. Para cada chamada a uma ação de API com suporte, o CloudTrail registra informações sobre a solicitação e a entidade que fez a chamada. Os eventos de log incluem o nome da ação, os parâmetros, valores de resposta e detalhes sobre o solicitante.

Para criar uma trilha

  1. Abra a página Trilhas do CloudTrail console do.

  2. Escolha Create Trail (Criar trilha).

  3. Em Trail name (Nome da trilha), insira um nome.

  4. Em S3 bucket (Bucket do S3), insira um nome.

  5. Escolha Criar.

  6. Salve o nome de recurso da Amazon (ARN) do bucket para adicioná-lo à função de execução do IAM, que será criada posteriormente.

Etapa 2: Criar um tópico do Amazon SNS

Crie um tópico do Amazon SNS para enviar uma notificação quando novos eventos de objeto tiverem ocorrido.

Para criar um tópico

  1. Abra a página Topics (Tópicos) do console do Amazon SNS.

  2. Escolha Create topic (Criar tópico).

  3. Em Topic name (Nome do tópico), insira um nome.

  4. Escolha Create topic (Criar tópico).

  5. Registre o ARN do tópico. Você precisará dele ao criar a função de execução do IAM e a função Lambda.

Etapa 3: Criar uma função de execução do IAM

Uma função de execução concede à sua função permissão para acessar recursos da AWS. Crie uma função de execução que conceda à função permissão para acessar o CloudWatch Logs, o Amazon S3 e o Amazon SNS.

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

  1. Abra a página Roles (Funções) do console do IAM.

  2. Selecione Create role.

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

    • Em Trusted entity (Entidade confiável), selecione Lambda.

    • Em Role Name (Nome da função), insira lambda-cloudtrail-role.

    • Em Permissions (Permissões), crie uma política personalizada com as instruções a seguir. Substitua os valores destacados pelos nomes do seu bucket e do tópico.

      { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:*" ], "Resource": "arn:aws:logs:*:*:*" }, { "Effect": "Allow", "Action": [ "s3:GetObject" ], "Resource": "arn:aws:s3:::my-bucket/*" }, { "Effect": "Allow", "Action": [ "sns:Publish" ], "Resource": "arn:aws:sns:us-west-2:123456789012:my-topic" } ] }
  4. Anote o ARN da função. Você precisará dele ao criar a função Lambda.

Etapa 4: Criar a função Lambda

A função Lambda a seguir processa logs do CloudTrail e envia uma notificação por meio do Amazon SNS quando um tópico do Amazon SNS é criado.

Para criar a função

  1. Crie uma pasta e atribua um nome que indique que ela é sua função Lambda (por exemplo, lambda-cloudtrail).

  2. Na pasta, crie um arquivo chamado index.js.

  3. Cole o seguinte código em index.js. Substitua o ARN do tópico do Amazon SNS pelo ARN que o Amazon S3 criou quando você criou o tópico do Amazon SNS.

    var aws = require('aws-sdk'); var zlib = require('zlib'); var async = require('async'); var EVENT_SOURCE_TO_TRACK = /sns.amazonaws.com/; var EVENT_NAME_TO_TRACK = /CreateTopic/; var DEFAULT_SNS_REGION = 'us-east-2'; var SNS_TOPIC_ARN = 'arn:aws:sns:us-west-2:123456789012:my-topic'; var s3 = new aws.S3(); var sns = new aws.SNS({ apiVersion: '2010-03-31', region: DEFAULT_SNS_REGION }); exports.handler = function(event, context, callback) { var srcBucket = event.Records[0].s3.bucket.name; var srcKey = event.Records[0].s3.object.key; async.waterfall([ function fetchLogFromS3(next){ console.log('Fetching compressed log from S3...'); s3.getObject({ Bucket: srcBucket, Key: srcKey }, next); }, function uncompressLog(response, next){ console.log("Uncompressing log..."); zlib.gunzip(response.Body, next); }, function publishNotifications(jsonBuffer, next) { console.log('Filtering log...'); var json = jsonBuffer.toString(); console.log('CloudTrail JSON from S3:', json); var records; try { records = JSON.parse(json); } catch (err) { next('Unable to parse CloudTrail JSON: ' + err); return; } var matchingRecords = records .Records .filter(function(record) { return record.eventSource.match(EVENT_SOURCE_TO_TRACK) && record.eventName.match(EVENT_NAME_TO_TRACK); }); console.log('Publishing ' + matchingRecords.length + ' notification(s) in parallel...'); async.each( matchingRecords, function(record, publishComplete) { console.log('Publishing notification: ', record); sns.publish({ Message: 'Alert... SNS topic created: \n TopicARN=' + record.responseElements.topicArn + '\n\n' + JSON.stringify(record), TopicArn: SNS_TOPIC_ARN }, publishComplete); }, next ); } ], function (err) { if (err) { console.error('Failed to publish notifications: ', err); } else { console.log('Successfully published all notifications.'); } callback(null,"message"); }); };
  4. Na pasta lambda-cloudtrail execute o script a seguir. Isso cria um arquivo package-lock.json e uma pasta node_modules, que lida com todas as dependências.

    $ npm install async
  5. Execute o script a seguir para criar um pacote de implantação.

    $ zip -r function.zip .
  6. Crie uma função Lambda chamada CloudTrailEventProcessing com o comando create-function executando o script a seguir. Faça as substituições indicadas.

    $ aws lambda create-function --function-name CloudTrailEventProcessing \ --zip-file fileb://function.zip --handler index.handler --runtime nodejs8.10 --timeout 10 --memory-size 1024 \ --role arn:aws:iam::123456789012:role/lambda-cloudtrail-role

Etapa 5: Adicionar permissões à política da função Lambda

A política de recursos da função Lambda precisa de permissões para permitir que o Amazon S3 invoque a função.

Como conceder ao Amazon S3 permissões para invocar a função

  1. Execute o seguinte comando add-permission. Substitua o ARN e o ID da conta pelos seus.

    $ aws lambda add-permission --function-name CloudTrailEventProcessing \ --statement-id Id-1 --action "lambda:InvokeFunction" --principal s3.amazonaws.com \ --source-arn arn:aws:s3:::my-bucket \ --source-account 123456789012

    Esse comando concede ao principal do serviço Amazon S3 (s3.amazonaws.com) permissões para executar a ação lambda:InvokeFunction. As permissões de invocação serão concedidas ao Amazon S3 somente se as seguintes condições forem atendidas:

    • O CloudTrail armazena um objeto de log no bucket especificado.

    • O bucket é de propriedade da conta especificada da AWS. Se o proprietário do bucket exclui um bucket, outra conta da AWS pode criar um bucket com o mesmo nome. Essa condição garante que somente a conta especificada da AWS possa invocar a função Lambda.

  2. Para visualizar a política de acesso da função Lambda, execute o comando get-policy a seguir e substitua o nome da função.

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

Etapa 6: Configurar notificações em um bucket do Amazon S3

Para solicitar que o Amazon S3 publique eventos criados por objetos no Lambda, adicione uma configuração de notificação ao bucket do S3. Na página de configuração, você deve especificar o seguinte:

  • Tipo de eventos – Quaisquer tipos de eventos que criam objetos.

  • Função Lambda – a função Lambda que você deseja que o Amazon S3 invoque.

Como configurar notificações

  1. Abra o console do Amazon S3.

  2. Escolha o bucket de origem.

  3. Escolha Properties (Propriedades).

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

    • Name (Nome)lambda-trigger

    • Events (Eventos)All object create events

    • Send to (Enviar para)Lambda function

    • LambdaCloudTrailEventProcessing

Quando o CloudTrail armazena logs no bucket, o Amazon S3 envia um evento para a função. O evento fornece informações, incluindo o nome do bucket e o nome da chave do objeto de log que o CloudTrail criou.