feat(ansible): SOPS replaces ansible-vault, one secret store in git #380

Merged
kblack0610 merged 1 commit from feat/sops-replaces-ansible-vault into master 2026-10-26 20:22:01 +00:00
Owner

Ansible's secrets move from ansible-vault to SOPS, so the repo has one secret store. rbw stays for passwords a human types.

What changes:

  • group_vars/<group>/vault.yml (4 files) become vault.sops.yaml, loaded by the community.sops vars plugin (ansible.cfg, requirements.yml). Var names are unchanged, so no role reads anything new.
  • .sops.yaml gets a first rule for ansible/*.sops.yaml with two recipients: the main key, and a new Ansible-only key.
  • The runner Secret swaps ansible-vault-pass for sops-age-key, which holds only the Ansible key. It cannot decrypt any Kubernetes Secret.
  • The runner job gets a pinned sops binary from an init container (ghcr.io/getsops/sops:v3.11.0-alpine), since the semaphore image has none.
  • About 25 docs and assert messages now say sops instead of ansible-vault. The four vault.yml.example templates are gone.
  • scripts/check-secret-store.py (in checks) fails on ansible-vault ciphertext, an inline !vault, any ansible-vault instruction, or a *.sops.yaml without a sops: block.

Verification:

  • sha256 of every vault_* var, as Ansible resolves it per host: identical on all 17 inventory hosts before and after.
  • Without the age key, a run stops with "Failed to get the data key" (rc 4).
  • The Ansible-only key decrypts the 4 Ansible files and fails on apps/ansible-runner/secret.yaml.
  • The guard passes on the tree and fails on each of 4 planted files (vault header, inline !vault, an instruction, a plaintext x.sops.yaml).
  • site.yml --check on the 12 hosts reachable without a sudo password: the PLAY RECAP and every changed task are identical before and after. The one failure on both sides is the login-password hash that is not set yet (next PR).
  • kubectl kustomize apps builds.

After merge: a manual runner job proves the init container and key in-cluster, then ~/.ansible-vault-pass is deleted.

https://claude.ai/code/session_012Wd941LKcWttC6KSG3VVVa

Ansible's secrets move from ansible-vault to SOPS, so the repo has one secret store. rbw stays for passwords a human types. What changes: - `group_vars/<group>/vault.yml` (4 files) become `vault.sops.yaml`, loaded by the `community.sops` vars plugin (`ansible.cfg`, `requirements.yml`). Var names are unchanged, so no role reads anything new. - `.sops.yaml` gets a first rule for `ansible/*.sops.yaml` with two recipients: the main key, and a new Ansible-only key. - The runner Secret swaps `ansible-vault-pass` for `sops-age-key`, which holds only the Ansible key. It cannot decrypt any Kubernetes Secret. - The runner job gets a pinned `sops` binary from an init container (`ghcr.io/getsops/sops:v3.11.0-alpine`), since the semaphore image has none. - About 25 docs and assert messages now say `sops` instead of `ansible-vault`. The four `vault.yml.example` templates are gone. - `scripts/check-secret-store.py` (in `checks`) fails on ansible-vault ciphertext, an inline `!vault`, any ansible-vault instruction, or a `*.sops.yaml` without a `sops:` block. Verification: - sha256 of every `vault_*` var, as Ansible resolves it per host: identical on all 17 inventory hosts before and after. - Without the age key, a run stops with "Failed to get the data key" (rc 4). - The Ansible-only key decrypts the 4 Ansible files and fails on `apps/ansible-runner/secret.yaml`. - The guard passes on the tree and fails on each of 4 planted files (vault header, inline `!vault`, an instruction, a plaintext `x.sops.yaml`). - `site.yml --check` on the 12 hosts reachable without a sudo password: the PLAY RECAP and every changed task are identical before and after. The one failure on both sides is the login-password hash that is not set yet (next PR). - `kubectl kustomize apps` builds. After merge: a manual runner job proves the init container and key in-cluster, then `~/.ansible-vault-pass` is deleted. https://claude.ai/code/session_012Wd941LKcWttC6KSG3VVVa
feat(ansible): SOPS replaces ansible-vault, one secret store in git
All checks were successful
checks / fleet-roster (pull_request) Successful in 10s
checks / zomboid-scripts (pull_request) Successful in 11s
checks / kustomize-builds (pull_request) Successful in 11s
4665483def
Ansible's five secrets move from ansible-vault files to
group_vars/<group>/vault.sops.yaml, read by the community.sops vars
plugin, so var names and roles are unchanged. The files are encrypted to
the main age key and to a new Ansible-only key that the in-cluster
runner holds, so the runner cannot open any Kubernetes Secret. The
runner gets a pinned sops binary from an init container.

Every vault_* var resolves to the same value on all 17 inventory hosts
before and after (sha256 per host). scripts/check-secret-store.py fails
CI on ansible-vault ciphertext or instructions, and on any *.sops.yaml
that is not encrypted.

Claude-Session: https://claude.ai/code/session_012Wd941LKcWttC6KSG3VVVa
kblack0610 deleted branch feat/sops-replaces-ansible-vault 2026-10-26 20:22:01 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kblack0610/home-config!380
No description provided.