Transforme sua Rotina de Desenvolvimento: AWS Local com LocalStack e Node.js
Introdução
Se você, assim como eu, lida com o desenvolvimento de soluções baseadas na cloud da Amazon (AWS), sabe que temos desafios particulares quanto a testar nossas aplicações e garantir que o funcionamento que temos em ambiente local é próximo ao que podemos esperar em produção. Por isso, hoje venho compartilhar com vocês uma ferramenta muito interessante que tem me auxiliado nesse processo: LocalStack.
Neste guia prático, mergulharemos no universo dessa ferramenta, explorando sua integração fluida com o Docker para proporcionar uma experiência de desenvolvimento eficaz e que pode agilizar bastante nosso trabalho. Iremos explorar alguns conceitos básicos e exemplificar tudo com uma aplicação Node.js que faz uso dos serviços SQS e SNS. Vamos juntos desbravar passo a passo como otimizar seu fluxo de desenvolvimento local de maneira descomplicada.
Sobre a LocalStack
LocalStack é um projeto de código aberto projetado para ser um stack AWS local totalmente funcional, voltado para desenvolvimento e testes. Ele permite que desenvolvedores testem suas aplicações localmente, eliminando a necessidade de incorrer em custos associados à execução de recursos na AWS durante o desenvolvimento. Seja para trabalhar em aplicações complexas com CDK, configurações com Terraform ou explorar serviços da AWS, o LocalStack acelera e simplifica o fluxo de trabalho de teste e desenvolvimento.
A ferramenta atualmente oferece suporte a uma variedade de serviços da AWS, como AWS Lambda, S3, DynamoDB, Kinesis, SQS, SNS, etc. O LocalStack opera como um emulador de serviços em nuvem em um único contêiner Docker na sua máquina local. Isso possibilita a execução, teste e depuração de aplicações AWS sem a necessidade de uma conexão com um provedor de nuvem remoto.
Configuração do ambiente
No nosso exemplo, vamos utilizar o Docker para provisionarmos o LocalStack e o Node JS para construírmos uma aplicação simples que utiliza dois serviços da AWS: SQS e SNS. Além disso, vamos construir um script bash que será executado durante a inicialização do container e criará - utilizando comandos da AWS CLI - os serviços e configurações que desejamos.
Começando pelo mais importante, vamos construir um arquivo docker-compose que expõe o serviço do LocalStack, com isso, podemos garantir que teremos um ambiente de desenvolvimento similar para todos os contribuintes no projeto.
version: '3.7'
services:
localstack:
container_name: "localstack"
image: localstack/localstack
ports:
- "127.0.0.1:4566:4566"
environment:
- SERVICES=sqs
- EDGE_PORT=4566
- DEBUG=1
- DOCKER_HOST=unix:///var/run/docker.sock
volumes:
- ./localstack_setup:/etc/localstack/init/ready.d
- /tmp/localstack:/tmp/localstack
- /var/run/docker.sock:/var/run/docker.sock
O código acima faz uso de uma imagem Docker da LocalStack e cria - dentre suas configurações padrão - um link para o script bash que criará os recursos na LocalStack e o script de inicialização do container: ./localstack_setup:/etc/localstack/init/ready.d
Nesse script, configuramos 4 funções:
create_queue
para criação de queues SQS.create_topic
para criação de tópicos SNS.guess_queue_arn_from_name
para buscar o Amazon Resource Name (ARN) de uma fila.link_queue_and_topic
para inscrever nossa queue SQS a um tópico SNS.
Adicionando o Node JS
Para obter acesso ao exemplo completo, basta seguir para este repositório. Aqui, irei demonstrar apenas os recursos básicos de integração do Node JS com os serviços da AWS, sem tratar as especificidades de cada recurso.
Na configuração da fila SQS, basicamente criaremos um arquivo onde iremos criar uma instância do SQS Client a partir das configurações da nossa infra local com LocalStack:
Para o tópico SNS, temos uma configuração semelhante:
Como podemos ver, o LocalStack permite que configuremos nossos recursos com as funções nativas da AWS, alterando apenas as variáveis de ambiente que determinam onde está o provider (LocalStack / Cloud AWS).
Além disso, ao termos um ambiente dockerizado podemos permitir que todos os devs possam startar o projeto sem grandes problemas, e, principalmente, sem a necessidade de sempre configurar os recursos que serão provisionados pela LocalStack.
Executando o código
Com nosso projeto devidamente configurado no docker-compose + bash, podemos executar o exemplo (disponível neste repositório).
# devemos ceder permissão para que o arquivo bootstrap.sh seja executado
chmod +x ./localstack_setup/bootstrap.sh
# executamos nossa imagem do localstack
docker-compose up -d
# damos start no projeto
npm run start:dev
Com o projeto em execução, nosso console irá apresentar a seguinte mensagem: Waiting for messages...
. Para que a fila seja notificada, podemos enviar mensagens para o endpoint http://localhost:8080/create
:
POST http://localhost:8080/create HTTP/1.1
content-type: application/json
{
"table": "14D",
"products": [
{"name": "coca-cola", "quantity": 2}
]
}
Após a execução de requisições, o console deve apresentar o resultado que foi recebido por nossa fila SQS.
Conclusão
Em resumo, a LocalStack oferece uma solução prática e conveniente para o desenvolvimento de aplicações que fazem uso de recursos provisionados pela AWS. É uma ferramenta particularmente útil quando buscamos agilidade, principalmente para testarmos alguns serviços pontuais, como o sistema de filas e notificações.
No mais, acho importante ressaltar que a confiabilidade do nosso projeto vai muito além dessas facilidades no ambiente local. As validações mais importantes ainda devem ser feitas na nuvem, e para isso, o desenvolvedor precisa ter domínio das estruturas principais que compõem seu ambiente de deployment.