diff --git a/infra/ansible/inventory/group_vars/all.yml b/infra/ansible/inventory/group_vars/all.yml index d4e548b..0404baf 100644 --- a/infra/ansible/inventory/group_vars/all.yml +++ b/infra/ansible/inventory/group_vars/all.yml @@ -4,8 +4,10 @@ # cloud-init created this login user (tofu var login_user); it has NOPASSWD sudo. ansible_user: k3s -# The kube-apiserver endpoint the whole stack agrees on: the primary node IP. -# Used for k3s --tls-san / 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]]['ansible_host'] }}" +# The kube-apiserver endpoint the whole stack agrees on: the primary's REAL node IP. +# NOTE: ansible_host is now the pfSense NAT SSH target (192.168.2.102:225x), NOT the node +# IP — so we read the real 192.168.1.x from k3s_node_ip instead. Used for k3s --tls-san / +# 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 diff --git a/infra/ansible/inventory/hosts.ini b/infra/ansible/inventory/hosts.ini index b83691d..8ce4374 100644 --- a/infra/ansible/inventory/hosts.ini +++ b/infra/ansible/inventory/hosts.ini @@ -1,23 +1,26 @@ -# Static inventory — ALIGNED with infra/tofu defaults (Proxmox migration IPs). -# Regenerate from tofu when IPs/names are overridden: -# cd ../tofu && tofu output -raw ansible_inventory > ../ansible/inventory/hosts.ini +# Static inventory — k3s node IPs ALIGNED with infra/tofu defaults (Proxmox migration IPs), +# but the SSH target is the pfSense NAT (see NAT HAND-OFF below) — this file is +# 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_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 -# 192.168.1.50/.51/.52. The PM reaches them over a pfSense NAT that is NOT yet created. -# Once the NAT/port-forward rule exists, the `ansible_host` (and possibly -# `ansible_port`) below may need to be the NAT-forwarded address:port instead of the -# raw node IP — do NOT guess it here. If the control node has direct LAN reachability -# to 192.168.1.0/24, the raw IPs below are correct as-is. +# NAT HAND-OFF (LIVE): the nodes live on the Proxmox LAN at 192.168.1.50/.51/.52, and +# Ansible reaches them over the pfSense NAT at 192.168.2.102, port-forwarded as +# 2250 -> 192.168.1.50:22, 2251 -> 192.168.1.51:22, 2252 -> 192.168.1.52:22. +# Therefore `ansible_host`/`ansible_port` below are the NAT SSH target (192.168.2.102:225x), +# and each node's REAL 192.168.1.x lives in the `k3s_node_ip` var — consumed for the k3s +# --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-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-dev-2 ansible_host=192.168.1.51 -k3s-dev-3 ansible_host=192.168.1.52 +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.2.102 ansible_port=2252 k3s_node_ip=192.168.1.52 [k3s_servers:children] k3s_primary diff --git a/infra/ansible/roles/k3s_server/tasks/main.yml b/infra/ansible/roles/k3s_server/tasks/main.yml index 728518e..d56740e 100644 --- a/infra/ansible/roles/k3s_server/tasks/main.yml +++ b/infra/ansible/roles/k3s_server/tasks/main.yml @@ -9,6 +9,8 @@ dest: "{{ k3s_install_script }}" 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 ansible.builtin.set_fact: k3s_common_args: >- @@ -19,7 +21,7 @@ --disable={{ k3s_disable }} --write-kubeconfig-mode=644 --tls-san={{ k3s_api_host }} - --node-ip={{ ansible_host }} + --node-ip={{ k3s_node_ip }} # --- primary: found the cluster -------------------------------------------- - name: Install k3s primary (cluster-init, embedded etcd) diff --git a/infra/devcontainer/dev.sh b/infra/devcontainer/dev.sh index b63c7ac..5e63441 100755 --- a/infra/devcontainer/dev.sh +++ b/infra/devcontainer/dev.sh @@ -43,6 +43,7 @@ run() { -v "${REPO_ROOT}:/work" -w /work \ -v "${HOME}/.ssh:/root/.ssh:ro" \ -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 KUBECONFIG="${DEV_KUBECONFIG:-/work/infra/ansible/.cache/dev.kubeconfig}" \ "$IMAGE" "$@"