iac: harden node lifecycle — tofu for_each + self-contained ansible rejoin
Implements T-1.5 findings F1/F2 (author-first, no cluster change). F1 (tofu): refactor libvirt node resources count -> for_each keyed by node name so single-node -replace/destroy cannot cascade to siblings. Add ordered-list/primary helper locals; update outputs.tf off the map; add moved.tf (12 moved blocks). tofu plan proves a pure state-address migration: 0 to add, 0 to change, 0 to destroy (all 12 'has moved to'). State-persist via a 0-change apply is operator-permission-gated. F2 (ansible): k3s_server secondary fetches the join token via delegate_to the primary (published fact as fast path), so a single-node rejoin with --limit k3s-dev-N is self-contained and no longer depends on a fact an earlier play had to set. Syntax-check + CI gate green. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
1 parent
ef33865a53
commit
95e3eafac6
5 files changed
+150
-38
No files matched your search
@@ -47,7 +47,29 @@
|
||||
k3s_node_token: "{{ k3s_token_raw.content | b64decode | trim }}"
|
||||
when: k3s_server_mode == 'primary'
|
||||
|
||||
# --- secondaries: join the existing cluster --------------------------------
|
||||
# --- secondaries: obtain the join token, then join the existing cluster -----
|
||||
# Fetch the token straight from the primary via delegate_to, falling back to it
|
||||
# only when the primary play didn't publish the fact this run. This makes a
|
||||
# single-node rejoin (`--limit k3s-dev-N`, primary NOT in the batch) self-
|
||||
# contained — delegate_to still reaches the primary even when it isn't a play
|
||||
# target, so the join no longer depends on a fact an earlier play had to set.
|
||||
# T-1.5 finding F2 (see DECISIONS-LOG.md).
|
||||
- name: Fetch the k3s node-token directly from the primary (secondary)
|
||||
ansible.builtin.slurp:
|
||||
src: /var/lib/rancher/k3s/server/token
|
||||
delegate_to: "{{ groups['k3s_primary'][0] }}"
|
||||
register: k3s_primary_token_raw
|
||||
when:
|
||||
- k3s_server_mode == 'secondary'
|
||||
- hostvars[groups['k3s_primary'][0]].k3s_node_token is not defined
|
||||
|
||||
- name: Resolve the join token (secondary)
|
||||
ansible.builtin.set_fact:
|
||||
k3s_join_token: >-
|
||||
{{ hostvars[groups['k3s_primary'][0]].k3s_node_token
|
||||
| default(k3s_primary_token_raw.content | b64decode | trim, true) }}
|
||||
when: k3s_server_mode == 'secondary'
|
||||
|
||||
- name: Install k3s secondary (join as server)
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
@@ -56,7 +78,7 @@
|
||||
creates: /etc/rancher/k3s/k3s.yaml
|
||||
environment:
|
||||
INSTALL_K3S_VERSION: "{{ k3s_version }}"
|
||||
K3S_TOKEN: "{{ hostvars[groups['k3s_primary'][0]]['k3s_node_token'] }}"
|
||||
K3S_TOKEN: "{{ k3s_join_token }}"
|
||||
when: k3s_server_mode == 'secondary'
|
||||
|
||||
- name: Wait for the k3s API to be serving locally
|
||||
|
||||
Reference in new issue
Block a user