Skip to main content
The Runpod Terraform provider lets you manage Runpod infrastructure declaratively using HashiCorp Terraform. Define pods, serverless endpoints, templates, and machines in HCL configuration files, apply them with terraform apply, and track state like any other Terraform-managed resource.

Prerequisites

Install and configure

Add the provider to your configuration

Create a main.tf file and declare the Runpod provider:
terraform {
  required_providers {
    runpod = {
      source  = "runpod/runpod"
      version = "~> 1.0"
    }
  }
}

provider "runpod" {
  api_key = var.runpod_api_key
}

Set your API key

The recommended approach is to pass your API key as an environment variable so it stays out of your configuration files:
export RUNPOD_API_KEY="your-api-key-here"
Or declare it as a Terraform variable and pass it at apply time:
variable "runpod_api_key" {
  description = "Runpod API key"
  type        = string
  sensitive   = true
}
terraform apply -var="runpod_api_key=your-api-key-here"

Initialize and apply

terraform init
terraform plan
terraform apply

Quick example: create a pod

This example creates a GPU pod running Miniconda with SSH enabled:
terraform {
  required_providers {
    runpod = {
      source  = "runpod/runpod"
      version = "~> 1.0"
    }
  }
}

provider "runpod" {
  api_key = var.runpod_api_key
}

variable "runpod_api_key" {
  type      = string
  sensitive = true
}

resource "runpod_pod" "my_pod" {
  image_name  = "runpod/miniconda:py3.10-cuda11.8.0"
  gpu_count   = 1
  gpu_type_id = "NVIDIA GeForce RTX 4090"
  cloud_type  = "SECURE"
  start_ssh   = true

  env = [
    "MY_VAR=hello"
  ]
}

output "pod_id" {
  value = runpod_pod.my_pod.id
}

output "pod_status" {
  value = runpod_pod.my_pod.status
}

Resources

runpod_pod

Creates and manages a Runpod pod.
resource "runpod_pod" "example" {
  image_name  = "runpod/miniconda:py3.10-cuda11.8.0"
  gpu_count   = 1
  gpu_type_id = "NVIDIA GeForce RTX 4090"
  cloud_type  = "SECURE"
  start_ssh   = true
}
Arguments
ArgumentTypeRequiredDescription
image_namestringOptional*Docker image name. Required if template_id is not set.
template_idstringOptional*Pod template ID. Required if image_name is not set.
machine_idstringOptionalMachine ID to deploy on.
gpu_type_idstringOptionalGPU type ID. Auto-selected if omitted.
gpu_countnumberOptionalNumber of GPUs. Default: 1.
cloud_typestringOptionalCOMMUNITY, SECURE, or ALL. Default: SECURE.
namestringOptionalPod name.
docker_argsstringOptionalDocker arguments.
envlist(string)OptionalEnvironment variables as ["KEY=VALUE", ...].
portnumberOptionalMain port for the pod.
portsstringOptionalPort configuration string (e.g. "8080/http,22/tcp").
volume_in_gbnumberOptionalPersistent volume size in GB.
volume_mount_pathstringOptionalPath to mount the volume inside the container.
volume_keystringOptionalVolume encryption key (sensitive).
container_disk_in_gbnumberOptionalContainer disk size in GB.
start_sshboolOptionalStart SSH on boot. Default: false.
start_jupyterboolOptionalStart Jupyter notebook on boot. Default: false.
bid_per_gpunumberOptionalBid price per GPU for interruptible (spot) pods.
stop_afterstringOptionalAuto-stop timestamp in ISO 8601 format.
terminate_afterstringOptionalAuto-terminate timestamp in ISO 8601 format.
Attributes (read-only)
AttributeDescription
idPod ID assigned after creation.
statusCurrent pod status.
cost_per_hrCost per hour.
memory_in_gbMemory allocated in GB.
vcpu_countVirtual CPU count.
cluster_ipCluster IP address.
created_atCreation timestamp.
lockedWhether the pod is locked.

runpod_pod_action

Performs an action on an existing pod. Use this to stop, resume, terminate, or reset a pod without destroying and recreating it.
resource "runpod_pod_action" "stop" {
  pod_id = runpod_pod.example.id
  action = "stop"
}
Arguments
ArgumentTypeRequiredDescription
pod_idstringRequiredID of the pod to act on.
actionstringRequiredAction to perform: stop, resume, terminate, or reset.
Attributes (read-only)
AttributeDescription
statusPod status after the action completes.

runpod_template

Creates and manages a reusable pod template. Templates let you define a standard configuration (image, environment variables, disk, ports) once and reuse it across multiple pods or endpoints.
resource "runpod_template" "my_template" {
  name       = "my-vllm-template"
  image_name = "runpod/worker-vllm:stable-cuda12.1.0"

  env = {
    MODEL_NAME = "meta-llama/Llama-3.1-8B-Instruct"
  }

  container_disk_in_gb = 20
  is_serverless        = true
}
Arguments
ArgumentTypeRequiredDescription
namestringRequiredTemplate name.
image_namestringRequiredDocker image name.
categorystringOptionalNVIDIA, AMD, or CPU.
container_disk_in_gbnumberOptionalContainer disk size in GB.
container_registry_auth_idstringOptionalRegistry auth ID for private images.
docker_entrypointlist(string)OptionalDocker entrypoint array.
docker_start_cmdlist(string)OptionalDocker start command array.
envmap(string)OptionalEnvironment variables as a key-value map.
is_publicboolOptionalMake the template publicly visible.
is_serverlessboolOptionalMark template as serverless.
portslist(string)OptionalPorts array.
volume_in_gbnumberOptionalVolume size in GB.
volume_mount_pathstringOptionalVolume mount path.
readmestringOptionalTemplate documentation.
Attributes (read-only)
AttributeDescription
idTemplate ID.
is_runpodWhether it’s an official Runpod template.
earnedCredits earned from template usage.
runtime_in_minRuntime in minutes.

runpod_endpoint

Creates and manages a serverless endpoint. Endpoints auto-scale workers based on demand.
resource "runpod_endpoint" "my_endpoint" {
  template_id  = runpod_template.my_template.id
  name         = "my-llm-endpoint"
  workers_min  = 0
  workers_max  = 3
  idle_timeout = 5
  gpu_count    = 1

  env = {
    MODEL_NAME = "meta-llama/Llama-3.1-8B-Instruct"
  }
}
Arguments
ArgumentTypeRequiredDescription
template_idstringRequiredTemplate ID for the endpoint.
namestringOptionalEndpoint name.
workers_minnumberOptionalMinimum number of workers (0 = scale to zero).
workers_maxnumberOptionalMaximum number of workers.
idle_timeoutnumberOptionalIdle timeout in minutes before scaling down.
gpu_countnumberOptionalNumber of GPUs per worker.
compute_typestringOptionalGPU or CPU.
network_volume_idstringOptionalSingle network volume ID to attach.
network_volume_idslist(string)OptionalMultiple network volume IDs to attach.
envmap(string)OptionalEnvironment variables as a key-value map.
data_center_idslist(string)OptionalRestrict workers to specific data center IDs.
Attributes (read-only)
AttributeDescription
idEndpoint ID.
created_atCreation timestamp.
versionEndpoint version.
template_versionTemplate version in use.
usersUser IDs with access to this endpoint.
workersList of active workers (id, pod_id, status, uptime_ms, start_time, last_busy_ms).

runpod_machine

Manages a machine listing. Primarily used by host providers to list machines and set pricing.
resource "runpod_machine" "my_machine" {
  gpu_type_id        = "NVIDIA GeForce RTX 4090"
  gpu_count          = 1
  secure_cloud       = true
  listed             = true
  host_price_per_gpu = 0.39
}
Arguments
ArgumentTypeRequiredDescription
gpu_type_idstringRequiredGPU type ID.
namestringOptionalMachine name.
gpu_countnumberOptionalNumber of GPUs. Default: 1.
cpu_countnumberOptionalNumber of CPUs.
memory_in_gbnumberOptionalMemory in GB.
disk_in_gbnumberOptionalDisk size in GB.
data_center_idstringOptionalData center ID.
locationstringOptionalLocation/country code.
secure_cloudboolOptionalUse Secure Cloud. Default: false.
listedboolOptionalList machine for others to use. Default: true.
host_price_per_gpunumberOptionalYour host price per GPU.
bid_price_per_gpunumberOptionalBid price per GPU.
Attributes (read-only)
AttributeDescription
idMachine ID.
verifiedWhether the machine is verified.
maintenance_modeWhether the machine is in maintenance mode.

Data sources

runpod_gpu_types

Lists all available GPU types with pricing information.
data "runpod_gpu_types" "available" {}

output "gpus" {
  value = data.runpod_gpu_types.available
}
Attributes
AttributeDescription
idGPU type ID.
display_nameGPU display name (e.g. NVIDIA GeForce RTX 4090).
manufacturerGPU manufacturer.
memory_in_gbVRAM in GB.
cuda_coresCUDA core count.
secure_cloudWhether available in Secure Cloud.
secure_priceSecure Cloud price per hour.
community_priceCommunity Cloud price per hour.

runpod_data_centers

Lists all available data centers.
data "runpod_data_centers" "all" {}
Attributes
AttributeDescription
idData center ID (e.g. US-TX-3).
nameData center name.
locationGeographic location.
global_networkWhether global network is enabled.

runpod_pod

Retrieves information about an existing pod by ID.
data "runpod_pod" "existing" {
  id = "abc123"
}
Arguments
ArgumentTypeRequiredDescription
idstringRequiredPod ID to look up.

runpod_machine

Retrieves information about a specific machine by ID.
data "runpod_machine" "host" {
  id = "machine-id"
}
Arguments
ArgumentTypeRequiredDescription
idstringRequiredMachine ID to look up.

runpod_machines

Lists machines, optionally filtered by listed status.
data "runpod_machines" "listed" {
  listed = true
}
Arguments
ArgumentTypeRequiredDescription
listedboolOptionalFilter by listed status.

runpod_template

Retrieves information about a template by ID.
data "runpod_template" "vllm" {
  id = "template-id"
}
Arguments
ArgumentTypeRequiredDescription
idstringRequiredTemplate ID to look up.

runpod_user

Retrieves information about the authenticated user.
data "runpod_user" "me" {}

output "ssh_key" {
  value = data.runpod_user.me.pub_key
}

Complete example: serverless endpoint

This example creates a template and a serverless endpoint for a vLLM worker, then outputs the endpoint ID.
terraform {
  required_providers {
    runpod = {
      source  = "runpod/runpod"
      version = "~> 1.0"
    }
  }
}

provider "runpod" {
  api_key = var.runpod_api_key
}

variable "runpod_api_key" {
  type      = string
  sensitive = true
}

resource "runpod_template" "vllm" {
  name       = "llama-vllm"
  image_name = "runpod/worker-vllm:stable-cuda12.1.0"

  env = {
    MODEL_NAME      = "meta-llama/Llama-3.1-8B-Instruct"
    HF_TOKEN        = var.hf_token
    MAX_MODEL_LEN   = "8192"
  }

  container_disk_in_gb = 20
  is_serverless        = true
}

variable "hf_token" {
  type      = string
  sensitive = true
}

resource "runpod_endpoint" "llm" {
  template_id  = runpod_template.vllm.id
  name         = "llama-3-1-8b"
  workers_min  = 0
  workers_max  = 5
  idle_timeout = 5
  gpu_count    = 1
}

output "endpoint_id" {
  value       = runpod_endpoint.llm.id
  description = "Endpoint ID — use in API requests as /v2/{endpoint_id}/run"
}
Run it:
terraform apply \
  -var="runpod_api_key=$RUNPOD_API_KEY" \
  -var="hf_token=$HF_TOKEN"