Evitando conflitos na infraestrutura
Tags: terraform, devops, iac, beginners
Published: 2021-11-08 15:13:12

Terraform State é uma das coisas mais legais da ferramenta por facilitar a gestão do codígo com times distribuídos evitando conflitos desnecessários na esteira. 

Sempre que você executa o Terraform, ele registra informações sobre a infraestrutura que criou em um arquivo de estado do Terraform. Por padrão, quando você executa o Terraform na pasta /foo/bar, o Terraform cria o arquivo /foo/bar/terraform.tfstate. Este arquivo contém um formato JSON personalizado que registra um mapeamento dos recursos do Terraform em seus arquivos de configuração para a representação desses recursos no mundo real. Por exemplo, digamos que sua configuração do Terraform contenha o seguinte:

```terraform
resource "aws_instance" "example" {
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"
}
```
Depois de executar o terraform apply, aqui está um pequeno snippet do conteúdo do arquivo terraform.tfstate

```terraform
{
  "version": 4,
  "terraform_version": "0.12.0",
  "serial": 1,
  "lineage": "1f2087f9-4b3c-1b66-65db-8b78faafc6fb",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "aws_instance",
      "name": "example",
      "provider": "provider.aws",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "ami": "ami-0c55b159cbfafe1f0",
            "availability_zone": "us-east-2c",
            "id": "i-00d689a0acc43af0f",
            "instance_state": "running",
            "instance_type": "t2.micro",
            "(...)": "(truncated)"
          }
        }
      ]
    }
  ]
}
```

Usando este formato JSON, o Terraform sabe que um recurso com tipo aws_instancee nome example corresponde a uma instância EC2 em sua conta AWS com ID i-00d689a0acc43af0f. Sempre que você executa o Terraform, ele pode buscar o status mais recente dessa instância EC2 da AWS e compará-lo com o que está em suas configurações do Terraform para determinar quais alterações precisam ser aplicadas. Em outras palavras, a saída do comando plan é uma diferença entre o código em seu computador e a infraestrutura implantada no mundo real, conforme descoberto por meio de IDs no arquivo de estado.

Beleza, só isso vai evitar conflitos localmente, para evitar conflitos em um time você precisaria que todo time estivesse usando esse mesmo State, vamos usar o S3 para isso. 

Para habilitar o armazenamento de estado remoto com S3, a primeira etapa é criar um bucket S3. Crie um main.tfarquivo em uma nova pasta (deve ser uma pasta diferente de onde você armazena as configurações da postagem anterior do blog) e na parte superior do arquivo, especifique AWS como o provedor:

```terraform
provider "aws" {
  region = "us-east-2"
}
```
Em seguida, crie um intervalo S3 usando o aws_s3_bucketresource:

```terraform
resource "aws_s3_bucket" "terraform_state" {
  bucket = "terraform-up-and-running-state"
  versioning {
    enabled = true
  }
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}
```
Aproveitei para ativar o versionamento do bucket com o parametro versioning enabled = true e a criptografia pois o State possui dados senssiveis. 

Para dizer ao Terraform para armazenar seu arquivo de estado neste bucket S3, você vai usar o terraform inti novamente. Este pequeno comando pode não apenas baixar o código do provedor, mas também configurar seu back-end Terraform. Além disso, o init é idempotente, por isso é seguro executá-lo indefinidamente.

```terraform
$ terraform init
Initializing the backend...
Acquiring state lock. This may take a few moments...
Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "local" 
  backend to the newly configured "s3" backend. No existing state 
  was found in the newly configured "s3" backend. Do you want to 
  copy this state to the new "s3" backend? Enter "yes" to copy and 
  "no" to start with an empty state.
  Enter a value:
```

O Terraform detectará automaticamente que você já tem um arquivo de estado localmente e solicitará que você o copie para o novo back-end S3. Se você digitar "yes", verá:

```terraform
Successfully configured the backend "s3"! Terraform will automatically use this backend unless the backend configuration changes.
```

Agora os outros colegas do time poderão usar o State se confirugrar o mesmo bucket 

```terraform
resource "aws_s3_bucket" "terraform_state" {
  bucket = "terraform-up-and-running-state"
}
```

Me conte como foi testar isso com seu time =D 

Vlw flw