Crie e execute trabalhos em lote com o Terraform e o Cloud Scheduler

Este tutorial explica como pode usar o Terraform para criar e executar tarefas em lote através de uma tarefa cron do Cloud Scheduler.

O Terraform é uma ferramenta de código aberto que lhe permite aprovisionar e gerir a infraestrutura especificando o estado pretendido nos ficheiros de configuração. Estes ficheiros podem ser tratados como código e armazenados em sistemas de controlo de versões, como o GitHub.

Embora o Terraform não tenha recursos para o Batch, este tutorial mostra como pode usar o Terraform para criar tarefas do Batch. Em concreto, pode usar o Terraform para agendar e executar uma tarefa cron do Cloud Scheduler que segmenta a API Batch para criar e executar tarefas do Batch. O Cloud Scheduler é um Google Cloud serviço que lhe permite agendar automaticamente tarefas cron e suporta o Terraform.

Este tutorial destina-se a utilizadores do Batch que já gerem infraestrutura com o Terraform e querem incorporar tarefas do Batch no Terraform.

Objetivos

  • Crie um diretório do Terraform e um ficheiro de configuração que defina uma tarefa cron do Cloud Scheduler que crie tarefas do Batch.
  • Implemente a configuração do Terraform para executar a tarefa cron.
  • Verifique se a tarefa cron cria tarefas em lote.
  • Atualize a configuração do Terraform para pausar a tarefa cron de modo a que deixe de criar tarefas do Batch.

Custos

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

Para gerar uma estimativa de custos com base na sua utilização prevista, 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.

Antes de começar

  1. Prepare o seu ambiente de desenvolvimento, seja o Cloud Shell ou um shell local:

    Cloud Shell

    Para usar um terminal online com a CLI gcloud e o Terraform já configurados, ative o Cloud Shell.

    Na parte inferior desta página, é iniciada uma sessão do Cloud Shell e é apresentado um comando. A sessão pode demorar alguns segundos a ser inicializada.

    Shell local

    Para usar um ambiente de desenvolvimento local, siga estes passos:

    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. Instale o 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 role (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. Certifique-se de que o seu projeto tem, pelo menos, uma conta de serviço com as autorizações necessárias para este tutorial.

    Em concreto, pode usar a mesma conta de serviço ou duas contas de serviço separadas para conceder as seguintes autorizações:

    • Permitir que a tarefa cron crie tarefas de lote e anexe a conta de serviço para as tarefas de lote.
    • Permitir que as tarefas em lote criem e acedam aos recursos necessários para a execução.

    Para garantir que as contas de serviço deste tutorial têm as autorizações necessárias para usar o Terraform para criar tarefas do Batch através de uma tarefa cron do Cloud Scheduler, peça ao seu administrador para conceder às contas de serviço deste tutorial as seguintes funções do IAM:

    Para mais informações sobre a atribuição de funções, consulte o artigo Faça a gestão do acesso a projetos, pastas e organizações.

    O administrador também pode conceder às contas de serviço deste tutorial as autorizações necessárias através de funções personalizadas ou outras funções predefinidas.

  6. Certifique-se de que tem as autorizações necessárias para este tutorial.

    Especificamente, precisa de autorizações para fazer o seguinte:

    • Crie uma tarefa cron e anexe a conta de serviço à tarefa cron.
    • Ver e eliminar a tarefa cron e as tarefas em lote.

    Para receber as autorizações de que precisa para usar o Terraform para criar tarefas do Batch através de uma tarefa cron do Cloud Scheduler, peça ao seu administrador para lhe conceder as seguintes funções do IAM:

Crie o diretório do Terraform e o ficheiro de configuração

Crie um diretório para o Terraform e um ficheiro de configuração que defina os recursos que quer criar ou atualizar com o Terraform. O ficheiro de configuração de exemplo para este tutorial define uma tarefa cron do Cloud Scheduler denominada batch-job-invoker. Quando está ativada, a tarefa cron batch-job-invokeré executada a cada 5 minutos para criar uma nova instância da tarefa em lote definida.

  1. Para criar um diretório e um novo ficheiro de configuração do Terraform (.tf) nesse diretório, escreva o seguinte comando e, em seguida, prima Enter:

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

    Este comando cria o diretório terraform, navega até ele e começa a definir um novo ficheiro de configuração main.tf na linha seguinte.

  2. Copie e cole a seguinte configuração do 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
        }
      }
    }
    
    

    Substitua o seguinte:

    • PROJECT_ID: o ID do projeto do seu projeto.
    • PROJECT_NUMBER: o número do projeto do seu projeto.
    • CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL: o endereço de email da conta de serviço que preparou para a tarefa cron do Cloud Scheduler.

      Por exemplo, para usar a conta de serviço predefinida do Compute Engine, especifique o seguinte:

      PROJECT_NUMBER-compute@developer.gserviceaccount.com
      
    • BATCH_SERVICE_ACCOUNT_EMAIL: o endereço de email da conta de serviço que preparou para tarefas em lote.

      Por exemplo, para usar a conta de serviço predefinida do Compute Engine, especifique o seguinte:

      PROJECT_NUMBER-compute@developer.gserviceaccount.com
      

    Esta configuração do Terraform define algumas variáveis de entrada e uma tarefa cron que contacta o método da API para criar uma tarefa em lote.

  3. Para guardar e fechar o ficheiro, prima Ctrl+D (ou Command+D no macOS).

Implemente a configuração do Terraform para criar a tarefa cron

Implemente a configuração do Terraform inicializando o Terraform, gerando as alterações planeadas e aplicando-as. Depois de implementar a configuração do Terraform, pode descrever os recursos no seu projeto para verificar se o Terraform criou com êxito a tarefa cron batch-job-invoker.

  1. Inicialize o Terraform no diretório:

    terraform init
    

    O resultado é semelhante ao seguinte:

    ...
    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. Gere o plano de execução do Terraform com base no estado atual do seu projeto e no ficheiro de configuração:

    terraform plan
    

    O resultado é semelhante ao seguinte, que mostra que o plano é criar a tarefa 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 o plano de modo a criar a tarefa cron batch-job-invoker, siga estes passos:

    1. Introduza o seguinte comando:

      terraform apply
      

      O resultado é semelhante ao comando terraform plan anterior, exceto que termina com um pedido de confirmação.

    2. Para confirmar e aplicar o plano, introduza yes.

      O resultado é semelhante ao seguinte:

      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 se a tarefa cron batch-job-invoker existe e está ativada, descreva-a:

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

    O resultado é semelhante ao seguinte:

    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: '...'
    

    Na saída, verifique se o campo state está definido como ENABLED.

Verifique se a tarefa cron cria uma tarefa em lote

Verifique se a tarefa cron batch-job-invoker está a criar corretamente trabalhos em lote.

  1. Aguarde 5 minutos para que a tarefa cronológica seja executada automaticamente ou acione a tarefa cronológica para execução imediata:

    gcloud scheduler jobs run batch-job-invoker --location us-central1
    
  2. Indique as tarefas em lote que foram criadas pela tarefa cron: batch-job-invoker

    gcloud batch jobs list \
    --filter labels.source=\"terraform_and_cloud_scheduler_tutorial\" \
    --sort-by ~createTime
    
    • A flag --filter labels.source=\"terraform_and_cloud_scheduler_tutorial\" filtra a lista para incluir apenas tarefas em lote que tenham uma etiqueta com a chave source e o valor terraform_and_cloud_scheduler_tutorial.
    • A opção --sort-by ~createTime ordena a lista do mais recente para o mais antigo.

Atualize a configuração do Terraform para pausar a tarefa cron

Depois de ter o número desejado de tarefas em lote, atualize e implemente a configuração do Terraform para pausar a tarefa cron batch-job-invoker. Se quiser atualizar outras propriedades da tarefa cron ou de tarefas em lote futuras, aplica-se o mesmo processo.

  1. Atualize o ficheiro de configuração do Terraform para pausar a tarefa cron definindo o 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. Gere o plano de execução do Terraform com base no estado atual do seu projeto e no ficheiro de configuração:

    terraform plan
    

    A saída é semelhante à seguinte, que mostra que o plano é atualizar o valor do campo paused de false para 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 o plano para atualizar a tarefa cron batch-job-invoker, siga estes passos:

    1. Introduza o seguinte comando:

      terraform apply
      

      O resultado é semelhante ao comando terraform plan anterior, exceto que termina com um pedido de confirmação.

    2. Para confirmar e aplicar o plano, introduza yes.

      O resultado é semelhante ao seguinte:

      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 se a tarefa cron batch-job-invoker está pausada, descreva-a:

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

    O resultado é semelhante ao seguinte:

    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: '...'
    

    Na saída, verifique se o campo state está definido como PAUSED.

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

  1. Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

  2. Aceda ao diretório principal e, em seguida, elimine o diretório do Terraform e todos os respetivos ficheiros.

    cd .. && rm -r terraform
    

Elimine recursos individuais

  1. Elimine a tarefa cron batch-job-invoker.

    terraform destroy
    
  2. Para eliminar todas as tarefas em lote deste tutorial, siga estes passos:

    1. Apresente uma lista de todas as tarefas em lote criadas pela tarefa cron batch-job-invoker:

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

      Registe o nome de cada trabalho que tem de eliminar.

    2. Elimine uma tarefa em lote deste tutorial:

      gcloud batch jobs delete JOB_NAME --location us-central1
      

      Substitua JOB_NAME pelo nome de um trabalho em lote.

      Repita este passo para todas as tarefas em lote.

  3. Se criou uma conta de serviço para este tutorial, elimine a conta de serviço:

    gcloud iam service-accounts delete SERVICE_ACCOUNT_EMAIL
    

    Substitua SERVICE_ACCOUNT_EMAIL pelo endereço de email de uma conta de serviço que criou para este tutorial. Ou seja, usou as seguintes contas de serviço:

    • CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL: a conta de serviço do Cloud Scheduler.
    • BATCH_SERVICE_ACCOUNT_EMAIL: a conta de serviço do Batch.

    Se criou duas contas de serviço separadas, repita este passo.

  4. Aceda ao diretório principal e, em seguida, elimine o diretório do Terraform e todos os respetivos ficheiros.

    cd .. && rm -r terraform
    

O que se segue?