# Confighub Confighub Skills Config As Data

> config-as-data

- Skill: `tomevault-io/confighub-confighub-skills-config-as-data` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/confighub-confighub-skills-config-as-data`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/confighub-confighub-skills-config-as-data/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/confighub-confighub-skills-config-as-data

---


# config-as-data

Authoring discipline for Kubernetes configuration stored in ConfigHub.

## The rule

A ConfigHub Unit contains **fully materialized YAML with literal values for every field**. Code (functions) operates on data. Data is the source of record. This is not a style preference — it's what makes ConfigHub's query, validation, mutation-graph, and revision-history features work. Re-rendered or templated Units break all of those.

If you're tempted to reach for Helm, Kustomize, Jsonnet, cdk8s, or a values file to _author_ new configuration for ConfigHub, stop and re-read this skill.

## When to use

- User is creating a new Kubernetes resource to store in a Unit.
- User is about to add a Helm chart or Kustomize overlay to a Unit's source.
- User asks how to "parameterize" a Unit, share config across environments, or keep a values file alongside YAML.
- User asks how to do something "like Helm values" or "like Kustomize overlays" in ConfigHub.
- User starts templating YAML (`{{ .Values.x }}`, `${VAR}`, `<% %>`) that will end up in a Unit.

## Do not load for

- One-shot `import-from-helm` / `import-from-kustomize` (those skills render once, then this discipline takes over for subsequent edits).
- Authoring config that will live in git or a chart repo, not in ConfigHub.
- Pure read / query tasks.

## Preflight gates

1. `cub organization list` succeeds (proves a valid token; `cub context get` / `cub info` / `cub version` don't require one) and `cub context get` returns a default space.
2. User has write permission on the target Space.
3. If authoring new config, confirm with the user which Space this Unit belongs to. Best practice: one Space per app × environment/region.

## The loop

### 1. Establish intent — authoring or migrating?

- **New resource from scratch.** Go to step 2.
- **Migrating existing Helm/Kustomize.** The right skill is `import-from-helm` or `import-from-kustomize` (future). If those aren't available, render once with `helm template` or `kustomize build`, strip runtime-only fields, and store the output as a Unit — then never re-render.

### 2. Produce literal YAML

First, check if the `skill-examples` Space has a relevant example Unit to use as a starting point:

```bash
cub unit get <example-slug> --space skill-examples -o yaml 2>/dev/null
```

The `skill-examples-bootstrap` skill seeds Units for common resource types (`hello-app`, `hello-statefulset`, `hello-daemonset`, `hello-job`, `hello-cronjob`, `hello-ingress`, `hello-netpol`, `hello-rbac`, `hello-hpa`, `hello-pdb`). If a matching example exists, adapt it. If not, scaffold from Kubernetes or hand-author:

```bash
kubectl create deployment my-app --image=confighubplaceholder:confighubplaceholder \
  --dry-run=client -o yaml \
  | yq 'del(.metadata.creationTimestamp, .status)' > my-app.yaml
```

Use `confighubplaceholder` for string fields and `999999999` for numeric fields that need to be supplied later. `vet-placeholders` will block apply while any remain.

For fields `kubectl create` doesn't cover, hand-author literal YAML — don't template. Consult `references/yaml-patterns.md` for common shapes. For specific resource types (StatefulSet, Ingress, NetworkPolicy, etc.), use the `kubernetes-resources` skill.

### 3. Store in a Unit

```bash
cub unit create --space <space> <unit-slug> my-app.yaml \
  --change-desc "<summary>

User prompt: <verbatim>
Clarifications: <condensed or 'none'>"
```

### 4. Fill in defaults via functions (not by hand)

Prefer the defaults functions over hand-editing — they're hermetic, idempotent, and record a clean revision:

```bash
cub function set --space <space> --unit <unit-slug> \
  set-container-resources-defaults --change-desc "..."

cub function set --space <space> --unit <unit-slug> \
  set-container-probe-defaults --change-desc "..."

cub function set --space <space> --unit <unit-slug> \
  set-pod-container-security-context-defaults --change-desc "..."
```

For Namespaces: `set-pod-security-defaults`. To guarantee `namespace:` is set: `ensure-namespaces`.

### 5. Make env-specific variations via Units, not templates

To vary config across environments:

- Create one Space per app × environment/region.
- Use upstream → downstream Unit relationships to clone baseline.
- Apply differences via functions: `set-container-image`, `set-replicas`, `set-env-var`, etc. — each recorded as a revision.

Don't introduce a values file. Don't introduce an overlay. The Space is the parameterization boundary.

For deeper guidance on Space layout (app-home Spaces, per-env Spaces, platform Spaces, naming conventions, and the upstream/downstream topology), load `space-topology`.

## Tool boundary

- Allowed: `cub` (mutations), `kubectl create --dry-run=client` and `kubectl explain` (scaffolding only), reading existing chart/overlay content for one-shot import.
- Not allowed: `helm install/upgrade`, `kustomize build` piped into ongoing editing, writing values files alongside a Unit's YAML, introducing template syntax into a Unit's data.

## Change description

Every `cub unit create`, `cub unit update`, `cub function set`, `cub run` call must pass `--change-desc`:

```
<summary line>

User prompt: <verbatim user prompt>
Clarifications: <condensed: "user confirmed target env is prod" / "user chose bundle granularity per-app" / "none">
```

## Stop conditions

- User insists on keeping a values file or template in the Unit. Explain the rule once; if they still want it, stop and hand back — this isn't the skill for that.
- Required field can only be filled correctly at apply time (e.g., a rendered secret from an external system). Use a placeholder + a function that fills it at apply — don't template.

## Verify chain

1. `cub unit get <slug> --space <space>` — inspect the stored YAML; confirm it is literal.
2. If the Space has validation Triggers wired up (see `triggers-and-applygates` for the setup), every `cub unit create` / `cub unit update` / `cub functionset` / `cub run` already runs them against the new revision — no extra step needed. If not, run the vet functions directly:
   - `cub function vet --space <space> --unit <slug> vet-placeholders` — no remaining placeholders (unless intentional for later fill).
   - `cub function vet --space <space> --unit <slug> vet-schemas` — valid against the target K8s version.
   - `cub function vet --space <space> --unit <slug> vet-format` — clean YAML.
3. To re-run a specific Trigger against a Unit — useful for validators whose arguments are awkward to retype on the CLI, like `vet-cel` and `vet-starlark`, where the configured Trigger already carries the CEL/Starlark expression:

   ```bash
   cub function vet --space <space> --unit <slug> --trigger <trigger-space>/<trigger-slug>
   ```

   The Trigger supplies the function name and its arguments, so the result matches what automatic validation would produce on a write. Less valuable for validators that take no arguments (`vet-schemas`, `vet-placeholders`, `vet-format`) — just call those directly.

## Evidence

- `cub unit get <slug> --space <space> --web` — opens the Unit in the GUI so the user can see the literal YAML and revision history.

## References

- `references/cub-cli.md`
- `references/functions-catalog.md`
- `references/yaml-patterns.md` — ConfigHub-native YAML patterns for all common resource types.
- Companion skills: `kubernetes-resources` (authoring specific resource types), `space-topology` (Space layout, upstream/downstream conventions), `triggers-and-applygates` (automatic validation on writes, running Triggers explicitly), `skill-examples-bootstrap` (seeds live examples in `skill-examples` Space).
- https://docs.confighub.com/markdown/background/config-as-data.md

---
> Source: [confighub/confighub-skills](https://github.com/confighub/confighub-skills) — distributed by [TomeVault](https://tomevault.io).
<!-- tomevault:4.0:skill_md:2026-05-22 -->

