# outputs.tf — surface the facts the Ansible inventory needs (Phase 1 T-1.1). # The primary node is the k3s cluster-init server and the k8sServiceHost the # Cilium bootstrap + Flux HelmRelease must agree on (docs/02 parity contract). output "node_names" { description = "Ordered VM hostnames." value = [for n in local.node_list : n.name] } output "node_ips" { description = "Ordered node static IPs (same order as node_names)." value = [for n in local.node_list : n.ip] } output "nodes" { description = "Per-node map name => ip, for building the Ansible inventory." value = { for n in local.node_list : n.name => n.ip } } output "primary_node_ip" { description = "First server IP — k3s --cluster-init host and Cilium k8sServiceHost (parity value)." value = local.primary.ip } output "k3s_api_endpoint" { description = "kube-apiserver endpoint used for k8sServiceHost/Port parity (docs/02)." value = "${local.primary.ip}:6443" } output "cilium_l2_vip_range" { description = "Reserved ingress VIP range for Cilium L2 announcement (WS-NET consumes in Phase 2)." value = "${var.cilium_l2_vip_range_start}-${var.cilium_l2_vip_range_end}" } # Rendered INI inventory for infra/ansible/. The Ansible dir also ships a static # inventory aligned with these defaults; regenerate it from this output if the # IPs/names are overridden. `tofu output -raw ansible_inventory > ../ansible/inventory/hosts.ini` output "ansible_inventory" { description = "Ready-to-write Ansible INI inventory aligned with tofu outputs." value = <<-EOT # GENERATED from tofu outputs — do not hand-edit; re-render on IP/name change. [k3s_primary] ${local.primary.name} ansible_host=${local.primary.ip} [k3s_secondary] %{for n in slice(local.node_list, 1, length(local.node_list))~} ${n.name} ansible_host=${n.ip} %{endfor~} [k3s_servers:children] k3s_primary k3s_secondary [k3s_servers:vars] ansible_user=${var.login_user} k3s_api_host=${local.primary.ip} EOT }