Armazene o estado do Terraform num contentor do Cloud Storage


Neste tutorial, vai aprender a armazenar o estado do Terraform num contentor do Cloud Storage.

Por predefinição, o Terraform armazena o estado localmente num ficheiro denominado terraform.tfstate. Esta configuração predefinida pode dificultar a utilização do Terraform para as equipas quando vários utilizadores executam o Terraform ao mesmo tempo e cada máquina tem a sua própria compreensão da infraestrutura atual.

Para ajudar a evitar estes problemas, esta página mostra como configurar um estado remoto que aponta para um contentor do Cloud Storage. O estado remoto é uma funcionalidade dos backends do Terraform.

Objetivos

Este tutorial mostra como fazer o seguinte:

  • Use o Terraform para aprovisionar um contentor do Cloud Storage para armazenar o estado do Terraform.
  • Adicione modelos no ficheiro de configuração do Terraform para migrar o estado do back-end local para o contentor do Cloud Storage.

Custos

Neste documento, usa os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custos com base na sua utilização projetada, use a calculadora de preços.

Os novos Google Cloud utilizadores podem ser elegíveis para uma avaliação gratuita.

Quando terminar as tarefas descritas neste documento, pode evitar a faturação contínua eliminando os recursos que criou. Para mais informações, consulte o artigo Limpe.

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

O contentor do Cloud Storage neste tutorial tem a funcionalidade de controlo de versões de objetos ativada para manter o histórico das suas implementações. A ativação da criação de versões de objetos aumenta os custos de armazenamento, que pode atenuar configurando a Gestão do ciclo de vida de objetos para eliminar versões de estado antigas.

Antes de começar

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

    Activate Cloud Shell

    O Cloud Shell está pré-instalado com o Terraform.

  2. Se estiver a usar uma shell local, siga estes passos:

  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:

    Em alternativa, pode criar uma função de IAM personalizada que contenha as seguintes autorizações:

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

    Como prática recomendada, recomendamos que o acesso ao contentor e aos ficheiros de estado aí armazenados seja controlado. Apenas um pequeno conjunto de utilizadores (por exemplo, o administrador principal da nuvem e a pessoa que atua como administrador alternativo ou de cópia de segurança) deve ter autorizações de administrador para o contentor. Os outros programadores devem ter autorizações para apenas escrever e ler objetos no contentor.

    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
      

    Reveja os ficheiros do Terraform

    1. Reveja o ficheiro main.tf:

      cat main.tf
      

      O resultado é semelhante ao seguinte

      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 ficheiro descreve os seguintes recursos:

      • random_id: este valor é anexado ao nome do contentor do Cloud Storage para garantir um nome único para o contentor do Cloud Storage.
      • google_storage_bucket: o contentor do Cloud Storage para armazenar o ficheiro de estado. Este contentor está configurado para ter as seguintes propriedades:
        • force_destroy está definido como false para garantir que o contentor não é eliminado se tiver objetos. Isto garante que as informações de estado no contentor não são eliminadas acidentalmente.
        • public_access_prevention está definido como enforced para garantir que o conteúdo do contentor não é exposto acidentalmente ao público.
        • uniform_bucket_level_access está definido como true para permitir o controlo do acesso ao contentor e ao respetivo conteúdo através de autorizações da IAM em vez de listas de controlo de acesso.
        • versioning está ativado para garantir que as versões anteriores do estado são preservadas no contentor.
      • local_file: um ficheiro local. O conteúdo deste ficheiro indica ao Terraform que deve usar o contentor do Cloud Storage como o back-end remoto assim que o contentor for criado.

    Aprovisione o contentor do Cloud Storage

    1. Inicialize o Terraform:

      terraform init
      

      Quando executa o terraform init pela primeira vez, o contentor de armazenamento na nuvem que especificou no ficheiro main.tf ainda não existe. Por isso, o Terraform inicializa um back-end local para armazenar o estado no sistema de ficheiros local.

    2. Aplique a configuração para aprovisionar recursos descritos no ficheiro main.tf:

      terraform apply
      

      Quando lhe for pedido, introduza yes.

      Quando executa terraform apply pela primeira vez, o Terraform aprovisiona o contentor do Cloud Storage para armazenar o estado. Também cria um ficheiro local. O conteúdo deste ficheiro indica ao Terraform que use o contentor do Cloud Storage como o back-end remoto para armazenar o estado.

    Migre o estado para o contentor do Cloud Storage

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

      terraform init -migrate-state
      

      O Terraform deteta que já tem um ficheiro de estado localmente e pede-lhe para migrar o estado para o novo contentor do Cloud Storage. Quando lhe for pedido, introduza yes.

    Depois de executar este comando, o estado do Terraform é armazenado no contentor do Cloud Storage. O Terraform extrai o estado mais recente deste contentor antes de executar um comando e envia o estado mais recente para o contentor depois de executar um comando.

    Limpar

    Para evitar incorrer em custos na sua conta do Google Cloud pelos recursos usados neste tutorial, elimine o projeto que contém os recursos ou mantenha o projeto e elimine os recursos individuais.

    Elimine o projeto

    Para evitar incorrer em cobranças na sua Google Cloud conta pelos recursos usados nesta página, siga estes passos.

    1. Abra o ficheiro 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 lhe for pedido, introduza yes.

    4. Elimine o ficheiro de estado:

      rm backend.tf
      
    5. Volte a configurar o back-end para ser local:

      terraform init -migrate-state
      

      Quando lhe for pedido, introduza yes.

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

      terraform destroy
      

      Quando lhe for pedido, introduza yes.

    O que se segue?