kupe_cluster
Manages a Kupe cluster for a tenant. Create and Update wait for the cluster to reach phase=Running before returning; Delete waits for the underlying ManagedCluster CR to finish terminating. Timeouts are configurable via the timeouts block (defaults: create/update 15m, delete 10m).
Destroy semantics
Section titled “Destroy semantics”terraform destroy (or removing this resource from configuration) is non-recoverable. When the cluster is deleted, the Kupe platform will:
- Permanently remove every workload running inside the cluster, along with its storage.
- Remove the cluster’s public DNS endpoint.
The same contract applies whether you delete via Terraform, the kupe CLI, or the Kupe Console.
Example Usage
Section titled “Example Usage”resource "kupe_cluster" "production" { name = "production" display_name = "Production" version = "1.32"
resources = { cpu = "4" memory = "16Gi" storage = "100Gi" }}
# HA cluster: 3 replicas, chart-managed external etcd StatefulSet, hard# anti-affinity, encrypted etcd at rest. Adds an hourly charge — see# your plan's HA rate.## `high_availability` is create-time-only. Changing this attribute on an# existing resource forces Terraform to replace (destroy + create) the# cluster — there is no in-place migration. Plan a blue-green swap via# GitOps if you need HA on an existing cluster.resource "kupe_cluster" "prod_eu1" { name = "prod-eu1" display_name = "Production EU1" version = "1.35" high_availability = true
resources = { cpu = "8" memory = "32Gi" storage = "200Gi" }}
# Expose the consumer-friendly rollup so downstream automation can branch# on operational state without inspecting individual conditions.output "prod_eu1_ha_phase" { description = "One of pending | ha-healthy | ha-degraded | ha-unavailable" value = kupe_cluster.prod_eu1.ha_phase}
output "prod_eu1_ha_ready" { description = "N of M control-plane replicas currently ready" value = "${kupe_cluster.prod_eu1.ha_replicas_ready} of ${kupe_cluster.prod_eu1.ha_replicas_desired}"}Schema
Section titled “Schema”Required
Section titled “Required”display_name(String) Human-readable display name (immutable after creation).name(String) Cluster name (immutable after creation).
Optional
Section titled “Optional”high_availability(Boolean) Enable a 3-replica HA control plane with HA etcd (chart-managed external etcd StatefulSet), hard anti-affinity, and encrypted-at-rest etcd via a per-cluster AES-CBC key. Adds an hourly charge — seedata.kupe_planfor the rate. Defaultfalse.
Create-time-only. This attribute is effectively immutable: changing it on an existing resource forces Terraform to replace the cluster (destroy + create). The operator rejects both directions of the toggle with canonical error codes (HA_ENABLE_ON_EXISTING_UNSUPPORTED, HA_DISABLE_UNSUPPORTED) — RequiresReplace here makes Terraform’s plan reflect that reality up front. Use a blue-green swap workflow if you need HA on an existing cluster: create a new HA cluster, redeploy via GitOps, swap traffic, then destroy the old.
resources(Attributes) Resource limits for the cluster. Updates send a partial PATCH that includes only the fields present in this block — fields you omit are left unchanged on the server. To change an individual field, write it explicitly. Removing the entireresourcesblock sends an emptyresourcesobject to the server to request clearing the limits. (see below for nested schema)timeouts(Attributes) (see below for nested schema)type(String, Deprecated) Deprecated. Cluster type. Onlysharedis supported today — the operator rejectsdedicatedwith the canonicalCLUSTER_DEDICATED_UNSUPPORTEDerror code. Leave unset (the provider defaults toshared) or omit from your configuration entirely. The attribute remains in the schema so that existing state migrates cleanly; future support for dedicated nodes will likely take a different shape (per-cluster node-pool reference) rather than reviving this enum.version(String) Kubernetes version (e.g., 1.31).
Read-Only
Section titled “Read-Only”created_at(String) Timestamp when the cluster was created.endpoint(String) Cluster API server endpoint.etag(String) Resource version used for optimistic locking during updates.ha_configured(Boolean) True once the operator has confirmed both 3/3 apiserver replicas AND 3/3 deployed-etcd replicas areReadyfor the first time. Etcd readiness is required because the OSS deployed-etcd path runs etcd in its own StatefulSet — quorum loss with healthy apiserver pods still blocks writes. Distinct fromhigh_availability(the requested state) — read this attribute when downstream automation needs to wait for HA to be operationally available, not just toggled on.ha_enabled_at(String) Timestamp whenha_configuredfirst became true. This is the billing anchor — HA hours accrue from this moment. Stamped once, never updated, never cleared.ha_etcd_replicas_desired(Number) Target HA etcd replica count (3 whenhigh_availability = true, 0 otherwise).ha_etcd_replicas_ready(Number) Count of deployed-etcd replicas currentlyReady. Exposed separately because the OSS deployed-etcd path runs etcd in its own StatefulSet — etcd quorum loss leaves the cluster unable to serve writes even when the apiserver replicas are healthy.ha_phase(String) Consumer-friendly HA rollup. One ofpending,ha-healthy,ha-degraded,ha-unavailable. Empty for non-HA clusters. Use this in downstream automation to branch on operational state without inspecting individual conditions.ha_replicas_desired(Number) Target HA replica count (3 whenhigh_availability = true, 0 otherwise).ha_replicas_ready(Number) Count of HA control-plane (apiserver) replicas currentlyReady. Zero for non-HA clusters.phase(String) Current cluster phase, for example Pending, Provisioning, Running, Upgrading, or Degraded.
Nested Schema for resources
Section titled “Nested Schema for resources”Optional:
cpu(String) CPU limit (e.g., 4, 500m).memory(String) Memory limit (e.g., 16Gi, 512Mi).storage(String) Storage limit (e.g., 100Gi).
Nested Schema for timeouts
Section titled “Nested Schema for timeouts”Optional:
create(String) A string that can be parsed as a duration consisting of numbers and unit suffixes, such as ”30s” or “2h45m”. Valid time units are “s” (seconds), “m” (minutes), “h” (hours).delete(String) A string that can be parsed as a duration consisting of numbers and unit suffixes, such as ”30s” or “2h45m”. Valid time units are “s” (seconds), “m” (minutes), “h” (hours). Setting a timeout for a Delete operation is only applicable if changes are saved into state before the destroy operation occurs.update(String) A string that can be parsed as a duration consisting of numbers and unit suffixes, such as ”30s” or “2h45m”. Valid time units are “s” (seconds), “m” (minutes), “h” (hours).
Import
Section titled “Import”Import is supported using the following syntax:
The terraform import command can be used, for example:
terraform import kupe_cluster.production production