Terraform と Cloud Scheduler を使用してバッチジョブを作成して実行する

このチュートリアルでは、Cloud Scheduler cron ジョブを使用することで、Terraform を使用して Batch ジョブを作成して実行する方法について説明します。

Terraform は、構成ファイルで目的の状態を指定することで、インフラストラクチャをプロビジョニングして管理できるオープンソース ツールです。これらのファイルはコードとして扱われ、GitHub のようなバージョン管理システムに保存できます。

Terraform には Batch 用のリソースはありませんが、このチュートリアルでは、Terraform を使用して Batch ジョブを作成する方法について説明します。具体的には、Terraform を使用して、Batch API をターゲットとして Batch ジョブを作成して実行する、Cloud Scheduler cron ジョブをスケジュールして実行します。Cloud Scheduler は、cron ジョブを自動的にスケジュールできる Google Cloud サービスで、Terraform をサポートしています。

このチュートリアルは、すでに Terraform でインフラストラクチャを管理していて、Batch ジョブを Terraform に組み込みたい Batch ユーザーを対象としています。

Terraform ディレクトリと構成ファイルを作成する

Terraform 用のディレクトリと、Terraform を使用して作成または更新するリソースを定義する構成ファイルを作成します。このチュートリアルのサンプル構成ファイルでは、batch-job-invoker という名前の Cloud Scheduler cron ジョブを定義しています。有効にすると、batch-job-invoker cron ジョブが 5 分ごとに実行され、定義された Batch ジョブの新しいインスタンスが作成されます。

  1. ディレクトリとそのディレクトリ内に新しい Terraform 構成(.tf)ファイルを作成するには、次のコマンドを入力して Enter を押します。

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

    このコマンドは terraform ディレクトリを作成し、そのディレクトリに移動して、次の行で新しい main.tf 構成ファイルの定義を開始します。

  2. 次の 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
        }
      }
    }
    
    

    以下を置き換えます。

    この Terraform 構成では、いくつかの入力変数と、API メソッドに接続して Batch ジョブを作成する cron ジョブを定義します。

  3. ファイルを保存して閉じるには、Ctrl+D(macOS の場合は Command+D)を押します。

Terraform 構成をデプロイして cron ジョブを作成する

Terraform を初期化し、計画された変更を生成して、これらの変更を適用することで、Terraform 構成をデプロイします。Terraform 構成をデプロイしたら、プロジェクトでリソースを記述して、Terraform が batch-job-invoker cron ジョブを正常に作成したことを確認できます。

  1. ディレクトリで Terraform を初期化します。

    terraform init
    

    出力は次のようになります。

    ...
    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. プロジェクトの現在の状態と構成ファイルに基づいて Terraform 実行プランを生成します。

    terraform plan
    

    出力は次のようになります。これは、batch-job-invoker cron ジョブを作成するプランであることを示しています。

    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. batch-job-invoker cron ジョブを作成するプランを適用するには、次の手順を多内ます。

    1. 次のコマンドを入力します。

      terraform apply
      

      出力は、確認プロンプトで終わる点を除いて、前の terraform plan コマンドと同様です。

    2. プランを確認して適用するには、「yes」と入力します。

      出力は次のようになります。

      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. batch-job-invoker cron ジョブが存在し、有効になっていることを確認するには、そのように記述します。

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

    出力は次のようになります。

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

    出力で、state フィールドが ENABLED に設定されていることを確認します。

cron ジョブで Batch ジョブが作成されることを確認する

batch-job-invoker cron ジョブで Batchジョブが正しく作成されていることを確認します。

  1. cron ジョブが自動的に実行されるまで 5 分間待つか、cron ジョブをトリガーしてすぐに実行します。

    gcloud scheduler jobs run batch-job-invoker --location us-central1
    
  2. batch-job-invoker cron ジョブによって作成された Batch ジョブを一覧表示します。

    gcloud batch jobs list \
    --filter labels.source=\"terraform_and_cloud_scheduler_tutorial\" \
    --sort-by ~createTime
    
    • --filter labels.source=\"terraform_and_cloud_scheduler_tutorial\" フラグは、キー source と値 terraform_and_cloud_scheduler_tutorial のラベルが付いた Batch ジョブのみを含むようにリストをフィルタします。
    • --sort-by ~createTime フラグは、リストを新しい順に並べ替えます。

cron ジョブを一時停止するように Terraform 構成を更新する

必要な数の Batch ジョブが作成されたら、Terraform 構成を更新してデプロイし、batch-job-invoker cron ジョブを一時停止します。cron ジョブまたは将来の Batch ジョブの他のプロパティを更新する場合も、同じプロセスが適用されます。

  1. cron ジョブを一時停止するように Terraform 構成ファイルを更新するには、paused フィールドを true に設定します。

    sed -i 's/paused           = false # this cron job is enabled/paused           = true # this cron job is paused/g' main.tf
    
  2. プロジェクトの現在の状態と構成ファイルに基づいて Terraform 実行プランを生成します。

    terraform plan
    

    出力は次のようになります。これは、paused フィールドの値を false から 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. batch-job-invoker cron ジョブを更新するプランを適用するには、次の手順を行います。

    1. 次のコマンドを入力します。

      terraform apply
      

      出力は、確認プロンプトで終わる点を除いて、前の terraform plan コマンドと同様です。

    2. プランを確認して適用するには、「yes」と入力します。

      出力は次のようになります。

      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. batch-job-invoker cron ジョブが一時停止されていることを確認するには、そのように記述します。

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

    出力は次のようになります。

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

    出力で、state フィールドが PAUSED に設定されていることを確認します。