Gerenciamento de Estado do Terraform

LinuxBeginner
Pratique Agora

Introdução

O Terraform utiliza um arquivo de estado (state file) para armazenar informações sobre a infraestrutura que ele gerencia. Este arquivo de estado é crucial, pois mapeia os recursos definidos em seus arquivos de configuração para os recursos do mundo real. Ao manter este estado, o Terraform pode determinar quais recursos criar, atualizar ou destruir.

Neste laboratório, você terá experiência prática com o gerenciamento do estado do Terraform. Você aprenderá a usar vários subcomandos do terraform state para inspecionar o estado atual, listar recursos gerenciados, renomear um recurso dentro do estado e atualizar (refresh) o estado para alinhá-lo com a infraestrutura real. Estas são habilidades fundamentais para qualquer usuário do Terraform.

Este é um Lab Guiado, que fornece instruções passo a passo para ajudá-lo a aprender e praticar. Siga as instruções cuidadosamente para completar cada etapa e ganhar experiência prática. Dados históricos mostram que este é um laboratório de nível iniciante com uma taxa de conclusão de 89%. Recebeu uma taxa de avaliações positivas de 91% dos estudantes.

Visualizar o estado atual com terraform show

Nesta etapa, você aprenderá a visualizar o estado atual usando o comando terraform show. Este comando fornece uma saída legível por humanos dos recursos atualmente gerenciados pelo Terraform, conforme registrado no arquivo de estado. É uma maneira segura e somente leitura de inspecionar o estado da sua infraestrutura.

O script de configuração para este laboratório já inicializou o Terraform e criou um recurso, gerando um arquivo terraform.tfstate. Vamos inspecioná-lo.

Execute o seguinte comando no seu terminal:

terraform show

Você verá uma saída detalhada descrevendo o recurso local_file que o Terraform está gerenciando.

## local_file.example:
resource "local_file" "example" {
    content              = "This is an example file managed by Terraform."
    content_base64sha256 = "F5EYZhFNzSXdE4CUftwQoDVqvdiufZpVyiLMqyZVOcQ="
    content_base65512 = "m1hvaxMuc/EhaKintyI54NSTTJ5yXpqHPCBNoHubF0rvF3JAj36lMj20aPcv21+3/OK+SqkiTlnT/LdvLCwqDA=="
    content_md5          = "a43bdd236c2f0f4d87452ba2ef0867e4"
    content_sha1         = "ec3adcab998872def2df6200fb03992ac6f237a4"
    content_sha256       = "17911866114dcd25dd1380947edc10a0356abdd8ae7d9a55ca22ccab265539c4"
    content_sha512       = "9b586f6b132e73f12168a8a7b72239e0d4934c9e725e9a873c204da07b9b174aef1772408f7ea5323db468f72fdb5fb7fce2be4aa9224e59d3fcb76f2c2c2a0c"
    directory_permission = "0777"
    file_permission      = "0777"
    filename             = "./example.txt"
    id                   = "ec3adcab998872def2df6200fb03992ac6f237a4"
}

Esta saída confirma que o Terraform está ciente de um recurso, local_file.example, e lista todos os seus atributos.

Inspecionar o arquivo de estado terraform.tfstate

Nesta etapa, você inspecionará o arquivo de estado bruto, terraform.tfstate. Embora o terraform show forneça uma visualização amigável, examinar o arquivo JSON bruto ajuda você a entender como o Terraform armazena os dados.

Aviso: Você quase nunca deve editar o arquivo terraform.tfstate manualmente. Modificações incorretas podem corromper seu estado e levar a problemas sérios. Estamos visualizando-o apenas para fins educacionais.

Use o comando cat para exibir o conteúdo do arquivo de estado:

cat terraform.tfstate

A saída será um objeto JSON. Ele contém metadados como a versão do Terraform e, o mais importante, um array de resources.

{
  "version": 4,
  "terraform_version": "1.13.3",
  "serial": 1,
  "lineage": "2a568739-a81d-ced7-dee1-7a92a1666022",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "local_file",
      "name": "example",
      "provider": "provider[\"registry.terraform.io/hashicorp/local\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "content": "This is an example file managed by Terraform.",
            "content_base64sha256": "...",
            "content_base64sha512": "...",
            "content_md5": "...",
            "content_sha1": "...",
            "content_sha256": "...",
            "content_sha512": "...",
            "directory_permission": "0777",
            "file_permission": "0777",
            "filename": "./example.txt",
            "id": "ec3adcab998872def2df6200fb03992ac6f237a4",
            "sensitive_content": null,
            "source": null
          },
          "sensitive_attributes": [
            [
              {
                "type": "get_attr",
                "value": "sensitive_content"
              }
            ]
          ],
          "identity_schema_version": 0
        }
      ]
    }
  ],
  "check_results": null
}

Estes dados brutos são o que o Terraform usa para criar planos de execução (execution plans).

Executar terraform state list para listar recursos

Nesta etapa, você usará o terraform state list para obter uma lista concisa de todos os recursos no estado (state). Quando sua infraestrutura crescer e você tiver dezenas ou centenas de recursos, o terraform show pode ser muito verboso. O comando state list fornece uma lista simples, separada por quebras de linha, dos endereços dos recursos.

Execute o comando no seu terminal:

terraform state list

A saída será muito direta, mostrando apenas o endereço do recurso que criamos.

local_file.example

Este comando é extremamente útil para scripting ou para identificar rapidamente o endereço de um recurso específico quando você precisa direcioná-lo com outros comandos.

Usar terraform state mv para renomear recurso

Nesta etapa, você aprenderá como renomear um recurso no arquivo de estado usando o terraform state mv. Esta é uma tarefa comum ao refatorar seu código Terraform. Se você renomear um bloco de recurso no seu arquivo .tf, o Terraform pensará que você deseja destruir o recurso antigo e criar um novo. O comando state mv permite que você atualize o arquivo de estado para corresponder às alterações do seu código, evitando destruição e criação desnecessárias.

Primeiro, vamos renomear o recurso no nosso arquivo de configuração. Abra o main.tf com o editor nano:

nano main.tf

Mude o nome do recurso de example para example_renamed. O arquivo deve ficar assim:

resource "local_file" "example_renamed" {
  content  = "This is an example file managed by Terraform."
  filename = "${path.module}/example.txt"
}

Pressione Ctrl+X, depois Y e Enter para salvar e sair.

Agora, execute o terraform plan para ver o que o Terraform pretende fazer:

terraform plan

O plano mostrará que o Terraform quer destruir local_file.example e criar local_file.example_renamed, o que não é o que queremos.

local_file.example: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

  ## local_file.example will be destroyed
  ## (because local_file.example is not in configuration)
  - resource "local_file" "example" {
      - content              = "This is an example file managed by Terraform." -> null
      - content_base64sha256 = "F5EYZhFNzSXdE4CUftwQoDVqvdiufZpVyiLMqyZVOcQ=" -> null
      - content_base64sha512 = "m1hvaxMuc/EhaKintyI54NSTTJ5yXpqHPCBNoHubF0rvF3JAj36lMj20aPcv21+3/OK+SqkiTlnT/LdvLCwqDA==" -> null
      - content_md5          = "a43bdd236c2f0f4d87452ba2ef0867e4" -> null
      - content_sha1         = "ec3adcab998872def2df6200fb03992ac6f237a4" -> null
      - content_sha256       = "17911866114dcd25dd1380947edc10a0356abdd8ae7d9a55ca22ccab265539c4" -> null
      - content_sha512       = "9b586f6b132e73f12168a8a7b72239e0d4934c9e725e9a873c204da07b9b174aef1772408f7ea5323db468f72fdb5fb7fce2be4aa9224e59d3fcb76f2c2c2a0c" -> null
      - directory_permission = "0777" -> null
      - file_permission      = "0777" -> null
      - filename             = "./example.txt" -> null
      - id                   = "ec3adcab998872def2df6200fb03992ac6f237a4" -> null
    }

  ## local_file.example_renamed will be created
  + resource "local_file" "example_renamed" {
      + content              = "This is an example file managed by Terraform."
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./example.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 1 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

Para corrigir isso, informaremos ao Terraform que simplesmente movemos o recurso. Execute o comando terraform state mv com o endereço antigo e o novo endereço:

terraform state mv local_file.example local_file.example_renamed

Você verá uma mensagem de confirmação:

Move "local_file.example" to "local_file.example_renamed"
Successfully moved 1 object(s).

Agora, execute o terraform plan novamente:

terraform plan

Desta vez, o Terraform relata que nenhuma alteração é necessária porque o estado agora corresponde à configuração.

local_file.example_renamed: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are needed.

Executar terraform refresh para atualizar o estado

Nesta etapa, você usará o terraform refresh para reconciliar o arquivo de estado com a infraestrutura do mundo real. Às vezes, alterações são feitas na sua infraestrutura fora do controle do Terraform. Isso é conhecido como "drift" (desvio). O comando refresh atualiza o arquivo de estado para refletir essas alterações.

Vamos simular o desvio excluindo manualmente o arquivo que o Terraform criou.

rm example.txt

Agora, se você executar um plano, o Terraform detectará que o arquivo está faltando e precisa ser recriado.

terraform plan
local_file.example_renamed: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  ## local_file.example_renamed will be created
  + resource "local_file" "example_renamed" {
      + content              = "This is an example file managed by Terraform."
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./example.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

No entanto, o comando terraform refresh também pode ser usado para atualizar explicitamente o estado. Este comando verifica os recursos reais e atualiza o arquivo de estado de acordo.

terraform refresh
local_file.example_renamed: Refreshing state... [id=ec3adcab998872def2df6200fb03992ac6f237a4]

Agora execute o terraform plan novamente para confirmar que o estado está atualizado.

terraform plan
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  ## local_file.example_renamed will be created
  + resource "local_file" "example_renamed" {
      + content              = "This is an example file managed by Terraform."
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./example.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

Você usou com sucesso o terraform refresh para corrigir o desvio de estado (state drift).

Resumo

Parabéns por concluir este laboratório sobre Gerenciamento de Estado do Terraform (Terraform State Management)!

Neste laboratório, você adquiriu experiência prática com subcomandos essenciais do terraform state. Você aprendeu a:

  • Usar o terraform show para visualizar uma representação legível por humanos do estado da sua infraestrutura.
  • Inspecionar o arquivo JSON bruto terraform.tfstate para entender sua estrutura.
  • Obter uma lista limpa de todos os recursos gerenciados com terraform state list.
  • Renomear com segurança um recurso na sua configuração e atualizar o estado de acordo usando terraform state mv.
  • Reconciliar seu arquivo de estado com a infraestrutura do mundo real e corrigir desvios (drift) usando terraform refresh.

Dominar esses comandos é fundamental para gerenciar sua infraestrutura de forma eficaz e confiante com o Terraform.