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]>
59 lines
2.0 KiB
Terraform
59 lines
2.0 KiB
Terraform
# 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
|
|
}
|