Customization Guide

Customization Guide

All site-specific deployment parameters flow from config/organization.yaml. This guide explains the current structure, how the repo uses it, and how to adapt it for a local-first deployment model.

config/organization.yaml As The Shared Config Surface

Rather than scattering core site identity across tfvars, app config, and docs, the repo keeps a shared operator config in config/organization.yaml.

The file does not replace stack tfvars. It provides the shared environment and cluster identity that the stack-specific tfvars build on top of.

Current Configuration Shape

Representative example:

organization:
  name: acme-corp
  full_name: "Acme Corp"
  group_path: acme-corp

clusters:
  - name: dev
    role: development
    physical_cluster: honey
    domain: dev.example.com
    context: honey
    kubeconfig_path: ~/.kube/kubeconfig-honey.yaml

  - name: prod
    role: production
    physical_cluster: honey
    domain: example.com
    context: honey
    kubeconfig_path: ~/.kube/kubeconfig-honey.yaml

namespaces:
  attic:
    dev: nix-cache
    prod: nix-cache
  arc_systems:
    all: arc-systems
  arc_runners:
    all: arc-runners
  dashboard:
    all: runner-dashboard
  gitlab_runners:
    all: gitlab-runners

network:
  management_plane: tailnet-private
  private_api_server: https://100.113.89.12:6443
  magicdns_zone: taila4c78d.ts.net

legacy_compatibility:
  civo:
    context: tinyland-civo-dev
    kubeconfig_path: ~/.kube/kubeconfig-civo.yaml

gitlab:
  url: https://gitlab.com
  project_id: ""
  agent_group: ""

Key Ideas

Logical Environments Versus Physical Cluster

clusters[].name is a logical deployment environment key used by:

  • ENV=dev or ENV=prod recipe selection
  • per-stack {env}.tfvars
  • generated dashboard environment config

It does not have to mean a separate physical cluster.

For the current on-prem target:

  • dev can map to physical_cluster: honey
  • prod can also map to physical_cluster: honey
  • both can use context: honey

That keeps environment intent and rollout separation without inventing fake extra clusters.

Namespace Split

The namespace block should make the platform boundary obvious:

  • attic.* for cache
  • arc_systems.all and arc_runners.all for the primary GitHub runner story
  • dashboard.all for the operator surface
  • gitlab_runners.all only for the residual legacy GitLab runner path

For the current Tinyland honey rollout, the live cache runtime already uses nix-cache. It is acceptable for multiple logical environments to map to that same cache namespace when you are documenting or operating the current local cluster truth rather than a hypothetical future split.

Compatibility Blocks

Keep residual non-primary inputs isolated:

  • legacy_compatibility.civo for tinyland-civo-dev (decommissioned April 2026)
  • gitlab.* only when GitLab-backed state or access compatibility is still needed

Do not copy those values into the primary on-prem environment entries unless you are intentionally using the compatibility path.

Common Customizations

Use honey As The Only Physical Cluster

This is the recommended current on-prem model:

clusters:
  - name: dev
    physical_cluster: honey
    context: honey

  - name: prod
    physical_cluster: honey
    context: honey

Change Domains Without Changing Cluster Auth

If you need separate ingress domains but the same cluster auth, change only the domain fields:

clusters:
  - name: dev
    domain: dev.example.com
  - name: prod
    domain: runners.example.com

Move Durable State Explicitly

Record node-role intent in the nodes block when you need docs and config to carry the same placement assumptions:

nodes:
  bumble:
    role: storage-and-stateful-worker
    tailscale_ip: 100.88.101.107
    placement_bias:
      - durable bulk storage
      - OpenEBS ZFS-backed volumes

Keep GitLab Optional

If you are no longer using GitLab-backed HTTP state or GitLab Agent access, the gitlab block can remain present but empty:

gitlab:
  url: https://gitlab.com
  project_id: ""
  agent_group: ""

Adding A New Logical Environment

Add a new entry under clusters:

clusters:
  - name: stage
    role: staging
    physical_cluster: honey
    domain: stage.example.com
    context: honey
    kubeconfig_path: ~/.kube/kubeconfig-honey.yaml

Then add the matching tfvars files you intend to use:

tofu/stacks/attic/stage.tfvars
tofu/stacks/arc-runners/stage.tfvars
tofu/stacks/runner-dashboard/stage.tfvars

and, if you use backend HCL files, matching backend entries:

config/backends/attic-stage.hcl
config/backends/arc-runners-stage.hcl
config/backends/runner-dashboard-stage.hcl

Generated Dashboard Environment Config

app/scripts/generate-environments.ts reads config/organization.yaml and generates the environment list used by the dashboard:

npx tsx app/scripts/generate-environments.ts

That generation step treats clusters[] as logical environment entries, so it is compatible with dev and prod both pointing to honey.

Notes

  • keep shared cluster identity in config/organization.yaml
  • keep stack-specific sizing, runner-set policy, and per-stack overrides in the stack tfvars
  • the repo now supports generic HTTP backend init at the root, but the final non-legacy backend authority is still an open decision

GloriousFlywheel