Executando verificação de segurança...
5

Use a AWS como um framework web e hospede seus projetos de graça

Ao longo do meu aprendizado como desenvolvedor criei uma série de projetos pessoais e estava me preparando para começar a criar projetos experimentais que pudessem virar projetos comerciais no futuro, mas depois de ficar órfão devido à descontinuação dos planos gratuitos do Heroku, o primeiro desafio era de como hospedar esses projetos. Ao iniciar minha pesquisa, eu criei alguns pré-requisitos:

  • Confiabilidade em primeiro lugar. Quero dormir tranquilo à noite e não ficar preocupado, pensando se meus aplicativos estão fora do ar devido a um serviço de hospedagem instável ou se os backups estão sendo realizados😌

  • Usar serviços gerenciados em vez de soluções manuais Em vez de gastar tempo fazendo trabalhos manuais como aplicar atualizações no sistema operacional do servidor ou fazer backups manuais do banco de dados, prefiro focar no problema que estou tentando resolver e no código que diferencia meu aplicativo dos outros😙

  • Tenha o menor custo possível, pois sou brasileiro e pagar em dólar é triste😭

  • Use padrões do mercado. Não quero investir meu tempo aprendendo sobre plataformas usadas apenas por projetos pequenos ou um pequeno nicho, prefiro aprender uma única plataforma que possa ser usada tanto pelo meu humilde projeto pessoal como uma solução complexa e capaz de suportar uma grande carga de trabalho

  • Capaz de executar tarefas de back-end: Deve fazer autenticação e ter um banco de dados persistente, por exemplo

Os custos de ter infraestrutura tradicional não são baixos

Pesquisei as opções de provedores cloud e todos eles ofereciam serviços semelhantes. A AWS tem a maior participação de mercado, por isso foi a primeira escolha natural. Basicamente, precisava de um lugar para executar meu código e ter um banco de dados. Para o servidor, eu poderia optar por uma solução totalmente gerenciada como AWS Lightsail em contêineres por US$ 7/mês.

Pesquisando sobre o custo de um banco de dados, o cenário não era muito animador. Se tivesse um único projeto pessoal, mesmo com poucos acessos no banco de dados, a instância AWS RDS mais barata sairia cerca de US$ 30/mês. Outra opção seria o banco de dados gerenciado fornecido pelo AWS Lightsail, resultando em um custo de US$ 15/mês.

Ainda assim, eu teria que gastar pelo menos 22 dólares/mês, o que daria mais de R$100. Isso é bem ruim, principalmente quando estou querendo criar projetos experimentais sem planos de receita a curto prazo. Além disso, nem é uma solução ideal, pois na maior parte do tempo o banco de dados ficaria oscioso, o que significa dinheiro jogado no lixo. E também não é muito escalável, pois criar mais outro projeto usando a mesma infraestrutura já adicionaria mais dólares na conta total.

Indo para o lado serverless da força

Ao fazer estimativas de preço na AWS Pricing Calculator, descobri que os serviços serverless podem ser gratuitos quando há apenas uso leve, graças ao Free Tier.
Mesmo com cargas de trabalho respeitáveis, eles têm custos bem baixos, que não ultrapassaria a marca de 5 ou 10 dólares/mês. Além disso, todos os serviços serverless são serviços gerenciados, o que significa que eu poderia focar apenas em criar código que é importante para mim, sem perder tempo gerenciando ou monitorando a infraestrutura

Antes de continuar, gostaria de esclarecer que serverless não é um tipo de serviço que não utiliza servidores, mas sim um serviço totalmente gerenciado, ou seja, muitos aspectos que seriam cuidados por mim em uma infraestrutura tradicional agora são cuidados pela AWS:

  • Aplicar patches de atualização no servidor
  • Balancear o tráfego entre servidores
  • Fazer backups do bancos de dados
  • Cuidar da segurança da infraestrutura
  • Aumentar ou diminuir a capacidade dos servidores

Pensando em um exemplo concreto, é possível criar uma API e se ela receber poucas requisições, ficaria disponível gratuitamente. Caso ela passe a receber centenas de milhões de requisições, a única coisa que mudaria seria o custo mensal e tudo isso mantendo a mesma infraestrutura😃

E se eu usasse os serviços serverless para substituir um framework web?

À primeira vista, os serviços da AWS parecem ser um monte de serviços desconexos, que precisariam ser criados, configurados e conectados manualmente, indo e voltando na página deles. Mas, estudando um pouco mais fundo, fica claro que não é a única maneira de criar e manter esses serviços.

O autor desse artigo já deu a dica de que serviços serverless podem ser usados como um framework web, como Rails, Django, Spring Boot, Nest, e pode até ser o próxima geração de frameworks web.
Nesse novo modelo de framework, eu escrevo o código da aplicação usando minha linguagem de programação favorita, acompanhado do código da infraestrutura, descrevendo que preciso de autenticação, API, armazenamento, por exemplo. Então eu poderia testar o código, armazená-lo no Github e criar toda a infraestrutura usando um único comando e o código da aplicação iria junto com esse deploy. Se eu precisar adicionar um novo serviço, seria como adicionar um novo recurso na minha aplicação: alterar o código, passar pelos testes, enviar para o Github e fazer o deploy.

Tudo isso é possível graças ao AWS CDK. Ele consegue criar serviços AWS com um código bem sucinto, pois usa padrões pré-definidos, então não é necessário descrever todos os detalhes, como no AWS Cloudformation. Aqui está um código do AWS CDK que cria uma API que usa uma função Lambda para processar as solicitações:

from constructs import Construct
from aws_cdk import (
    Stack,
    aws_lambda as _lambda,
    aws_apigateway as apigw,
)
class CdkWorkshopStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        
        # Cria um AWS Lambda e aponta onde o código em Python está
        my_lambda = _lambda.Function(
            self, 'HelloHandler',
            runtime=_lambda.Runtime.PYTHON_3_7,
            code=_lambda.Code.from_asset('lambda'),
            handler='hello.handler',
        )
        
        # Cria uma API e aponta o Lambda definida na variável my_lambda para receber a requisição
        apigw.LambdaRestApi(
            self, 'Endpoint',
            handler=my_lambda,
        )

É só isso! Ao dar deploy nesse código, é criado uma API, pronta para receber solicitações. Para fazer a mesma coisa na página do Console AWS seria necessário clicar vários botões, configurar todas as permissões e fazer todo o trabalho novamente para cada região diferente da AWS. Neste exemplo do CDK, todas as autorizações necessárias para que os serviços interajam entre si são criadas automaticamente e as configurações padrão são aplicadas por padrão caso o desenvolvedor não mencione no código do CDK.

Para aqueles que já estão familiarizados com um framework web para Python chamado Flask, um equivalente serverless da AWS está disponível como AWS Chalice e é muito semelhante ao Flask em termos de sintaxe. Ao usá-lo, é possível integrar a autenticação ou um banco de dados como seria feito usando o Flask, escrevendo uma ou duas linhas de código. O código abaixo para Chalice cria uma API com rotas GET e POST que criam Usuários e Perfis. Ambas as rotas usam um banco de dados DynamoDB, e as rotas POST usam o AWS Cognito para fornecer autenticação e funcionalidade de login/logout:

import os
import boto3
from chalice import Chalice, CognitoUserPoolAuthorizer


app = Chalice(app_name='cdkdemo')
dynamodb = boto3.resource('dynamodb')
dynamodb_table = dynamodb.Table(os.environ.get('APP_TABLE_NAME'))

# Creates an Cognito Authorizer for the API
authorizer = CognitoUserPoolAuthorizer(
    'cdk-test-pool',  # Name of authorizer
    [os.environ.get('USER_POOL_ID')] # Gets User Pool ARN
)

@app.route('/users', methods=['POST'], authorizer=authorizer)
def create_user():
    """ Cria ou atualiza um usuário em uma tabela do DynamoDB """
    # Pega o JSON no corpo da requisição
    request = app.current_request.json_body
    
    # Cria um item
    item = {
        'PK': f'User#{request["username"]}',
        'SK': f'Profile#{request["username"]}',
    }
    
    # Item é criado ou atualizado no banco de dados
    dynamodb_table.put_item(Item=item)
    
    # Returna um dicionário vazio
    return {}
 
@app.route('/users/{username}', methods=['GET'])
def get_user(username):
    """ Retorna um usuário de uma tabela DynamoDB """
    # Cria uma chave a ser buscada
    key = {
        'PK': f'User#{username}',
        'SK': 'Profile#{username}',
    }
    
    # Retorna a chave do banco de dados
    item = dynamodb_table.get_item(Key=key)['Item']
    return item

O AWS Chalice cria automaticamente tudo o que é necessário para que o aplicativo seja executado na AWS e se integra perfeitamente ao AWS CDK. Claro, é possível obter o mesmo resultado usando diretamente as funções Lambda, mas usar o Chalice é muito mais natural.

Organização do Código

Alguns de vocês podem estar se perguntando como organizar os códigos da infraestrutura e do aplicativo. Ambos os códigos devem fazer parte do mesmo repositório e estar separados em pastas diferentes, como no exemplo abaixo:

├── infrastructure
│ ├── app.py #Código da infraestrutura AWS
│ ├── requirements.txt #Dependências do código de infraestrutura
├── runtime
│ ├── app.py #Código referente ao AWS Chalice
│ ├── requirements.txt #Dependências do aplicativo Chalice
└── requirements.txt #Contém referências para os 2 requirements.txt

Cada infrastructure e runtime devem ter seus próprios testes, mas devem compartilhar o mesmo ambiente virtual. Para instalar todas as dependências, você usa apenas o arquivo requirements.txt da pasta raiz, que contém apenas as referências dos outros arquivos requirements.txt.

Resumindo

Aprender e usar os serviços da AWS tem sido uma longa jornada para mim. Tive uma boa dose de frustração e desespero quando me deparei com erros inesperados e documentação confusa da AWS e isso adiciona uma tonelada de complexidades em relação a uma hospedagem mais simples, como Heroku, DigitalOcean ou pythonanywhere. Pensando no que vivi até agora, posso resumir algumas desvantagens ao trabalhar com a AWS:

Contras

  • É necessário aprender sobre uma grande quantidade de serviços AWS e como eles se relacionam entre si

  • Possui uma lógica muito diferente em relação aos frameworks tradicionais, o que leva um certo tempo para se acostumar

  • Necessário vender a alma para o Jeff Bezos😈
    Usar vários serviços da AWS e investir tempo para aprendê-los significa que será mais difícil mudar para outro provedor cloud. Mudar dados que estão na AWS para outros serviços equivalentes pode ser bem doloroso. É como mudar da Apple para o Android ou vice-versa

  • Os custos do serverless podem ser altos se os serviços não forem configurados corretamente e acabarem consumindo mais tempo do servidor do que deveriam ou se receberem cargas muito altas💰💰

  • A documentação da AWS é de dar sono e às vezes está desatualizada e é difícil de achar certas informações. As informações do AWS Cognito, por exemplo, estão espalhadas entre diferentes sites da AWS: na documentação, na documentação do CDK e nos vários artigos que foram criados ao longo dos anos

Mas as vantagens superam as desvantagens:

Prós

  • Serverless é uma forma moderna de criar infraestrutura com flexibilidade e baixo custo

  • Depois de superar a curva de aprendizado, torna-se fácil construir ou replicar infraestruturas complexas em muito pouco tempo

  • Os serviços da AWS têm ótima integração, especialmente se usar o AWS CDK

  • Custo zero ou baixo custo, mas é capaz de responder a picos de demanda e gerenciar grandes cargas de trabalho

  • A AWS é usada por muitas empresas, tem uma grande comunidade e o conhecimento de serverless está em alta demanda📈

  • A AWS tem muito material para aprendizado gratuito ou pago, como vídeos, tutoriais e artigos, criados pela própria AWS ou outros terceiros

  • Em vez de pagar um salário integral de um DevOps ou especialista em banco de dados, você paga uma pequena taxa mensal para a AWS, que pode ser reduzida ou cancelada a qualquer momento, trazendo grande flexibilidade

Isso é tudo por hoje! Se você tiver comentários ou perguntas, fique à vontade!

Carregando publicação patrocinada...
2

Para ideias assim eu usaria a Deta.sh

Vantagens - só subir o projeto e rodar! Desde que seja Python ou node :)

Desvantagem - o Banco de dados só pode ser o deles! Que não é ruim. Mas tem que aprender!

Ou usar de outro lugar - ta cheio de empresa que tem parte gratis em banco
postGres, mysql ou mongoDB

1

Eu não conhecia o Deta e achei ele bem interessante, mas uma coisa que me deixou com o pé atrás é que ele é totalmente grátis e ainda estão trabalhando em um produto que gere renda para eles. Na própria Home deles:

How are you going to make money?

We're working on a big, parallel product that we will be announcing soon. This product will be responsible for generating revenue. Stay tuned!

Eu ficaria com o pé atrás para investir tempo para aprender a tecnologias deles ou deixar um aplicativo que tenha alguma importância rodando nele. Nada impede que amanhã ou daqui a um mês eles saiam de ar pq a grana acabou.

1

Igual qualquer startup.

Whatsapp até não rende nada!
Facebok demorou anos pra isso!
Instagram tbm demorou!

Uber.
WeWork.
Tesla.
Spotify.
Twitter.
Nubank.

Tem uma lista de startup ai famosa que não gera lucro ou nem sabe como!

Isso é normal!

Mas eu acho que eles vão fazer um sistema de propagandas tipo adsense
é o que seria bom pra eles.

Eles dão o server + o sistema de propagandas quem sabe sistema de assinaturas pros clientes e facilita tudo!

Era o que eu faria :)

1

O custo para instalar e desinstalar um app de chat ou de música no celular é zero. Agora se eu invisto dias e meses aprendendo e praticando uma nova tecnologia, eu não quero que todo meu esforço seja jogado no lixo se a empresa falir ou resolver pivotar para outro produto ou mercado(como é bem comum nas startups). A startup quer atingir escala, se ela não conseguir esse objetivo num curto espaço de tempo, ela joga tudo fora e não vai ficar mantendo produto para os clientes que se arriscaram e investiram tempo nela.

Achei o serviço legal e quero experimentar em breve, mas não colocaria nada sério lá, nem investiria muito tempo com eles.

1
2
1

Que interessante, não sabia que a Vercel tinha função serverless também, achava que era só para servir os arquivos do frontend. Pelo que vi, ele usa a mesma infraestrutura da AWS, mas mais simplificado. Vou tentar usar ele para projetos mais simples.

Uma desvantagem que vi é que o banco de dados deve ser criado no MongoDB ou no DynamoDB, então não teria um arquivo versionado com as configurações da infraestrutura. E também não tem um sistema de autenticação pronto, como o Cognito, que já vem até com uma UI customizável.

1

Quanto aos bancos eu realmente não sei se podem ser somente estes. Eu escrevi esse artigo no início de 2021, antes de começar a trabalhar como Dev. A ideia é ter um banco com alta disponibilidade, baixa latência e que pode ser consumido remotamente.

Com esses aspectos, o DynamoDB que é o da própria AWS, é a melhor solução. Outra que funciona bem é o FaunaDB e MongoDB. Nessa época, eu iria testar banco SQL chamado cockroachDB (alguma coisa lembra barataDB rsrs), que é basicamente um Postgres super sayajin, mas consegui um emprego, então deixei de lado.

2
1

Caraca, que doideira esse Klotho, criando recursos a partir de comentários no código!😱
Não conhecia também o termo IfC, muito obrigado por compartilhar!

1

AWS é um serviço muito bom, mas até mesmo o Free Tier deles é arriscado vir alguma surpresa no fim do mês e para testes muitas vezes esquecemos ou deixamos de lado, isso pode comprometer valores cobrados no final, eu não indicaria como alternativa de host gratuito.