Valkey Factories
Factory functions for the Hyperspike Valkey operator with built-in readiness evaluation. Manage Valkey clusters as Kubernetes-native resources.
The integration provisions Valkey infrastructure. Application data-plane behavior—commands, Streams consumer groups, acknowledgements, retries, and dead-letter policy—belongs in the application or framework using a Valkey client, not in TypeKro.
Import
// Import specific functions (recommended)
import { valkey } from 'typekro/valkey';
// Or namespace import
import * as valkeyModule from 'typekro/valkey';Quick Example
import { valkey } from 'typekro/valkey';
const cache = valkey({
name: 'app-cache',
namespace: 'default',
spec: {
shards: 3,
replicas: 1,
volumePermissions: true,
storage: {
spec: {
storageClassName: 'gp3',
resources: { requests: { storage: '10Gi' } },
},
},
resources: {
requests: { cpu: '250m', memory: '512Mi' },
limits: { cpu: '1', memory: '2Gi' },
},
prometheus: true,
},
id: 'appCache',
});Available Factories
| Factory | Kind | Scope | Description |
|---|---|---|---|
valkey | Valkey | Namespace | Valkey cluster (sharded with optional replicas) |
valkeyHelmRepository | HelmRepository | Namespace | OCI Helm registry for the operator |
valkeyHelmRelease | HelmRelease | Namespace | Operator installation via Helm |
valkeyBootstrap / valkeyOperatorInstallation | Composition | Cluster infrastructure | Complete, explicitly owned operator installation |
valkeyHelmRepositoryBootstrap | Composition | Cluster singleton | Shared OCI repository owner |
valkey()
Creates a Valkey cluster managed by the Hyperspike operator.
const cache = valkey({
name: 'prod-cache',
namespace: 'caching',
spec: {
// Cluster topology
shards: 3, // Number of primary nodes (default: 3)
replicas: 1, // Replicas per shard (default: 0)
// Storage
volumePermissions: true,
storage: {
spec: {
storageClassName: 'gp3',
resources: { requests: { storage: '50Gi' } },
},
},
// Resources
resources: {
requests: { cpu: '500m', memory: '1Gi' },
limits: { cpu: '2', memory: '4Gi' },
},
// Security
tls: true,
certIssuer: 'letsencrypt-prod',
certIssuerType: 'ClusterIssuer',
anonymousAuth: false,
servicePassword: { name: 'valkey-secret', key: 'password' },
// Monitoring
prometheus: true,
serviceMonitor: true,
prometheusLabels: { prometheus: 'kube-prometheus' },
// External access via Envoy proxy
externalAccess: {
enabled: true,
type: 'Proxy',
proxy: {
replicas: 2,
hostname: 'valkey.example.com',
},
},
// Scheduling
nodeSelector: { 'node-type': 'cache' },
tolerations: [{
key: 'dedicated',
operator: 'Equal',
value: 'cache',
effect: 'NoSchedule',
}],
},
id: 'prodCache',
});Hyperspike replica behavior
Hyperspike v0.0.61 documents that replicas currently creates additional primary nodes rather than replicas. Track upstream issue #186 before relying on this field for high availability. This is especially important for durable Valkey Streams queues.
Valkey Readiness
The readiness evaluator checks the Hyperspike status model:
| State | Ready | Reason |
|---|---|---|
status.ready: true | true | Ready |
status.ready: false with condition | false | Condition reason (e.g., ShardsNotReady) |
status.ready: false without condition | false | NotReady |
No ready field | Falls back to condition-based evaluation | |
| Missing status | false | StatusMissing |
External Access Modes
- Proxy (default) — Envoy proxy for external connections with optional TLS
- LoadBalancer — Kubernetes LoadBalancer service per shard
Bootstrap Composition
Install the Hyperspike Valkey operator via Helm:
import { valkeyBootstrap } from 'typekro/valkey';
// 'kro' = KRO mode — creates a ResourceGraphDefinition for continuous reconciliation
// 'direct' = Direct mode — applies resources immediately without KRO controller
const factory = valkeyBootstrap.factory('kro', {
namespace: 'valkey-operator-system', // Where the operator pods run
waitForReady: true,
});
await factory.deploy({
name: 'valkey-operator',
namespace: 'valkey-operator-system', // Owned child: operator pods run here
values: {
nodeSelector: { 'kubernetes.io/os': 'linux' },
},
});valkeyBootstrap creates and owns the operator namespace as a graph child. If it stayed a graph child, KRO would delete that namespace when the instance is deleted — potentially deleting the instance before KRO clears its finalizer and deadlocking namespace termination. TypeKro therefore auto-detects the ownership and hoists the owned Namespace out of the RGD graph, emitting it as a retained resource created outside the graph (deps-first); the instance CR stays in its natural namespace. Direct mode has no KRO custom-resource finalizer and is unaffected.
values is the raw Helm passthrough and merges last. The older customValues field remains as a deprecated compatibility alias; when both are present, values wins. The Flux OCI HelmRepository is owned by the complete bootstrap and defaults to the operator namespace. Custom repositoryName, repositoryNamespace, and repositoryUrl values are propagated to the HelmRelease source reference. The official chart remains the sole owner of its cluster-wide RBAC; TypeKro does not duplicate those resources.
The bootstrap has an explicit owner lifecycle: deleting its KRO instance uninstalls the operator. Application compositions that share one cluster operator should wrap valkeyBootstrap with TypeKro's singleton() using concrete, graph-authoring-time settings. Deleting an application then removes only the singleton reference, not the operator owner.
Bootstrap Status
instance.status.ready // boolean — operator is running
instance.status.phase // 'Ready' | 'Installing' | 'Failed'
instance.status.failed // boolean — true if Ready condition is explicitly False
instance.status.version // deployment-time version; default is normalized to v0.0.61If failed is true, check the HelmRelease conditions directly for controller-specific failure details.
Usage in Compositions
import { type } from 'arktype';
import { kubernetesComposition } from 'typekro';
import { Deployment, Service } from 'typekro/simple';
import { valkey } from 'typekro/valkey';
const AppWithCache = kubernetesComposition({
name: 'app-with-cache',
kind: 'AppWithCache',
spec: type({ name: 'string', image: 'string' }),
status: type({ ready: 'boolean', cacheReady: 'boolean' }),
}, (spec) => {
const cache = valkey({
id: 'cache',
name: `${spec.name}-cache`,
spec: { shards: 3, volumePermissions: true },
});
const deploy = Deployment({
id: 'app',
name: spec.name,
image: spec.image,
env: {
VALKEY_HOST: `${spec.name}-cache`,
VALKEY_PORT: '6379',
},
});
return {
ready: deploy.status.readyReplicas > 0,
cacheReady: cache.status.ready,
};
});Prerequisites
The Hyperspike Valkey operator must be installed. Use the valkeyBootstrap composition or install manually:
LATEST=$(curl -s https://api.github.com/repos/hyperspike/valkey-operator/releases/latest | jq -cr .tag_name)
helm install valkey-operator \
--namespace valkey-operator-system \
--create-namespace \
oci://ghcr.io/hyperspike/valkey-operator \
--version ${LATEST}-chartFor TLS support, cert-manager must be installed with an appropriate certificate issuer.
Valkey Streams queues
This factory is suitable for provisioning the Valkey service behind an application queue, including persistent storage, authentication, TLS, resource limits, and scheduling. TypeKro intentionally does not expose XADD, consumer-group, acknowledgement, retry, or dead-letter APIs. Those semantics should be implemented by the application layer using a Valkey-compatible client.
Hyperspike v0.0.61 is not a durable queue provider. Its generated valkey.conf enables periodic RDB snapshots but sets appendonly no, and the CRD does not expose a server-config override. A pod failure can therefore lose writes since the latest snapshot. TypeKro's live integration verifies ordinary commands and Streams plus explicit-RDB restart recovery, but it does not claim AOF or queue-grade durability. Use this provider for caches and workloads that accept that recovery point; use a configurable Valkey provider (or an upstream operator release with AOF configuration) before backing an authoritative queue.
The operator-generated password Secret uses the Valkey resource name and the password key when anonymousAuth is false and servicePassword is omitted, per the v0.0.61 CRD contract.
Next Steps
- Kubernetes Factories — Core Kubernetes resources
- CloudNativePG — PostgreSQL cluster management
- Cert-Manager — TLS certificate management
- Hyperspike Documentation — Upstream reference