> ## Documentation Index
> Fetch the complete documentation index at: https://docs.coreweave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Terraform으로 러너 관리하기

> CoreWeave Terraform 공급자를 사용하여 CoreWeave Sandbox 관리형 러너를 배포, 설정 및 임포트하세요.

`coreweave_sandbox_managed_runner` 리소스를 사용하여 CoreWeave Kubernetes Service (CKS) 클러스터에서 러너와 해당 러너의 샌드박스 정책을 관리하세요. Terraform은 의도한 설정을 기록하고 불일치를 감지하며, 관리형 러너 API를 통해 설정 변경 사항을 적용합니다.

전체 속성 스키마는 [관리형 러너 리소스 레퍼런스](/platform/terraform/resources/sandbox_managed_runner)를 참조하세요. 같은 작업을 CLI 및 REST로 수행하는 워크플로는 [러너 배포 및 관리](/ko/products/sandboxes/operations/managed-runners)를 참조하세요.

## 시작하기 전에

다음 리소스와 도구가 필요합니다.

* Terraform 및 [CoreWeave Terraform 공급자](/platform/terraform). 예시에서는 `0.x` 시리즈 중 공급자 버전 `0.26.0` 이상을 사용합니다.
* 기존 CKS 클러스터와 해당 클러스터의 범용 고유 식별자(UUID) 및 Availability Zone. 이 값은 Cloud console의 [Clusters](https://console.coreweave.com/clusters) 페이지에서 확인할 수 있습니다.
* `SANDBOX_ADMIN` 권한이 있는 CoreWeave API 액세스 토큰. [API 액세스 토큰 관리](/security/authn-authz/manage-api-access-tokens) 및 [Manage Access Policies](/security/iam/access-policies/manage)를 참조하세요.
* 액세스 제어가 적용된 Terraform 상태 백엔드. Terraform은 러너 환경 재정의 값과 정책 값을 민감한 값으로 표시하더라도 이를 상태에 저장할 수 있습니다.

CKS 클러스터 하나에는 관리형 러너를 최대 하나만 호스팅할 수 있습니다. 클러스터에 이미 러너가 있다면 설정을 적용하기 전에 [해당 러너를 임포트하세요](#import-an-existing-runner).

## 인증 설정

공급자는 `COREWEAVE_API_TOKEN`을 읽습니다. 토큰을 이미 `CW_API_KEY`로 export한 경우에는 공급자가 사용하는 환경 변수를 설정하세요.

```bash theme={"system"}
export COREWEAVE_API_TOKEN="$CW_API_KEY"
```

공급자는 기본적으로 `https://api.coreweave.com`을 사용합니다. 인증은 CoreWeave Intelligent CLI 로그인과는 별개로 처리됩니다. 토큰을 Terraform 설정 파일에 넣지 마세요.

## 러너 정의

다음 설정을 `main.tf` 파일에 저장하세요. 이 설정은 stable 출시 채널, 주간 유지보수 시간, 그리고 샌드박스 리소스 기본값과 기본 수명을 지정하는 정책이 적용된 러너를 생성합니다.

```terraform title="main.tf" theme={"system"}
terraform {
  required_providers {
    coreweave = {
      source  = "coreweave/coreweave"
      version = "~> 0.26"
    }
  }
}

provider "coreweave" {}

variable "runner_id" {
  type        = string
  description = "Runner identifier, unique within your organization."
}

variable "cluster_id" {
  type        = string
  description = "UUID of the existing CKS cluster."
}

variable "zone" {
  type        = string
  description = "Availability Zone of the existing CKS cluster."
}

resource "coreweave_sandbox_managed_runner" "runner" {
  runner_id  = var.runner_id
  cluster_id = var.cluster_id
  zone       = lower(var.zone)

  spec = {
    release_channel = "RELEASE_CHANNEL_STABLE"
    maintenance_policy = {
      windows = [{ cron = "0 2 * * SAT", duration_seconds = 3600 }]
    }
    overrides = {
      resources = {
        cpu_request    = "1"
        memory_request = "2Gi"
        cpu_limit      = "4"
        memory_limit   = "8Gi"
      }
    }
  }

  policy = {
    display_name = "Sandbox constraints"
    constraints = {
      resources = {
        default_cpu    = "1"
        default_memory = "2Gi"
        max_cpu        = "8"
        max_memory     = "32Gi"
        max_gpu_count  = 0
      }
      lifecycle = { default_lifetime_seconds = 3600 }
    }
  }
}

output "runner_status" {
  value = {
    runner_id           = coreweave_sandbox_managed_runner.runner.runner_id
    install_status      = coreweave_sandbox_managed_runner.runner.install_status
    connection_status   = coreweave_sandbox_managed_runner.runner.connection_status
    active_revision     = coreweave_sandbox_managed_runner.runner.active_revision
    target_revision     = coreweave_sandbox_managed_runner.runner.target_revision
    rollout_in_progress = coreweave_sandbox_managed_runner.runner.rollout_in_progress
  }
}
```

두 리소스 섹션은 서로 용도가 다릅니다.

* `spec`은 러너를 설정합니다. 이 예제에서는 `spec.overrides.resources`로 러너 자체 파드의 크기를 지정하고, 유지보수 시간은 매주 토요일 오전 2시(UTC)에 시작됩니다.
* `policy`는 러너가 서빙하는 샌드박스를 설정합니다. 이 예제에서는 샌드박스 컨테이너마다 CPU와 메모리 한도를 지정하고, `max_gpu_count = 0`으로 GPU 사용을 금지하며, 기본 수명을 1시간으로 설정합니다. 기본 수명은 최대 수명이 아닙니다. 워크로드에 맞게 제약 조건을 조정하려면 [샌드박스 정책 설정](/ko/products/sandboxes/profiles/configure)을 참조하세요.

`policy` 객체는 필수입니다. 명시적인 빈 객체는 빈 정책을 의도한 경우에만 사용하세요. `zone` 값은 소문자여야 하며, `lower(var.zone)`을 사용하면 이 조건이 보장됩니다.

`[RUNNER-ID]`, `[CLUSTER-ID]`, `[ZONE]`을 각각 러너 식별자, CKS 클러스터 UUID, Availability Zone으로 바꾼 다음 값을 `terraform.tfvars` 파일에 저장하세요.

```terraform title="terraform.tfvars" theme={"system"}
runner_id  = "[RUNNER-ID]"
cluster_id = "[CLUSTER-ID]"
zone       = "[ZONE]"
```

## 롤아웃 적용 및 확인

설정을 적용하고 러너 롤아웃을 확인하려면 다음 단계를 완료하세요.

1. 공급자를 초기화하고 설정을 검증하세요.

   ```bash theme={"system"}
   terraform init
   terraform validate
   ```

2. 플랜을 검토하고 적용하세요.

   ```bash theme={"system"}
   terraform plan -out=runner.tfplan
   terraform apply runner.tfplan
   ```

   적용에 성공했다면 API가 설정을 수락했다는 뜻입니다. 러너 설치와 롤아웃은 비동기로 계속 진행됩니다.

3. 관측된 상태를 새로 고치고 출력을 확인하세요.

   ```bash theme={"system"}
   terraform plan -refresh-only -out=runner-status.tfplan
   terraform apply runner-status.tfplan
   terraform output runner_status
   ```

   `install_status`가 `RUNNER_INSTALL_STATUS_READY`이고, `connection_status`가 `RUNNER_CONNECTION_STATUS_CONNECTED`이며, `active_revision`이 `target_revision`과 같으면 러너가 준비 완료 상태입니다. 아직 프로비저닝 중이라면 롤아웃이 더 진행된 후 다시 새로 고치세요. 설치에 실패하면 계산된 `install_error` 속성에서 자세한 내용을 확인할 수 있습니다.

## 설정 업데이트

`main.tf` 파일에서 리소스를 편집하고 새 플랜을 검토한 다음 적용하세요. 이후에 적용할 때도 의도한 상태가 유지되도록, 원하는 정책 및 재정의 설정 전체를 Terraform에서 관리하세요. CLI 또는 API로 변경한 내용은 불일치로 표시될 수 있으며, 이후 Terraform을 적용하면 되돌려질 수 있습니다.

`spec` 내부의 선택 설정을 제거하면 명시적인 API 업데이트 마스크를 통해 해당 설정이 재설정됩니다. 재정의 값을 변경하면 `spec.overrides` 객체 전체가 대체되므로, 유지하려는 다른 재정의 값도 함께 남겨 두세요. 최종 확정된 `deployment_spec`은 읽기 전용입니다.

공급자는 정책 리비전 토큰(`etag`)을 사용하므로, 다른 곳에서 정책을 동시에 편집하면 적용이 실패할 수 있습니다. 재시도하기 전에 상태를 새로 고치고 새 플랜을 검토하세요. `runner_id`, `cluster_id` 또는 `zone`을 변경하면 러너가 기존 위치에서 업데이트되지 않고 새로 교체됩니다.

### 러너 선호도 설정

선호도를 사용하려면 `spec.overrides.affinity`가 포함된 공급자 릴리스가 필요합니다. 공급자 `0.26.0`에는 이 속성이 없습니다. 이 속성을 지원하는 버전이 나오기 전까지는 [REST 선호도 예시](/ko/products/sandboxes/operations/managed-runners#example-configure-runner-affinity)를 사용하세요. 이후 apply 과정에서 REST로 변경한 내용을 덮어쓰지 않도록 Terraform 설정과 맞춰 두세요.

지원되는 공급자를 설치했다면 다음 속성을 기존 `spec.overrides` 객체에 병합하세요. 예시 라벨은 클러스터의 노드에서 사용하는 라벨로 바꾸세요.

```terraform title="Affinity attribute inside spec.overrides" theme={"system"}
affinity = jsonencode({
  nodeAffinity = {
    preferredDuringSchedulingIgnoredDuringExecution = [{
      weight = 100
      preference = {
        matchExpressions = [{
          key      = "example.com/capacity-class"
          operator = "In"
          values   = ["on-demand"]
        }]
      }
    }]
  }
})
```

이 속성에는 노드 선호도, 파드 선호도, 파드 안티어피니티를 포함한 Kubernetes `Affinity` JSON을 지정할 수 있습니다. `jsonencode()` 내부의 키는 Kubernetes 카멜 케이스를 사용합니다. 이 선호(preferred) 규칙은 조건에 맞는 다른 노드도 계속 사용할 수 있도록 두므로 온디맨드 우선 배치를 보장하지 않습니다. 기존 노드 셀렉터와 톨러레이션은 그대로 적용됩니다.

선호도는 러너 파드에만 적용되며, 샌드박스 파드 배치나 [노드 할당 예산](/ko/products/sandboxes/operations/node-allocation-budgets)은 설정하지 않습니다.

선호도는 부분적으로 병합되지 않고 전체가 대체됩니다. 상속된 선호도를 포함한 모든 규칙을 지우려면 `affinity = jsonencode({})`로 설정하세요. 플랫폼 기본값으로 복원하려면 이 속성을 제거하세요. 두 경우 모두 `spec.overrides`에 있는 다른 속성 중 계속 필요한 속성은 그대로 두세요.

## 기존 러너 임포트하기

러너 설정 예시의 리소스와 변수를 정의하고, 적용하기 전에 정책과 사양을 기존 러너에 맞게 수정하세요. `[RUNNER-ID]`는 API 토큰에 연결된 조직의 러너 식별자로 바꾸세요.

```bash theme={"system"}
terraform init
terraform import coreweave_sandbox_managed_runner.runner '[RUNNER-ID]'
terraform plan
```

임포트하면 러너를 새로 생성하지 않고 기존 러너를 Terraform 상태에 기록합니다. 적용하기 전에 플랜을 검토하고 임포트된 값에 맞게 설정을 조정하세요. Terraform은 클러스터 UUID가 아닌 러너 식별자를 임포트 ID로 사용합니다.

## 러너 제거

설정에서 리소스와 해당 리소스를 가리키는 모든 참조(`runner_status` 출력 포함)를 제거하세요. 그런 다음 생성된 플랜을 검토하고 적용하세요. 리소스를 삭제하면 관리형 러너가 해제됩니다. 공급자는 삭제가 완료될 때까지 최대 30분간 기다린 후 상태에서 해당 리소스를 제거합니다.

## 참조

관련 워크플로와 레퍼런스 정보는 다음 페이지를 참조하세요.

* [관리형 러너 리소스 레퍼런스](/platform/terraform/resources/sandbox_managed_runner).
* [러너 배포 및 관리](/ko/products/sandboxes/operations/managed-runners).
* [샌드박스 정책 설정](/ko/products/sandboxes/profiles/configure).
