Armazenar o estado do Terraform em um bucket do Cloud Storage

Neste tutorial, você aprenderá a armazenar o estado do Terraform em um bucket do Cloud Storage.

Por padrão, o Terraform armazena o estado localmente em um arquivo chamado terraform.tfstate. Essa configuração padrão pode dificultar o uso do Terraform para as equipes quando muitos usuários o executam ao mesmo tempo e cada máquina tem o próprio entendimento da infraestrutura atual.

Para ajudar a evitar esses problemas, esta página mostra como configurar um estado remoto que aponta para um bucket do Cloud Storage. O estado remoto é um recurso de back-ends do Terraform.

Objetivos

Este tutorial mostra como fazer o seguinte:

  • Usar o Terraform para provisionar um bucket do Cloud Storage para armazenar o estado do Terraform.
  • Adicione modelos no arquivo de configuração do Terraform para migrar o estado a partir do back-end local para o bucket do Cloud Storage.

Custos

Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na sua projeção de uso, use a calculadora de preços.

Novos usuários do Google Cloud podem estar qualificados para um teste gratuito.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Para mais informações, consulte Limpeza.

O Cloud Storage incorre custos de armazenamento, operações de leitura e gravação, saída de rede e replicação.

O bucket do Cloud Storage neste tutorial tem o controle de versões de objetos ativado para manter o histórico das implantações. Ativar o controle de versões do objeto aumenta os custos de armazenamento, que podem ser reduzidos com a configuração do Gerenciamento do ciclo de vida de objetos para excluir versões mais antigas.

Antes de começar

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    O Cloud Shell vem pré-instalado com o Terraform.

  2. Se você estiver usando um shell local, siga estas etapas:

  3. Create or select a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.
    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  4. Verify that billing is enabled for your Google Cloud project.

  5. Enable the Cloud Storage API:

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    gcloud services enable storage.googleapis.com
  6. Grant roles to your user account. Run the following command once for each of the following IAM roles: roles/storage.admin

    gcloud projects add-iam-policy-binding PROJECT_ID --member="user:USER_IDENTIFIER" --role=ROLE

    Replace the following:

    Como alternativa, é possível criar um papel personalizado do IAM que contenha as seguintes permissões:

    • storage.buckets.create
    • storage.buckets.list
    • storage.objects.get
    • storage.objects.create
    • storage.objects.delete
    • storage.objects.update

    Como prática recomendada, recomendamos controlar o acesso ao bucket e aos arquivos de estado armazenados nele. Apenas um pequeno grupo de usuários (por exemplo, o administrador principal da nuvem e a pessoa que atua como administrador alternativo ou de backup) deve ter permissões de administrador para o bucket. Os outros desenvolvedores precisam ter permissões para gravar e ler apenas objetos no bucket.

    Prepare o ambiente

    1. Clone o repositório do GitHub que contém exemplos do Terraform:

      git clone https://github.com/terraform-google-modules/terraform-docs-samples.git --single-branch
      
    2. Mude para o diretório de trabalho:

      cd terraform-docs-samples/storage/remote_terraform_backend_template
      

    Revisar os arquivos do Terraform

    1. Revise o arquivo main.tf:

      cat main.tf
      

      A saída será assim

      resource "random_id" "default" {
        byte_length = 8
      }
      
      resource "google_storage_bucket" "default" {
        name     = "${random_id.default.hex}-terraform-remote-backend"
        location = "US"
      
        force_destroy               = false
        public_access_prevention    = "enforced"
        uniform_bucket_level_access = true
      
        versioning {
          enabled = true
        }
      }
      
      resource "local_file" "default" {
        file_permission = "0644"
        filename        = "${path.module}/backend.tf"
      
        # You can store the template in a file and use the templatefile function for
        # more modularity, if you prefer, instead of storing the template inline as
        # we do here.
        content = <<-EOT
        terraform {
          backend "gcs" {
            bucket = "${google_storage_bucket.default.name}"
          }
        }
        EOT
      }

      Este arquivo descreve os seguintes recursos:

      • random_id: é anexado ao nome do bucket do Cloud Storage para garantir um nome exclusivo.
      • google_storage_bucket: o bucket do Cloud Storage para armazenar o arquivo de estado. Esse bucket está configurado para ter as seguintes propriedades:
        • force_destroy é definido como false para garantir que o bucket não seja excluído se houver objetos nele. Isso garante que as informações de estado armazenadas no bucket não sejam excluídas acidentalmente.
        • public_access_prevention é definido como enforced para garantir que o conteúdo do bucket não seja exposto ao público acidentalmente.
        • uniform_bucket_level_access está definido como true para permitir o controle do acesso ao bucket e ao conteúdo dele usando permissões do IAM em vez de listas de controle de acesso.
        • O versioning é ativado para garantir que versões anteriores do estado sejam preservadas no bucket.
      • local_file: um arquivo local. O conteúdo desse arquivo instrui o Terraform a usar o bucket do Cloud Storage como back-end remoto depois que o bucket for criado.

    Provisionar o bucket do Cloud Storage

    1. Inicialize o Terraform:

      terraform init
      

      Quando você executa terraform init pela primeira vez, o bucket do Cloud Storage especificado no arquivo main.tf ainda não existe, portanto, o Terraform inicializa um back-end local para armazenar o estado no sistema de arquivos local.

    2. Aplique a configuração para provisionar os recursos descritos no arquivo main.tf:

      terraform apply
      

      Quando solicitado, digite yes.

      Quando você executa terraform apply pela primeira vez, o Terraform provisiona o bucket do Cloud Storage para armazenar o estado. Ele também cria um arquivo local. O conteúdo desse arquivo instrui o Terraform a usar o bucket do Cloud Storage como o back-end remoto para armazenar o estado.

    Migrar o estado para o bucket do Cloud Storage

    1. Migre o estado do Terraform para o back-end remoto do Cloud Storage:

      terraform init -migrate-state
      

      O Terraform detecta se você já tem um arquivo de estado localmente e solicita a migração do estado para o novo bucket do Cloud Storage. Quando solicitado, digite yes.

    Depois da execução desse comando, o estado do Terraform é armazenado no bucket do Cloud Storage. O Terraform extrai o estado mais recente desse bucket antes de executar um comando e o envia para o bucket depois da execuçãode um comando.

    Limpar

    Para evitar cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

    Excluir o projeto

    Para evitar cobranças na conta do Google Cloud pelos recursos usados nesta página, siga as etapas abaixo.

    1. Abra o arquivo main.tf.

    2. No recurso google_storage_bucket.default, atualize o valor de force_destroy para true.

    3. Aplique a configuração atualizada:

      terraform apply
      

      Quando solicitado, digite yes.

    4. Exclua o arquivo de estado:

      rm backend.tf
      
    5. Reconfigure o back-end para ser local:

      terraform init -migrate-state
      

      Quando solicitado, digite yes.

    6. Execute o seguinte comando para excluir os recursos do Terraform:

      terraform destroy
      

      Quando solicitado, digite yes.

    A seguir