top of page
Foto do escritorRan Isenberg

AWS Lambda Cookbook - Parte 4 - Melhores práticas de variáveis de ambiente


Foto de RODNAE Productions de Pexels
Foto de RODNAE Productions de Pexels

O que torna um manipulador AWS Lambda resiliente, rastreável e fácil de manter? Como você escreve tal código?

Nesta série de blogs, tentarei responder a essas perguntas compartilhando meu conhecimento e as melhores práticas do AWS Lambda, para que você não cometa os mesmos erros que eu cometi.

  • Esta série de blogs apresenta progressivamente as melhores práticas e utilitários, adicionando um utilitário por vez.

  • Parte 1 focada em Registro.

  • A Parte 2 focou na Observabilidade: monitoramento e rastreamento.

  • A Parte 3 focou na Observabilidade do Domínio de Negócios .

  • A Parte 5 focou na Validação de Entrada .

  • A Parte 6 focou em Configuração e Sinalizadores de Recursos.

  • A Parte 7 focou em como iniciar seu próprio serviço Serverless em dois cliques.

  • Parte 8 focado nas melhores práticas do AWS CDK .

Este blog se concentra nas melhores práticas de variáveis de ambiente.

O código neste post foi movido para um projeto de código aberto que você pode usar: O modelador de variáveis de ambiente da AWS:

 

Fornecerei um projeto Python de modelo de manipulador AWS Lambda funcional e de código aberto.

Este manipulador incorpora as melhores práticas do Serverless e tem todos os recursos necessários para um manipulador adequado e pronto para produção.

Durante esta série de blogs, abordarei registro, observabilidade, validação de entrada, sinalizadores de recursos, configuração dinâmica e como usar variáveis de ambiente com segurança.

Embora os exemplos de código sejam escritos em Python, os princípios são válidos para todas as linguagens de programação suportadas pelas funções do AWS Lambda.

Você pode encontrar a maioria dos exemplos neste repositório do GitHub , incluindo o código de implantação do CDK.


 

https://www.youtube.com/watch?v=2SxThkgFofo&ab_channel=FeminaÍndia
https://www.youtube.com/watch?v=2SxThkgFofo&ab_channel=FeminaÍndia
De acordo com a documentação oficial do AWS Lambda, “ Variáveis de ambiente são pares de strings (chave-valor) armazenadas na configuração específica da versão de uma função”.

Variáveis de ambiente são frequentemente vistas como um utilitário essencial. Elas servem como configuração estática de função do AWS Lambda. Seus valores são definidos durante a implantação do Lambda, e a única maneira de alterá-los é reimplantar a função do Lambda com valores atualizados.

No entanto, muitos engenheiros os usam de forma insegura, apesar de serem uma parte tão integral e fundamental de qualquer implantação de função do AWS Lambda. Esse uso pode causar bugs desagradáveis ou até mesmo travamentos na produção.


Este blog mostrará como analisar, validar e usar corretamente suas variáveis de ambiente no seu Python AWS Lambda, tanto no código de implantação quanto no código de função do AWS Lambda.


 

O básico

Vamos começar com as suposições fundamentais.

  1. Variáveis de ambiente Python são armazenadas em um dicionário no módulo 'os' — os.environ . Essas variáveis, pares de strings chave-valor, podem ser acessadas individualmente chamando os.getenv('my_var_name') . Se 'my_var_name' não for definido como uma variável de ambiente, esta função retornará um objeto None em vez de uma string .

  2. As variáveis de ambiente da função AWS Lambda são definidas em um código de implantação de uma infraestrutura como estrutura de código, como AWS CDK / Serverless / Terraform etc.

 

Variáveis de ambiente comuns: más práticas

Uso esporádico e inseguro de os.getenv

Muitos desenvolvedores acessam os.getenv esporadicamente nos arquivos de função do AWS Lambda.

No entanto, eles geralmente não verificam se os valores são válidos. Além disso , alguns valores de variáveis de ambiente podem ter suposições ocultas. Por exemplo, eles podem representar um formato de string ARN válido ou um ponto de extremidade HTTP REST. No entanto, a maioria dos desenvolvedores não valida os valores durante o tempo de execução.

Eles assumem que está tudo bem, já que seus testes não falharam.

Se a cobertura de teste deles for genuinamente excelente e cobrir cada chamada os.getenv , eles podem estar fora do alcance do perigo. No entanto, suponha que esse não seja o caso; uma falha/bug horrível pode estar à espreita no código, esperando por uma configuração incorreta no código de implantação do AWS Lambda.

Em outros casos, as variáveis de ambiente servem como valores de configuração personalizados para bibliotecas e dependências de terceiros. Deixar de validar esses valores de configuração antes de usá-los pode causar comportamento inesperado ou bugs. Pense em um logger, um rastreador de observabilidade ou um manipulador de banco de dados cuja configuração padrão você deseja substituir.


 

Desordem de código de implantação

Ao definir variáveis de ambiente em infraestrutura como estruturas de código como CDK/Serverless/Terraform, você normalmente começa com um pequeno dicionário de variáveis de ambiente e seus valores. No entanto, esse dicionário aumentará de tamanho e se tornará mais difícil de manter ao longo do tempo. É crucial entender quais variáveis são usadas e por quê.

Como as variáveis são usadas em vários lugares no código da função ou em suas dependências de terceiros (conforme argumentado acima), rastrear quais variáveis são usadas e quais podem ser removidas com segurança se torna desafiador. Além disso, devido à cobertura de teste menos que perfeita, remover variáveis de ambiente se torna uma operação arriscada.

Então as pessoas não fazem isso e as variáveis raramente são removidas.


 

Melhores práticas para variáveis de ambiente

Queremos abordar as duas práticas ruins mencionadas acima.

Primeiro, precisamos definir um esquema de variáveis de ambiente por manipulador. Esse esquema nos informa precisamente quais variáveis de ambiente a função do AWS Lambda usa em seu código e dependências. O esquema também pode definir restrições de valor.

Em segundo lugar, validaremos e analisaremos as variáveis de ambiente de acordo com o esquema predefinido quando a função AWS Lambda for acionada. Uma validação exceção é gerada com todos os detalhes de exceção relevantes em caso de configuração incorreta.

Terceiro, precisamos de uma função getter global para variáveis de ambiente validadas que qualquer arquivo na função AWS Lambda possa chamar.

E, por fim, o código de implantação, ou seja, o código CDK/Serverless, definirá e configurará apenas variáveis que fazem parte do esquema.

Ok, vamos para a solução proposta.


https://pydantic-docs.helpmanual.io/
https://pydantic-docs.helpmanual.io/

Ferramentas do ofício

Definiremos e analisaremos o esquema com Pydantic , uma biblioteca de análise e validação orientada a desempenho. Leia mais sobre Pydantic no meu primeiro blog .

O inicializador de variáveis de ambiente fornecerá o dicionário ' os.environ' como entrada para o analisador Pydantic. O Pydantic levantará uma exceção 'ValidationError' muito detalhada se um ou mais parâmetros falharem na validação.

Além disso, gostaríamos de acessar essas variáveis em todos os arquivos de função do AWS Lambda com a mesma facilidade de uso que chamar 'os.getenv' nos proporciona, MAS de maneira segura.

Chamaremos uma função getter que retorna uma instância global da configuração analisada.

É importante observar que 'os.getenv' ainda funciona e pode ser usado por dependências de terceiros.


 

Inicializar e analisar variáveis de ambiente

Vamos definir um novo decorador Python que inicializará as variáveis de ambiente: ' init_environment_variables'.

Usaremos a fábrica de middleware do AWS Lambda Powertools , o decorador ' lambda_handler_decorator' para criar um novo decorador de manipulador do AWS Lambda.

Vamos dar uma olhada no código abaixo.

Na linha 10, definimos uma instância de esquema global, ' ENV_CONF.'

Na linha 13, usamos o middleware factory do AWS Lambda Powertools para transformar 'init_environment_variables' em um decorador. O decorador aceita três parâmetros de decorador de manipulador AWS Lambda regulares (handler, event e context) e um próprio: o parâmetro ' model' . Este parâmetro é o nome da classe do esquema que definimos.

Na linha 18, a mágica acontece. Passamos o dicionário 'os.environ' como kwargs para o construtor de classe ' model ' do Pydantic. O Pydantic levantará uma exceção detalhada ' ValidationError ' caso o dicionário de variáveis de ambiente falhe na validação.

Quando o código chega à linha 22, a instância global ' ENV_CONF ' é analisada e validada, e o manipulador Lambda pode ser acionado com segurança.

Na linha 25, a função getter global, ' get_environment_variables', retornará 'ENV_CONF' instância global. Pode ser chamado em qualquer lugar no código do manipulador do AWS Lambda, incluindo funções internas.


Colocaremos esse código no arquivo do analisador de ambiente na pasta utility, pois todos os handles e funções o usam. Cada handler pode definir um schema diferente.


 

É hora do Schema!

Esquemas. Foto de Tima Miroshnichenko de Pexels
Esquemas. Foto de Tima Miroshnichenko de Pexels

Vamos definir um esquema Pydantic com o nome de ' MyHandlerEnvVars .'

Se você se lembra, implementamos utilitários logger, tracer e metrics nas três partes anteriores desta série de blogs . Podemos configurar esses utilitários com variáveis de ambiente e alterar o nome do serviço e o nível de log .

Além disso, vamos supor que nosso manipulador, ' my_handler ', requer duas variáveis adicionais: um ARN de função que ele assume durante sua execução e um URL de ponto de extremidade da API HTTP REST que ele usa.

Definiremos todas as quatro variáveis no esquema abaixo.

Todos os esquemas do Pydantic estendem a classe ' BaseModel' do Pydantic, transformando-os em uma classe de dados.

O esquema define quatro variáveis de ambiente: ' LOG_LEVEL,' 'POWERTOOLS_SERVICE_NAME,' ' ROLE_ARN,' e ' REST_API.'

Na linha 6 , 'MyHandlerEnvVars' estende a classe padrão 'BaseModel' do Pydantic.

Este esquema garante que:

  1. 'LOG_LEVEL' é uma das strings na lista Literal.

  2. 'ROLE_ARN' existe e tem entre 20 e 2048 caracteres, conforme definido aqui.

  3. 'REST_API' é uma URL HTTP válida.

  4. 'POWERTOOLS_SERVICE_NAME' é uma string não vazia.

O esquema residirá em uma nova pasta de esquemas na pasta de manipuladores.

 

Juntando tudo

Vamos adicionar os utilitários inicializador e getter de variáveis de ambiente aos utilitários logger, tracer e metric já implementados nos blogs anteriores.

Você pode encontrar todos os exemplos de código neste repositório do GitHub.


Na linha 8, importamos o esquema das variáveis de ambiente do manipulador.

Na linha 9, importamos as duas funções de inicialização e getter que colocamos na pasta utilitys.

Na linha 18, adicionamos o novo decorador, ' init_environment_variables ,' e definimos o argumento 'model' como ' MyHandlerEnvVars ,' o esquema definido anteriormente.

Na linha 25, usamos a função getter para acessar a classe de dados do esquema analisado global de nossas variáveis de ambiente e, na linha 26, registramos todas as quatro variáveis do nosso esquema.


Código de Implantação

Este código AWS CDK define as variáveis do esquema ' MyHandlerEnvVars' e define seus valores. Veja especificamente a função '__add_post_lambda_integration'.


Próximo

Isso conclui a quarta parte da série.

Junte-se a mim na próxima parte sobre ranthebuilder.cloud , onde analiso e valido entradas de eventos do AWS Lambda.

bottom of page