Crear y ejecutar trabajos de Batch con Terraform y Cloud Scheduler


En este tutorial se explica cómo puedes usar Terraform para crear y ejecutar trabajos por lotes mediante una tarea cron de Cloud Scheduler.

Terraform es una herramienta de código abierto que te permite aprovisionar y gestionar infraestructura especificando el estado deseado en archivos de configuración. Estos archivos se pueden tratar como código y almacenar en sistemas de control de versiones como GitHub.

Aunque Terraform no tiene recursos para Batch, en este tutorial se muestra cómo puedes usar Terraform para crear trabajos de Batch. En concreto, puedes usar Terraform para programar y ejecutar un trabajo cron de Cloud Scheduler que se dirija a la API Batch para crear y ejecutar trabajos de Batch. Cloud Scheduler es un Google Cloud servicio que te permite programar automáticamente tareas cron y es compatible con Terraform.

Este tutorial está dirigido a usuarios de Batch que ya gestionan la infraestructura con Terraform y quieren incorporar trabajos de Batch a Terraform.

Objetivos

  • Crea un directorio de Terraform y un archivo de configuración que defina una tarea cron de Cloud Scheduler que cree tareas de Batch.
  • Despliega la configuración de Terraform para ejecutar la tarea cron.
  • Verifica que el trabajo cron crea trabajos de Batch.
  • Actualiza la configuración de Terraform para pausar la tarea cron de forma que deje de crear tareas de Batch.

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.

Antes de empezar

  1. Prepara tu entorno de desarrollo, ya sea Cloud Shell o un shell local:

    Cloud Shell

    Para usar un terminal online con la CLI de gcloud y Terraform ya configurados, activa Cloud Shell.

    En la parte inferior de esta página, se inicia una sesión de Cloud Shell y se muestra un mensaje de la línea de comandos. La sesión puede tardar unos segundos en inicializarse.

    Shell local

    Para usar un entorno de desarrollo local, sigue estos pasos:

    1. Install the Google Cloud CLI.

    2. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

    3. To initialize the gcloud CLI, run the following command:

      gcloud init
    4. Instala Terraform.
  2. 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.

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

  4. Enable the Batch, Compute Engine, Cloud Logging, Cloud Scheduler, and Resource Manager APIs:

    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 batch.googleapis.com compute.googleapis.com logging.googleapis.com  cloudscheduler.googleapis.com cloudresourcemanager.googleapis.com
  5. Asegúrate de que tu proyecto tenga al menos una cuenta de servicio con los permisos necesarios para este tutorial.

    En concreto, puedes usar la misma cuenta de servicio o dos cuentas de servicio independientes para conceder los siguientes permisos:

    • Permite que la tarea cron cree tareas de Batch y adjunte la cuenta de servicio a las tareas de Batch.
    • Permite que los trabajos de Batch creen y accedan a los recursos necesarios para ejecutarse.

    Para asegurarte de que las cuentas de servicio de este tutorial tienen los permisos necesarios para usar Terraform y crear trabajos de Batch a través de un trabajo cron de Cloud Scheduler, pide a tu administrador que conceda a las cuentas de servicio de este tutorial los siguientes roles de gestión de identidades y accesos:

    Para obtener más información sobre cómo conceder roles, consulta el artículo Gestionar el acceso a proyectos, carpetas y organizaciones.

    Es posible que tu administrador también pueda conceder a las cuentas de servicio de este tutorial los permisos necesarios a través de roles personalizados u otros roles predefinidos.

  6. Asegúrate de que tienes los permisos necesarios para seguir este tutorial.

    En concreto, necesitas permisos para hacer lo siguiente:

    • Crea una tarea cron y adjunta la cuenta de servicio a la tarea cron.
    • Ver y eliminar las tareas cron y las tareas por lotes.

    Para obtener los permisos que necesitas para usar Terraform y crear tareas de Batch mediante una tarea cron de Cloud Scheduler, pide a tu administrador que te conceda los siguientes roles de gestión de identidades y accesos:

Crear el directorio y el archivo de configuración de Terraform

Crea un directorio para Terraform y un archivo de configuración que defina los recursos que quieras crear o actualizar con Terraform. El archivo de configuración de ejemplo de este tutorial define una tarea cron de Cloud Scheduler llamada batch-job-invoker. Cuando está habilitada, la tarea cron batch-job-invoker se ejecuta cada 5 minutos para crear una nueva instancia del trabajo por lotes definido.

  1. Para crear un directorio y un archivo de configuración de Terraform (.tf) en ese directorio, escribe el siguiente comando y, a continuación, pulsa Enter:

    mkdir terraform && cd terraform && cat > main.tf
    

    Este comando crea el directorio terraform, te lleva a él y empieza a definir un nuevo archivo de configuración main.tf en la línea siguiente.

  2. Copia y pega la siguiente configuración de Terraform:

    # define variables
    variable "project_id" {
      type        = string
      description = "The project name to use."
      default = "PROJECT_ID"
    }
    
    variable "project_number" {
      type        = string
      description = "The project number to use."
      default = "PROJECT_NUMBER"
    }
    
    variable "region" {
      type        = string
      description = "The region where resources are created."
      default = "us-central1"
    }
    
    variable "cloud_scheduler_service_account_email" {
      type        = string
      description = "The service account email."
      default = "CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL"
    }
    
    variable "batch_service_account_email" {
      type        = string
      description = "The service account email."
      default = "BATCH_SERVICE_ACCOUNT_EMAIL"
    }
    
    # define a Cloud Scheduler cron job which triggers Batch jobs
    resource "google_cloud_scheduler_job" "batch-job-invoker" {
      paused           = false # this cron job is enabled
      name             = "batch-job-invoker"
      project          = var.project_id
      region           = var.region
      schedule         = "*/5 * * * *" # when enabled, run every 5 minutes
      time_zone        = "America/Los_Angeles"
      attempt_deadline = "180s"
    
      retry_config {
        max_doublings        = 5
        max_retry_duration   = "0s"
        max_backoff_duration = "3600s"
        min_backoff_duration = "5s"
      }
    
      # when this cron job runs, create and run a Batch job
      http_target {
        http_method = "POST"
        uri = "https://batch.googleapis.com/v1/projects/${var.project_id}/locations/${var.region}/jobs"
        headers = {
          "Content-Type" = "application/json"
          "User-Agent"   = "Google-Cloud-Scheduler"
        }
        # Batch job definition
        body = base64encode(<<EOT
        {
          "taskGroups":[
            {
              "taskSpec": {
                "runnables":{
                  "script": {
                    "text": "echo Hello world! This job was created using Terraform and Cloud Scheduler."
                  }
                }
              }
            }
          ],
          "allocationPolicy": {
            "serviceAccount": {
              "email": "${var.batch_service_account_email}"
            }
          },
          "labels": {
            "source": "terraform_and_cloud_scheduler_tutorial"
          },
          "logsPolicy": {
            "destination": "CLOUD_LOGGING"
          }
        }
        EOT
        )
        oauth_token {
          scope                 = "https://www.googleapis.com/auth/cloud-platform"
          service_account_email = var.cloud_scheduler_service_account_email
        }
      }
    }
    
    

    Haz los cambios siguientes:

    • PROJECT_ID: el ID de proyecto de tu proyecto.
    • PROJECT_NUMBER: el número de proyecto de tu proyecto.
    • CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL: la dirección de correo de la cuenta de servicio que has preparado para el trabajo cron de Cloud Scheduler.

      Por ejemplo, para usar la cuenta de servicio predeterminada de Compute Engine, especifica lo siguiente:

      PROJECT_NUMBER-compute@developer.gserviceaccount.com
      
    • BATCH_SERVICE_ACCOUNT_EMAIL: la dirección de correo electrónico de la cuenta de servicio que has preparado para las tareas de Batch.

      Por ejemplo, para usar la cuenta de servicio predeterminada de Compute Engine, especifica lo siguiente:

      PROJECT_NUMBER-compute@developer.gserviceaccount.com
      

    Esta configuración de Terraform define algunas variables de entrada y un trabajo cron que se pone en contacto con el método de la API para crear un trabajo de Batch.

  3. Para guardar y cerrar el archivo, pulsa Ctrl+D (o Command+D en macOS).

Desplegar la configuración de Terraform para crear la tarea cron

Despliega la configuración de Terraform inicializando Terraform, generando los cambios planificados y aplicando estos cambios. Después de implementar la configuración de Terraform, puedes describir los recursos de tu proyecto para verificar que Terraform ha creado correctamente el trabajo cron batch-job-invoker.

  1. Inicializa Terraform en el directorio:

    terraform init
    

    El resultado debería ser similar al siguiente:

    ...
    Terraform has been successfully initialized!
    
    You may now begin working with Terraform. Try running "terraform plan" to see
    any changes that are required for your infrastructure. All Terraform commands
    should now work.
    
    If you ever set or change modules or backend configuration for Terraform,
    rerun this command to reinitialize your working directory. If you forget, other
    commands will detect it and remind you to do so if necessary.
    
  2. Genera el plan de ejecución de Terraform en función del estado actual de tu proyecto y del archivo de configuración:

    terraform plan
    

    El resultado es similar al siguiente, que muestra que el plan es crear la tarea cron batch-job-invoker:

    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:
    
      # google_cloud_scheduler_job.batch-job-invoker will be created
      + resource "google_cloud_scheduler_job" "batch-job-invoker" {
          + id        = (known after apply)
          + name      = "batch-job-invoker"
          + paused    = false
          + project   = "PROJECT_ID"
          + region    = "us-central1"
          + schedule  = "*/5 * * * *"
          + state     = (known after apply)
          + time_zone = "America/Los_Angeles"
    
          + http_target {
              + body        = "..."
              + headers     = {
                  + "Content-Type" = "application/json"
                  + "User-Agent"   = "Google-Cloud-Scheduler"
                }
              + http_method = "POST"
              + uri         = "https://batch.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/jobs"
    
              + oauth_token {
                  + scope                 = "https://www.googleapis.com/auth/cloud-platform"
                  + service_account_email = "CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL"
                }
            }
    
          + retry_config {
              + max_backoff_duration = "3600s"
              + max_doublings        = 5
              + max_retry_duration   = "0s"
              + min_backoff_duration = "5s"
              + retry_count          = (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.
    
  3. Para aplicar el plan y crear el trabajo cron batch-job-invoker, siga estos pasos:

    1. Introduce el siguiente comando:

      terraform apply
      

      El resultado es similar al del comando terraform plan anterior, pero termina con una petición de confirmación.

    2. Para confirmar y aplicar el plan, introduce yes.

      El resultado debería ser similar al siguiente:

      google_cloud_scheduler_job.batch-job-invoker: Creating...
      google_cloud_scheduler_job.batch-job-invoker: Creation complete after 0s [id=projects/PROJECT_ID/locations/us-central1/jobs/batch-job-invoker]
      
      Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
      
  4. Para verificar que el trabajo cron batch-job-invoker existe y está habilitado, descríbelo:

    gcloud scheduler jobs describe batch-job-invoker --location us-central1
    

    El resultado debería ser similar al siguiente:

    attemptDeadline: 180s
    httpTarget:
      body: ...
      headers:
        Content-Type: application/json
        User-Agent: Google-Cloud-Scheduler
      httpMethod: POST
      oauthToken:
        scope: https://www.googleapis.com/auth/cloud-platform
        serviceAccountEmail: CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL
      uri: https://batch.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/jobs
    lastAttemptTime: '...'
    name: projects/PROJECT_ID/locations/us-central1/jobs/batch-job-invoker
    retryConfig:
      maxBackoffDuration: 3600s
      maxDoublings: 5
      maxRetryDuration: 0s
      minBackoffDuration: 5s
    schedule: '*/5 * * * *'
    scheduleTime: '...'
    state: ENABLED
    status: {}
    timeZone: America/Los_Angeles
    userUpdateTime: '...'
    

    En el resultado, comprueba que el campo state esté configurado como ENABLED.

Verificar que la tarea cron crea una tarea de Batch

Verifica que la tarea cron batch-job-invoker cree correctamente trabajos por lotes.

  1. Espera 5 minutos a que se ejecute la tarea cron automáticamente o actívala para que se ejecute inmediatamente:

    gcloud scheduler jobs run batch-job-invoker --location us-central1
    
  2. Lista las tareas de Batch que ha creado la tarea cron batch-job-invoker:

    gcloud batch jobs list \
    --filter labels.source=\"terraform_and_cloud_scheduler_tutorial\" \
    --sort-by ~createTime
    
    • La marca --filter labels.source=\"terraform_and_cloud_scheduler_tutorial\" filtra la lista para incluir solo los trabajos por lotes que tengan una etiqueta con la clave source y el valor terraform_and_cloud_scheduler_tutorial.
    • La bandera --sort-by ~createTime ordena la lista de más reciente a más antiguo.

Actualiza la configuración de Terraform para pausar la tarea cron

Cuando tengas el número de tareas de Batch que quieras, actualiza e implementa la configuración de Terraform para pausar la tarea cron batch-job-invoker. Si quiere actualizar otras propiedades del trabajo cron o de los trabajos de Batch futuros, se aplica el mismo proceso.

  1. Actualiza el archivo de configuración de Terraform para pausar el trabajo cron definiendo el campo paused como true:

    sed -i 's/paused           = false # this cron job is enabled/paused           = true # this cron job is paused/g' main.tf
    
  2. Genera el plan de ejecución de Terraform en función del estado actual de tu proyecto y del archivo de configuración:

    terraform plan
    

    El resultado es similar al siguiente, que muestra que el plan es actualizar el valor del campo paused de false a true:

    google_cloud_scheduler_job.batch-job-invoker: Refreshing state... [id=projects/PROJECT_ID/locations/us-central1/jobs/batch-job-invoker]
    
    Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
      ~ update in-place
    
    Terraform will perform the following actions:
    
      # google_cloud_scheduler_job.batch-job-invoker will be updated in-place
      ~ resource "google_cloud_scheduler_job" "batch-job-invoker" {
            id               = "projects/PROJECT_ID/locations/us-central1/jobs/batch-job-invoker"
            name             = "batch-job-invoker"
          ~ paused           = false -> true
            # (6 unchanged attributes hidden)
    
          ~ http_target {
              ~ headers     = {
                  + "User-Agent"   = "Google-Cloud-Scheduler"
                    # (1 unchanged element hidden)
                }
                # (3 unchanged attributes hidden)
    
                # (1 unchanged block hidden)
            }
    
            # (1 unchanged block hidden)
        }
    
    Plan: 0 to add, 1 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.
    
  3. Para aplicar el plan y actualizar el trabajo cron batch-job-invoker, sigue estos pasos:

    1. Introduce el siguiente comando:

      terraform apply
      

      El resultado es similar al del comando terraform plan anterior, pero termina con una petición de confirmación.

    2. Para confirmar y aplicar el plan, introduce yes.

      El resultado debería ser similar al siguiente:

      google_cloud_scheduler_job.batch-job-invoker: Modifying... [id=projects/PROJECT_ID/locations/us-central1/jobs/batch-job-invoker]
      google_cloud_scheduler_job.batch-job-invoker: Modifications complete after 1s [id=projects/PROJECT_ID/locations/us-central1/jobs/batch-job-invoker]
      
      Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
      
  4. Para verificar que el trabajo cron batch-job-invoker está en pausa, descríbelo:

    gcloud scheduler jobs describe batch-job-invoker --location us-central1
    

    El resultado debería ser similar al siguiente:

    attemptDeadline: 180s
    httpTarget:
      body: ...
      headers:
        Content-Type: application/json
        User-Agent: Google-Cloud-Scheduler
      httpMethod: POST
      oauthToken:
        scope: https://www.googleapis.com/auth/cloud-platform
        serviceAccountEmail: CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL
      uri: https://batch.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/jobs
    lastAttemptTime: '...'
    name: projects/PROJECT_ID/locations/us-central1/jobs/batch-job-invoker
    retryConfig:
      maxBackoffDuration: 3600s
      maxDoublings: 5
      maxRetryDuration: 0s
      minBackoffDuration: 5s
    schedule: '*/5 * * * *'
    scheduleTime: '...'
    state: PAUSED
    status: {}
    timeZone: America/Los_Angeles
    userUpdateTime: '...'
    

    En el resultado, comprueba que el campo state esté configurado como PAUSED.

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

  1. Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

  2. Ve al directorio principal y, a continuación, elimina el directorio de Terraform y todos sus archivos.

    cd .. && rm -r terraform
    

Eliminar recursos concretos

  1. Elimina la tarea cron batch-job-invoker.

    terraform destroy
    
  2. Para eliminar todos los trabajos por lotes de este tutorial, sigue estos pasos:

    1. Lista todas las tareas de Batch que ha creado la tarea cron batch-job-invoker:

      gcloud batch jobs list \
      --filter labels.source=\"terraform_and_cloud_scheduler_tutorial\" \
      --sort-by ~createTime
      

      Anota el nombre de cada trabajo que quieras eliminar.

    2. Para eliminar un trabajo por lotes de este tutorial, sigue estos pasos:

      gcloud batch jobs delete JOB_NAME --location us-central1
      

      Sustituye JOB_NAME por el nombre de un trabajo por lotes.

      Repite este paso con todos los trabajos por lotes.

  3. Si has creado una cuenta de servicio para este tutorial, elimínala:

    gcloud iam service-accounts delete SERVICE_ACCOUNT_EMAIL
    

    Sustituye SERVICE_ACCOUNT_EMAIL por la dirección de correo de una cuenta de servicio que hayas creado para este tutorial. En concreto, has usado las siguientes cuentas de servicio:

    • CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL: la cuenta de servicio de Cloud Scheduler.
    • BATCH_SERVICE_ACCOUNT_EMAIL: la cuenta de servicio de Batch.

    Si has creado dos cuentas de servicio independientes, repite este paso.

  4. Ve al directorio principal y, a continuación, elimina el directorio de Terraform y todos sus archivos.

    cd .. && rm -r terraform
    

Siguientes pasos