.NET e AWS S3 com LocalStack: Como desenvolver com buckets S3 locais
Simplificando o teste na nuvem com LocalStack
Introdução
LocalStack é uma estrutura de código aberto que nos permite emular os principais serviços da AWS localmente, facilitando o desenvolvimento e o teste de aplicativos na nuvem sem incorrer no custo e na complexidade da implantação em um ambiente de nuvem real.
Neste post, mostrarei como configurá-lo para emular buckets S3 e como interagir com esses buckets a partir de um aplicativo C#.
Executando o LocalStack
O LocalStack pode ser executado como uma CLI ou usando um container. Neste post, explicarei como executá-lo em um container com docker run e docker-compose.
Container
Para iniciar um container com uma instância do LocalStack, execute o seguinte comando:
docker run --rm -it -p 4566:4566 -p 4510-4559:4510-4559 -e EXTRA_CORS_ALLOWED_ORIGINS=https://app.localstack.cloud. localstack/localstack:1.3.1
Observe que ele está expondo a porta 4566 e as portas 4510 a 4559 e permitindo o acesso CORS de https://app.localstack.cloud. (para permitir o acesso do painel do LocalStack).
latest para evitar problemas com novas versões atualizadas automaticamente.Docker compose
Iniciar o LocalStack a partir do docker compose é tão fácil quanto. Basta adicionar o serviço localstack, como abaixo, a um arquivo docker-compose.yaml:
| |
Em seguida, execute o seguinte comando:
docker-compose up
latest para evitar problemas com novas versões atualizadas automaticamente.EXTRA_CORS_ALLOWED_ORIGINS com o valor https://app.localstack.cloud. para permitir o acesso do painel do LocalStack.Painel do LocalStack
O LocalStack tem um painel baseado na web que nos permite gerenciar e configurar seus serviços e visualizar seus logs.
Acesse https://app.localstack.cloud. e ele se conectará à instância do LocalStack em execução localmente.
Ele é executado no navegador, portanto, não há necessidade de expor nenhuma porta à Internet.

EXTRA_CORS_ALLOWED_ORIGINS não foi definida corretamente como https://app.localstack.cloud.. Veja aqui.Interagindo com o LocalStack usando a AWS CLI
Usaremos a AWS CLI para interagir com o LocalStack. Se você não tiver a AWS CLI, consulte aqui para obter instruções sobre como instalá-la.
Configurando um perfil para o LocalStack
A AWS CLI requer credenciais ao ser executada. O LocalStack não valida as credenciais por padrão, portanto, criará um perfil com qualquer coisa como chave de acesso e chave secreta apenas para deixar a CLI feliz.
- Em um terminal, digite
aws configure --profile localstack; - Para
AWS Access Key ID [None]:, digite qualquer coisa; - Para
AWS Secret Access Key [None]:, digite qualquer coisa; - Para
Default region name [None]:, digite a região que você preferir (por exemplo,us-east-1); - Para
Default output format [None]:, digitejson.
Como criar um bucket usando a AWS CLI
Para criar um bucket S3 no LocalStack, usaremos o comando aws s3 mb (mb é a abreviação de Make Bucket).
O comando abaixo criará um bucket com o nome local-bucket-name usando o perfil da AWS CLI que criamos anteriormente com o nome localstack. É importante passar o parâmetro --endpoint ou então ele tentará criar o bucket na AWS.
aws s3 mb s3://local-bucket-name --endpoint http://localhost:4566 --profile localstack
Olhando para o painel do LocalStack, podemos ver que o bucket foi criado:

Como listar o conteúdo de um bucket usando a AWS CLI
Para ver o conteúdo de um bucket, podemos usar o comando aws s3 ls:
aws s3 ls s3://local-bucket-name --endpoint http://localhost:4566 --profile localstack
Ou use o painel do LocalStack:

Acessando o LocalStack do .NET
Para acessar um bucket S3 do LocalStack no .NET, usamos as mesmas bibliotecas que usamos para acessá-lo na AWS.
Neste exemplo, usarei os pacotes NuGet AWSSDK.S3 e AWSSDK.Extensions.NETCore.Setup, ambos da AWS.
Como o AmazonS3Client obtém os dados de acesso da AWS?
Ao ser executado na AWS, o AmazonS3Client obterá seus dados de acesso da função IAM anexada ao serviço que o executa. Ao ser executado localmente, ele obterá do perfil da AWS CLI chamado default ou das configurações que passamos para ele.
No código abaixo, estou verificando uma seção de configuração com o nome AWS, que não está presente no ambiente de produção. Se for encontrado, defino as propriedades Region, ServiceURL e ForcePathStyle do AmazonS3Config e passo-o para a criação do AmazonS3Client.
Program.cs
| |
AwsExtensions.cs
| |
O appsettings.Development.json tem as configurações apontando para a instância do LocalStack:
appsettings.Development.json
| |
ForcePathStyle força o uso de URLs estilizadas https://s3.amazonaws.com/<bucket-name>/<object-key> em vez de URLs https://<bucket-name>.s3.amazonaws.com/<object-key>.O
ForcePathStyleprecisa ser definido comotruepara que oAmazonS3Clientfuncione com o LocalStack.
Enviar uma imagem para o bucket S3
Usando APIs mínimas, criei um endpoint que recebe um arquivo e o salva no bucket S3.
O código é direto:
Program.cs
| |
Agora, podemos testá-lo no Postman:

Obter uma imagem do bucket S3
Também criei um endpoint que retorna o arquivo com a chave passada por parâmetro do bucket S3:
| |
Testando no Postman, podemos ver a imagem enviada anteriormente:

