ansible(proxmox): route Ansible via pfSense NAT; decouple k3s node-ip from ansible_host; mount vault-pass into dev container

- inventory routes SSH via 192.168.2.102:2250/2251/2252; new k3s_node_ip carries
  each node's real 192.168.1.x for --node-ip / k3s_api_host / Cilium parity
- dev.sh bind-mounts ~/.config/home-k3s/ansible-vault-pass (ro) so vaulted
  playbooks can run in the pinned container (ansible.cfg vault_password_file)

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
jakman85andClaude Opus 4.8 committed 2026-08-25 11:55:37 -05:00
1 parent 28d200caf2
commit 1ff25318c9
4 files changed
+25 -17

No files matched your search

+6 -4
View File
@@ -4,8 +4,10 @@
# cloud-init created this login user (tofu var login_user); it has NOPASSWD sudo. # cloud-init created this login user (tofu var login_user); it has NOPASSWD sudo.
ansible_user: k3s ansible_user: k3s
# The kube-apiserver endpoint the whole stack agrees on: the primary node IP. # The kube-apiserver endpoint the whole stack agrees on: the primary's REAL node IP.
# Used for k3s --tls-san / secondary --server AND for Cilium k8sServiceHost so the # NOTE: ansible_host is now the pfSense NAT SSH target (192.168.2.102:225x), NOT the node
# Ansible bootstrap and the Flux HelmRelease stay in PARITY (docs/02 contract). # IP — so we read the real 192.168.1.x from k3s_node_ip instead. Used for k3s --tls-san /
k3s_api_host: "{{ hostvars[groups['k3s_primary'][0]]['ansible_host'] }}" # secondary --server AND for Cilium k8sServiceHost so the Ansible bootstrap and the Flux
# HelmRelease stay in PARITY (docs/02 contract).
k3s_api_host: "{{ hostvars[groups['k3s_primary'][0]]['k3s_node_ip'] }}"
k3s_api_port: 6443 k3s_api_port: 6443
+15 -12
View File
@@ -1,23 +1,26 @@
# Static inventory — ALIGNED with infra/tofu defaults (Proxmox migration IPs). # Static inventory — k3s node IPs ALIGNED with infra/tofu defaults (Proxmox migration IPs),
# Regenerate from tofu when IPs/names are overridden: # but the SSH target is the pfSense NAT (see NAT HAND-OFF below) — this file is
# cd ../tofu && tofu output -raw ansible_inventory > ../ansible/inventory/hosts.ini # HAND-MAINTAINED and must NOT be regenerated from `tofu output -raw ansible_inventory`.
# #
# k3s_primary = the --cluster-init server (embedded-etcd founder + Cilium k8sServiceHost). # k3s_primary = the --cluster-init server (embedded-etcd founder + Cilium k8sServiceHost).
# k3s_secondary = the two servers that join it. All three are servers (HA embedded etcd). # k3s_secondary = the two servers that join it. All three are servers (HA embedded etcd).
# #
# NAT HAND-OFF (PM to finalize): the nodes now live on the Proxmox LAN at # NAT HAND-OFF (LIVE): the nodes live on the Proxmox LAN at 192.168.1.50/.51/.52, and
# 192.168.1.50/.51/.52. The PM reaches them over a pfSense NAT that is NOT yet created. # Ansible reaches them over the pfSense NAT at 192.168.2.102, port-forwarded as
# Once the NAT/port-forward rule exists, the `ansible_host` (and possibly # 2250 -> 192.168.1.50:22, 2251 -> 192.168.1.51:22, 2252 -> 192.168.1.52:22.
# `ansible_port`) below may need to be the NAT-forwarded address:port instead of the # Therefore `ansible_host`/`ansible_port` below are the NAT SSH target (192.168.2.102:225x),
# raw node IP — do NOT guess it here. If the control node has direct LAN reachability # and each node's REAL 192.168.1.x lives in the `k3s_node_ip` var — consumed for the k3s
# to 192.168.1.0/24, the raw IPs below are correct as-is. # --node-ip, the API/tls-san endpoint (k3s_api_host), and general in-cluster parity.
# This file is HAND-MAINTAINED for the NAT: do NOT blindly regenerate it from
# tofu output -raw ansible_inventory
# because tofu has no knowledge of the pfSense NAT and would overwrite the mapping below.
[k3s_primary] [k3s_primary]
k3s-dev-1 ansible_host=192.168.1.50 k3s-dev-1 ansible_host=192.168.2.102 ansible_port=2250 k3s_node_ip=192.168.1.50
[k3s_secondary] [k3s_secondary]
k3s-dev-2 ansible_host=192.168.1.51 k3s-dev-2 ansible_host=192.168.2.102 ansible_port=2251 k3s_node_ip=192.168.1.51
k3s-dev-3 ansible_host=192.168.1.52 k3s-dev-3 ansible_host=192.168.2.102 ansible_port=2252 k3s_node_ip=192.168.1.52
[k3s_servers:children] [k3s_servers:children]
k3s_primary k3s_primary
@@ -9,6 +9,8 @@
dest: "{{ k3s_install_script }}" dest: "{{ k3s_install_script }}"
mode: "0755" mode: "0755"
# --node-ip uses k3s_node_ip (the real 192.168.1.x), NOT ansible_host — the latter is
# now the pfSense NAT SSH target (192.168.2.102:225x) and must not be advertised to k3s.
- name: Compose the common k3s server flags - name: Compose the common k3s server flags
ansible.builtin.set_fact: ansible.builtin.set_fact:
k3s_common_args: >- k3s_common_args: >-
@@ -19,7 +21,7 @@
--disable={{ k3s_disable }} --disable={{ k3s_disable }}
--write-kubeconfig-mode=644 --write-kubeconfig-mode=644
--tls-san={{ k3s_api_host }} --tls-san={{ k3s_api_host }}
--node-ip={{ ansible_host }} --node-ip={{ k3s_node_ip }}
# --- primary: found the cluster -------------------------------------------- # --- primary: found the cluster --------------------------------------------
- name: Install k3s primary (cluster-init, embedded etcd) - name: Install k3s primary (cluster-init, embedded etcd)
+1
View File
@@ -43,6 +43,7 @@ run() {
-v "${REPO_ROOT}:/work" -w /work \ -v "${REPO_ROOT}:/work" -w /work \
-v "${HOME}/.ssh:/root/.ssh:ro" \ -v "${HOME}/.ssh:/root/.ssh:ro" \
-v "${HOME}/.config/sops:/root/.config/sops" \ -v "${HOME}/.config/sops:/root/.config/sops" \
-v "${HOME}/.config/home-k3s/ansible-vault-pass:/root/.config/home-k3s/ansible-vault-pass:ro" \
-e LIBVIRT_DEFAULT_URI=qemu:///system \ -e LIBVIRT_DEFAULT_URI=qemu:///system \
-e KUBECONFIG="${DEV_KUBECONFIG:-/work/infra/ansible/.cache/dev.kubeconfig}" \ -e KUBECONFIG="${DEV_KUBECONFIG:-/work/infra/ansible/.cache/dev.kubeconfig}" \
"$IMAGE" "$@" "$IMAGE" "$@"