diff --git a/README.md b/README.md index ebe6404..13748b2 100644 --- a/README.md +++ b/README.md @@ -177,7 +177,7 @@ Set these in your Gitea repository settings (**Settings** → **Secrets** → ** ## GitOps (Flux) -This repo now includes a Flux GitOps layout for phased migration from imperative Ansible applies to continuous reconciliation. +This repo uses Flux for continuous reconciliation after Terraform + Ansible bootstrap. ### Runtime secrets @@ -217,17 +217,11 @@ Terraform/bootstrap secrets remain in Gitea Actions secrets and are not managed 3. Apply `clusters/prod/flux-system/` once to establish source + reconciliation graph. 4. Bootstrap-only Ansible creates prerequisite secrets; Flux manages addon lifecycle after bootstrap. -### Current migration status +### Current addon status -- `addon-observability-content` is now GitOps-managed from `infrastructure/addons/observability-content/`. -- `addon-observability` is now GitOps-managed from `infrastructure/addons/observability/` using Flux `HelmRelease` resources for: - - `kube-prometheus-stack` - - `loki` - - `promtail` -- Remaining addons stay suspended until migrated. -- During transition, avoid applying Grafana content from both Flux and Ansible at the same time. - -Ansible `site.yml` now skips `observability` and `observability-content` roles by default when `observability_gitops_enabled=true` (default). +- Core infrastructure addons are Flux-managed from `infrastructure/addons/`. +- Active Flux addons include `addon-ccm`, `addon-csi`, `addon-tailscale-operator`, `addon-tailscale-proxyclass`, `addon-external-secrets`, `addon-observability`, and `addon-observability-content`. +- Ansible is limited to cluster bootstrap, private-access setup, and prerequisite secret creation for Flux-managed addons. ## Observability Stack @@ -237,7 +231,7 @@ Flux deploys a lightweight observability stack in the `observability` namespace: - `loki` - `promtail` -Grafana content is managed as code via ConfigMaps in `infrastructure/addons/observability-content/` (Flux), migrated from `ansible/roles/observability-content/`. +Grafana content is managed as code via ConfigMaps in `infrastructure/addons/observability-content/`. Grafana and Prometheus are exposed through a single Tailscale front door backed by Traefik when the Tailscale Kubernetes Operator is healthy. diff --git a/ansible/roles/k3s-agent/defaults/main.yml b/ansible/roles/k3s-agent/defaults/main.yml index 6a2798f..8cc646a 100644 --- a/ansible/roles/k3s-agent/defaults/main.yml +++ b/ansible/roles/k3s-agent/defaults/main.yml @@ -3,3 +3,4 @@ k3s_version: latest k3s_server_url: "" k3s_token: "" k3s_node_ip: "" +k3s_kubelet_cloud_provider_external: true diff --git a/ansible/roles/k3s-agent/tasks/main.yml b/ansible/roles/k3s-agent/tasks/main.yml index fef9f60..492be21 100644 --- a/ansible/roles/k3s-agent/tasks/main.yml +++ b/ansible/roles/k3s-agent/tasks/main.yml @@ -16,7 +16,10 @@ INSTALL_K3S_VERSION: "{{ k3s_version if k3s_version != 'latest' else '' }}" K3S_URL: "{{ k3s_server_url }}" K3S_TOKEN: "{{ k3s_token }}" - command: /tmp/install-k3s.sh agent --node-ip {{ k3s_node_ip }} + command: >- + /tmp/install-k3s.sh agent + --node-ip {{ k3s_node_ip }} + {% if k3s_kubelet_cloud_provider_external | bool %}--kubelet-arg=cloud-provider=external{% endif %} args: creates: /usr/local/bin/k3s-agent when: not k3s_agent_binary.stat.exists diff --git a/ansible/roles/k3s-server/defaults/main.yml b/ansible/roles/k3s-server/defaults/main.yml index b6397b4..c8f4549 100644 --- a/ansible/roles/k3s-server/defaults/main.yml +++ b/ansible/roles/k3s-server/defaults/main.yml @@ -3,3 +3,6 @@ k3s_version: latest k3s_token: "" k3s_node_ip: "" k3s_primary_public_ip: "" +k3s_disable_embedded_ccm: true +k3s_disable_servicelb: true +k3s_kubelet_cloud_provider_external: true diff --git a/ansible/roles/k3s-server/tasks/main.yml b/ansible/roles/k3s-server/tasks/main.yml index eb07174..ddd901e 100644 --- a/ansible/roles/k3s-server/tasks/main.yml +++ b/ansible/roles/k3s-server/tasks/main.yml @@ -61,7 +61,16 @@ environment: INSTALL_K3S_VERSION: "{{ k3s_version if k3s_version != 'latest' else '' }}" K3S_TOKEN: "{{ k3s_token }}" - command: /tmp/install-k3s.sh server --cluster-init --advertise-address={{ k3s_primary_ip }} --node-ip={{ k3s_node_ip }} --tls-san={{ k3s_primary_ip }} --tls-san={{ k3s_primary_public_ip }} + command: >- + /tmp/install-k3s.sh server + --cluster-init + --advertise-address={{ k3s_primary_ip }} + --node-ip={{ k3s_node_ip }} + --tls-san={{ k3s_primary_ip }} + --tls-san={{ k3s_primary_public_ip }} + {% if k3s_disable_embedded_ccm | bool %}--disable-cloud-controller{% endif %} + {% if k3s_disable_servicelb | bool %}--disable=servicelb{% endif %} + {% if k3s_kubelet_cloud_provider_external | bool %}--kubelet-arg=cloud-provider=external{% endif %} when: - k3s_install_needed - k3s_primary | default(false) @@ -75,7 +84,14 @@ environment: INSTALL_K3S_VERSION: "{{ k3s_version if k3s_version != 'latest' else '' }}" K3S_TOKEN: "{{ k3s_token }}" - command: /tmp/install-k3s.sh server --server https://{{ k3s_primary_ip }}:6443 --advertise-address={{ k3s_node_ip }} --node-ip={{ k3s_node_ip }} + command: >- + /tmp/install-k3s.sh server + --server https://{{ k3s_primary_ip }}:6443 + --advertise-address={{ k3s_node_ip }} + --node-ip={{ k3s_node_ip }} + {% if k3s_disable_embedded_ccm | bool %}--disable-cloud-controller{% endif %} + {% if k3s_disable_servicelb | bool %}--disable=servicelb{% endif %} + {% if k3s_kubelet_cloud_provider_external | bool %}--kubelet-arg=cloud-provider=external{% endif %} register: secondary_install rescue: