Terraform と Cloud Scheduler を使用して Batch ジョブを作成、実行する


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

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

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

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

目標

  • Terraform ディレクトリと、バッチジョブを作成する Cloud Scheduler cron ジョブを定義する構成ファイルを作成します。
  • Terraform 構成をデプロイして cron ジョブを実行します。
  • cron ジョブがバッチジョブを作成することを確認します。
  • Terraform 構成を更新して、cron ジョブを一時停止し、Batch ジョブの作成を停止します。

費用

このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。 新しい Google Cloud ユーザーは無料トライアルをご利用いただける場合があります。

このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。

始める前に

  1. 開発環境(Cloud Shell またはローカルシェル)を準備します。

    Cloud Shell

    gcloud CLI と Terraform がすでに設定されているオンライン ターミナルを使用するには、Cloud Shell をアクティブにします。

    このページの下部で Cloud Shell セッションが開始し、コマンドライン プロンプトが表示されます。セッションが初期化されるまで数秒かかることがあります。

    ローカルシェル

    ローカル開発環境を使用する手順は次のとおりです。

    1. Google Cloud CLI をインストールします。
    2. gcloud CLI を初期化するには:

      gcloud init
    3. Terraform をインストールします
  2. Google Cloud プロジェクトを作成または選択します

    • Google Cloud プロジェクトを作成します。

      gcloud projects create PROJECT_ID

      PROJECT_ID は、作成する Google Cloud プロジェクトの名前に置き換えます。

    • 作成した Google Cloud プロジェクトを選択します。

      gcloud config set project PROJECT_ID

      PROJECT_ID は、実際の Google Cloud プロジェクト名に置き換えます。

  3. Google Cloud プロジェクトで課金が有効になっていることを確認します

  4. Batch, Compute Engine, Cloud Logging, Cloud Scheduler, and Resource Manager API を有効にします。

    gcloud services enable batch.googleapis.comcompute.googleapis.comlogging.googleapis.comcloudscheduler.googleapis.comcloudresourcemanager.googleapis.com
  5. プロジェクトに、このチュートリアルで必要な権限を含むサービス アカウントが 1 つ以上設定されていることを確認します。

    具体的には、同じサービス アカウントまたは 2 つの個別のサービス アカウントを使用して、次の権限を付与できます。

    • cron ジョブがバッチジョブを作成し、バッチジョブのサービス アカウントを関連付けることができます。
    • バッチジョブに、実行に必要なリソースを作成してアクセスする許可を与えます。

    このチュートリアルのサービス アカウントに、Terraform を使用して Cloud Scheduler cron ジョブによって Batch ジョブを作成するために必要な権限が確実に付与されるようにするには、このチュートリアルのサービス アカウントに次の IAM ロールを付与するように管理者に依頼してください。

    ロールの付与の詳細については、アクセスの管理をご覧ください。

    管理者は、カスタムロールまたはその他の事前定義ロールを使用して、このチュートリアルのサービス アカウントに必要な権限を付与することもできます。

  6. このチュートリアルで必要な権限があることを確認します。

    具体的には、次の操作を行うための権限が必要です。

    • cron ジョブを作成し、cron ジョブのサービス アカウントを追加します。
    • cron ジョブと バッチジョブを表示して削除します。

    Terraform を使用して Cloud Scheduler cron ジョブを使用して Batch ジョブを作成するために必要な権限を取得するには、管理者に次の IAM ロールを付与するよう依頼してください。

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

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

  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_number}/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 構成では、いくつかの入力変数と、Batch ジョブを作成するための API メソッドに接続する 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_NUMBER/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_NUMBER/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-job-invoker cron ジョブが正しくバッチジョブを作成していることを確認します。

  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 フラグは、リストを新しいものから古いものへ並べ替えます。

Terraform 構成を更新して cron ジョブを一時停止する

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

  1. Terraform 構成ファイルを更新して cron ジョブを一時停止します。それには、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_NUMBER/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 に設定されていることを確認します。

クリーンアップ

このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。

プロジェクトの削除

  1. Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

  2. 親ディレクトリに移動し、Terraform ディレクトリとそのすべてのファイルを削除します。

    cd .. && rm -r terraform
    

リソースを個別に削除する

  1. batch-job-invoker cron ジョブを削除します。

    terraform destroy
    
  2. このチュートリアルから Batch ジョブをすべて削除する手順は次のとおりです。

    1. batch-job-invoker cron ジョブによって作成されたすべての Batch ジョブを一覧表示します。

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

      削除する各ジョブの名前を記録します。

    2. このチュートリアルから Batch ジョブを削除します。

      gcloud batch jobs delete JOB_NAME --location us-central1
      

      JOB_NAME は、Batch ジョブの名前に置き換えます。

      すべての Batch ジョブに対してこの手順を繰り返します。

  3. このチュートリアル用のサービス アカウントを作成した場合は、サービス アカウントを削除します。

    gcloud iam service-accounts delete SERVICE_ACCOUNT_EMAIL
    

    SERVICE_ACCOUNT_EMAIL は、このチュートリアルで作成したサービス アカウントのメールアドレスに置き換えます。つまり、次のサービス アカウントを使用しました。

    • CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL: Cloud Scheduler のサービス アカウント。
    • BATCH_SERVICE_ACCOUNT_EMAIL: Batch のサービス アカウント。

    2 つのサービス アカウントを作成した場合は、この手順を繰り返します。

  4. 親ディレクトリに移動し、Terraform ディレクトリとそのすべてのファイルを削除します。

    cd .. && rm -r terraform
    

次のステップ