Terraform 및 Cloud Scheduler를 사용하여 Batch 작업 만들기 및 실행

이 튜토리얼에서는 Terraform을 사용하여 Cloud Scheduler 크론 작업을 통해 Batch 작업을 만들고 실행하는 방법을 설명합니다.

Terraform은 구성 파일에 원하는 상태를 지정하여 인프라를 프로비저닝하고 관리할 수 있는 오픈소스 도구입니다. 이러한 파일을 코드로 취급하고 GitHub와 같은 버전 제어 시스템에 저장할 수 있습니다.

Terraform에는 Batch 리소스가 없지만 이 튜토리얼에서 Terraform을 사용하여 Batch 작업을 만드는 방법을 설명합니다. 구체적으로 Terraform을 사용하여 Batch API를 대상으로 하는 Cloud Scheduler 크론 작업을 예약하고 실행하여 Batch 작업을 만들고 실행할 수 있습니다. Cloud Scheduler는 크론 작업을 자동으로 예약할 수 있는 Google Cloud 서비스이며 Terraform을 지원합니다.

이 튜토리얼은 Terraform으로 인프라를 이미 관리하고 있으며 Batch 작업을 Terraform에 통합하려는 Batch 사용자를 대상으로 합니다.

Terraform 디렉터리 및 구성 파일 만들기

Terraform의 디렉터리와 Terraform을 사용하여 만들거나 업데이트할 리소스를 정의하는 구성 파일을 만듭니다. 이 튜토리얼의 예시 구성 파일은 batch-job-invoker라는 Cloud Scheduler 크론 작업을 정의합니다. 사용 설정된 경우 batch-job-invoker 크론 작업은 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
        }
      }
    }
    
    

    다음을 바꿉니다.

    • PROJECT_ID: 프로젝트의 프로젝트 ID입니다.
    • PROJECT_NUMBER: 프로젝트의 프로젝트 번호입니다.
    • CLOUD_SCHEDULER_SERVICE_ACCOUNT_EMAIL: Cloud Scheduler 크론 작업을 위해 준비한 서비스 계정의 이메일 주소입니다.

      예를 들어 Compute Engine 기본 서비스 계정을 사용하려면 다음을 지정합니다.

      PROJECT_NUMBER-compute@developer.gserviceaccount.com
      
    • BATCH_SERVICE_ACCOUNT_EMAIL: 일괄 작업에 대해 준비한 서비스 계정의 이메일 주소입니다.

      예를 들어 Compute Engine 기본 서비스 계정을 사용하려면 다음을 지정합니다.

      PROJECT_NUMBER-compute@developer.gserviceaccount.com
      

    이 Terraform 구성은 Batch 작업을 만들기 위해 API 메서드에 연결하는 일부 입력 변수 및 크론 작업을 정의합니다.

  3. 파일을 저장하고 닫으려면 Ctrl+D(macOS에서는 Command+D)를 누릅니다.

Terraform 구성을 배포하여 크론 작업 만들기

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 크론 작업을 만드는 계획임을 보여줍니다.

    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 크론 작업을 만드는 계획을 적용하려면 다음 단계를 따르세요.

    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로 설정되어 있는지 확인합니다.

크론 작업이 Batch 작업을 만드는지 확인

batch-job-invoker 크론 작업이 Batch 작업을 올바르게 만들고 있는지 확인합니다.

  1. 크론 작업이 자동으로 실행될 때까지 5분간 기다리거나 크론 작업을 트리거하여 즉시 실행합니다.

    gcloud scheduler jobs run batch-job-invoker --location us-central1
    
  2. batch-job-invoker 크론 작업으로 생성된 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 구성을 업데이트하여 크론 작업 일시중지

원하는 수의 Batch 작업이 완료되면 Terraform 구성을 업데이트하고 배포하여 batch-job-invoker 크론 작업을 일시중지합니다. 크론 작업 또는 향후 Batch 작업의 다른 속성을 업데이트하려면 동일한 프로세스가 적용됩니다.

  1. paused 필드를 true로 설정하여 크론 작업을 일시중지하도록 Terraform 구성 파일을 업데이트합니다.

    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 크론 작업을 업데이트하는 계획을 적용하려면 다음 단계를 따르세요.

    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 크론 작업이 일시중지되었는지 확인하려면 다음 명령어를 실행합니다.

    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로 설정되어 있는지 확인합니다.