Almacenar el estado de Terraform en un segmento de Cloud Storage


En este tutorial, aprenderás a almacenar el estado de Terraform en un segmento de Cloud Storage.

De forma predeterminada, Terraform almacena el estado de forma local en un archivo llamado terraform.tfstate. Esta configuración predeterminada puede dificultar el uso de Terraform a los equipos cuando varios usuarios ejecutan Terraform al mismo tiempo y cada máquina tiene su propia interpretación de la infraestructura actual.

Para evitar estos problemas, en esta página se explica cómo configurar un estado remoto que apunte a un segmento de Cloud Storage. El estado remoto es una función de los backends de Terraform.

Objetivos

En este tutorial te explicamos cómo hacer lo siguiente:

  • Usa Terraform para aprovisionar un segmento de Cloud Storage en el que almacenar el estado de Terraform.
  • Añade plantillas al archivo de configuración de Terraform para migrar el estado del backend local al segmento de Cloud Storage.

Costes

En este documento, se utilizan los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costes basada en el uso previsto, utiliza la calculadora de precios.

Los usuarios nuevos Google Cloud pueden disfrutar de una prueba gratuita.

Cuando termines las tareas que se describen en este documento, puedes evitar que se te siga facturando eliminando los recursos que has creado. Para obtener más información, consulta la sección Limpiar.

Cloud Storage incurre en costes de almacenamiento, operaciones de lectura y escritura, salida de red y replicación.

El segmento de Cloud Storage de este tutorial tiene habilitada la gestión de versiones de objetos para conservar el historial de tus implementaciones. Si habilitas la gestión de versiones de objetos, aumentarán los costes de almacenamiento, que puedes reducir configurando la gestión del ciclo de vida de los objetos para eliminar las versiones antiguas.

Antes de empezar

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

    Activate Cloud Shell

    Terraform viene preinstalado en Cloud Shell.

  2. Si usas un shell local, sigue estos pasos:

  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:

    También puedes crear un rol de gestión de identidades y accesos personalizado que contenga los siguientes permisos:

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

    Como práctica recomendada, te aconsejamos que controles el acceso al bucket y a los archivos de estado que se almacenan en él. Solo un pequeño grupo de usuarios (por ejemplo, el administrador principal de la nube y la persona que actúe como administrador alternativo o de respaldo) debe tener permisos de administrador para el bucket. Los otros desarrolladores solo deben tener permisos para escribir y leer objetos en el segmento.

    Preparar el entorno

    1. Clona el repositorio de GitHub que contiene ejemplos de Terraform:

      git clone https://github.com/terraform-google-modules/terraform-docs-samples.git --single-branch
      
    2. Cambia al directorio de trabajo:

      cd terraform-docs-samples/storage/remote_terraform_backend_template
      

    Revisar los archivos de Terraform

    1. Revisa el archivo main.tf:

      cat main.tf
      

      La salida es similar a la siguiente:

      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
      }

      En este archivo se describen los siguientes recursos:

      • random_id: se añade al nombre del segmento de Cloud Storage para asegurar que el nombre del segmento de Cloud Storage sea único.
      • google_storage_bucket: el segmento de Cloud Storage en el que se almacenará el archivo de estado. Este contenedor está configurado para tener las siguientes propiedades:
        • force_destroy se define como false para asegurarse de que el segmento no se elimine si contiene objetos. De esta forma, te aseguras de que la información de estado del contenedor no se elimine por error.
        • public_access_prevention está configurado como enforced para asegurarse de que el contenido del segmento no se exponga accidentalmente al público.
        • uniform_bucket_level_access se define como true para permitir el control del acceso al segmento y a su contenido mediante permisos de gestión de identidades y accesos en lugar de listas de control de acceso.
        • versioning está habilitado para asegurarse de que las versiones anteriores del estado se conserven en el contenedor.
      • local_file: un archivo local. El contenido de este archivo indica a Terraform que use el segmento de Cloud Storage como backend remoto una vez que se haya creado el segmento.

    Aprovisionar el segmento de Cloud Storage

    1. Inicializa Terraform:

      terraform init
      

      La primera vez que ejecutas terraform init, el segmento de Cloud Storage que has especificado en el archivo main.tf aún no existe, por lo que Terraform inicializa un backend local para almacenar el estado en el sistema de archivos local.

    2. Aplica la configuración para aprovisionar los recursos descritos en el archivo main.tf:

      terraform apply
      

      Cuando se te solicite, introduce yes.

      Cuando ejecutas terraform apply por primera vez, Terraform aprovisiona el segmento de Cloud Storage para almacenar el estado. También crea un archivo local. El contenido de este archivo indica a Terraform que use el segmento de Cloud Storage como backend remoto para almacenar el estado.

    Migrar el estado a un segmento de Cloud Storage

    1. Migra el estado de Terraform al backend remoto de Cloud Storage:

      terraform init -migrate-state
      

      Terraform detecta que ya tienes un archivo de estado localmente y te pide que migres el estado al nuevo segmento de Cloud Storage. Cuando se te solicite, introduce yes.

    Después de ejecutar este comando, el estado de Terraform se almacena en el segmento de Cloud Storage. Terraform extrae el estado más reciente de este bucket antes de ejecutar un comando y envía el estado más reciente al bucket después de ejecutar un comando.

    Limpieza

    Para evitar que los recursos utilizados en este tutorial se cobren en tu cuenta de Google Cloud, elimina el proyecto que contiene los recursos o conserva el proyecto y elimina los recursos.

    Eliminar el proyecto

    Para evitar que se apliquen cargos en tu Google Cloud cuenta por los recursos utilizados en esta página, sigue estos pasos.

    1. Abre el archivo main.tf.

    2. En el recurso google_storage_bucket.default, actualiza el valor de force_destroy a true.

    3. Aplica la configuración actualizada:

      terraform apply
      

      Cuando se te solicite, introduce yes.

    4. Elimina el archivo de estado:

      rm backend.tf
      
    5. Reconfigura el backend para que sea local:

      terraform init -migrate-state
      

      Cuando se te solicite, introduce yes.

    6. Ejecuta el siguiente comando para eliminar los recursos de Terraform:

      terraform destroy
      

      Cuando se te solicite, introduce yes.

    Siguientes pasos