Phase 1 (author-only): node provisioning IaC — tofu + cloud-init + Ansible (T-1.1/1.2/1.3)
OpenTofu libvirt module (k3s-dev NAT 10.73.0.0/24, 3x 6GiB/4vCPU VMs, 20G OS +
40G thin data, host-passthrough), cloud-init baseline (k3s/Cilium/Longhorn
prereqs, static net), Ansible k3s-HA + Cilium (kube-proxy replacement, Gateway
API, Hubble; flannel/kube-proxy/Traefik disabled). PM fix: escape ${...} in a
cloud-init template comment (tofu templatefile parse). tofu fmt/init/validate =
Success; ansible --syntax-check + yamllint pass. NOTHING executed (no apply).
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
1 parent
224cd8ac35
commit
f2a7e42068
29 files changed
+1168
-6
No files matched your search
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# cilium role defaults (ADR-0002, docs/02 Cilium-ownership contract).
|
||||
# This role performs the INITIAL Cilium install; the Flux platform/cilium
|
||||
# HelmRelease adopts config afterward. The parity-critical values
|
||||
# (kubeProxyReplacement, k8sServiceHost/Port) are templated from k3s_api_host.
|
||||
|
||||
# Pin inside the platform/cilium HelmRelease window (>=1.16.0 <1.17.0).
|
||||
cilium_version: "1.16.5"
|
||||
cilium_chart_repo_name: "cilium"
|
||||
cilium_chart_repo_url: "https://helm.cilium.io/"
|
||||
cilium_namespace: "kube-system"
|
||||
|
||||
# Gateway API CRDs (standard channel) must exist BEFORE Cilium with gatewayAPI.enabled.
|
||||
# Cilium 1.16 targets Gateway API v1.2.x.
|
||||
gateway_api_version: "v1.2.1"
|
||||
gateway_api_crd_urls:
|
||||
- "https://github.com/kubernetes-sigs/gateway-api/releases/download/{{ gateway_api_version }}/standard-install.yaml"
|
||||
# TLSRoute (experimental) is required by Cilium's Gateway API support.
|
||||
- "https://raw.githubusercontent.com/kubernetes-sigs/gateway-api/{{ gateway_api_version }}/config/crd/experimental/gateway.networking.k8s.io_tlsroutes.yaml"
|
||||
|
||||
# Local kubeconfig fetched from the primary. *.kubeconfig is gitignored.
|
||||
cilium_kubeconfig: "{{ playbook_dir }}/../.cache/dev.kubeconfig"
|
||||
cilium_values_path: "{{ playbook_dir }}/../.cache/cilium-values.yaml"
|
||||
|
||||
# dev: single operator replica to save RAM (PHASE1-SCOPE RAM ceiling). NOT a
|
||||
# parity field — Flux may differ here; only kubeProxyReplacement/k8sServiceHost
|
||||
# /k8sServicePort must match the HelmRelease.
|
||||
cilium_operator_replicas: 1
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
# Install Cilium as the CNI (ADR-0002). Runs from the controller (dev container,
|
||||
# which has kubectl + helm) against a kubeconfig fetched from the primary node.
|
||||
# The cluster is NotReady until this completes — expected (PHASE1-SCOPE risks).
|
||||
# run_once: this whole role acts on the cluster once, not per host.
|
||||
|
||||
- name: Fetch the k3s kubeconfig from the primary
|
||||
ansible.builtin.slurp:
|
||||
src: /etc/rancher/k3s/k3s.yaml
|
||||
register: k3s_kubeconfig_raw
|
||||
delegate_to: "{{ groups['k3s_primary'][0] }}"
|
||||
run_once: true
|
||||
|
||||
- name: Ensure the local cache dir exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ cilium_kubeconfig | dirname }}"
|
||||
state: directory
|
||||
mode: "0700"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
|
||||
- name: Write kubeconfig locally (server rewritten to the primary IP)
|
||||
ansible.builtin.copy:
|
||||
content: >-
|
||||
{{ k3s_kubeconfig_raw.content | b64decode
|
||||
| regex_replace('https://127.0.0.1:6443',
|
||||
'https://' ~ k3s_api_host ~ ':' ~ k3s_api_port) }}
|
||||
dest: "{{ cilium_kubeconfig }}"
|
||||
mode: "0600"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
|
||||
- name: Install Gateway API CRDs (must precede Cilium gatewayAPI.enabled)
|
||||
ansible.builtin.command:
|
||||
cmd: "kubectl apply -f {{ item }}"
|
||||
environment:
|
||||
KUBECONFIG: "{{ cilium_kubeconfig }}"
|
||||
loop: "{{ gateway_api_crd_urls }}"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
changed_when: true
|
||||
|
||||
- name: Add the Cilium Helm repo
|
||||
ansible.builtin.command:
|
||||
cmd: "helm repo add {{ cilium_chart_repo_name }} {{ cilium_chart_repo_url }}"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
register: cilium_repo_add
|
||||
changed_when: "'has been added' in cilium_repo_add.stdout"
|
||||
failed_when:
|
||||
- cilium_repo_add.rc != 0
|
||||
- "'already exists' not in cilium_repo_add.stderr"
|
||||
|
||||
- name: Update Helm repos
|
||||
ansible.builtin.command:
|
||||
cmd: "helm repo update {{ cilium_chart_repo_name }}"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
changed_when: false
|
||||
|
||||
- name: Render the Cilium values file (parity-critical settings from k3s_api_host)
|
||||
ansible.builtin.template:
|
||||
src: cilium-values.yaml.j2
|
||||
dest: "{{ cilium_values_path }}"
|
||||
mode: "0644"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
|
||||
- name: Install/upgrade Cilium via Helm
|
||||
ansible.builtin.command:
|
||||
cmd: >-
|
||||
helm upgrade --install cilium {{ cilium_chart_repo_name }}/cilium
|
||||
--version {{ cilium_version }}
|
||||
--namespace {{ cilium_namespace }}
|
||||
--values {{ cilium_values_path }}
|
||||
--wait --timeout 10m
|
||||
environment:
|
||||
KUBECONFIG: "{{ cilium_kubeconfig }}"
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
changed_when: true
|
||||
@@ -0,0 +1,40 @@
|
||||
# Cilium Helm values — rendered by the Ansible bootstrap (T-1.3).
|
||||
# PARITY CONTRACT (docs/02): the fields marked [parity] MUST equal the
|
||||
# platform/cilium HelmRelease values, or Flux and the bootstrap fight over the CNI.
|
||||
---
|
||||
# [parity] k3s kube-proxy is disabled → Cilium replaces it (ADR-0001/0002).
|
||||
kubeProxyReplacement: true
|
||||
# [parity] = the k3s API endpoint (primary node IP). The Flux HelmRelease's
|
||||
# k8sServiceHost "REPLACE-ME" must be set to this same value.
|
||||
k8sServiceHost: "{{ k3s_api_host }}"
|
||||
k8sServicePort: {{ k3s_api_port }}
|
||||
|
||||
# Ingress via Gateway API — no Traefik (docs/09, ADR-0002).
|
||||
gatewayAPI:
|
||||
enabled: true
|
||||
|
||||
# Egress-class steering (ADR-0002; VPN model ADR-0013, Phase 2/3).
|
||||
egressGateway:
|
||||
enabled: true
|
||||
|
||||
# Flow observability / isolation audit (ADR-0002).
|
||||
hubble:
|
||||
enabled: true
|
||||
relay:
|
||||
enabled: true
|
||||
ui:
|
||||
enabled: true
|
||||
|
||||
# Ingress VIP announcement on the NAT LAN. IP pool / CiliumL2AnnouncementPolicy
|
||||
# (from the reserved 10.73.0.240-.250 range) is authored by WS-NET in Phase 2.
|
||||
l2announcements:
|
||||
enabled: true
|
||||
|
||||
# k3s ships its own cgroup mount; point Cilium at it instead of auto-mounting.
|
||||
cgroup:
|
||||
autoMount:
|
||||
enabled: false
|
||||
hostRoot: /run/cilium/cgroupv2
|
||||
|
||||
operator:
|
||||
replicas: {{ cilium_operator_replicas }}
|
||||
Reference in new issue
Block a user