'Resource Management'
Overview
This guide walks through adding a Kubernetes manifest and a Helm release to a cluster, previewing changes before they apply, and cleanly removing a resource later. See Cluster Resources for the concepts and full schema reference.
Declare a manifest resource
Add a resources entry to a cluster (or template) YAML, pointing at a local manifest file:
spec: resources: - name: nginx-ingress source: ./resource-files/nginx-ingress.yaml namespace: ingress-nginxapiVersion: apps/v1kind: Deploymentmetadata: name: nginx-ingress-controllerspec: replicas: 2 # ...---apiVersion: v1kind: Servicemetadata: name: nginx-ingress-controllerspec: type: LoadBalancer # ...A source can also be a remote reference — useful for sharing a manifest across repositories, the same way remote workflow references work:
- name: cert-manager-crds source: github.com/myorg/manifests//cert-manager/crds.yaml@v1.14.0Commit and run:
hyve reconcile[production] Resource nginx-ingress: drift detected (config changed) — applyingspec.appliedResources is now populated and committed (to cluster-state/production.state.yaml, not production.yaml itself — see Reconciler state file) — inspect it any time with:
hyve cluster resources productionDeclare a Helm resource
spec: resources: - name: cert-manager helm: chart: cert-manager repo: https://charts.jetstack.io version: v1.14.0 namespace: cert-manager values: installCRDs: "true"The next reconcile runs helm upgrade --install. Changing values, version, or chart is detected the same way a manifest content change is — it’s hashed and compared, triggering a re-apply.
Declare a secret resource
Unlike a manifest or Helm resource, a secret: resource’s values don’t come from anything committed to Git — they’re resolved from whatever environment hyve reconcile (or hyve serve) is actually running in:
spec: resources: - name: github-secrets secret: namespace: default keys: [PANGOLIN_ENDPOINT, NEWT_ID, NEWT_SECRET]Get those three variables into the reconciling process’s environment first — a CI job’s env: block, a local export, however you’re running Hyve — then reconcile:
hyve reconcile[production] Resource github-secrets: drift detected (config changed) — applyingIf a listed variable isn’t set, the resource fails loudly instead of applying a partial Secret:
[production] reconcile error: resource github-secrets: render secret failed: secret resource: missing required environment variable(s): NEWT_SECRETTo store a value under a different key than the environment variable it came from — e.g. because a chart expects a fixed key name — use the {env, key} mapping form for that entry:
spec: resources: - name: portainer-admin-password secret: namespace: portainer keys: - {env: PORTAINER_PASSWORD, key: password}Preview before applying
hyve reconcile --dry-run resolves and diffs everything for real (both read-only) but skips every mutating call — nothing is applied, deleted, or committed:
hyve reconcile --dry-run[production] DRY RUN: resource nginx-ingress drift detected (config changed) — would apply[production] DRY RUN: resource cert-manager drift detected (live drift) — would apply[production] DRY RUN: 2 resource(s) with drift, 0 unchangedThis is whole-cycle read-only, not just resources — a not-yet-created cluster is reported as “would create”, not actually created, so --dry-run is safe to run broadly rather than only against clusters you already know are ACTIVE.
Removing a resource
Prefer marking it for deletion over just deleting the YAML block:
spec: resources: - name: nginx-ingress source: ./resource-files/nginx-ingress.yaml namespace: ingress-nginx delete: truehyve reconcile[production] Resource nginx-ingress: delete:true — removing 2 tracked object(s)The next commit shows the resource entry gone from spec.resources entirely — Hyve removes it automatically once deletion succeeds, the same way a cluster’s own YAML file disappears once spec.delete: true finishes processing.
If you remove the YAML block directly instead (skipping delete: true), Hyve treats it as an orphan and — by default — only warns:
[production] Warning: resource "nginx-ingress" is orphaned (removed from spec.resources without delete:true) — set delete:true to remove it, or reconcile.strictResourceDelete: true to auto-pruneSet reconcile.strictResourceDelete: true in hyve.yaml if you want orphans pruned automatically instead of just flagged — see Cluster Resources → Removing a resource for the full safety rationale.
For a secret: resource specifically, you don’t need delete: true to drop just one key — remove it from keys: and reconcile; it’s actually removed from the live Secret, not left stale. See Dropping one key from a Secret resource.
Troubleshooting
Resource keeps re-applying every reconcile
Check kubectl diff --server-side -f <manifest> yourself — something outside Hyve (another controller, a mutating webhook that rewrites a field) is likely fighting with the applied state. Server-side apply’s field ownership can also cause this if another tool applies the same fields with a different field manager.
"exactly one of source, helm, or secret must be set"
A resource entry needs exactly one of source, helm, or secret — not two, not zero. Check for a typo (e.g. Source vs source — YAML is case-sensitive) or a stray block left over from converting a resource from one kind to another.
Resource source resolves to a directory error
source must name a single file — .yaml/.yml suffix required for a remote ref. There’s no directory-expansion form for resources (unlike remote workflow installs) — split a directory of manifests into individual resources entries instead.
secret resource: missing required environment variable(s)
One or more names in keys: aren’t set in the environment hyve reconcile/hyve serve is actually running in. This is a hard error by design — a secret: resource never applies a Secret with fewer keys than declared. Set the variable in whatever’s running Hyve (CI job env:, local export, server container env) and reconcile again.
helm: command not found
Install helm on the machine (or CI runner) that runs hyve reconcile — Hyve doesn’t install tools for you, the same as kubectl.