Como utilizar recursos AWS localmente?

Durante o desenvolvimento de uma aplicação é comum termos a necessidade de interagir com vários serviços externo como um banco de dados, uma fila ou um cache distribuído.

Quando estamos desenvolvendo em ambiente AWS, precisamos utilizar e consumir todos estes serviços diretamente da nuvem, exigindo que a infraestrutura e os serviços já estejam devidamente criados, configurados e disponíveis em uma conta AWS para que possamos começar a codificar.

Isso pode dificultar o desenvolvimento local e aumentar seus custos, já que teremos a dependência de estarmos sempre conectados à nuvem mesmo durante a fase inicial do desenvolvimento e a necessidade de pagarmos por todos estes recursos sem que a aplicação esteja pronta.

Algumas vezes precisamos alterar algum desses recursos para ver como a aplicação se comporta, mas dificilmente teremos a liberdade de manipular recursos que foram criados e padronizados para o uso de todo o time.

É ai que entra em cena o LocalStack: uma ferramenta open-source escrita em Python que funciona como um emulador dos serviços que estão disponíveis na AWS diretamente em sua máquina.

O LocalStack funciona emulando todos os serviços da AWS em um único container que irá rodar em sua máquina, dessa maneira você pode começar seu desenvolvimento local e interagir com todos os serviços necessários da AWS, sem precisar de uma conexão com a nuvem e dos recursos criados na AWS.

Como utilizar o LocalStack?

O LocalStack possui três principais requisitos: python, pip e docker.

Para verificar se você já possui eles instalados em sua máquina, digite os comandos abaixo.

python --version
pip --version
docker --version

Caso você não possua algum dos três, é necessário a instalação antes de seguir os passos abaixo.

Há diversas maneiras de rodar o LocalStack. Podemos rodar através do docker, docker-compose, helm, mas a que veremos aqui é através da CLI do próprio LocalStack.

Para isso precisamos instalar a CLI:

python3 -m pip install localstack

Agora se certifique que o LocalStack foi instalado corretamente:

localstack --version

Com tudo instalado é hora de iniciar o serviço:

localstack start

Para testar se o LocalStack está funcionando, irei utilizar a CLI da AWS. Ela não é um requisito para a execução do LocalStack, pois podemos interagir com ele de diversas formas, mas é uma maneira bem prática de interagir tanto com a AWS quanto com o LocalStack.

Ao enviar um comando para exibir todos os buckets S3 criados em minha conta AWS, eu tenho o seguinte resultado:

aws s3 ls
2022-06-08 23:31:40 demo-bucket-rafa ## buckets criados em minha conta AWS

Para executarmos o mesmo comando no LocalStack e simular uma cloud local, utilizamos o mesmo comando acrescentando o parâmetro endpoint-url, informando a URL e porta que o LocalStack está em execução. Você pode conferir a URL e porta padrão no comando abaixo:

aws s3 ls --endpoint-url=http://localhost:4566

Dessa vez eu não obtive nenhum resultado do comando acima, pois eu não tenho nenhum bucket local. Isso significa que o LocalStack funcionou.

Para criarmos um bucket e verificarmos se ele foi criado localmente:

aws s3api create-bucket \
--endpoint-url=http://localhost:4566 \
    --bucket localstack-bucket \
    --region us-east-1
aws s3 ls --endpoint-url=http://localhost:4566
2022-09-15 22:04:24 localstack-bucket ## bucket criado localmente via LocalStack

Muito legal né?

A interação com o LocalStack é praticamente igual com a interação na AWS, utilizamos os mesmos comandos e APIs, com a diferença de um parâmetro que indica a URL e porta do serviço.

Agora que já vimos a utilização do LocalStack com a CLI da AWS, será que isso também funciona via SDK?

Considere o código abaixo que lista todos os buckets em minha conta AWS e utiliza a SDK do S3 (AWSSDK.S3)

public static async Task Main(string[] args)
        {
            var client = new AmazonS3Client();
            var buckets = await client.ListBucketsAsync();

            foreach (S3Bucket bucket in buckets.Buckets)
            {
                Console.WriteLine(bucket.BucketName);
            }
        }

Como podemos fazer para emularmos o S3 para agilizar nosso desenvolvimento?

Muito parecido com a CLI da AWS, basta adicionarmos um parâmetro especificando a URL e porta de execução do LocalStack:

public static async Task Main(string[] args)
        {
            var client = new AmazonS3Client(new AmazonS3Config
            {
                ServiceURL = "http://localhost:4566"
            });

            var buckets = await client.ListBucketsAsync();

            foreach (S3Bucket bucket in buckets.Buckets)
            {
                Console.WriteLine(bucket.BucketName);
            }
        }

Dessa maneira, temos exatamente o mesmo código que pode tanto ser testado local quanto na AWS.

O LocalStack é uma ferramenta excelente que nos entrega agilidade e funciona muito bem, além de estar disponível abertamente para download.

No entanto, é bom termos em mente que nem todos os serviços da AWS estão disponíveis na versão Community que utilizamos neste post.

Confira aqui todos os serviços e recursos da AWS que o LocalStack suporta e qual é a versão necessária (Community ou Pro)

Espero que tenham gostado do post!

Dúvida e sugestões são bem-vindas, fiquem à vontade para comentar e contribuir 🙂