Files
Andy Molenda 8821fad205 docs(ceph): realign with partition/region model and CI/CD, retire ADRs
* docs(ceph): inline ADR rationale and drop the ADR set

Fold each linked ADR's rationale into the prose it supported, then remove
the ADR files, the README index row, and the stray code-comment reference --
no ADR trace remains.

True up the docs to the partition/region/ceph-cluster layout (#222) in the
same pass: state keys (yucca/<partition>/<region>/<stack>), inventory paths
(<partition>-<region>/<cluster>), stack dirs, and the recover runbook's S3
state paths. Reframe architecture's env section around partitions/regions
with sietch as staging/austin.

* docs(ceph): editorial pass to align docs with current code and CI/CD

Rewrite the ceph docs against the actual code rather than the pre-refactor
state:

- partition/region/ceph-cluster layout throughout: state keys
  yucca/<partition>/<region>/<stack>, inventories <partition>-<region>/<cluster>,
  the real clusters.auto.tfvars schema (partition/region, not environment/datacenter)
- sietch reframed as staging/austin with secrets in yucca_tf_staging; vault
  hierarchy flipped from dev-primary to staging-primary
- live CI/CD (.github/workflows/infra.yml): per-partition read/write service
  accounts delivered as GitHub secrets (OP_TF_YUCCA_<ENV>_ENV[_WRITE]),
  plan/apply gating, NetBird overlay (Tailscale retired)
- correct the CEPH_ENV guidance (export works; deliberately kept out of mise
  [env]) across README, CONTRIBUTING, scripts.md, adding-a-cluster
- drop the obsolete "read SA token from a 1P item" dance from the runbooks
- fix stale vaults, paths, examples, and the inventory-provision.ini name

* docs(ceph): transliterate docs to plain ASCII

Replace non-ASCII punctuation and box-drawing with ASCII equivalents across
the ceph docs: em/en dashes to --/-, middot separators to commas, arrows to
->, directory-tree box-drawing to |-- / `--, section sign to "section", x for
the multiply glyph, and >= / <= / ~ for the math glyphs. No content changes.

* docs(ceph): fix broken rotate-ssh-key link in scripts.md

The "Related" link pointed at runbooks/rotate-ssh-key.md, which does not
exist (a pre-existing dangling link). SSH-key rotation lives in
rotate-secrets.md; point at its "Rotating SSH keys" section.

* docs(ceph): style polish from per-doc review

Tighten verbal texture flagged by a per-doc style pass; no structural changes.

- correctness: ansible-play.sh runs ansible-playbook, it does not exec, so the
  trap fires from the still-alive wrapper -- fix the "exec"/SIGKILL claims in
  scripts.md, architecture.md, secrets.md
- cut recurring tics: "DR belt"/"belt-and-suspenders" -> "disaster recovery",
  "a lost laptop is a non-event", "by design", "system mesh"
- unstuff long dash/semicolon sentences in architecture (vault-password
  history, provision/baseline split), secrets (SSH-key paragraph), patterns
- recover-bad-tofu-apply: move the dormant-1P-items aside into one note,
  consolidate the repeated caveats
- misc: naming grammar fix + drop trivia, hardware "would"/"blindly",
  rotate-secrets "after confidence", drop a dead snippet line, fix the 16+
  numeric hedge

* docs(ceph): make add-node and recover runbooks CI-aware

Now that infra.yml applies the stacks and runs the full ceph convergence on
merge, refresh the two runbooks the pipeline changed:

- add-node: lead with the manual-vs-CI split. The TF + host_vars change is a
  PR; the only operator-only step is the physical provisioning (live-image
  boot + provision.yml), which CI can't do; baseline/tune/join/harden run in
  CI on merge. Keep the by-hand convergence as a documented fallback.
- recover-bad-tofu-apply: note that applies now run in CI with the partition
  write SA, so the bad apply is usually a failed CI run; CI does not self-heal,
  recovery is operator-run locally.

* docs(tf,talos): finish ADR purge into tf, fix sietch vault, mark talos dormant

- complete the ADR removal that stopped at ansible/ceph: drop the dangling
  ADR-009/010 references from tf/README.md (link + related line) and the ceph
  module / stack code comments, so no ADR trace remains repo-wide
- tf/README: the sietch cluster example uses yucca_tf_staging (was yucca_tf_dev)
- ansible/talos: add a "second-class, not actively used" status banner to the
  README and architecture doc so readers don't treat the converged/libvirt
  Talos docs as live

Left untouched: the Tailscale / SA-token / CI sections of tf/README -- those
are mid-migration in another owner's lane (bye-tailscale is in flight; fabric
still rides Tailscale by design).
2026-06-29 13:04:15 -07:00

3.9 KiB

Adding a role

How to create a new Ansible role in this project. The heavy lifting is in the existing roles -- this doc is the skeleton + wiring + pre-submit checklist; copy an exemplar for idioms.

For code-level patterns (idempotency, changed_when, handlers, secrets handling, shell conventions), see patterns.md. For how roles compose into the overall pipeline, see architecture.md section 6.

Skeleton

roles/<role_name>/
|-- defaults/main.yml     required -- every variable with a default + comment
|-- meta/main.yml         required -- author, license, Ansible version
|-- tasks/main.yml        required -- imports sub-task files, tagged
|-- handlers/main.yml     if the role restarts/reloads services
|-- templates/*.j2        Jinja2 templates
`-- molecule/default/     optional -- test scenario

Role names use snake_case (ceph_deploy, os_tuning).

Cluster-level variables use the ceph_ prefix (overridable in group_vars/all/vars.yml). Role-internal variables use the <role_name>_ prefix. The .ansible-lint config skips var-naming[no-role-prefix] because all roles share the ceph_ prefix for cluster-level settings -- this is intentional.

Exemplars to copy from

Copy this when you're writing... Role
A phased deployment with tags ceph_deploy
Modular sub-task files with header comments baseline
Kernel/sysctl values with units documented os_tuning
Per-device-class settings + feature toggles hardware_tuning
Templated firewall config with opt-in features security
Ceph CLI shell tasks with changed_when patterns ceph_tuning

Every existing role has a header comment block at the top of defaults/main.yml explaining its scope -- open one and mirror the shape.

Wiring into the pipeline

1. Playbook wrapper

Create a top-level playbook (e.g. my-feature.yml) that imports the role:

---
# Brief description + usage tags.
- name: My feature
  hosts: ceph_nodes
  become: true
  roles:
    - my_role_name

2. site.yml (if part of full deploy)

Insert in the correct dependency position in site.yml:

- import_playbook: my-feature.yml

Order matters -- see architecture.md section 6 "Why this order matters".

3. mise run deploy (if part of full deploy)

Add to the deploy task in yucca-root .mise/config.toml (or ansible/ceph/.mise.toml if the task lives there). Always invoke via the wrapper so secrets resolve:

echo "=== My feature ===" && scripts/ansible-play.sh my-feature.yml

4. Optional: standalone mise task

For playbooks useful to run independently (like bench, drift, status):

[tasks.my-feature]
description = "One-line description"
run = "scripts/ansible-play.sh my-feature.yml"

See scripts.md for the wrapper reference.

Molecule test (optional)

Not every role needs one -- the ceph_deploy role is the only one with a full scenario today. If you're writing something non-trivial, copy roles/ceph_deploy/molecule/default/ as a starting point.

Pre-submit checklist

Before opening a PR, verify:

  • mise run lint passes clean (yamllint + ansible-lint + shellcheck)
  • mise run check passes syntax-check with the role's playbook
  • Every variable in defaults/main.yml has a comment explaining what it does
  • All modules use FQCN (ansible.builtin.apt, not apt)
  • All shell/command tasks have changed_when
  • All shell tasks set args.executable: /bin/bash and include set -o pipefail
  • Secret-handling tasks have no_log: true
  • meta/main.yml has author, license, description, min_ansible_version: "2.19"
  • Tags on import_tasks in main.yml
  • Playbook wrapper exists at ansible/ceph/ root
  • Role is added to site.yml in the correct position (if part of full deploy)
  • Anti-patterns in patterns.md section Anti-patterns not violated