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

image

Photo by Hack Capital on Unsplash

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 Back-end terraform determina como o arquivo de estado é armazenado.
O back-end 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 Back-end 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://andersonlima.tech/blog/jogando-mario-na-aws-terrafor-docker/

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

terraform init  
terraform apply

image

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 bucket **** e o arquivo de estado será salvo dentro dela. Dessa forma você pode utilizar só um bucket e usa-lo como back-end para vários projetos.

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

terraform init

image

Saída do console após o terraform init

image

Pasta do projeto criada no S3

image

terraform.tfstate no S3

Bloqueio de estados

Ao usar back-end remoto os estados da sua infraestrutura ficam 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….

image

Para resolver esse possíveis imprevistos vamos utilizar um table 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 back-end 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"
    }
}

Agora basta iniciar novamente seu back-end remoto e voia la….

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