Almacena el estado de Terraform en un bucket de Cloud Storage


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

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

Para ayudarte a evitar esos problemas, en esta página, se muestra cómo configurar un estado remoto que apunte a un bucket de Cloud Storage. El estado remoto es una característica de los backends de Terraform.

Objetivos

En este instructivo, se muestra cómo realizar lo siguiente:

  • Usar Terraform para aprovisionar un bucket de Cloud Storage para almacenar el estado de Terraform.
  • Agregar plantillas en el archivo de configuración de Terraform para migrar el estado del backend local al bucket de Cloud Storage.

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Cuando finalices las tareas que se describen en este documento, puedes borrar los recursos que creaste para evitar que continúe la facturación. Para obtener más información, consulta Cómo realizar una limpieza.

Cloud Storage genera costos por el almacenamiento, las operaciones de lectura y escritura, la salida de red y la replicación.

El bucket de Cloud Storage en este instructivo tiene habilitado el control de versiones de objetos para mantener el historial de tus implementaciones. Habilitar el control de versiones de objetos aumenta los costos de almacenamiento, lo cual se puede mitigar si configuras la Administración del ciclo de vida de los objetos para que borre versiones de estado antiguas.

Antes de comenzar

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

    Activate Cloud Shell

    Cloud Shell viene preinstalado con Terraform.

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

  3. Create or select a Google Cloud project.

    • 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. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  5. Enable the Cloud Storage API:

    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_IDENTIFIER" --role=ROLE

    Como alternativa, puedes crear un rol de IAM 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, sugerimos controlar el acceso al bucket y los archivos de estado almacenados allí. Solo un pequeño conjunto de usuarios (por ejemplo, el administrador principal de la nube y la persona que actúa como administrador alternativo o de respaldo) deben tener permisos de administrador para el bucket. Los otros desarrolladores deben tener permisos para escribir y leer objetos en el bucket.

Prepare el entorno

  1. Clona el repositorio de GitHub que contiene las muestras 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
    

Revisa los archivos de Terraform

  1. Revisa el archivo main.tf:

    cat main.tf
    

    El resultado es similar al que se muestra a continuación:

    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: Esto se agrega al nombre del bucket de Cloud Storage a fin de garantizar que haya un nombre único para el bucket.
    • google_storage_bucket: Es el bucket de Cloud Storage en el que se almacenará el archivo de estado. Este bucket está configurado para tener las siguientes propiedades:
      • force_destroy se configura como false para garantizar que el bucket no se borre si hay objetos en él. Esto garantiza que la información de estado en el bucket no se borre por accidente.
      • public_access_prevention se establece en enforced para garantizar que el contenido del bucket no se exponga accidentalmente al público.
      • uniform_bucket_level_access se establece en true para permitir controlar el acceso al bucket y su contenido con permisos de IAM en lugar de listas de control de acceso.
      • versioning está habilitado para garantizar que las versiones anteriores del estado se conserven en el bucket.
    • local_file: Un archivo local. El contenido de este archivo le indica a Terraform que use el bucket de Cloud Storage como backend remoto una vez que se cree el bucket.

Aprovisiona el bucket de Cloud Storage

  1. Inicializa Terraform mediante este comando:

    terraform init
    

    Cuando ejecutas terraform init por primera vez, el bucket de Cloud Storage que especificaste 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, ingresa yes.

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

Migra el estado al bucket 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 de forma local y te solicita que migres el estado al nuevo bucket de Cloud Storage. Cuando se te solicite, ingresa yes.

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

Realiza una limpieza

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

Borra el proyecto

Sigue estos pasos para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos que usaste en esta página.

  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, ingresa yes.

  4. Borra el archivo de estado:

    rm backend.tf
    
  5. Vuelve a configurar el backend para que sea local:

    terraform init -migrate-state
    

    Cuando se te solicite, ingresa yes.

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

    terraform destroy
    

    Cuando se te solicite, ingresa yes.

¿Qué sigue?