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


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

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

Terraform には Batch のリソースはありませんが、このチュートリアルでは、Terraform を使用して Batch ジョブを作成する方法について説明します。具体的には、Terraform を使用して、Batch API をターゲットとする Cloud Scheduler cron ジョブをスケジュールして実行し、Batch ジョブを作成して実行できます。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. Install the Google Cloud CLI.
    2. To initialize the gcloud CLI, run the following command:

      gcloud init
    3. 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. このチュートリアルで必要な権限を持つ 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 構成では、いくつかの入力変数と、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 ジョブによって作成されたバッチジョブを一覧表示します。

    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 のラベルを持つバッチジョブのみが含まれるようにリストをフィルタします。
    • --sort-by ~createTime フラグを使用すると、リストが新しい順に並べ替えられます。

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

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

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

    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. このチュートリアルのすべてのバッチジョブを削除する手順は次のとおりです。

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

      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 は、バッチジョブの名前に置き換えます。

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

  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
    

次のステップ