Terraform Backends S3 — Trabalhando em Equipe

Terraform Backends S3 — Trabalhando em Equipe

Salvando arquivos de estado remotamente e bloqueando acessos simultâneos.

Ao trabalhar em equipe com Terraform o primeiro problema que incomoda é o fato do arquivo de estado do Terraform ser gerado localmente. Isso praticamente inviabiliza o uso da ferramenta por um time. Para resolver este problema utilizamos os backends remotos.

Um Backend terraform determina como o arquivo de estado é armazenado.
O backend por padrão é configurado para salvar o estado localmente mas também é possível armazenar o estado remotamente, fazer a execuções remotas e etc…

Configurando Backend remoto na AWS

Para isso precisamos apenas de um bucket S3. Então vamos criar este recurso com o próprio Terraform.

Em um diretório a sua escolha crie o arquivo bucket-s3.tf com o seguinte conteúdo:

provider "aws" {
    profile    = "defaults"
    region     = "sa-east-1"
}
resource "aws_s3_bucket" "bucket-backend" {
    bucket = "bucket-backend-s3"
    versioning {
        enabled = true
    }
    lifecycle {
        prevent_destroy = true
    }
    tags = {
        Name = "backend-S3"
    }
}

Altere os nomes das chaves, Bucket e Profile.

Bucket – Nome único para o seu bucket.

Profile – Nome do profile criado no seu AWS-CLI.

A instalação e configuração do AWS-CLI eu expliquei em mais detalhes no artigo abaixo:

https://medium.com/@anderon.delima/jogando-super-m%C3%A1rio-na-aws-terraform-docker-95405e8bf5bb

No diretório onde você criou o arquivo, use os comandos abaixo para criar o bucket na AWS:

terraform init
terraform apply
Bucket S3 criado com sucesso

Então beleza, já criamos o bucket para o backend… mas como usar?

Nos meus projetos normalmente eu crio um arquivo chamado backend.tf  no mesmo diretório onde meus recursos estão, com o seguinte conteúdo:

terraform {
    backend "s3" {
        profile    = "defaults"
        bucket = "bucket-backend-s3"
        region = "sa-east-1"
        encrypt = "true"
        key = "project-name/terraform.tfstate"
    }
}

Neste recurso você só precisa alterar o nome do seu Bucket, a Região e principalmente a Key que indica como será a organização dos estados no seu bucket.

No exemplo a key vai criar uma pasta chamada project-name dentro do seu buckete e o arquivo de estado será salvo dentro dela. Dessa forma você pode utilizar só um bucket e usa-lo como backend para vários projetos.

A partir de agora pra gente usar o nosso backend basta fazer as alterações no arquivo do backend, jogar ele no nosso projeto e rodar novamente um:

terraform init
Saída do console após o terraform init
Pasta do projeto criada no S3
terraform.tfstate no S3

Bloqueio de estados

Ao usar o backend remoto os estados da sua infraestrutura podem ficar disponíveis para mais pessoas de uma equipe, então imagine que duas pessoas estão fazendo alterações na mesma infraestrutura ao mesmo tempo….

Para resolver esse possíveis imprevistos vamos utilizar uma tabela do DinamoDB para bloquear nossos arquivos de estado.

Essa etapa é bem simples, basta criar o arquivo dinamodb-table.tf com o seguinte conteúdo:

resource "aws_dynamodb_table" "dynamodb-backend" {
  name = "dynamodb-backend"
  hash_key = "LockID"
  read_capacity = 20
  write_capacity = 20
  attribute {
    name = "LockID"
    type = "S"
  } 
  tags = {
    Name = "dynamodb-backend"
  }
}

E no seu arquivo de configuração do backend precisamos apenas indicar o uso desta table que acabamos de criar.

Seu arquivo backend.tf deve ficar assim:

terraform {
    backend "s3" {
        profile    = "defaults"
        bucket = "bucket-backend-s3"
        region = "sa-east-1"
        encrypt = "true"
        dynamodb_table = "dynamodb-backend"
        key = "project-name/terraform.tfstate"e
    }
}

Agora basta iniciar novamente seu backend remoto e voia là….

Os arquivos criados neste artigo estão todos disponíveis no seguinte repositório: 
https://github.com/Anderon-lima/terraform-backend-s3

Tags: , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *