Artigo original: AWS Lambda Interview Questions and Answers

Neste artigo, abordarei algumas das perguntas mais comuns que surgem em entrevistas sobre o AWS Lambda.

Observe que esta não é uma lista exaustiva – você pode usar este guia, no entanto, como uma referência para atualizar seu conhecimento e obter indicações de estudos mais aprofundados.

A maioria das perguntas será baseada em sua experiência ou em determinados cenários. As perguntas estão nos títulos e você encontrará, logo abaixo delas, observações sobre o raciocínio por trás de fazer as perguntas.

Explique seu último projeto envolvendo o AWS Lambda

O entrevistador quer saber sobre sua experiência na vida real usando o AWS Lambda. Não blefe aqui, pois o entrevistador pode fazer mais perguntas com base nas respostas a essa pergunta.

Você pode ter criado uma API sem servidor (em inglês, serverless), sistemas envolvendo microsserviços, conversão de imagem/vídeo, análise de logs e muito mais. Apenas explique seu projeto em detalhes e fale sobre os benefícios comerciais desse projeto para que o entrevistador saiba que você está vendo o quadro geral.

Quais serviços você integrou com o AWS Lambda?

Essa é uma extensão da pergunta anterior. Ela não é uma lista completa de todas as fontes de eventos que podem se conectar ao AWS Lambda. Conte apenas sobre os serviços que você realmente usou.

Você pode ter usado S3, SNS, SQS, Kinesis, DynamoDB, SES ou outros. Nem todos os projetos serão completamente sem servidor.

Se você usou algum componente sem servidor junto com o AWS Lambda, mencione-os também. Por exemplo, você pode ter usado AWS Lambda com RDS. Se você usou essa configuração, pode explicar sobre isso em seu raciocínio.

Explique o conceito de inicializações a quente e a frio (warm and cold starts) no AWS Lambda

Há duas razões para fazer esta pergunta. Eles querem saber os tempos de execução que você usou e querem saber se você conhece os outros tempos de execução que podem causar uma inicialização a frio.

Os serviços Lambda recebem uma solicitação para executar uma função lambda. O serviço prepara o ambiente de execução baixando o código da função do manipulador e alocando memória junto com outra configuração.

Mesmo que você não seja cobrado por esse tempo de preparação do ambiente de execução, terá que enfrentar o atraso na chamada de sua função lambda. Esse atraso é chamado de "inicialização a frio" (do inglês, "cold start").

O tempo de inicialização a frio é menos significativo para ambientes de tempo de execução do TypeScript e do Python, sendo um pouco maior para ambientes de tempo de execução do Java ou do C#.

Para melhorar o desempenho, o serviço lambda manterá o ambiente de execução por algum tempo. Quando você receber a solicitação para a mesma função lambda novamente durante esse período, seu manipulador poderá começar a executar imediatamente. Esse tipo de chamada é chamada de "inicialização a quente" (do inglês, "warm start").

image-18
Fonte da imagem

Qual é a diferença entre invocação síncrona e assíncrona no AWS Lambda?

Mesmo que pareça uma pergunta direta, ela tem muitas implicações para o seu design e tratamento de erros.

Na invocação síncrona, o chamador aguardará a conclusão da execução. Na invocação assíncrona, contudo, o chamador colocará o evento em uma fila interna que, posteriormente, será processada na função lambda.

image-19
Fonte da imagem

Um ponto importante a ser observado aqui é que você não pode ditar o tipo de invocação. Isso depende do serviço que você usa com o AWS Lambda.

Por exemplo, se você estiver criando APIs sem servidor usando o API Gateway, será uma invocação síncrona. Se você, no entanto, estiver usando o S3, será uma invocação assíncrona.

Como você implementa tratamento de erros e lógica de novas tentativas no Lambda?

Qualquer componente no sistema orientado a eventos que possa falhar, falhará. Então, o entrevistador quer saber como você lidou com o erro e como tentou novamente em seus projetos anteriores. Abaixo estão alguns exemplos. Sempre explique com exemplos concretos.

Isso depende do serviço que você está usando com o AWS Lambda. Vamos discutir alguns exemplos.

Se você estiver criando uma API sem servidor, é melhor retornar esse erro para o client de chamada (pode ser uma aplicação de front-end neste caso). Em seguida, você permite que sua lógica de front-end decida o que exibir ao usuário com base no tipo de erro.

Se você estiver usando o Lambda com SQS, é melhor usar uma Dead Letter Queue para saber quais mensagens não foram processadas. Por esse mesmo motivo, muitos dos sistemas que usam SNS também podem usar SQS.

No código abaixo, estamos usando uma dead letter queue. Se alguma mensagem não for processada após um determinado número de vezes (conforme especificado por maxReceiveCount), ela será enviada para a "fila de mensagens mortas". Esse comportamento é específico para lambda quando usado junto com filas.

const queue = new sqs.Queue(this, 'AwsLambdaSqsQueue', {
      visibilityTimeout: cdk.Duration.seconds(300),
      receiveMessageWaitTime: cdk.Duration.seconds(20),
      deadLetterQueue: {
        queue: new sqs.Queue(this, 'AwsLambdaDlq'),
        maxReceiveCount: 5,
      },
    });

Quando o lambda é invocado com qualquer outro serviço, você pode configurar o número de tentativas com um valor máximo de 2. Isso significa que você pode ter, no máximo, duas tentativas além da chamada inicial. Por exemplo, você deseja acionar com base no upload do objeto S3 e seu lambda tentará no máximo três vezes.

Explique seus fluxos de trabalho para desenvolvimento e implantação de funções do AWS Lambda

Fale sobre os frameworks que você usou. O entrevistador pode esperar que você fale sobre o teste de funções lambda também.

Você pode explicar quais frameworks você usou para desenvolver e implantar funções lambda. Você também pode falar sobre qualquer ferramenta de IaC (Infraestrutura como Código) que você usou.

Abaixo, temos uma lista não exaustiva dos frameworks mais usados:

  • Serverless
  • AWS CDK
  • AWS SAM
  • CloudFormation
  • Pulumi

Se você já usou o Terraform, também pode falar sobre isso.

O Lambda pode ser invocado quando você recebe um e-mail para um determinado endereço de e-mail de suporte? Se sim, projete esse sistema. Se não, explique por quê.

Sim, você pode. Você pode criar um conjunto de regras de recebimento e adicionar uma regra que acione a função lambda.

Você deve armazenar o e-mail no S3 e acionar o lambda depois disso para que possa ter a cópia do e-mail para qualquer referência futura.

Você pode consultar este artigo (em inglês) sobre como receber e-mails de um formulário de contato.

image-20
Fonte da imagem

Uma função lambda pode chamar outra função lambda?

O entrevistador quer saber se você conhece esse antipadrão.

Você pode fazer isso, mas não é recomendado. Se quiser criar um fluxo de trabalho que envolva várias funções lambda, você pode usar as funções de etapa.

image-21
Fonte da imagem

Você pode ler mais sobre funções de etapa aqui.

Outra abordagem padrão é emitir um evento e acionar um lambda com base no evento. Você pode usar SQS, SNS ou EventBridge como intermediário para esses eventos.

Você pode executar consultas em uma instância do RDS (em uma sub-rede privada) usando o Lambda?

Sim, você pode executar a consulta no RDS usando o AWS Lambda. Para isso, você pode ter seu lambda dentro da mesma VPC.

Pode haver algumas implicações de desempenho se você usar o AWS Lambda diretamente com o RDS. Isso ocorre devido ao tempo de criação da conexão do banco de dados. Para evitar essas implicações, você pode usar um RDS Proxy.

image-22
Fonte da imagem

Aqui está um guia passo a passo detalhado (em inglês) que mostra como fazer isso.

O AWS Lambda fornece muitos benefícios. Quais são as desvantagens de se usar o AWS Lambda?

O entrevistador quer saber sobre o seu processo de pensamento. Não diga que o AWS Lambda resolve todos os problemas. 🙂

Sim, o Lambda oferece muitos benefícios, como custo e escalabilidade, sem a necessidade de manter os servidores. Ele, porém, não é a resposta para tudo. Como qualquer serviço, ele tem seus próprios problemas (e você deve ser capaz de discuti-los):

  • Depuração: se você estiver usando arquiteturas sem servidor usando o Lambda, talvez precise contar com o log para encontrar a causa raiz do problema. Isso ocorre porque seu aplicativo será distribuído em muitos serviços/funções lambda.
  • Teste: você pode simular serviços da AWS em seu teste local. É melhor, no entanto, ter um ambiente separado na AWS para testar seus lambdas. Isso torna o teste um pouco complexo.
  • Tarefas em segundo plano: o Lambda tem um limite de tempo limite de 15 minutos. Se você deseja que qualquer tarefa específica leve mais de 15 minutos, talvez seja necessário mudar para o Fargate ou alguma outra solução.
  • Custo: se você estiver executando um aplicativo de alto tráfego que processa as solicitações 24 horas por dia, 7 dias por semana, o uso de lambda pode ser caro. É melhor usar Fargate, EC2 ou outros serviços, se você tiver alto tráfego constante.

Como você gerencia simultaneidade e dimensionamento no AWS Lambda?

Você ganhará pontos de bônus se falar sobre os problemas que enfrentou nessas situações.

Simultaneidade (em inglês, concurrency) é a capacidade de executar várias funções lambda ao mesmo tempo. O dimensionamento (scaling) é o processo de aumentar o número de cópias de sua função lambda para lidar com as solicitações recebidas.

Você pode controlar a simultaneidade definindo o valor de simultaneidade reservada para que apenas o número mencionado de funções lambda seja invocado.

Abaixo está o diagrama de alto nível de como lambda escala de acordo com o número de mensagens na fila.

image-23
Fonte da imagem

Observação: há algum comportamento estranho se você tentar limitar o AWS Lambda quando usado com a fila padrão do SQS. Você pode usar uma fila FIFO para resolver esse problema.

Como você passa variáveis de ambiente para o AWS Lambda?

O entrevistador pode querer saber como você passa informações sigilosas, por exemplo.

Existem diferentes maneiras de passar variáveis de ambiente para o AWS Lambda, dependendo do tipo de valor que está sendo passado.

Dados não confidenciais: se você deseja passar informações não confidenciais, pode passar os valores diretamente para as variáveis de ambiente da função lambda. Esses valores, contudo, seriam visíveis no console da AWS no serviço Lambda. No exemplo de código abaixo, estamos passando o nome da tabela DynamoDB diretamente como variável de ambiente, pois não são dados confidenciais:

   const readDDBLambdaFn = new NodejsFunction(this, 'readDDBLambdaFn', {
      entry: path.join(__dirname, '../src/lambdas', 'read-ddb.ts'),
      ...nodeJsFunctionProps,
      functionName: 'readDDBLambdaFn',
      environment: {
        tableName: table.tableName,
      },
    });

Dados confidenciais: se você deseja transmitir dados confidenciais, como senhas e chaves de API, pode usar um gerenciador de segredos ou um armazenamento de parâmetros. Porém, você precisa se certificar de fornecer as funções necessárias ao Lambda para acessar e descriptografar segredos dos respectivos serviços.

No trecho de código abaixo, NÃO estamos passando o segredo real. Em vez disso, estamos apenas passando o ARN (Amazon Resource Name) do segredo.

const rdsLambdaFn = new NodejsFunction(this, 'rdsLambdaFn', {
      entry: path.join(__dirname, '../src/lambdas', 'rds-lambda.ts'),
      ...nodeJsFunctionProps,
      functionName: 'rdsLambdaFn',
      environment: {
        DB_ENDPOINT_ADDRESS: dbInstance.dbInstanceEndpointAddress,
        DB_NAME: databaseName,
        DB_SECRET_ARN: dbInstance.secret?.secretFullArn || '',
      },
      vpc,
      vpcSubnets: vpc.selectSubnets({
        subnetType: ec2.SubnetType.PRIVATE_WITH_EGRESS,
      }),
    });

Em seguida, no lambda, você pode obter o segredo real dinamicamente na função lambda, conforme mostrado abaixo:

export const handler = async (event: any, context: any): Promise<any> => {
    const host = process.env.DB_ENDPOINT_ADDRESS || '';
    const database = process.env.DB_NAME || '';
    const dbSecretArn = process.env.DB_SECRET_ARN || '';
    const secretManager = new AWS.SecretsManager({
      region: 'us-east-1',
    });
    const secretParams: AWS.SecretsManager.GetSecretValueRequest = {
      SecretId: dbSecretArn,
    };
    const dbSecret = await secretManager.getSecretValue(secretParams).promise();
    const secretString = dbSecret.SecretString || '';

    const { password } = JSON.parse(secretString);

}

O autor deste artigo escreveu um tutorial detalhado aqui sobre o mesmo tópico.

Digamos que você tenha alguma ferramenta .exe executável dependente do Windows. Você pode carregá-la em um bucket do S3. Você pode executar este binário com alguns parâmetros usando o AWS Lambda?

Essa é mais uma pergunta para garantir que você entende o ambiente de execução do AWS Lambda – especificamente, o sistema operacional que ele usa.

Não, você não seria capaz de fazer isso, pois o AWS Lambda usa o Linux como sistema operacional. O Linux não seria capaz de executar um binário dependente do Windows.

Como você reutilizaria código entre funções do AWS Lambda?

Existem duas maneiras de reutilizar o código em muitas funções do AWS Lambda:

  • Usar as camadas do Lambda: você pode armazenar seu código ou lógica em camadas do lambda, que você pode reutilizar em diferentes funções do lambda.

Abaixo está um código de alto nível para criar e consumir camadas do lambda usando aws cdk:

    const logicLayer = new lambda.LayerVersion(this, 'logic-layer', {
      compatibleRuntimes: [
        lambda.Runtime.NODEJS_14_X,
        lambda.Runtime.NODEJS_16_X,
      ],
      layerVersionName: 'business-logic-layer',
      code: lambda.Code.fromAsset('src/layers/business-logic'),
      description: 'Business logic layer',
    });


    const lambdaWithLayer = new NodejsFunction(this, 'lambdaWithLayer', {
      entry: path.join(__dirname, '../src/lambdas', 'lambda.ts'),
      ...nodeJsFnProps,
      functionName: 'lambdaWithLayer',
      handler: 'handler',
      layers: [logicLayer, utilsLayer],
    });
  • Usar monorepo: você pode usar mono repos e pacotes criados dinamicamente em tempo de implantação.

O que acontece com suas funções lambda se você excluir uma camada lambda?

Nesta pergunta, o entrevistador quer ver o quanto você entende de camadas lambda.

As funções lambda existentes que usam essa camada excluída continuarão a funcionar – pois as camadas lambda são mescladas com as funções lambda no momento da implantação.

Você, no entanto, não poderá criar uma nova função lambda usando essa camada lambda excluída.

Você pode aprender mais sobre camadas lambda aqui e eu escrevi um guia sobre o mesmo tópico aqui (ambas as referências em inglês).

Você pode aumentar o tamanho de um pacote de implantação se você usa camadas lambda?

Não, você não pode aumentar o tamanho do pacote de implantação se usar camadas lambda. O tamanho máximo de implantação de 50 MB compactado inclui o tamanho da função lambda e suas camadas lambda associadas.

Se você tiver uma grande base de código e quiser aumentar a implantação, poderá executar contêineres no AWS Lambda.

Posso pegar minha aplicação da web dockerizada existente e executá-la usando o Lambda?

Não. Você não pode pegar nenhuma aplicação do Express, Springboot ou .NET Core (ou qualquer outra aplicação) como está e colocá-la dentro do lambda.

Dito isso, saiba que existem algumas bibliotecas que permitem colocar aplicações que usam esses frameworks da web no AWS Lambda. Internamente, essas bibliotecas convertem essas aplicações da web em APIs compatíveis com o AWS Lambda. Você pode ver um desses exemplos aqui (em inglês).

Ao usar esses frameworks, o tamanho de suas funções lambda será maior e resultará em tempos de inicialização mais longos.

Lembre-se de que, mesmo ao usar contêineres com Lambda, a API de tempo de execução existente do Lambda permanece a mesma. O Lambda ainda vai:

  • ser uma única função
  • ser invocado por um evento ou manualmente
  • ter um limite de tempo de 15 minutos.

Como você pode ver no código abaixo, não haverá alteração na API lambda. A vantagem de usar o Docker é que você pode usar pacotes grandes sem se preocupar com o tamanho.

import { Context, APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda';

export const handler = async (
  event: APIGatewayEvent,
  context: Context
): Promise<APIGatewayProxyResult> => {
  console.log(`Event: ${JSON.stringify(event, null, 2)}`);
  console.log(`Context: ${JSON.stringify(context, null, 2)}`);
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Running this handler from docker',
    }),
  };
};

e é assim que você o usa:

 const repo = ecr.Repository.fromRepositoryName(
      this,
      'dockerLambda',
      'docker-lambda'
    );

    const dockerLambda = new lambda.DockerImageFunction(
      this,
      'DockerLambdaFunction',
      {
        code: lambda.DockerImageCode.fromEcr(repo),
      }
    );

O autor deste artigo escreveu um tutorial passo a passo sobre execução de contêineres do Docker para sua aplicação em aws lambda aqui (em inglês).

Como você compartilha arquivos grandes entre funções lambda?

Você pode usar o Elastic File System (EFS) para compartilhar arquivos grandes entre diferentes funções.

Você pode criar um access point (em português, ponto de acesso) no EFS, criado com as permissões apropriadas, e usar esse access point em seu caminho de montagem em seu lambda.

Todos os arquivos gravados nesse caminho de montagem estarão acessíveis a todas as outras funções lambda, desde que tenham o caminho de montagem com as permissões apropriadas.

Abaixo vemos o diagrama lógico de alto nível sobre como usar o AWS Lambda com o Elastic File System (EFS):

image-24
Fonte da imagem

Você pode ler sobre isso aqui (em inglês e um pouco antigo). O autor deste artigo escreveu um guia passo a passo prático mais recente aqui (em inglês) sobre EFS com funções Lambda.

Conclusão

Espero que este artigo tenha ajudado você a se preparar para entrevistas que envolvam o AWS Lambda.

Obrigado por ler até aqui. O autor também escreve sobre aws e tecnologias sem servidor em https://www.cloudtechsimplified.com (blog em inglês). Se estiver interessado, pode se inscrever no blog dele.