Como usar Terraform + Localstack (com Docker)

rotirotirafa

Rafael Rotiroti

Posted on March 17, 2023

Como usar Terraform + Localstack (com Docker)

Vou separar esse artigo em 4 partes: motivação, teoria, prática, conclusão.

A intenção é ser um conteúdo leve, introdutório e nada de terno e gravata, que atenda desde de pessoas iniciantes e até mesmo mais experientes.

Estou voltando a escrever agora e pretendo voltar a produzir esse tipo de conteúdo ao longo desse ano. Sugestões e feedback são muito bem vindos!

Motivação

No fim do ano passado eu estava um pouco incomodado com o fato de saber apenas sobre o Terraform teoricamente... queria aprender e ter a capacidade de usar diariamente de forma mais autonoma, só que eu queria estudar com calma, fazer uma aplicação prática para válidar o conhecimento e etc.

Em Janeiro tirei uns dias de férias para descansar, fui viajar e quando voltei tinha uma semana livre, tempo perfeito para se atualizar e colocar minhas ideias em dia.

Terraform foi o escolhido da vez!

Teoria

Como vamos utilizar Terraform, Docker e Localstack vou fazer um pequeno resumo de cada um.

O Terraform é uma tecnologia IaaC (Infrastructure as a Code ou Infraestrutura como código, como prefirir.), permite que você provisione sua infraestura em nuvem através de código, numa estrutura bem familiar ao JSON

O Docker é uma plataforma que faz a criação de administração de containers, ou seja, permite que você isole e esteja preparado para fazer deploy do seu ambiente para nuvem.

O Localstack é uma ferramenta que permite que você desenvolva e teste suas aplicações localmente, ou seja, permite que você utilize e simule tecnologias como SNS, Lambda, SQS, Dynamo e etc no seu ambiente local.

A ideia é basicamente usar o Terraform para provisionar a infraestrutura dentro da minha máquina local, para isso utilizei o Localstack que simula toda minha infraestrutura da AWS dentro dos containeres do Docker.

Prática

Presumo que o Docker, Terraform e AWS CLI estejam configurados e instalados em sua máquina e então podemos iniciar a configuração do Localstack.

Criaremos o arquivo docker-compose.yml com a seguinte instrução:



version: "3.8"

services:
  localstack:
    image: localstack/localstack:1.3.1
    environment: 
      - AWS_DEFAULT_REGION=sa-east-1
      - AWS_ACCESS_KEY_ID=teste
      - AWS_SECRET_ACCESS_KEY=teste
      - EDGE_PORT=4566
      - DATA_DIR=${DATA_DIR-}
      - HOST_TMP_FOLDER=${TMPDIR:-/tmp/}localstack
      - DOCKER_HOST=unix:///var/run/docker.sock
    ports:
      - '4566-4587:4566-4587'
    volumes:
      - localstack-data:/tmp/localstack
      - "/var/run/docker.sock:/var/run/docker.sock"
    networks:
      - dev_to

volumes:
  localstack-data:
    name: localstack-data

networks:
  dev_to:
    name: dev_to


Enter fullscreen mode Exit fullscreen mode

De forma resumida, estamos pedindo para o Docker criar a partir da imagem Localstack(1.3.1) um container. Detalhe na EDGE_PORT=4566 que falarei mais adiante sobre ela!

Com o comando docker compose up -d o Docker vai criar e subir o container na sua máquina local e prover todos os recursos que o Localstack dispõe.

Rode o comando docker ps e veja se obtem um resultado parecido:

Resultado do Docker PS, container ativo!

Com nosso container no ar e com o Localstack provisionado já podemos partir para o que interessa: Terraform!

No meio do caminho acabei recebendo uma dica de um amigo sobre o TFLocal que foi muito útil, pois ao utilizar o Terraform, precisamos apontar pro ambiente local e o TFLocal foi desenvolvido justamente para o cenário com Localstack.

Para instalar, basta ter o Python e rodar pip install terraform-local

Com isso, vamos escrever nosso arquivo main.tf



provider "aws" {
  region                     = "sa-east-1"
  access_key                 = "teste"
  secret_key                 = "teste"
  skip_credentials_validation = true
  skip_requesting_account_id = true
  skip_metadata_api_check    = true
}


resource "aws_dynamodb_table" "basic-dynamodb-table" {
  name           = "GameScores"
  billing_mode   = "PROVISIONED"
  read_capacity  = 20
  write_capacity = 20
  hash_key       = "UserId"
  range_key      = "GameTitle"

  attribute {
    name = "UserId"
    type = "S"
  }

  attribute {
    name = "GameTitle"
    type = "S"
  }

  attribute {
    name = "TopScore"
    type = "N"
  }

  ttl {
    attribute_name = "TimeToExist"
    enabled        = false
  }

  global_secondary_index {
    name               = "GameTitleIndex"
    hash_key           = "GameTitle"
    range_key          = "TopScore"
    write_capacity     = 10
    read_capacity      = 10
    projection_type    = "INCLUDE"
    non_key_attributes = ["UserId"]
  }

  tags = {
    Name        = "dynamodb-table-1"
    Environment = "production"
  }
}


Enter fullscreen mode Exit fullscreen mode

O arquivo main.tf é responsável por entender qual será o Provider(AWS, GCP, Azure) a ser utilizado e quais serviços serão criados, no exemplo acima eu quis utilizar o mesmo exemplo no site do Terraform que é criar uma tabela no DynamoDB.

Com o arquivo finalizado, podemos iniciar os comandos que vão realmente criar tudo lá dentro para nós, então abra seu terminal e digite: tflocal init

O comando tflocal init faz exatamente o mesmo que o terraform init faz, inicia a configuração do terraform de acordo com o que temos de instrução no main.tf

Em seguida, tflocal plan. Que por sua vez, vai carregar as suas configurações e te mostrar o que tem para ser feito como planejado.

E por final, tflocal apply -auto-approve, esse comando Apply realmente vai fazer a criação (nesse caso DynamoDB) dos serviços que foram planejados e a flag -auto-approve faz com que não haja a necessidade de confirmar com um "yes" na linha de comando.

Pronto, temos tudo criado e a mensagem que apareceu no terminal deve ter sido algo assim:

Resultado do TFlocal apply

Para ver se sua table criou, basta rodar aws dynamodb list-tables --endpoint-url http://localhost:4566:

Lista de tabelas via AWS Cli

A partir daqui, pode inserir registros na tabela e até mesmo usar o NoSQL Workbench para ter uma GUI de visualização.

Lembra que eu falei sobre o a EDGE_PORT=4566 ?

Veja que eu utilizei ela na minha consulta via CLI, ou seja todos os comandos que eu for fazer de consulta ou apontamentos via código localmente eu devo fazer na porta 4566, pois o localstack está roteando internamente e inteligentemente para os serviços solicitados. Se eu fosse consultar um SQS ou SNS eu apontaria para essa mesma porta 4566 e etc. Obviamente é algo configurável, pode ser utilizado as portas que consta nas docs do Localstack mas eu acho que é algo facilita nossa vida em meio tantas POCs (Prove of concept) que fazemos por ai.

Conclusão

Na minha opnião, desenvolver e testar local é melhor forma de você desenvolver antes de subir para um ambiente de DEV. Por ser um ambiente controlado as ferramentas como Docker, Localstack, Terraform fazem com que tenhamos um ganho absurdo de produtividade e testabilidade.

Além de conseguir testar muitas features sem gastar $ é uma ótima forma de válidar e testar as coisas!

Eu recomendo fortemente combinar essas ferramentas para o uso no dia a dia, fazendo com que nossas entregas além de validadas sejam mais consistentes.

O amigo que mencionei é o Renato Rodrigues, ele que deu a dica de usar o tflocal para iniciar meus estudos com o Terraform usando Localstack. Fica aqui meu agradecimento!

Links que utilizei de inspiração:

💖 💪 🙅 🚩
rotirotirafa
Rafael Rotiroti

Posted on March 17, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related