17 Jul
17Jul

The term "Microservice Architecture" has sprung up over the last few years to describe a particular way of designing software applications as suites of independently deployable services. While there is no precise definition of this architectural style, there are certain common characteristics around organization around business capability, automated deployment, intelligence in the endpoints, and decentralized control of languages and data.[Fowler/Lewis 2014


AWS Lambda é um serviço da AWS que permite a execução de código sem servidor. O modelo gerencia aspectos mundanos como escalabilidade e disponibilidade, mas cria novos desafios a serem superados, incluindo separação de ambientes, CI/CD e governança. Neste artigo veremos alguns aspectos importantes de como lidar corretamente com microserviços utilizando AWS Lambda.


Versions e Aliases

O modelo de governança do Lambda implementa dois conceitos fundamentais e sem os quais ficará difícil de gerenciar ambientes complexos. O primeiro conceito é o de "version", o segundo é chamado de "alias". 

Versions são imutáveis e não possuem relação com o versionamento tradicional de um SCM. Uma version é numerada sequencialmente em ordem crescente (1, 2, 3 etc) e pode ser consumida diretamente:

minha-funcao:1 

No caso o ":1" acima indica qual version queremos que seja executada. Novas versions podem (e devem) ser criadas quando existe alguma mudança no código (sempre na versão de base chamada de $LATEST. No caso acima, uma nova version seria numerada como ":2". Isto permite que tenhamos diferentes versions disponíveis para execução, mas cria a questão: Como lidar com estas mudanças num ambiente de produção? Preciso modificar o código de quem chama para indicar qual versão deve ser executada? 

Entra em cena o alias 

Um alias é como um sufixo que damos para uma função indicando seu propósito ou criando uma separação entre ambientes. Aliases são associados com versions. No exemplo anterior a função a ser chamada passaria a ser referenciada não mais pelo número da versão, mas pelo alias. Aliases podem ser criados diretamente no console do Lambda ou ainda via AWS CLI.

Menu de controle de alias e version


Lista de versions e aliases criados (com respectivas versions associadas)


No exemplo acima a versão a ser executada será a apontada pelo alias. O Lambda fornece uma API específica para associar uma versão a um alias.

Uma função pode ter vários alias, cada um associado a uma version distinta (ou à mesma version):


minha-funcao:DEV
minha-funcao:PROD


Relacionamento entre versions e aliases


Podemos ter tantos aliases quantos forem necessários (exemplo, aliases para ambientes de testes do usuário - GAMMA)

Alias
Versão
DEV
$LATEST
GAMMA
2
PROD
1


Mas como automatizar a chamada pelo alias? Preciso criar uma função para cada "ambiente"? 

O caminho correto é ter apenas uma única função, criando tantos aliases e versions qunato forem necessários. A forma como o alias correto é determinado depende do serviço. Em resumo temos duas formas distintas: através de algum recurso do serviço (stage variables no caso API Gateway) ou por convenção, definindo o nome do serviço de acordo com o ambiente como um sufixo (SQS, SNS, S3 etc). A partir da análise do nome do serviço, podemos determinar qual alias será chamado.


Configurando o API Gateway para trabalhar com aliases

Quando publicamos uma API o API Gateway permite a criação do que a AWS chama de "stage variables" em cada stage. Basicamente é uma estrutura JSON que é disponibilizada no event da função Lambda, como pode ser visto no exemplo abaixo:

Stages no API Gateway para uma API


Aba stage variables no stage "DEV" da API.


O truque é criar a variável "lambdaStage" em cada stage(DEV, GAMMA PROD etc), mas com um valor relativo ao stage, neste caso o próprio nome do stage.

No nome da função Lambda associada à API, colocamos a referência do alias, exemplo:

Definindo o nome da função Lambda


Note que o nome da função será resolvido dinamicamente, então o API Gateway não tem como definir as permissões apropriadas para que a função seja chamada. O API Gateway alerta sobre este problema e fornece um exemplo de linha de comando para que seja criada a policy necessária para que a função Lambda possa ser chamada pelo API Gateway.


Alerta da necessidade de adicionar a permissão à função Lambda


Basta copiar e colar na linha de comando, substituindo ${stageVariables.lambdaStage} pelo stage. Este passo deve ser automatizado dentro de um processo DevOps para evitar intervenção manual. Isto será alvo de um próximo artigo. Para efeitos deste artigo, o comando seria alterado e executado da seguinte forma:


aws lambda add-permission   --function-name "arn:aws:lambda:us-east-1:525324176518:function:jetoildelivery-authorizationservices-cmslogin:DEV"   --source-arn "arn:aws:execute-api:us-east-1:123456789012:fo2ba0srdf/*/POST/v1/authenticationservices/cmslogin"   --principal apigateway.amazonaws.com   --statement-id 2a930763-7ca1-45be-a30b-aee06d340df6-DEV   --action lambda:InvokeFunction


No caso acima, depois de autorizar para DEV, basta trocar por outro ambiente para autorizar o API Gateway a chamar a função (GAMMA, PROD). Assegure-se de ter criado corretamente os aliases anteriormente.


Considerações finais

Alguns frameworks open source possuem uma forma diferente de lidar com o processo DevOps do Lambda. Dois frameworks populares (Serverless e ClaudiaJS) em particular não fazem uso de aliases e versions, gerando uma função para cada ambiente (Serverless) ou uma nova camada para tratar as chamadas (ClaudiaJS). Use aliases e versions como desenhado pela AWS para manter a simplificidade do seu projeto, adotar melhores práticas no desenvolvimento de APIs e manter a governança do seu ambiente.


Emerson Lopes
Arquiteto de soluções na nuvem
emersonlopes@gmail.com 

Comentários
* O e-mail não será publicado no site.
ESTE SITE FOI CRIADO USANDO