Criar e executar jobs em lote usando o Terraform e o Cloud Scheduler


Neste tutorial, explicamos como usar o Terraform para criar e executar jobs em lote usando um job cron do Cloud Scheduler.

O Terraform é uma ferramenta de código aberto que permite provisionar e gerenciar infraestruturas especificando o estado desejado em arquivos de configuração. Esses arquivos podem ser tratados como código e armazenados em sistemas de controle de versões, como o GitHub.

Embora o Terraform não tenha recursos para o Batch, este tutorial mostra como usar o Terraform para criar trabalhos em lote. Especificamente, é possível usar o Terraform para programar e executar um job cron do Cloud Scheduler que tem como destino a API Batch para criar e executar jobs do Batch. O Cloud Scheduler é um Google Cloud serviço que permite programar automaticamente cron jobs e oferece suporte ao Terraform.

Este tutorial é destinado a usuários do Batch que já gerenciam infraestrutura com o Terraform e querem incorporar jobs do Batch ao Terraform.

Objetivos

  • Crie um diretório do Terraform e um arquivo de configuração que defina um job cron do Cloud Scheduler que cria jobs em lote.
  • Implante a configuração do Terraform para executar o job do cron.
  • Verifique se o job cron cria jobs em lote.
  • Atualize a configuração do Terraform para pausar o cron job e interromper a criação de jobs do lote.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

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

    Cloud Shell

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

    Na parte de baixo desta página, uma sessão do Cloud Shell é iniciada e mostra um prompt de linha de comando. A inicialização da sessão pode levar alguns segundos.

    Shell local

    Para usar um ambiente de desenvolvimento local, siga estas etapas:

    1. Install the Google Cloud CLI.
    2. To initialize the gcloud CLI, run the following command:

      gcloud init
    3. Instale o Terraform.
  2. 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.

  3. Make sure that billing is enabled for your Google Cloud project.

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

    gcloud services enable batch.googleapis.com compute.googleapis.com logging.googleapis.com  cloudscheduler.googleapis.com cloudresourcemanager.googleapis.com
  5. Verifique se o projeto tem pelo menos uma conta de serviço com as permissões necessárias para este tutorial.

    Especificamente, você pode usar a mesma conta de serviço ou duas contas de serviço separadas para conceder as seguintes permissões:

    • Permita que o job cron crie jobs em lote e anexe a conta de serviço para eles.
    • Permita que os trabalhos em lote criem e acessem os recursos necessários para execução.

    Para garantir que as contas de serviço deste tutorial tenham as permissões necessárias para usar o Terraform para criar jobs do Batch em um job cron do Cloud Scheduler, peça ao administrador para conceder às contas de serviço deste tutorial os seguintes papéis do IAM:

    Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

    O administrador também pode conceder às contas de serviço deste tutorial as permissões necessárias por meio de papéis personalizados ou outros papéis predefinidos.

  6. Verifique se você tem as permissões necessárias para este tutorial.

    Especificamente, você precisa de permissões para fazer o seguinte:

    • Crie um trabalho do cron e anexe a conta de serviço a ele.
    • Acesse e exclua o job cron e os jobs em lote.

    Para receber as permissões necessárias para usar o Terraform para criar jobs do Batch usando um job cron do Cloud Scheduler, peça ao administrador para conceder a você os seguintes papéis do IAM:

Criar o diretório e o arquivo de configuração do Terraform

Crie um diretório para o Terraform e um arquivo de configuração que defina os recursos que você quer criar ou atualizar usando o Terraform. O arquivo de exemplo de configuração deste tutorial define um job cron do Cloud Scheduler chamado batch-job-invoker. Quando ativado, o job de cron batch-job-invoker é executado a cada 5 minutos para criar uma nova instância do job de lote definido.

  1. Para criar um diretório e um novo arquivo de configuração do Terraform (.tf) nesse diretório, digite o comando a seguir e pressione Enter:

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

    Esse comando cria o diretório terraform, navega até ele e começa a definir um novo arquivo de configuração main.tf na próxima linha.

  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:

    • 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 e-mail da conta de serviço que você preparou para o job cron do Cloud Scheduler.

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

      PROJECT_NUMBER-compute@developer.gserviceaccount.com
      
    • BATCH_SERVICE_ACCOUNT_EMAIL: o endereço de e-mail da conta de serviço que você preparou para trabalhos em lote.

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

      PROJECT_NUMBER-compute@developer.gserviceaccount.com
      

    Essa configuração do Terraform define algumas variáveis de entrada e um job cron que entra em contato com o método da API para criar um job do Batch.

  3. Para salvar e fechar o arquivo, pressione Ctrl+D (ou Command+D no macOS).

Implantar a configuração do Terraform para criar o trabalho do cron

Implante a configuração do Terraform inicializando o Terraform, gerando as mudanças planejadas e aplicando essas mudanças. Depois de implantar a configuração do Terraform, você pode descrever os recursos no seu projeto para verificar se o Terraform criou o job cron batch-job-invoker.

  1. Inicialize o Terraform no diretório:

    terraform init
    

    O resultado será assim:

    ...
    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 arquivo de configuração:

    terraform plan
    

    A saída é semelhante à seguinte, que mostra que o plano é criar o job 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 e criar a tarefa cron batch-job-invoker, siga estas etapas:

    1. Digite este comando:

      terraform apply
      

      A saída é semelhante ao comando terraform plan anterior, mas termina com uma solicitação de confirmação.

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

      O resultado será assim:

      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 o job de cron batch-job-invoker existe e está ativado, descreva-o:

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

    O resultado será assim:

    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 o job cron cria um job em lote

Verifique se o job de cron batch-job-invoker está criando jobs de lote corretamente.

  1. Aguarde cinco minutos para que o job cron seja executado automaticamente ou acione o job cron para execução imediata:

    gcloud scheduler jobs run batch-job-invoker --location us-central1
    
  2. Liste os jobs em lote criados pelo job de 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 jobs em lote que tenham um rótulo com a chave source e o valor terraform_and_cloud_scheduler_tutorial.
    • A flag --sort-by ~createTime classifica a lista do mais recente para o mais antigo.

Atualizar a configuração do Terraform para pausar o cron job

Depois de ter o número desejado de jobs em lote, atualize e implante a configuração do Terraform para pausar o job de cron batch-job-invoker. Se você quiser atualizar outras propriedades da tarefa cron ou de futuros trabalhos em lote, este mesmo processo será aplicado.

  1. Atualize o arquivo de configuração do Terraform para pausar o trabalho 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 arquivo 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 e atualizar o job do cron batch-job-invoker, siga estas etapas:

    1. Digite este comando:

      terraform apply
      

      A saída é semelhante ao comando terraform plan anterior, mas termina com uma solicitação de confirmação.

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

      O resultado será assim:

      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 o job de cron batch-job-invoker está pausado, descreva-o:

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

    O resultado será assim:

    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 cobranças na sua conta do Google Cloud pelos recursos usados no tutorial, exclua o projeto que os contém ou mantenha o projeto e exclua os recursos individuais.

Excluir o projeto

  1. Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

  2. Acesse o diretório pai e exclua o diretório do Terraform e todos os arquivos dele.

    cd .. && rm -r terraform
    

Excluir recursos individuais

  1. Exclua o cron job batch-job-invoker.

    terraform destroy
    
  2. Para excluir todos os jobs em lote deste tutorial, siga estas etapas:

    1. Liste todos os jobs em lote que foram criados pelo job de cron batch-job-invoker:

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

      Anote o nome de cada job que você precisa excluir.

    2. Exclua um job em lote neste tutorial:

      gcloud batch jobs delete JOB_NAME --location us-central1
      

      Substitua JOB_NAME pelo nome de um job em lote.

      Repita essa etapa para todos os trabalhos em lote.

  3. Se você criou uma conta de serviço para este tutorial, exclua-a:

    gcloud iam service-accounts delete SERVICE_ACCOUNT_EMAIL
    

    Substitua SERVICE_ACCOUNT_EMAIL pelo endereço de e-mail de uma conta de serviço que você criou para este tutorial. Especificamente, você 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 você criou duas contas de serviço separadas, repita esta etapa.

  4. Acesse o diretório pai e exclua o diretório do Terraform e todos os arquivos dele.

    cd .. && rm -r terraform
    

A seguir