top of page
  • Foto do escritorRan Isenberg

AWS Lambda Cookbook  - Parte 6 -  Melhores práticas de configuração e sinalizadores de recursos


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 4 focou em Variáveis de Ambiente .

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

  • 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 em sinalizadores de recursos e práticas recomendadas de configuração.

 

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 todos os exemplos neste repositório do GitHub , incluindo o código de implantação do CDK.


 

TL;DR Vídeo


Esta postagem do blog também está disponível como uma palestra na conferência no vídeo abaixo:


 

Configuração da função AWS Lambda


Uma configuração de função do AWS Lambda geralmente é um par de parâmetros chave-valor acessados durante o tempo de execução, afetando seu fluxo lógico.

Esses parâmetros variam de configurações gerais (lista de regiões suportadas, URLs de serviço, etc.) a definições complexas de sinalizadores de recursos (ativar/desativar recursos de código).

Durante meu trabalho com funções do AWS Lambda, percebi que precisava de um método rápido e direto para alterar o comportamento da minha função do AWS Lambda sem alterar seu código. Alterar a configuração da função do AWS Lambda parecia a abordagem correta, pois poderia alterar a saída ou os efeitos colaterais da função do AWS Lambda.


No entanto, como você faz isso rapidamente? Como você armazena os diferentes tipos de configurações? Como você pode acessá-los de forma eficiente e segura?


Este blog explicará as práticas recomendadas para armazenar a configuração e os sinalizadores de recursos do AWS Lambda e fornecerá uma solução Python totalmente funcional.

Os sinalizadores de recursos inteligentes são sinalizadores de recursos que são avaliados em tempo de execução e podem alterar seus valores de acordo com o contexto da sessão.

A solução Python é baseada em um SDK que desenvolvi e doei ao excelente repositório AWS Lambda Powertools GitHub.

 

Existem inúmeras opções para armazenar a configuração da função do AWS Lambda.

Vamos supor que mapeamos nossa configuração para um formato de configuração JSON que desejamos usar em nosso manipulador AWS Lambda.

Aqui estão as opções mais comuns para armazenar essa configuração:

  1. Variáveis de ambiente.

  2. Empacote o arquivo de configuração JSON com a função.

  3. Armazenamento de parâmetros do AWS SSM/AWS Secrets Manager

  4. Tabela do AWS DynamoDB.

  5. Configuração do AWS AppConfig.

Podemos dividir essas opções em duas categorias: configurações estáticas e dinâmicas.

Ao entender a diferença entre eles e definir o caso de uso de cada opção, você pode escolher a solução de armazenamento que melhor atende às suas necessidades.

Dica: provavelmente será uma mistura de configurações estáticas e dinâmicas.


Configurações estáticas x dinâmicas


Configurações estáticas não mudam durante o tempo de execução da função; portanto, elas são estáticas.

Configurações estáticas incluem variáveis de ambiente ou um arquivo de configuração JSON empacotado com o manipulador. Essas configurações são implantadas com a função e não podem ser alteradas a menos que a função seja reimplantada.

Por outro lado, configurações dinâmicas podem ser alteradas fora do escopo da função do AWS Lambda e alterar o comportamento da função durante o tempo de execução.

As configurações dinâmicas são armazenadas no repositório de parâmetros do AWS SSM, em uma tabela do AWS DynamoDB ou em uma configuração do AWS AppConfig (pode haver outras opções também, mas essas são as mais comuns).

Configurações dinâmicas são mais complexas, pois exigem um pipeline de CI/CD dedicado, separado do pipeline de CI/CD da função do AWS Lambda.

Essa separação é crítica; o pipeline diferente desacopla a função do AWS Lambda de sua configuração e permite atualizar a configuração sem reimplantar o pipeline da função do AWS Lambda.

Criar e manter mais pipelines de CI/CD aumenta a complexidade, mas vale a pena.

Esses pipelines são rápidos por design, pois não têm lógica além de carregar um arquivo de configuração JSON para um serviço da AWS e exigem menos testes do que um serviço completo baseado em AWS Lambda.

Em uma crise de produção, é possível reverter rapidamente uma configuração incorreta ou desabilitar um sinalizador de recurso problemático em vez de reimplantar a função do AWS Lambda com uma configuração estática atualizada enquanto aguarda a conclusão de um pipeline de CI/CD de serviço *muito* longo.

TL;DR: Configurações dinâmicas exigem um pipeline de CI/CD rápido e separado, o que permite um tempo de reação rápido aos problemas em detrimento da manutenção extra do pipeline de CI/CD.

 

Qual opção de armazenamento de configuração você deve usar?

Cada tipo de configuração tem seu lugar.

Use configuração estática para configurações que não mudam rapidamente e não exigem mudanças rápidas em ambientes de produção.

Esteja ciente de que as variáveis de ambiente têm um limite de tamanho máximo devido às restrições do sistema operacional.

Se você atingir o limite, mova as configurações para um arquivo de configurações estáticas (agrupado com o código do AWS Lambda) ou armazene-as como uma configuração dinâmica .

Você pode ler mais sobre variáveis de ambiente e melhores práticas no meu blog aqui .


Uma configuração que você espera mudar ou deseja ter a capacidade de mudar rapidamente deve ser salva como uma configuração dinâmica .

Além disso, os sinalizadores de recursos, por sua natureza, devem ser armazenados como configurações dinâmicas .


Como abordamos a configuração estática como variáveis de ambiente em um blog anterior ,

vamos nos concentrar na configuração dinâmica e revisar os requisitos para um SDK de utilitário de configuração dinâmica e escolher a melhor opção de armazenamento para as configurações dinâmicas.

 

Experiência do usuário do utilitário de configuração dinâmica

Quando projetei o utilitário apresentado nesta postagem do blog, eu queria oferecer suporte a configurações dinâmicas e sinalizadores de recursos inteligentes.

O que são sinalizadores de recursos "inteligentes"?

Os sinalizadores de recursos inteligentes exigem avaliação em tempo de execução e podem ter valores diferentes para diferentes sessões de função do AWS Lambda. Imagine enviar um novo recurso para produção, mas habilitá-lo apenas para clientes específicos. Um sinalizador de recurso inteligente precisará avaliar o nome do cliente e decidir se o valor final é 'True/False' de acordo com um conjunto de regras e condições predefinidas. Os sinalizadores de recurso inteligente são definidos por regras, condições e ações que determinam o valor final.

Discutiremos isso em detalhes mais adiante.


Os requisitos

  1. Use o arquivo JSON para descrever valores de configuração e sinalizadores de recursos inteligentes.

  2. Forneça uma API simples para obter configuração em qualquer lugar no código da função do AWS Lambda.

  3. Forneça uma API simples para avaliar valores de sinalizadores de recursos inteligentes.

  4. Durante o tempo de execução, armazene a configuração em um cache local com um TTL configurável para reduzir chamadas de API para a AWS (para buscar a configuração JSON) e o custo total.

  5. Suporte integrado para modelos Pydantic . Usamos o Pydantic para serializar e validar a configuração JSON (validação de entrada e variáveis de ambiente) ao longo desta série de blogs, então faz sentido usá-lo para analisar a configuração dinâmica.

Agora que entendemos os requisitos e o valor de ter uma configuração dinâmica nas funções do AWS Lambda, vamos discutir o "onde".


Onde armazenamos a configuração JSON dinâmica?

 

AWS AppConfig - O melhor serviço de armazenamento de configuração dinâmica

Logotipo do AWS AppConfig
Configuração de aplicativo da AWS

Vamos relembrar nossas opções de armazenamento. Ao eliminar as opções static only, ficamos com:

  1. Armazenamento de parâmetros do AWS SSM/Serviço de segredos da AWS

  2. AWS DynamoDB

  3. Configuração de aplicativo da AWS

Acredito que o AWS AppConfig é o melhor serviço de armazenamento de configuração dinâmica para funções do AWS Lambda. Deixe-me explicar o porquê.


O AWS AppConfig é um serviço autogerenciado que armazena configurações de TEXTO simples/YAML/JSON para serem consumidas por vários clientes.

Usaremos isso no contexto de configuração dinâmica e alternância de recursos e armazenaremos um único arquivo JSON que contém tanto sinalizadores de recursos quanto valores de configuração. O AWS AppConfig pode ser o serviço aparente para armazenar a configuração da função do AWS Lambda devido apenas ao seu nome. Ao pesquisar os recursos específicos de configuração do serviço, fica ainda mais claro que o AWS AppConfig é mais adequado do que o AWS DynamoDB e o AWS SSM Parameter.

Vamos rever suas vantagens:

  1. FedRAMP Altamente certificado

  2. Totalmente sem servidor

  3. Suporte pronto para uso para validações de esquema executadas antes de uma atualização de configuração.

  4. A integração pronta para uso com os alarmes do AWS CloudWatch aciona uma reversão automática de configuração se uma atualização de configuração falhar nas suas funções do AWS Lambda. Leia mais sobre isso aqui .

  5. Você pode definir estratégias de implantação de configuração. Estratégias de implantação definem como e quando alterar uma configuração. Leia mais sobre isso aqui .

  6. Ele fornece uma única API que fornece acesso a sinalizadores de configuração e recursos — mais sobre isso abaixo.

  7. O AWS AppConfig fornece integrações com outros serviços, como Atlassian Jira e AWS CodeDeploy. Clique aqui para obter detalhes.

O AWS DynamoDB e o AWS SSM têm vantagens e casos de uso diferentes, mas não são otimizados para armazenamento de configuração do AWS Lambda e arquivos JSON.

Você deve usar o AWS SSM Parameter Store para armazenamento de segredos (ou o AWS Secrets Manager para casos de uso mais avançados, rotação automática, integração RDS, etc.), mas não para configuração padrão. Ele não tem todos os recursos específicos de configuração descritos nas linhas 4-7.

Você pode armazenar configurações dinâmicas no DynamoDB . No entanto, ele não tem todos os recursos específicos de configuração descritos nas linhas 4-7.

 

Vamos implantar uma configuração JSON!

No modelo do GitHub da série de blogs, a implantação da configuração no AWS AppConfig é feita por meio de uma construção CDK que cuida da lógica para você.

Você precisa criar um pipeline separado para configuração dinâmica e usar a construção CDK fornecida.

Você pode ler mais sobre isso aqui .

Como funciona o AWS AppConfig?

AppConfig consiste em hierarquias de configuração.

Seu pipeline de CI/CD criará um aplicativo que se correlaciona com o nome do seu serviço AWS Lambda. Um aplicativo pode conter várias configurações para vários AWS Lambdas ou uma configuração usada por todas as funções AWS Lambda no serviço; a escolha é sua.

Aplicação 'test-service' no nível superior
Aplicação 'test-service' no nível superior

Então, ele criará um ambiente. Um aplicativo tem uma lista de ambientes ('dev,' 'stage,' 'production,' etc.)

ambiente 'dev' do aplicativo de serviço de teste
ambiente 'dev' do aplicativo de serviço de teste

Cada ambiente pode ter vários perfis de configuração.

Cada perfil define a versão atual de uma configuração, seus valores (em formato JSON/YAML/texto simples) e a estratégia de implantação a ser usada ao implantá-lo.

Depois que a configuração for implantada, ela ficará assim:

A configuração 'test-applicaton-profile' é implantada
A configuração 'test-applicaton-profile' é implantada

Você pode ler mais sobre estratégias de implantação aqui .

 

Obtendo sinalizadores de configuração e recursos

Buscando uma configuração

Dividiremos esta parte em duas: buscar configuração dinâmica e buscar sinalizadores de recursos.

AWS Lambda Powertools para o resgate

Tive o privilégio de projetar e doar um utilitário de configuração dinâmica para o repositório AWS Lambda Powertools. O utilitário é chamado de 'feature flags', mas ele busca tanto feature flags quanto configurações.

O utilitário integra-se imediatamente ao AWS AppConfig.

Ele fornece uma maneira fácil de consumir a configuração JSON do AWS AppConfig e salvá-la em um cache local dedicado. O cache reduz o custo total e melhora o desempenho, pois você paga por chamada de API do AWS AppConfig. O cache também tem um TTL (time-to-live) configurável.

Observe que o utilitário requer permissões adicionais do IAM que permitem 'appconfig:GetLatestConfiguration' e 'appconfig:StartConfigurationSession'.

 

Vamos buscar a configuração dinâmica

Vamos definir nosso arquivo JSON de configuração dinâmica do manipulador do AWS Lambda com base no manipulador do AWS Lambda apresentado nos blogs anteriores: o 'serviço de pedidos'.

Um cliente pode comprar várias quantidades de um item como parte de um pedido. Cada cliente pertence a um país de origem. O manipulador lidou com as solicitações de pedidos e foi apresentado nos blogs anteriores da série.

Vamos adicionar a configuração dinâmica.

O serviço suporta entrega de pedidos somente para uma lista fechada de países. A lista pode ser atualizada dinamicamente, e os países podem ser adicionados ou removidos.

Uma configuração JSON potencial se parece com isto:

Vamos definir o esquema Pydantic correspondente:

Agora, vamos definir nosso SDK que usa o utilitário feature flags e adicionar a análise de configuração JSON do Pydantic. Definiremos duas funções.

A primeira função, ' get_dynamic_configuration_store ', será usada para inicializar e obter a instância singleton do utilitário de configuração.

A segunda função, ' parse_configuration ', é usada para buscar nossa configuração JSON (sem sinalizadores de recursos) e analisá-la com o modelo de esquema ' MyConfiguration ' que acabamos de definir.

Vamos dar uma olhada no código abaixo:

Na linha 4, importamos o utilitário de sinalizadores de recursos do AWS Lambda Powertools e renomeamos a importação para um nome mais adequado, ' DynamicConfiguration ', porque ele fornece acesso aos sinalizadores de recursos e aos valores de configuração.

Nas linhas 24 a 34, inicializamos o armazenamento de configuração AWS AppConfig, que serve como classe getter de configuração.

Na linha 26, usamos o analisador de variáveis de ambiente que implementamos na parte 4 da série e obtemos as variáveis de ambiente que o armazenamento de configuração do AWS AppConfig requer.

Requer diversas novas variáveis de ambiente:

  1. Nome do aplicativo de configuração do AWS AppConfig.

  2. Nome do ambiente AWS AppConfig.

  3. Nome da configuração do AWS AppConfig a ser buscado.

  4. TTL do cache em minutos ('max_age' na linha 31). Eu usaria o padrão de 5 minutos.

Na linha 32, definimos a chave do dicionário JSON para armazenar definições de sinalizadores de recursos inteligentes.

Usaremos a chave ' features .' Os sinalizadores de recurso são opcionais e não precisam fazer parte do arquivo JSON. No entanto, definiremos dois sinalizadores mais tarde.

Na linha 34, inicializamos o utilitário de sinalizadores de recursos do AWS Lambda Powertools.

Na linha 49, buscamos o arquivo JSON do AWS AppConfig e usamos a configuração 'raw', ou seja, o arquivo JSON autêntico que foi carregado.

Na linha 50, usamos o Pydantic para analisar a configuração de acordo com o esquema e capturar quaisquer erros de validação de esquema. Retornamos uma instância de dataclass assim que a validação for bem-sucedida para que possamos acessar qualquer valor de configuração facilmente.

 

Vamos ver esse código em ação em um código de manipulador do AWS Lambda. Este trecho de código é uma versão simplificada do manipulador gradualmente introduzido em posts de blog anteriores.

Na linha 15, inicializamos as variáveis de ambiente porque a função ' parse_configuration ' as utiliza na linha 18.

Na linha 18, chamamos ' parse_configuration ' e fornecemos o nome da classe do nosso esquema de configuração. Esta API pode ser usada em qualquer lugar no código da função AWS Lambda.

Após a primeira chamada, o arquivo JSON é salvo no cache por 5 minutos, e qualquer chamada para ' parse_configuration ' não incorrerá em cobrança adicional do AWS AppConfig.

Na linha 23, imprimimos os valores de configuração e os acessamos como uma classe de dados regular.

Nas linhas 19 a 21, tratamos de qualquer erro de configuração dinâmica que possa ocorrer, erro de conexão do AWS AppConfig ou falha do arquivo JSON em cumprir nosso modelo de validação de esquema.

 

Vamos definir e buscar sinalizadores de recursos inteligentes e regulares

Vamos supor que nosso manipulador AWS Lambda suporta dois sinalizadores de recursos:

  1. Desconto de dez por cento para o pedido atual: Verdadeiro/Falso .

  2. Recurso premium para o cliente: Verdadeiro/Falso .

Um desconto de dez por cento é um sinalizador de recurso regular . De acordo com a política da loja, um desconto de dez por cento pode ser ativado ou desativado. Ele não muda de acordo com a entrada da sessão; é True ou False para todas as entradas.

Por outro lado, os recursos premium são disponibilizados apenas para clientes específicos.

O sinalizador de recurso de recursos premium é baseado em uma regra. É um sinalizador de recurso inteligente .

O valor dos sinalizadores de recursos é Falso para todos, exceto para clientes muito específicos.

Para usar os recursos de sinalizadores de recursos do AWS Lambda Powertools, precisamos criar um arquivo JSON que corresponda à linguagem do SDK.

Você pode ler mais sobre isso aqui .


Definição de sinalizadores de recursos regulares não inteligentes

Definir o sinalizador de desconto de dez por cento é simples. Ele tem uma chave e um dicionário contendo uma chave de valor 'padrão' com um valor booleano. Vamos supor que o sinalizador de recurso esteja habilitado.

Vamos adicioná-lo à configuração atual que já temos:


Definição JSON de sinalizadores de recursos inteligentes

Agora, vamos adicionar o sinalizador de recurso inteligente, recursos premium.

Queremos habilitá-lo apenas para clientes do 'RanTheBuilder'.

A estrutura JSON é simples.

  1. Cada recurso tem um valor padrão sob a chave padrão . Pode ser qualquer valor JSON válido (booleano, int etc.).

  2. Cada recurso pode ter regras opcionais que determinam o valor avaliado.

  3. Cada regra consiste em um valor padrão a ser retornado (em caso de uma correspondência — w hen_match ) e uma lista de condições. Apenas uma regra pode corresponder.

  4. Cada condição consiste em um nome de ação (que é mapeado para um operador no código do mecanismo de regras) e um par de chave-valor que serve como um argumento para o mecanismo de regras do SDK.

Nosso arquivo JSON de configuração agora contém sinalizadores de recursos (inteligentes e não inteligentes) e configuração geral. Os sinalizadores de recursos são definidos somente dentro da chave raiz 'features'.


Neste exemplo, a regra é correspondida (o que retorna um valor True para o sinalizador) quando o dicionário de contexto tem uma chave ' customer_name' com um valor de ' RanTheBuilder ' EQUALS ' RanTheBuilder .'

Há muitas ações suportadas para condições como STARTSWITH , ENDSWITH , EQUALS , etc.

Você pode ler mais sobre as regras, condições, lógica e ações suportadas aqui .

 

Juntando tudo

Definiremos os nomes dos sinalizadores de recursos em uma enumeração para que eles possam ser buscados por valores de enumeração em vez de strings "mágicas" codificadas.

O esquema de configuração atualizado do arquivo Python agora terá esta aparência:

 

Vamos redefinir nosso arquivo JSON de configuração dinâmica do manipulador AWS Lambda e adicionar ambos os sinalizadores de recurso avaliando chamadas. Colocaremos a definição dos sinalizadores de ambos os recursos sob a chave ' features ' no arquivo JSON, que corresponde à variável envelope no repositório AppConfig que definimos na linha 32 do arquivo SDK de configuração dinâmica.


Na linha 18, buscamos a configuração do AWS AppConfig e a salvamos como um todo no cache.

Na linha 24, avaliamos o valor de configuração não inteligente. Como ele não é inteligente, ele não tem contexto de sessão (o contexto do dicionário está vazio). O valor padrão é False se a definição do sinalizador de recurso tiver sido removida acidentalmente do arquivo JSON no AWS AppConfig.

Na configuração atual, a linha 29 imprimirá o valor True .

Na linha 31, avaliamos o sinalizador de recurso inteligente. Passamos o nome do cliente como parte do dicionário de contexto. Nesse caso, a regra corresponderá, e o recurso avalia True .

Entretanto, se o customer_name fosse diferente, a regra não teria correspondências e o recurso seria avaliado como False .


 

Próximo

Isso conclui a sexta parte da série.

Junte-se a mim na próxima e última parte, onde mostrarei como você pode usar o repositório de modelos do GitHub e criar seu serviço.

Comments


bottom of page