Serverless Framework - Iniciando com AWS Lambda

Eae pessoal, tudo bem?

Já faz um tempo que fiz dois posts relacionados a Arquitetura Serverless, e hoje vou postar o primeiro tutorial de como fazer uso desta maravilha utilizando a linguagem Golang como principal.

Logo abaixo vou deixar anexado o repositório deste post no Github, e vou tentar trazer também uma atualização futura do mesmo projeto feito em Nodejs e Python, então fique ligado na lista de repositórios que vou manter uma nota de quais linguagens já foram adicionadas.

Aperta o cinto e vamos lá :)

  1. Posts relacionados
  2. Arquitetura Serverless
  3. Serverless Framework
    1. Casos de sucesso
    2. Provedoras de serviço já disponíveis na ferramenta
  4. AWS Lambda
    1. Definições de preço
  5. Projeto de exemplo
  6. Instalação
    1. Instalando o NVM
    2. Instalando o Nodejs + NPM
    3. Instalando o Serverless Framework
  7. Desenvolvimento
    1. Configurar as credenciais de acesso da AWS no Serverless Framework
    2. Gerar o código inicial de um Lambda com linguagem Golang na AWS, retornando um json de teste aleatório
    3. Deploy do projeto
    4. Executar a função pelo terminal com o Serverless Framework
    5. Executar a função pelo protocolo HTTP
    6. Remover o projeto da AWS
  8. Conclusão

Posts relacionados

Introdução ao Serverless com Amazon AWS

AWS eficiente com Serverless Framework

Arquitetura Serverless

Aaahhhh Arquitetura Serverless, coisa linda, coisa magnífica.

Não há uma visão clara sobre Arquitetura Serverless, mas podemos dizer que ela é denominada aos projetos que são executados em determinadas provedoras de serviços sem que exista um servidor físico atuando no seu projeto 24 horas por dia, assim esta arquitetura incorpora os modelos BaaSbackend as a service” e FaaS “Functions as a Service”.

Nas palavras do especialista Mike Roberts:

Serverless architectures are application designs that incorporate third-party “Backend as a Service” (BaaS) services, and/or that include custom code run in managed, ephemeral containers on a “Functions as a Service” (FaaS) platform. By using these ideas, and related ones like single-page applications, such architectures remove much of the need for a traditional always-on server component. Serverless architectures may benefit from significantly reduced operational cost, complexity, and engineering lead time, at a cost of increased reliance on vendor dependencies and comparatively immature supporting services.

Martinfowler - Serverless

Serverless Framework

O Serverless Framework é uma ferramenta de linha de comando desenvolvida em código aberto que ajuda os desenvolvedores na criação das aplicações serverless, disponibilizando um padrão de configuração que com uma simples linha de comando, cria toda a estrutura necessária para rodar o sistema na provedora escolhida.

Atualmente podemos dizer que ela já se tornou a ferramenta core de muitos desenvolvedores freelancers e grandes empresas quando falamos de deploy de sistemas nesta arquitetura.

Serverless Framework - Website

Serverless Framework - Github

Casos de sucesso

No site dos desenvolvedores podemos ver que a ferramenta já é utilizada por grandes empresas como:

  1. Coca-Cola
  2. EA Games
  3. Nordstorm
  4. Expedia
  5. Reuters

Não só grandes empresas como também temos inúmeras pequenas empresas e desenvolvedores utilizando a ferramenta, não é atoa que na data deste post eles já atingiram 29mil stars no Github, e mais de 3200 forks do projeto.

Provedoras de serviço já disponíveis na ferramenta

Como é uma ferramenta para ajudar tanto em deploys de sistemas serverless como também para construção de ambientes, na atual data deste post já podemos trabalhar com oito provedoras.

  1. Amazon AWS
  2. Microsoft Azure
  3. IBM OpenWhisk
  4. Google Cloud Platform
  5. Kubeless
  6. Spotinst
  7. Fn
  8. Cloudflare

Mas estamos falando de uma ferramenta que está em constante atualização, portanto vou deixar aqui da lista de provedoras junto com suas documentações.

Provedoras

AWS Lambda

O AWS Lambda é um serviço da Amazon AWS que permite a execução de códigos sem a necessidade de provisionar ou gerenciar um servidor, tendo como custo somente o tempo de execução do código e a quantidade de solicitações.

Basicamente enviamos um código para a AWS com alguns critérios de execução, em seguida o código fica esperando para ser executado.

O mais legal é que após a execução do código, o Lambda é desligado e você não será cobrado por isso até a chegada de outra execução.

Definições de preço

Basicamente o Lambda tem seu custo baseado na quantidade de chamadas ao código junto do tempo de execução que este código levou até ser finalizado.

Este tempo é dividido em pacotes de 100ms, e cada pacote tem seu preço modificado dependendo da quantidade de memória configurada nos critérios de execução.

Abaixo vou deixar a tabela com as possibilidades de configuração, mas vale ressaltar que os valores mudam, e você pode acessar esta tabela atualizada nas Definição de preço do AWS Lambda.

Memória (MB) Segundos de nível gratuito por mês Preço por 100ms (USD)
128 3.200.000 0,000000208
256 1.600.000 0,000000417
512 800.000 0,000000834
1024 400.000 0,000001667
2.048 200.000 0,000003334
3.008 136.170 0,000004897

Clique aqui para vizualizar a tabela completa

Memória (MB) Segundos de nível gratuito por mês Preço por 100 ms (USD)
128 3.200.000 0,000000208
192 2.133.333 0,000000313
256 1.600.000 0,000000417
320 1.280.000 0,000000521
384 1.066.667 0,000000625
448 914.286 0,000000729
512 800.000 0,000000834
576 711.111 0,000000938
640 640.000 0,000001042
704 581.818 0,000001146
768 533.333 0,000001250
832 492.308 0,000001354
896 457.143 0,000001459
960 426.667 0,000001563
1024 400.000 0,000001667
1.088 376.471 0,000001771
1.152 355.556 0,000001875
1.216 336.842 0,000001980
1.280 320.000 0,000002084
1.344 304.762 0,000002188
1.408 290.909 0,000002292
1.472 278.261 0,000002396
1.536 266.667 0,000002501
1.600 256.000 0,000002605
1.664 246.154 0,000002709
1.728 237.037 0,000002813
1.792 228.571 0,000002917
1.856 220.690 0,000003021
1.920 213.333 0,000003126
1.984 206.452 0,000003230
2.048 200.000 0,000003334
2.112 193.939 0,000003438
2.176 188.235 0,000003542
2.240 182.857 0,000003647
2.304 177.778 0,000003751
2.368 172.973 0,000003855
2.432 168.421 0,000003959
2.496 164.103 0,000004063
2.560 160.000 0,000004168
2.624 156.098 0,000004272
2.688 152.381 0,000004376
2.752 148.837 0,000004480
2.816 145.455 0,000004584
2.880 142.222 0,000004688
2.944 139.130 0,000004793
3.008 136.170 0,000004897


Existem também alguns custos adicionais como transferência de dados, adicional de regiões, encadeamento de outros serviços em geral… então vou deixar aqui o link das Definição de preço do AWS Lambda para quem quiser se aprofundar melhor, pois existem dados mais detalhados e sempre atualizados.

Projeto de exemplo

O objetivo do projeto deste post vai ser criar uma função Lambda para testes onde vamos seguir o seguintes passos:

  1. Configurar as credenciais de acesso da AWS no Serverless Framework.
  2. Gerar o código inicial de um Lambda com linguagem Golang na AWS.
  3. Fazer o deploy do projeto.
  4. Executar a função pelo terminal com o Serverless Framework.
  5. Executar a função pelo protocolo HTTP.
  6. Remover o projeto da AWS.

Vamos utilizar o Linux como sistema operacional e como vamos desenvolver a função em Go vamos partir do princípio que já temos ele instalado na máquina.

Como este post é o início de uma série de posts que vamos trabalhar utilizando AWS Lambda + Serverless Framework, vamos focar hoje em desenvolver somente o básico para aprender como tudo funciona.

Logo em seguida o objetivo será criar novos posts com forks deste projeto inicial, visando utilizar mais a fundo esta combinação.

Entõooonce fique relax, que vai ter mais! :)

Go go go! Bora trabalhar!!!

Instalação

Atualmente o Serverless Framework possui sua instalação a partir do NPM, então logo de início vamos precisar ter o Nodejs + NPM instalado na máquina.

Quando eu preciso instalar esta combinação, eu acabo usando o NVM “Node Version Manager”, isso deixa mais fácil gerenciar, atualizar e deixar tudo tintin quando o assunto é Nodejs.

Instalando o NVM

Para instalar o NVM devemos ir até o repositório do projeto no Github e seguir os seguintes passos.

Abra o seu terminal e execute o código:

$ curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

ou

$ wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash

Reinicie o terminal e tente executar o comando nvm -v, se o comando rodou podemos agora instalar o Nodejs + NPM.

Caso algo deu errado, siga a instalação detalhada pelo repositório original acessando aqui o Repositório NVM.

Instalando o Nodejs + NPM

Agora podemos continuar e instalar nosso conjunto do Nodejs + NPM, executando a sequência abaixo:

  1. Liste as versões do Nodejs executando nvm ls-remote.
  2. Escolha a última versão LTS, como por exemplo: v10.15.3.
  3. Execute o comando nvm install v10.15.3, para instalar.

Pronto, agora temos o Nodejs e o NPM funcionando e podemos instalar o Serverless Framework.

Instalando o Serverless Framework

Para instalar o Serverless Framework, vamos precisar fazer muuuuita coisa, infelizmente isso é sofrido, então siga os passos abaixo.

Execute em seu terminal o seguinte comando:

$ npm install serverless -g

Pronto agora temos o Serverless Framework funcionando na máquina com o comando serverless ou alenas sls.

Viu que sofrido? :3

Desenvolvimento

Ufa… Finalmente chegamos na parte legal, ficar instalando e deixando tudo pronto é meio chato hehe.

A partir daqui, vamos seguir as etapas de desenvolvimento descritas no início do post, assim vamos etapa por etapa desenvolvendo e comitando nosso projeto na sequência.

1. Configurar as credenciais de acesso da AWS no Serverless Framework

Para o Serverless Framework ter acesso a nossa conta da AWS precisamos primeiro gerar um usuário e ter em mãos o aws_access_key_id e o aws_secret_access_key do nosso usuário.

Vou mostrar o modo mais prático para utilizar neste exemplo, e depois você pode conhecer mais profundamente as políticas de segurança e ajustar tudo.

  1. Acesse o serviço IAM no console da AWS navegue até a aba Users para criar um novo usuário.
  2. Escolha um nome para o novo usuário e logo abaixo selecione o tipo Programmatic access, e clique em Next: Permissions.
  3. Clique a aba Attach existing policies directly que fica logo no início da nova tela, e selecione a opção AdministratorAccess na lista que aparece abaixo, em seguida clique em Next: Tags.
  4. Pule esta etapa e clique em Next: Review.
  5. Revise todos os dados e clique em Create user.

Pronto agora temos em mãos o aws_access_key_id e o aws_secret_access_key.

Agora vamos executar o seguinte comando no terminal para registrar este usuário no nosso Serverless Framework desta máquina.

Substitua cada um dos dados e execute:

$ sls config credentials -p aws -k <aws_access_key_id> -s <aws_secret_access_key>

Pronto agora temos acesso a nossa conta na AWS, porém vale ressaltar que este usuário nós criamos somente como exemplo para agilizar o post, mas é de extrema importância que você crie o mesmo seguindo as políticas de segurança informadas pela Amazon AWS no serviço do IAM.

2. Gerar o código inicial de um Lambda com linguagem Golang na AWS, retornando um json de teste aleatório.

Essa geralmente é a parte que todo mundo fica com aquele pensamento de “Putz, configuração inicial sempre dá trabalho”, mas essa é uma das questões que o Serverless Framework ajuda bastante!

Logo de cara, temos no repositório uma grande lista de templates já prontos com cada tipo de linguagem suportada, e isso ajuda muito!

Lista de templates

Vamos usar o aws-go, e iniciar nosso projeto executando o código abaixo:

$ sls create --template aws-go

O comando executado, baixa os arquivos do nosso template direto do repositório que vimos logo acima, então temos agora a seguinte estrutura:

.
├── hello
│  └── main.go
├── world
│  └── main.go
├── Makefile
└── serverless.yml

Logo de início já ganhamos duas funções prontinhas, o Makefile para compilação do código e um aquivo em especial chamado serverless.yml onde vamos colocar todas as configurações que precisamos para nosso projeto, desde configurações de acesso HTTP para as funções, até se necessário adicionar tabelas no banco de dados DynamoDB por exemplo.

Explicando um pouco sobre o arquivo serverless.yml

service: aws-go

frameworkVersion: ">=1.28.0 <2.0.0"

provider:
  name: aws
  runtime: go1.x

package:
 exclude:
   - ./**
 include:
   - ./bin/**

functions:
  hello:
    handler: bin/hello
    events:
      - http:
          path: hello
          method: get
  world:
    handler: bin/world
    events:
      - http:
          path: world
          method: get
  1. service: O nome do serviço que estamos criando na AWS, podemos mudar para outro de nossa preferência, porém temos que tomar cuidado para não duplicar, pois este nome é o ID do nosso projeto.
  2. frameworkVersion: Define a versão do Serverless Framework que é necessário utilizar para fazer deploy deste projeto.
  3. provider.name: Define a provedora.
  4. provider.runtime: Define a linguagem que vamos utilizar.
  5. package: Define os pacotes que devem ser excluidos e incluidos no deploy, podendo ser removidos algumas coisas que são usadas somente para desenvolvimento em geral.
  6. funcion.<name>: Define o ID da nossa função.
  7. funcion.<name>.handler: Define o arquivo que contem o código de execução da função.
  8. funcion.<name>.evends:: Define a lista de eventos de acionamento que vamos atrelar nesta função, podendo ser chamadas HTTP, chamadas por eventos de storage S3 em geral.
  9. funcion.<name>.evends - http:: Adiciona um evento de execução do tipo HTTP-GET utilizando o path /hello e o /world.

Lembrando que se for necessário, podemos ter vários e vários eventos para uma função, como na documentação do framework:

...
# 'functions' in serverless.yml
functions:
  createUser:
    handler: handler.users
    events:
      - http:
          path: users/create
          method: post
      - http:
          path: users/update
          method: put
      - http:
          path: users/delete
          method: delete
...

Mais pra frente vamos ver que para cada necessidade existe uma configuração que vamos adicionar neste arquivo, e assim vamos ter tudo funcionando somente com o uso do framework e sem acesso ao console da AWS.

Vamos modificar agora algumas coisas nessa configuração.

Removendo a função world

Vamos apagar a pasta da função world e remover ela do arquivo Makefile, para ficar com a seguinte estrutura:

.
├── hello
│   └── main.go
├── LICENSE
├── Makefile
├── README.md
└── serverless.yml

Modificando nosso serverless.yml

Vamos também retirar a função world da configuração do nosso projeto, já que não existe mais para fazer deploy, e vamos aproveitar para mudar o nome do nosso serviço para post-aws-lambda-go-example, assim vamos deixar tudo organizado.

Nosso serverless.yml vai ficar assim:

service: post-aws-lambda-go-example

frameworkVersion: ">=1.28.0 <2.0.0"

provider:
  name: aws
  runtime: go1.x

package:
 exclude:
   - ./**
 include:
   - ./bin/**

functions:
  hello:
    handler: bin/hello
    events:
      - http:
          path: hello
          method: get

3. Deploy do projeto

Como já temos o framework configurado com as credenciais e o template de exemplo, então agora basta executar os comandos abaixo, que vamos ter nosso projeto instalado na AWS sem nenhum esforço adicional.

$ make
$ sls deploy

Olha que legal, o Serverless Framework fez todo o trabalho, subindo o projeto no AWS S3, criou a função e fez a configuração para acesso HTTP-GET na url https://6txmi7akv1.execute-api.us-east-1.amazonaws.com/dev/hello.

Mas podemos notar que como não informamos a configuração de região, o framework enviou a nossa função para ser executada em us-east-1.

Huum… não é bem o que a gente queria, então vamos pedir para mudar :( bubu.

Nós estamos no BRASILSILSIL!!

Modificando configuração de região

Para modificar a região do projeto vamos adicionar uma propriedade em provider.region do nosso arquivo serverless.yml.

Então agora podemos executar o sls deploy com a seguinte edição na configuração do provider:

...
provider:
  name: aws
  runtime: go1.x
  region: sa-east-1
...

Agora nossa url passou para https://6txmi7akv1.execute-api.sa-east-1.amazonaws.com/dev/hello e está executando em sa-east-1 melhorando o tempo de resposta das nossas funções.

4. Executar a função pelo terminal com o Serverless Framework

Para executar uma função diretamente pelo terminal usando o Serverless Framework, vamos usar o seguinte comando:

$ sls invoke --function hello

Pronto, a função foi executada na AWS e o nosso retorno foi um json que segue o padrão do serviço API Gateway, já que configuramos nossa função para trabalhar também com o protocolo HTTP.

5. Executar a função pelo protocolo HTTP

Para facilitar esta parte vou enviar a chamada utilizando o curl, assim não precisamos de nenhum outro programa como o Postman ou algo do tipo instalado.

$ curl https://6txmi7akv1.execute-api.sa-east-1.amazonaws.com/dev/hello

6. Remover o projeto da AWS

Com apenas um comando podemos remover todo o deploy de um projeto.

$ sls remove

Vale ressaltar que se algo foi modificado direto pelo console da AWS, o Serverless Framework pode não conseguir remover seu projeto por alguns motivos, então sempre procure usar o serverless.yml para modificações.

Conclusão

Pronto!!! Viu como é fácil?

Como eu trabalho praticamente 100% com Arquitetura Serverless o setup que usei neste post é algo do meu cotidiano, não só para desenvolver funções mas também para gerenciar tudo que eu preciso para meus projetos, como bases no DynamoDB, skills da Alexa em geral.

Fiz este post para servir de ponto de partida para outros que vou escrever, mostrando o quanto é fácil desenvolver de forma serverless e que não precisamos mais nos preocupar com escalabilidade ou custos de pequenos projetos.

O que vale é criar! fazer! inovar!

Também vou trazer posts relacionados a otimização dos códigos, visto que no AWS Lambda cada MB e tempo utilizado conta no seu bolso.

Se este post te ajudar, compartilhe com seus amigos e vamos espalhar conhecimento!

Obrigado. :)

Compartilhe este post.